1 /******************************************************************************
2  * File:   ogrdxf_polyline_smooth.h
3  *
4  * Project:  Interpolation support for smooth POLYLINE and LWPOLYLINE entities.
5  * Purpose:  Definition of classes for OGR .dxf driver.
6  * Author:   TJ Snider, timsn@thtree.com
7  *           Ray Gardener, Daylon Graphics Ltd.
8  *
9  ******************************************************************************
10  * Copyright (c) 2010 Daylon Graphics Ltd.
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included
20  * in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  ****************************************************************************/
30 
31 #ifndef OGRDXF_SMOOTH_POLYLINE_H_INCLUDED
32 #define OGRDXF_SMOOTH_POLYLINE_H_INCLUDED
33 
34 #include "ogrsf_frmts.h"
35 #include "cpl_conv.h"
36 #include <vector>
37 #include "assert.h"
38 
39 class DXFSmoothPolylineVertex
40 {
41 public:
42     double x;
43     double y;
44     double z;
45     double bulge;
46 
DXFSmoothPolylineVertex()47     DXFSmoothPolylineVertex()
48         {
49             x = y = z = bulge = 0.0;
50         }
51 
DXFSmoothPolylineVertex(double dfX,double dfY,double dfZ,double dfBulge)52     DXFSmoothPolylineVertex( double dfX, double dfY, double dfZ,
53                              double dfBulge )
54         {
55             set(dfX, dfY, dfZ, dfBulge);
56         }
57 
set(double dfX,double dfY,double dfZ,double dfBulge)58     void set( double dfX, double dfY, double dfZ, double dfBulge )
59         {
60             x = dfX;
61             y = dfY;
62             z = dfZ;
63             bulge = dfBulge;
64         }
65 
scale(double s)66     void scale(double s)
67         {
68             x *= s;
69             y *= s;
70         }
71 
length()72     double length() const
73         {
74             return (sqrt(x*x + y*y));
75         }
76 
normalize()77     void normalize()
78         {
79             const double len = length();
80             assert(len != 0.0);
81 
82             x /= len;
83             y /= len;
84         }
85 
shares_2D_pos(const DXFSmoothPolylineVertex & v)86     bool shares_2D_pos(const DXFSmoothPolylineVertex& v) const
87         {
88             return (x == v.x && y == v.y);
89         }
90 };
91 
92 class DXFSmoothPolyline
93 {
94     // A DXF polyline that includes vertex bulge information.
95     // Call Tessellate() to convert to an OGRGeometry.
96     // We treat Z as constant over the entire string; this may
97     // change in the future.
98 
99 private:
100     std::vector<DXFSmoothPolylineVertex> m_vertices;
101     mutable bool                         m_blinestringstarted;
102     bool                                 m_bClosed;
103     int                                  m_dim;
104     bool                                 m_bUseMaxGapWhenTessellatingArcs;
105 
106 public:
DXFSmoothPolyline()107     DXFSmoothPolyline() : m_blinestringstarted(false), m_bClosed(false),
108                           m_dim(2), m_bUseMaxGapWhenTessellatingArcs(false) { }
109 
110     OGRGeometry* Tessellate() const;
111 
size()112     size_t size() const { return m_vertices.size(); }
113 
SetSize(int n)114     void SetSize( int n ) { m_vertices.reserve(n); }
115 
AddPoint(double dfX,double dfY,double dfZ,double dfBulge)116     void AddPoint(double dfX, double dfY, double dfZ, double dfBulge)
117         {
118             m_vertices.push_back(DXFSmoothPolylineVertex(dfX, dfY, dfZ, dfBulge));
119         }
120 
121     void Close();
122 
IsEmpty()123     bool IsEmpty() const { return m_vertices.empty(); }
124 
setCoordinateDimension(int n)125     void setCoordinateDimension( int n ) { m_dim = n; }
126 
SetUseMaxGapWhenTessellatingArcs(bool bVal)127     void SetUseMaxGapWhenTessellatingArcs( bool bVal )
128     { m_bUseMaxGapWhenTessellatingArcs = bVal; }
129 
130 private:
131     void EmitArc(const DXFSmoothPolylineVertex&, const DXFSmoothPolylineVertex&,
132                  double radius, double len, double saggita,
133                  OGRLineString*, double dfZ = 0.0) const;
134 
135     void EmitLine(const DXFSmoothPolylineVertex&, const DXFSmoothPolylineVertex&,
136                   OGRLineString*) const;
137 };
138 
139 #endif  /* OGRDXF_SMOOTH_POLYLINE_H_INCLUDED */
140