1 /******************************************************************************
2 **  libDXFrw - Library to read/write DXF files (ascii & binary)              **
3 **                                                                           **
4 **  Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com               **
5 **                                                                           **
6 **  This library is free software, licensed under the terms of the GNU       **
7 **  General Public License as published by the Free Software Foundation,     **
8 **  either version 2 of the License, or (at your option) any later version.  **
9 **  You should have received a copy of the GNU General Public License        **
10 **  along with this program.  If not, see <http://www.gnu.org/licenses/>.    **
11 ******************************************************************************/
12 
13 #ifndef DRW_BASE_H
14 #define DRW_BASE_H
15 
16 #define DRW_VERSION "0.6.3"
17 
18 #include <string>
19 #include <list>
20 #include <cmath>
21 
22 #ifdef DRW_ASSERTS
23 # define drw_assert(a) assert(a)
24 #else
25 # define drw_assert(a)
26 #endif
27 
28 #define UTF8STRING std::string
29 #define DRW_UNUSED(x) (void)x
30 
31 #if defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
32 #  define DRW_WIN
33 #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
34 #    define DRW_WIN
35 #elif defined(__MWERKS__) && defined(__INTEL__)
36 #  define DRW_WIN
37 #else
38 #  define DRW_POSIX
39 #endif
40 
41 #ifndef M_PI
42  #define M_PI       3.141592653589793238462643
43 #endif
44 #ifndef M_PI_2
45  #define M_PI_2       1.57079632679489661923
46 #endif
47 #define M_PIx2      6.283185307179586 // 2*PI
48 #define ARAD 57.29577951308232
49 
50 typedef signed char dint8;              /* 8 bit signed */
51 typedef signed short dint16;            /* 16 bit signed */
52 typedef signed int dint32;              /* 32 bit signed */
53 typedef long long int dint64;           /* 64 bit signed */
54 
55 typedef unsigned char duint8;           /* 8 bit unsigned */
56 typedef unsigned short duint16;         /* 16 bit unsigned */
57 typedef unsigned int duint32;           /* 32 bit unsigned */
58 typedef unsigned long long int duint64; /* 64 bit unsigned */
59 
60 typedef float dfloat32;                 /* 32 bit floating point */
61 typedef double ddouble64;               /* 64 bit floating point */
62 typedef long double ddouble80;          /* 80 bit floating point */
63 
64 
65 namespace DRW {
66 
67 //! Version numbers for the DXF Format.
68 enum Version {
69     UNKNOWNV,     /*!< UNKNOWN VERSION. */
70     AC1006,       /*!< R10. */
71     AC1009,       /*!< R11 & R12. */
72     AC1012,       /*!< R13. */
73     AC1014,       /*!< R14. */
74     AC1015,       /*!< ACAD 2000. */
75     AC1018,       /*!< ACAD 2004. */
76     AC1021,       /*!< ACAD 2007. */
77     AC1024,       /*!< ACAD 2010. */
78     AC1027        /*!< ACAD 2013. */
79 };
80 
81 enum error {
82 BAD_NONE,             /*!< No error. */
83 BAD_UNKNOWN,          /*!< UNKNOWN. */
84 BAD_OPEN,             /*!< error opening file. */
85 BAD_VERSION,          /*!< unsupported version. */
86 BAD_READ_METADATA,    /*!< error reading metadata. */
87 BAD_READ_FILE_HEADER, /*!< error in file header read process. */
88 BAD_READ_HEADER,      /*!< error in header vars read process. */
89 BAD_READ_HANDLES,     /*!< error in object map read process. */
90 BAD_READ_CLASSES,     /*!< error in classes read process. */
91 BAD_READ_TABLES,      /*!< error in tables read process. */
92 BAD_READ_BLOCKS,      /*!< error in block read process. */
93 BAD_READ_ENTITIES,    /*!< error in entities read process. */
94 BAD_READ_OBJECTS      /*!< error in objects read process. */
95 };
96 
97 enum DBG_LEVEL {
98     NONE,
99     DEBUG
100 };
101 
102 //! Special codes for colors
103 enum ColorCodes {
104     ColorByLayer = 256,
105     ColorByBlock = 0
106 };
107 
108 //! Spaces
109 enum Space {
110     ModelSpace = 0,
111     PaperSpace = 1
112 };
113 
114 //! Special kinds of handles
115 enum HandleCodes {
116     NoHandle = 0
117 };
118 
119 //! Shadow mode
120 enum ShadowMode {
121     CastAndReceieveShadows = 0,
122     CastShadows = 1,
123     ReceiveShadows = 2,
124     IgnoreShadows = 3
125 };
126 
127 //! Special kinds of materials
128 enum MaterialCodes {
129     MaterialByLayer = 0
130 };
131 
132 //! Special kinds of plot styles
133 enum PlotStyleCodes {
134     DefaultPlotStyle = 0
135 };
136 
137 //! Special kinds of transparencies
138 enum TransparencyCodes {
139     Opaque = 0,
140     Transparent = -1
141 };
142 
143 } // namespace DRW
144 
145 //! Class to handle 3D coordinate point
146 /*!
147 *  Class to handle 3D coordinate point
148 *  @author Rallaz
149 */
150 class DRW_Coord {
151 public:
DRW_Coord()152     DRW_Coord():x(0), y(0),z(0) {}
DRW_Coord(double ix,double iy,double iz)153     DRW_Coord(double ix, double iy, double iz): x(ix), y(iy),z(iz){}
154 
155 /*!< convert to unitary vector */
unitize()156     void unitize(){
157         double dist;
158 		dist = hypot(hypot(x, y), z);
159         if (dist > 0.0) {
160             x= x/dist;
161             y= y/dist;
162             z= z/dist;
163         }
164     }
165 
166 public:
167     double x;
168     double y;
169     double z;
170 };
171 
172 
173 //! Class to handle vertex
174 /*!
175 *  Class to handle vertex for lwpolyline entity
176 *  @author Rallaz
177 */
178 class DRW_Vertex2D {
179 public:
DRW_Vertex2D()180     DRW_Vertex2D(): x(0), y(0), stawidth(0), endwidth(0), bulge(0){}
181 
DRW_Vertex2D(double sx,double sy,double b)182     DRW_Vertex2D(double sx, double sy, double b): x(sx), y(sy), stawidth(0), endwidth(0), bulge(b) {}
183 
184 public:
185     double x;                 /*!< x coordinate, code 10 */
186     double y;                 /*!< y coordinate, code 20 */
187     double stawidth;          /*!< Start width, code 40 */
188     double endwidth;          /*!< End width, code 41 */
189     double bulge;             /*!< bulge, code 42 */
190 };
191 
192 
193 //! Class to handle header vars
194 /*!
195 *  Class to handle header vars
196 *  @author Rallaz
197 */
198 class DRW_Variant {
199 public:
200     enum TYPE {
201         STRING,
202         INTEGER,
203         DOUBLE,
204         COORD,
205         INVALID
206     };
207 //TODO: add INT64 support
DRW_Variant()208     DRW_Variant(): sdata(std::string()), vdata(), content(0), vType(INVALID), vCode(0) {}
209 
DRW_Variant(int c,dint32 i)210     DRW_Variant(int c, dint32 i): sdata(std::string()), vdata(), content(i), vType(INTEGER), vCode(c){}
211 
DRW_Variant(int c,duint32 i)212     DRW_Variant(int c, duint32 i): sdata(std::string()), vdata(), content(static_cast<dint32>(i)), vType(INTEGER), vCode(c) {}
213 
DRW_Variant(int c,double d)214     DRW_Variant(int c, double d): sdata(std::string()), vdata(), content(d), vType(DOUBLE), vCode(c) {}
215 
DRW_Variant(int c,UTF8STRING s)216     DRW_Variant(int c, UTF8STRING s): sdata(s), vdata(), content(&sdata), vType(STRING), vCode(c) {}
217 
DRW_Variant(int c,DRW_Coord crd)218     DRW_Variant(int c, DRW_Coord crd): sdata(std::string()), vdata(crd), content(&vdata), vType(COORD), vCode(c) {}
219 
DRW_Variant(const DRW_Variant & d)220     DRW_Variant(const DRW_Variant& d): sdata(d.sdata), vdata(d.vdata), content(d.content), vType(d.vType), vCode(d.vCode) {
221         if (d.vType == COORD)
222             content.v = &vdata;
223         if (d.vType == STRING)
224             content.s = &sdata;
225     }
226 
~DRW_Variant()227     ~DRW_Variant() {
228     }
229 
addString(int c,UTF8STRING s)230     void addString(int c, UTF8STRING s) {vType = STRING; sdata = s; content.s = &sdata; vCode=c;}
addInt(int c,int i)231     void addInt(int c, int i) {vType = INTEGER; content.i = i; vCode=c;}
addDouble(int c,double d)232     void addDouble(int c, double d) {vType = DOUBLE; content.d = d; vCode=c;}
addCoord(int c,DRW_Coord v)233     void addCoord(int c, DRW_Coord v) {vType = COORD; vdata = v; content.v = &vdata; vCode=c;}
setCoordX(double d)234     void setCoordX(double d) { if (vType == COORD) vdata.x = d;}
setCoordY(double d)235     void setCoordY(double d) { if (vType == COORD) vdata.y = d;}
setCoordZ(double d)236     void setCoordZ(double d) { if (vType == COORD) vdata.z = d;}
type()237     enum TYPE type() { return vType;}
code()238     int code() { return vCode;}            /*!< returns dxf code of this value*/
239 
240 private:
241     std::string sdata;
242     DRW_Coord vdata;
243 
244 private:
245     union DRW_VarContent{
246         UTF8STRING *s;
247         dint32 i;
248         double d;
249         DRW_Coord *v;
250 
DRW_VarContent(UTF8STRING * sd)251         DRW_VarContent(UTF8STRING *sd):s(sd){}
DRW_VarContent(dint32 id)252         DRW_VarContent(dint32 id):i(id){}
DRW_VarContent(double dd)253         DRW_VarContent(double dd):d(dd){}
DRW_VarContent(DRW_Coord * vd)254         DRW_VarContent(DRW_Coord *vd):v(vd){}
255     };
256 
257 public:
258     DRW_VarContent content;
259 private:
260     enum TYPE vType;
261     int vCode;            /*!< dxf code of this value*/
262 
263 };
264 
265 //! Class to handle dwg handles
266 /*!
267 *  Class to handle dwg handles
268 *  @author Rallaz
269 */
270 class dwgHandle{
271 public:
dwgHandle()272     dwgHandle(){
273         code=0;
274         size=0;
275         ref=0;
276     }
~dwgHandle()277     ~dwgHandle(){}
278     duint8 code;
279     duint8 size;
280     duint32 ref;
281 };
282 
283 //! Class to convert between line width and integer
284 /*!
285 *  Class to convert between line width and integer
286 *  verifying valid values, if value is not valid
287 *  returns widthDefault.
288 *  @author Rallaz
289 */
290 class DRW_LW_Conv{
291 public:
292     enum lineWidth {
293         width00 = 0,       /*!< 0.00mm (dxf 0)*/
294         width01 = 1,       /*!< 0.05mm (dxf 5)*/
295         width02 = 2,       /*!< 0.09mm (dxf 9)*/
296         width03 = 3,       /*!< 0.13mm (dxf 13)*/
297         width04 = 4,       /*!< 0.15mm (dxf 15)*/
298         width05 = 5,       /*!< 0.18mm (dxf 18)*/
299         width06 = 6,       /*!< 0.20mm (dxf 20)*/
300         width07 = 7,       /*!< 0.25mm (dxf 25)*/
301         width08 = 8,       /*!< 0.30mm (dxf 30)*/
302         width09 = 9,       /*!< 0.35mm (dxf 35)*/
303         width10 = 10,      /*!< 0.40mm (dxf 40)*/
304         width11 = 11,      /*!< 0.50mm (dxf 50)*/
305         width12 = 12,      /*!< 0.53mm (dxf 53)*/
306         width13 = 13,      /*!< 0.60mm (dxf 60)*/
307         width14 = 14,      /*!< 0.70mm (dxf 70)*/
308         width15 = 15,      /*!< 0.80mm (dxf 80)*/
309         width16 = 16,      /*!< 0.90mm (dxf 90)*/
310         width17 = 17,      /*!< 1.00mm (dxf 100)*/
311         width18 = 18,      /*!< 1.06mm (dxf 106)*/
312         width19 = 19,      /*!< 1.20mm (dxf 120)*/
313         width20 = 20,      /*!< 1.40mm (dxf 140)*/
314         width21 = 21,      /*!< 1.58mm (dxf 158)*/
315         width22 = 22,      /*!< 2.00mm (dxf 200)*/
316         width23 = 23,      /*!< 2.11mm (dxf 211)*/
317         widthByLayer = 29, /*!< by layer (dxf -1) */
318         widthByBlock = 30, /*!< by block (dxf -2) */
319         widthDefault = 31  /*!< by default (dxf -3) */
320     };
321 
lineWidth2dxfInt(enum lineWidth lw)322     static int lineWidth2dxfInt(enum lineWidth lw){
323         switch (lw){
324         case widthByLayer:
325             return -1;
326         case widthByBlock:
327             return -2;
328         case widthDefault:
329             return -3;
330         case width00:
331             return 0;
332         case width01:
333             return 5;
334         case width02:
335             return 9;
336         case width03:
337             return 13;
338         case width04:
339             return 15;
340         case width05:
341             return 18;
342         case width06:
343             return 20;
344         case width07:
345             return 25;
346         case width08:
347             return 30;
348         case width09:
349             return 35;
350         case width10:
351             return 40;
352         case width11:
353             return 50;
354         case width12:
355             return 53;
356         case width13:
357             return 60;
358         case width14:
359             return 70;
360         case width15:
361             return 80;
362         case width16:
363             return 90;
364         case width17:
365             return 100;
366         case width18:
367             return 106;
368         case width19:
369             return 120;
370         case width20:
371             return 140;
372         case width21:
373             return 158;
374         case width22:
375             return 200;
376         case width23:
377             return 211;
378         default:
379             break;
380         }
381         return -3;
382     }
383 
lineWidth2dwgInt(enum lineWidth lw)384     static int lineWidth2dwgInt(enum lineWidth lw){
385         return static_cast<int> (lw);
386     }
387 
dxfInt2lineWidth(int i)388     static enum lineWidth dxfInt2lineWidth(int i){
389         if (i<0) {
390             if (i==-1)
391                 return widthByLayer;
392             else if (i==-2)
393                 return widthByBlock;
394             else if (i==-3)
395                 return widthDefault;
396         } else if (i<3) {
397             return width00;
398         } else if (i<7) {
399             return width01;
400         } else if (i<11) {
401             return width02;
402         } else if (i<14) {
403             return width03;
404         } else if (i<16) {
405             return width04;
406         } else if (i<19) {
407             return width05;
408         } else if (i<22) {
409             return width06;
410         } else if (i<27) {
411             return width07;
412         } else if (i<32) {
413             return width08;
414         } else if (i<37) {
415             return width09;
416         } else if (i<45) {
417             return width10;
418         } else if (i<52) {
419             return width11;
420         } else if (i<57) {
421             return width12;
422         } else if (i<65) {
423             return width13;
424         } else if (i<75) {
425             return width14;
426         } else if (i<85) {
427             return width15;
428         } else if (i<95) {
429             return width16;
430         } else if (i<103) {
431             return width17;
432         } else if (i<112) {
433             return width18;
434         } else if (i<130) {
435             return width19;
436         } else if (i<149) {
437             return width20;
438         } else if (i<180) {
439             return width21;
440         } else if (i<205) {
441             return width22;
442         } else {
443             return width23;
444         }
445         //default by default
446         return widthDefault;
447     }
448 
dwgInt2lineWidth(int i)449     static enum lineWidth dwgInt2lineWidth(int i){
450         if ( (i>-1 && i<24) || (i>28 && i<32) ) {
451             return static_cast<lineWidth> (i);
452         }
453         //default by default
454         return widthDefault;
455     }
456 };
457 
458 #endif
459 
460 // EOF
461 
462