1 /**********************************************************
2 * Version $Id: dl_dxf.cpp 911 2011-02-14 16:38:15Z reklov_w $
3 *********************************************************/
4 /****************************************************************************
5 ** $Id: dl_dxf.cpp 911 2011-02-14 16:38:15Z reklov_w $
6 **
7 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
8 **
9 ** This file is part of the dxflib project.
10 **
11 ** This file may be distributed and/or modified under the terms of the
12 ** GNU General Public License version 2 as published by the Free Software
13 ** Foundation and appearing in the file LICENSE.GPL included in the
14 ** packaging of this file.
15 **
16 ** Licensees holding valid dxflib Professional Edition licenses may use
17 ** this file in accordance with the dxflib Commercial License
18 ** Agreement provided with the Software.
19 **
20 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
21 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 **
23 ** See http://www.ribbonsoft.com for further details.
24 **
25 ** Contact info@ribbonsoft.com if any conditions of this licensing are
26 ** not clear to you.
27 **
28 **********************************************************************/
29
30 #include "dl_dxf.h"
31
32 #include <algorithm>
33 #include <string>
34 #include <cstdio>
35 #include <cassert>
36 #include <cmath>
37
38 #include "dl_attributes.h"
39 #include "dl_codes.h"
40 #include "dl_creationinterface.h"
41 #include "dl_writer_ascii.h"
42
43
44 /**
45 * Default constructor.
46 */
DL_Dxf()47 DL_Dxf::DL_Dxf() {
48 styleHandleStd = 0;
49 version = VER_2000;
50
51 vertices = NULL;
52 maxVertices = 0;
53 vertexIndex = 0;
54
55 knots = NULL;
56 maxKnots = 0;
57 knotIndex = 0;
58
59 controlPoints = NULL;
60 maxControlPoints = 0;
61 controlPointIndex = 0;
62
63 leaderVertices = NULL;
64 maxLeaderVertices = 0;
65 leaderVertexIndex = 0;
66
67 hatchLoops = NULL;
68 maxHatchLoops = 0;
69 hatchLoopIndex = -1;
70 hatchEdges = NULL;
71 maxHatchEdges = NULL;
72 hatchEdgeIndex = NULL;
73 dropEdges = false;
74 }
75
76
77
78 /**
79 * Destructor.
80 */
~DL_Dxf()81 DL_Dxf::~DL_Dxf() {
82 if (vertices!=NULL) {
83 delete[] vertices;
84 }
85 if (knots!=NULL) {
86 delete[] knots;
87 }
88 if (controlPoints!=NULL) {
89 delete[] controlPoints;
90 }
91 if (leaderVertices!=NULL) {
92 delete[] leaderVertices;
93 }
94 if (hatchLoops!=NULL) {
95 delete[] hatchLoops;
96 }
97 if (hatchEdges!=NULL) {
98 for (int i=0; i<maxHatchLoops; ++i) {
99 if (hatchEdges[i]!=NULL) {
100 delete[] hatchEdges[i];
101 }
102 }
103 delete[] hatchEdges;
104 }
105 if (maxHatchEdges!=NULL) {
106 delete[] maxHatchEdges;
107 }
108 if (hatchEdgeIndex!=NULL) {
109 delete[] hatchEdgeIndex;
110 }
111 }
112
113
114
115 /**
116 * @brief Reads the given file and calls the appropriate functions in
117 * the given creation interface for every entity found in the file.
118 *
119 * @param file Input
120 * Path and name of file to read
121 * @param creationInterface
122 * Pointer to the class which takes care of the entities in the file.
123 *
124 * @retval true If \p file could be opened.
125 * @retval false If \p file could not be opened.
126 */
in(const string & file,DL_CreationInterface * creationInterface)127 bool DL_Dxf::in(const string& file, DL_CreationInterface* creationInterface) {
128 FILE *fp;
129 firstCall = true;
130 currentEntity = DL_UNKNOWN;
131 int errorCounter = 0;
132
133 fp = fopen(file.c_str(), "rt");
134 if (fp) {
135 while (readDxfGroups(fp, creationInterface, &errorCounter)) {}
136 fclose(fp);
137 if (errorCounter>0) {
138 std::cerr << "DXF Filter: There have been " << errorCounter <<
139 " errors. The drawing might be incomplete / incorrect.\n";
140 }
141 return true;
142 }
143
144 return false;
145 }
146
147
148
149 /**
150 * Reads a DXF file from an existing stream.
151 *
152 * @param stream The string stream.
153 * @param creationInterface
154 * Pointer to the class which takes care of the entities in the file.
155 *
156 * @retval true If \p file could be opened.
157 * @retval false If \p file could not be opened.
158 */
159 #ifndef __GCC2x__
in(std::stringstream & stream,DL_CreationInterface * creationInterface)160 bool DL_Dxf::in(std::stringstream& stream,
161 DL_CreationInterface* creationInterface) {
162
163 int errorCounter = 0;
164
165 if (stream.good()) {
166 firstCall=true;
167 currentEntity = DL_UNKNOWN;
168 while (readDxfGroups(stream, creationInterface, &errorCounter)) {}
169 if (errorCounter>0) {
170 std::cerr << "DXF Filter: There have been " << errorCounter <<
171 " errors. The drawing might be incomplete / incorrect.\n";
172 }
173 return true;
174 }
175 return false;
176 }
177 #endif
178
179
180
181 /**
182 * @brief Reads a group couplet from a DXF file. Calls another function
183 * to process it.
184 *
185 * A group couplet consists of two lines that represent a single
186 * piece of data. An integer constant on the first line indicates
187 * the type of data. The value is on the next line.\n
188 *
189 * This function reads a couplet, determines the type of data, and
190 * passes the value to the the appropriate handler function of
191 * \p creationInterface.\n
192 *
193 * \p fp is advanced so that the next call to \p readDXFGroups() reads
194 * the next couplet in the file.
195 *
196 * @param fp Handle of input file
197 * @param creationInterface Handle of class which processes entities
198 * in the file
199 *
200 * @retval true If EOF not reached.
201 * @retval false If EOF reached.
202 */
readDxfGroups(FILE * fp,DL_CreationInterface * creationInterface,int * errorCounter)203 bool DL_Dxf::readDxfGroups(FILE *fp, DL_CreationInterface* creationInterface,
204 int* errorCounter) {
205
206 bool ok = true;
207 static int line = 1;
208
209 // Read one group of the DXF file and chop the lines:
210 if (DL_Dxf::getChoppedLine(groupCodeTmp, DL_DXF_MAXLINE, fp) &&
211 DL_Dxf::getChoppedLine(groupValue, DL_DXF_MAXLINE, fp) ) {
212
213 groupCode = (unsigned int)stringToInt(groupCodeTmp, &ok);
214
215 if (ok) {
216 //std::cerr << groupCode << "\n";
217 //std::cerr << groupValue << "\n";
218 line+=2;
219 processDXFGroup(creationInterface, groupCode, groupValue);
220 } else {
221 std::cerr << "DXF read error: Line: " << line << "\n";
222 if (errorCounter!=NULL) {
223 (*errorCounter)++;
224 }
225 // try to fix:
226 std::cerr << "DXF read error: trying to fix..\n";
227 // drop a line to sync:
228 DL_Dxf::getChoppedLine(groupCodeTmp, DL_DXF_MAXLINE, fp);
229 }
230 }
231
232 return !feof(fp);
233 }
234
235
236
237 /**
238 * Same as above but for stringstreams.
239 */
240 #ifndef __GCC2x__
readDxfGroups(std::stringstream & stream,DL_CreationInterface * creationInterface,int * errorCounter)241 bool DL_Dxf::readDxfGroups(std::stringstream& stream,
242 DL_CreationInterface* creationInterface,
243 int* errorCounter) {
244
245 bool ok = true;
246 static int line = 1;
247
248 // Read one group of the DXF file and chop the lines:
249 if (DL_Dxf::getChoppedLine(groupCodeTmp, DL_DXF_MAXLINE, stream) &&
250 DL_Dxf::getChoppedLine(groupValue, DL_DXF_MAXLINE, stream) ) {
251
252 groupCode = (unsigned int)stringToInt(groupCodeTmp, &ok);
253
254 if (ok) {
255 //std::cout << "group code: " << groupCode << "\n";
256 //std::cout << "group value: " << groupValue << "\n";
257 line+=2;
258 processDXFGroup(creationInterface, groupCode, groupValue);
259 } else {
260 std::cerr << "DXF read error: Line: " << line << "\n";
261 if (errorCounter!=NULL) {
262 (*errorCounter)++;
263 }
264 // try to fix:
265 //std::cerr << "DXF read error: trying to fix..\n";
266 // drop a line to sync:
267 //DL_Dxf::getChoppedLine(groupCodeTmp, DL_DXF_MAXLINE, stream);
268 }
269 }
270 return !stream.eof();
271 }
272 #endif
273
274
275
276 /**
277 * @brief Reads line from file & strips whitespace at start and newline
278 * at end.
279 *
280 * @param s Output\n
281 * Pointer to character array that chopped line will be returned in.
282 * @param size Size of \p s. (Including space for NULL.)
283 * @param fp Input\n
284 * Handle of input file.
285 *
286 * @retval true if line could be read
287 * @retval false if \p fp is already at end of file
288 *
289 * @todo Change function to use safer FreeBSD strl* functions
290 * @todo Is it a problem if line is blank (i.e., newline only)?
291 * Then, when function returns, (s==NULL).
292 */
getChoppedLine(char * s,unsigned int size,FILE * fp)293 bool DL_Dxf::getChoppedLine(char *s, unsigned int size, FILE *fp) {
294 if (!feof(fp)) {
295 // The whole line in the file. Includes space for NULL.
296 char* wholeLine = new char[size];
297 // Only the useful part of the line
298 char* line;
299
300 line = fgets(wholeLine, size, fp);
301
302 if (line!=NULL && line[0] != '\0') { // Evaluates to fgets() retval
303 // line == wholeLine at this point.
304 // Both guaranteed to be NULL terminated.
305
306 // Strip leading whitespace and trailing CR/LF.
307 stripWhiteSpace(&line);
308
309 strncpy(s, line, size);
310 s[size] = '\0';
311 // s should always be NULL terminated, because:
312 assert(size > strlen(line));
313 }
314
315 delete[] wholeLine; // Done with wholeLine
316
317 return true;
318 } else {
319 s[0] = '\0';
320 return false;
321 }
322 }
323
324
325
326 /**
327 * Same as above but for stringstreams.
328 */
329 #ifndef __GCC2x__
getChoppedLine(char * s,unsigned int size,std::stringstream & stream)330 bool DL_Dxf::getChoppedLine(char *s, unsigned int size,
331 std::stringstream& stream) {
332
333 if (!stream.eof()) {
334 // Only the useful part of the line
335 char* line = new char[size+1];
336 char* oriLine = line;
337 stream.getline(line, size);
338 stripWhiteSpace(&line);
339 strncpy(s, line, size);
340 s[size] = '\0';
341 assert(size > strlen(s));
342 delete[] oriLine;
343 return true;
344 } else {
345 s[0] = '\0';
346 return false;
347 }
348 }
349 #endif
350
351
352
353 /**
354 * @brief Strips leading whitespace and trailing Carriage Return (CR)
355 * and Line Feed (LF) from NULL terminated string.
356 *
357 * @param s Input and output.
358 * NULL terminates string.
359 *
360 * @retval true if \p s is non-NULL
361 * @retval false if \p s is NULL
362 */
stripWhiteSpace(char ** s)363 bool DL_Dxf::stripWhiteSpace(char** s) {
364 // last non-NULL char:
365 int lastChar = strlen(*s) - 1;
366
367 // Is last character CR or LF?
368 while ( (lastChar >= 0) &&
369 (((*s)[lastChar] == 10) || ((*s)[lastChar] == 13) ||
370 ((*s)[lastChar] == ' ' || ((*s)[lastChar] == '\t'))) ) {
371 (*s)[lastChar] = '\0';
372 lastChar--;
373 }
374
375 // Skip whitespace, excluding \n, at beginning of line
376 while ((*s)[0]==' ' || (*s)[0]=='\t') {
377 ++(*s);
378 }
379
380 return ((*s) ? true : false);
381 }
382
383
384
385 /**
386 * Processes a group (pair of group code and value).
387 *
388 * @param creationInterface Handle to class that creates entities and
389 * other CAD data from DXF group codes
390 *
391 * @param groupCode Constant indicating the data type of the group.
392 * @param groupValue The data value.
393 *
394 * @retval true if done processing current entity and new entity begun
395 * @retval false if not done processing current entity
396 */
processDXFGroup(DL_CreationInterface * creationInterface,int groupCode,const char * groupValue)397 bool DL_Dxf::processDXFGroup(DL_CreationInterface* creationInterface,
398 int groupCode, const char *groupValue) {
399
400 // Init on first call
401 if (firstCall) {
402 for (int i=0; i<DL_DXF_MAXGROUPCODE; ++i) {
403 values[i][0] = '\0';
404 }
405 settingValue[0] = '\0';
406 firstCall=false;
407 }
408
409 // Indicates comment or dxflib version:
410 if (groupCode==999) {
411 if (groupValue!=NULL) {
412 if (!strncmp(groupValue, "dxflib", 6)) {
413 libVersion = getLibVersion(&groupValue[7]);
414 }
415
416 addComment(creationInterface, groupValue);
417 }
418 }
419
420 // Indicates start of new entity or var
421 else if (groupCode==0 || groupCode==9) {
422
423 // If new entity is encountered, the last one must be complete
424 // prepare attributes which can be used for most entities:
425 char name[DL_DXF_MAXLINE+1];
426 if ((values[8])[0]!='\0') {
427 strcpy(name, values[8]);
428 }
429 // defaults to layer '0':
430 else {
431 strcpy(name, "0");
432 }
433
434 int width;
435 // Compatibillity with qcad1:
436 if ((values[39])[0]!='\0' &&
437 (values[370])[0]=='\0') {
438 width = toInt(values[39], -1);
439 }
440 // since autocad 2002:
441 else if ((values[370])[0]!='\0') {
442 width = toInt(values[370], -1);
443 }
444 // default to BYLAYER:
445 else {
446 width = -1;
447 }
448
449 int color;
450 color = toInt(values[62], 256);
451
452 char linetype[DL_DXF_MAXLINE+1];
453 strcpy(linetype, toString(values[6], "BYLAYER"));
454
455 attrib = DL_Attributes(values[8], // layer
456 color, // color
457 width, // width
458 linetype); // linetype
459 creationInterface->setAttributes(attrib);
460
461 creationInterface->setExtrusion(toReal(values[210], 0.0),
462 toReal(values[220], 0.0),
463 toReal(values[230], 1.0),
464 toReal(values[30], 0.0));
465
466 // Add the last entity via creationInterface
467 switch (currentEntity) {
468 case DL_SETTING:
469 addSetting(creationInterface);
470 break;
471
472 case DL_LAYER:
473 addLayer(creationInterface);
474 break;
475
476 case DL_BLOCK:
477 addBlock(creationInterface);
478 break;
479
480 case DL_ENDBLK:
481 endBlock(creationInterface);
482 break;
483
484 case DL_ENTITY_POINT:
485 addPoint(creationInterface);
486 break;
487
488 case DL_ENTITY_LINE:
489 addLine(creationInterface);
490 break;
491
492 case DL_ENTITY_POLYLINE:
493 //bulge = toReal(values[42]);
494 // fall through
495 case DL_ENTITY_LWPOLYLINE:
496 addPolyline(creationInterface);
497 break;
498
499 case DL_ENTITY_VERTEX:
500 addVertex(creationInterface);
501 break;
502
503 case DL_ENTITY_SPLINE:
504 addSpline(creationInterface);
505 break;
506
507 case DL_ENTITY_ARC:
508 addArc(creationInterface);
509 break;
510
511 case DL_ENTITY_CIRCLE:
512 addCircle(creationInterface);
513 break;
514
515 case DL_ENTITY_ELLIPSE:
516 addEllipse(creationInterface);
517 break;
518
519 case DL_ENTITY_INSERT:
520 addInsert(creationInterface);
521 break;
522
523 case DL_ENTITY_MTEXT:
524 addMText(creationInterface);
525 break;
526
527 case DL_ENTITY_TEXT:
528 addText(creationInterface);
529 break;
530
531 case DL_ENTITY_ATTRIB:
532 addAttrib(creationInterface);
533 break;
534
535 case DL_ENTITY_DIMENSION: {
536 int type = (toInt(values[70], 0)&0x07);
537
538 switch (type) {
539 case 0:
540 addDimLinear(creationInterface);
541 break;
542
543 case 1:
544 addDimAligned(creationInterface);
545 break;
546
547 case 2:
548 addDimAngular(creationInterface);
549 break;
550
551 case 3:
552 addDimDiametric(creationInterface);
553 break;
554
555 case 4:
556 addDimRadial(creationInterface);
557 break;
558
559 case 5:
560 addDimAngular3P(creationInterface);
561 break;
562
563 case 6:
564 addDimOrdinate(creationInterface);
565 break;
566
567 default:
568 break;
569 }
570 }
571 break;
572
573 case DL_ENTITY_LEADER:
574 addLeader(creationInterface);
575 break;
576
577 case DL_ENTITY_HATCH:
578 addHatch(creationInterface);
579 break;
580
581 case DL_ENTITY_IMAGE:
582 addImage(creationInterface);
583 break;
584
585 case DL_ENTITY_IMAGEDEF:
586 addImageDef(creationInterface);
587 break;
588
589 case DL_ENTITY_TRACE:
590 addTrace(creationInterface);
591 break;
592
593 case DL_ENTITY_3DFACE:
594 add3dFace(creationInterface);
595 break;
596
597 case DL_ENTITY_SOLID:
598 addSolid(creationInterface);
599 break;
600
601 case DL_ENTITY_SEQEND:
602 endSequence(creationInterface);
603 break;
604
605 default:
606 break;
607 }
608
609
610 // reset all values (they are not persistent and only this
611 // way we can detect default values for unstored settings)
612 for (int i=0; i<DL_DXF_MAXGROUPCODE; ++i) {
613 values[i][0] = '\0';
614 }
615 settingValue[0] = '\0';
616 settingKey[0] = '\0';
617
618
619 // Last DXF entity or setting has been handled
620 // Now determine what the next entity or setting type is
621
622 int prevEntity = currentEntity;
623
624 // Read DXF settings:
625 if (groupValue[0]=='$') {
626 currentEntity = DL_SETTING;
627 strncpy(settingKey, groupValue, DL_DXF_MAXLINE);
628 settingKey[DL_DXF_MAXLINE] = '\0';
629 }
630 // Read Layers:
631 else if (!strcmp(groupValue, "LAYER")) {
632 currentEntity = DL_LAYER;
633
634 }
635 // Read Blocks:
636 else if (!strcmp(groupValue, "BLOCK")) {
637 currentEntity = DL_BLOCK;
638 } else if (!strcmp(groupValue, "ENDBLK")) {
639 currentEntity = DL_ENDBLK;
640
641 }
642 // Read entities:
643 else if (!strcmp(groupValue, "POINT")) {
644 currentEntity = DL_ENTITY_POINT;
645 } else if (!strcmp(groupValue, "LINE")) {
646 currentEntity = DL_ENTITY_LINE;
647 } else if (!strcmp(groupValue, "POLYLINE")) {
648 currentEntity = DL_ENTITY_POLYLINE;
649 } else if (!strcmp(groupValue, "LWPOLYLINE")) {
650 currentEntity = DL_ENTITY_LWPOLYLINE;
651 } else if (!strcmp(groupValue, "VERTEX")) {
652 currentEntity = DL_ENTITY_VERTEX;
653 } else if (!strcmp(groupValue, "SPLINE")) {
654 currentEntity = DL_ENTITY_SPLINE;
655 } else if (!strcmp(groupValue, "ARC")) {
656 currentEntity = DL_ENTITY_ARC;
657 } else if (!strcmp(groupValue, "ELLIPSE")) {
658 currentEntity = DL_ENTITY_ELLIPSE;
659 } else if (!strcmp(groupValue, "CIRCLE")) {
660 currentEntity = DL_ENTITY_CIRCLE;
661 } else if (!strcmp(groupValue, "INSERT")) {
662 currentEntity = DL_ENTITY_INSERT;
663 } else if (!strcmp(groupValue, "TEXT")) {
664 currentEntity = DL_ENTITY_TEXT;
665 } else if (!strcmp(groupValue, "MTEXT")) {
666 currentEntity = DL_ENTITY_MTEXT;
667 } else if (!strcmp(groupValue, "ATTRIB")) {
668 currentEntity = DL_ENTITY_ATTRIB;
669 } else if (!strcmp(groupValue, "DIMENSION")) {
670 currentEntity = DL_ENTITY_DIMENSION;
671 } else if (!strcmp(groupValue, "LEADER")) {
672 currentEntity = DL_ENTITY_LEADER;
673 } else if (!strcmp(groupValue, "HATCH")) {
674 currentEntity = DL_ENTITY_HATCH;
675 } else if (!strcmp(groupValue, "IMAGE")) {
676 currentEntity = DL_ENTITY_IMAGE;
677 } else if (!strcmp(groupValue, "IMAGEDEF")) {
678 currentEntity = DL_ENTITY_IMAGEDEF;
679 } else if (!strcmp(groupValue, "TRACE")) {
680 currentEntity = DL_ENTITY_TRACE;
681 } else if (!strcmp(groupValue, "SOLID")) {
682 currentEntity = DL_ENTITY_SOLID;
683 } else if (!strcmp(groupValue, "3DFACE")) {
684 currentEntity = DL_ENTITY_3DFACE;
685 } else if (!strcmp(groupValue, "SEQEND")) {
686 currentEntity = DL_ENTITY_SEQEND;
687 } else {
688 currentEntity = DL_UNKNOWN;
689 }
690
691 // end of old style POLYLINE entity
692 if (prevEntity==DL_ENTITY_VERTEX && currentEntity!=DL_ENTITY_VERTEX) {
693 endEntity(creationInterface);
694 }
695
696 return true;
697
698 } else {
699 // Group code does not indicate start of new entity or setting,
700 // so this group must be continuation of data for the current
701 // one.
702 if (groupCode<DL_DXF_MAXGROUPCODE) {
703
704 bool handled = false;
705
706 switch (currentEntity) {
707 case DL_ENTITY_MTEXT:
708 handled = handleMTextData(creationInterface);
709 break;
710
711 case DL_ENTITY_LWPOLYLINE:
712 handled = handleLWPolylineData(creationInterface);
713 break;
714
715 case DL_ENTITY_SPLINE:
716 handled = handleSplineData(creationInterface);
717 break;
718
719 case DL_ENTITY_LEADER:
720 handled = handleLeaderData(creationInterface);
721 break;
722
723 case DL_ENTITY_HATCH:
724 handled = handleHatchData(creationInterface);
725 break;
726
727 default:
728 break;
729 }
730
731 if (!handled) {
732 // Normal group / value pair:
733 strncpy(values[groupCode], groupValue, DL_DXF_MAXLINE);
734 values[groupCode][DL_DXF_MAXLINE] = '\0';
735 }
736 }
737
738 return false;
739 }
740 return false;
741 }
742
743
744
745 /**
746 * Adds a comment from the DXF file.
747 */
addComment(DL_CreationInterface * creationInterface,const char * comment)748 void DL_Dxf::addComment(DL_CreationInterface* creationInterface, const char* comment) {
749 creationInterface->addComment(comment);
750 }
751
752
753
754 /**
755 * Adds a variable from the DXF file.
756 */
addSetting(DL_CreationInterface * creationInterface)757 void DL_Dxf::addSetting(DL_CreationInterface* creationInterface) {
758 int c = -1;
759 for (int i=0; i<=380; ++i) {
760 if (values[i][0]!='\0') {
761 c = i;
762 break;
763 }
764 }
765
766 // string
767 if (c>=0 && c<=9) {
768 creationInterface->setVariableString(settingKey,
769 values[c], c);
770 }
771 // vector
772 else if (c>=10 && c<=39) {
773 if (c==10) {
774 creationInterface->setVariableVector(
775 settingKey,
776 toReal(values[c]),
777 toReal(values[c+10]),
778 toReal(values[c+20]),
779 c);
780 }
781 }
782 // double
783 else if (c>=40 && c<=59) {
784 creationInterface->setVariableDouble(settingKey,
785 toReal(values[c]),
786 c);
787 }
788 // int
789 else if (c>=60 && c<=99) {
790 creationInterface->setVariableInt(settingKey,
791 toInt(values[c]),
792 c);
793 }
794 // misc
795 else if (c>=0) {
796 creationInterface->setVariableString(settingKey,
797 values[c],
798 c);
799 }
800 }
801
802
803
804 /**
805 * Adds a layer that was read from the file via the creation interface.
806 */
addLayer(DL_CreationInterface * creationInterface)807 void DL_Dxf::addLayer(DL_CreationInterface* creationInterface) {
808 // correct some impossible attributes for layers:
809 attrib = creationInterface->getAttributes();
810 if (attrib.getColor()==256 || attrib.getColor()==0) {
811 attrib.setColor(7);
812 }
813 if (attrib.getWidth()<0) {
814 attrib.setWidth(1);
815 }
816 if (!strcasecmp(attrib.getLineType().c_str(), "BYLAYER") ||
817 !strcasecmp(attrib.getLineType().c_str(), "BYBLOCK")) {
818 attrib.setLineType("CONTINUOUS");
819 }
820
821 // add layer
822 creationInterface->addLayer(DL_LayerData(values[2],
823 toInt(values[70])));
824 }
825
826
827
828 /**
829 * Adds a block that was read from the file via the creation interface.
830 */
addBlock(DL_CreationInterface * creationInterface)831 void DL_Dxf::addBlock(DL_CreationInterface* creationInterface) {
832 DL_BlockData d(
833 // Name:
834 values[2],
835 // flags:
836 toInt(values[70]),
837 // base point:
838 toReal(values[10]),
839 toReal(values[20]),
840 toReal(values[30]));
841
842 creationInterface->addBlock(d);
843 }
844
845
846
847 /**
848 * Ends a block that was read from the file via the creation interface.
849 */
endBlock(DL_CreationInterface * creationInterface)850 void DL_Dxf::endBlock(DL_CreationInterface* creationInterface) {
851 creationInterface->endBlock();
852 }
853
854
855
856 /**
857 * Adds a point entity that was read from the file via the creation interface.
858 */
addPoint(DL_CreationInterface * creationInterface)859 void DL_Dxf::addPoint(DL_CreationInterface* creationInterface) {
860 DL_PointData d(toReal(values[10]),
861 toReal(values[20]),
862 toReal(values[30]));
863 creationInterface->addPoint(d);
864 }
865
866
867
868 /**
869 * Adds a line entity that was read from the file via the creation interface.
870 */
addLine(DL_CreationInterface * creationInterface)871 void DL_Dxf::addLine(DL_CreationInterface* creationInterface) {
872 DL_LineData d(toReal(values[10]),
873 toReal(values[20]),
874 toReal(values[30]),
875 toReal(values[11]),
876 toReal(values[21]),
877 toReal(values[31]));
878
879 creationInterface->addLine(d);
880 }
881
882
883
884 /**
885 * Adds a polyline entity that was read from the file via the creation interface.
886 */
addPolyline(DL_CreationInterface * creationInterface)887 void DL_Dxf::addPolyline(DL_CreationInterface* creationInterface) {
888 DL_PolylineData pd(maxVertices, toInt(values[71], 0), toInt(values[72], 0), toInt(values[70], 0));
889 creationInterface->addPolyline(pd);
890
891 if (currentEntity==DL_ENTITY_LWPOLYLINE) {
892 for (int i=0; i<maxVertices; i++) {
893 DL_VertexData d(vertices[i*4],
894 vertices[i*4+1],
895 vertices[i*4+2],
896 vertices[i*4+3]);
897
898 creationInterface->addVertex(d);
899 }
900 creationInterface->endEntity();
901 }
902 }
903
904
905
906 /**
907 * Adds a polyline vertex entity that was read from the file
908 * via the creation interface.
909 */
addVertex(DL_CreationInterface * creationInterface)910 void DL_Dxf::addVertex(DL_CreationInterface* creationInterface) {
911 DL_VertexData d(toReal(values[10]),
912 toReal(values[20]),
913 toReal(values[30]),
914 //bulge);
915 toReal(values[42]));
916
917 //bulge = toReal(values[42]);
918
919 creationInterface->addVertex(d);
920 }
921
922
923
924 /**
925 * Adds a spline entity that was read from the file via the creation interface.
926 */
addSpline(DL_CreationInterface * creationInterface)927 void DL_Dxf::addSpline(DL_CreationInterface* creationInterface) {
928 DL_SplineData sd(toInt(values[71], 3),
929 maxKnots,
930 maxControlPoints,
931 toInt(values[70], 4));
932 /*DL_SplineData sd(toInt(values[71], 3), toInt(values[72], 0),
933 toInt(values[73], 0), toInt(values[70], 4));*/
934 creationInterface->addSpline(sd);
935
936 int i;
937 for (i=0; i<maxControlPoints; i++) {
938 DL_ControlPointData d(controlPoints[i*3],
939 controlPoints[i*3+1],
940 controlPoints[i*3+2]);
941
942 creationInterface->addControlPoint(d);
943 }
944 for (i=0; i<maxKnots; i++) {
945 DL_KnotData k(knots[i]);
946
947 creationInterface->addKnot(k);
948 }
949 }
950
951
952
953 /**
954 * Adds an arc entity that was read from the file via the creation interface.
955 */
addArc(DL_CreationInterface * creationInterface)956 void DL_Dxf::addArc(DL_CreationInterface* creationInterface) {
957 DL_ArcData d(toReal(values[10]),
958 toReal(values[20]),
959 toReal(values[30]),
960 toReal(values[40]),
961 toReal(values[50]),
962 toReal(values[51]));
963
964 creationInterface->addArc(d);
965 }
966
967
968
969 /**
970 * Adds a circle entity that was read from the file via the creation interface.
971 */
addCircle(DL_CreationInterface * creationInterface)972 void DL_Dxf::addCircle(DL_CreationInterface* creationInterface) {
973 DL_CircleData d(toReal(values[10]),
974 toReal(values[20]),
975 toReal(values[30]),
976 toReal(values[40]));
977
978 creationInterface->addCircle(d);
979 }
980
981
982
983 /**
984 * Adds an ellipse entity that was read from the file via the creation interface.
985 */
addEllipse(DL_CreationInterface * creationInterface)986 void DL_Dxf::addEllipse(DL_CreationInterface* creationInterface) {
987 DL_EllipseData d(toReal(values[10]),
988 toReal(values[20]),
989 toReal(values[30]),
990 toReal(values[11]),
991 toReal(values[21]),
992 toReal(values[31]),
993 toReal(values[40], 1.0),
994 toReal(values[41], 0.0),
995 toReal(values[42], 2*M_PI));
996
997 creationInterface->addEllipse(d);
998 }
999
1000
1001
1002 /**
1003 * Adds an insert entity that was read from the file via the creation interface.
1004 */
addInsert(DL_CreationInterface * creationInterface)1005 void DL_Dxf::addInsert(DL_CreationInterface* creationInterface) {
1006 DL_InsertData d(values[2],
1007 // insertion point
1008 toReal(values[10], 0.0),
1009 toReal(values[20], 0.0),
1010 toReal(values[30], 0.0),
1011 // scale:
1012 toReal(values[41], 1.0),
1013 toReal(values[42], 1.0),
1014 toReal(values[43], 1.0),
1015 // angle:
1016 toReal(values[50], 0.0),
1017 // cols / rows:
1018 toInt(values[70], 1),
1019 toInt(values[71], 1),
1020 // spacing:
1021 toReal(values[44], 0.0),
1022 toReal(values[45], 0.0));
1023
1024 creationInterface->addInsert(d);
1025 }
1026
1027
1028
1029 /**
1030 * Adds a trace entity (4 edge closed polyline) that was read from the file via the creation interface.
1031 *
1032 * @author AHM
1033 */
addTrace(DL_CreationInterface * creationInterface)1034 void DL_Dxf::addTrace(DL_CreationInterface* creationInterface) {
1035 DL_TraceData td;
1036
1037 for (int k = 0; k < 4; k++) {
1038 td.x[k] = toReal(values[10 + k]);
1039 td.y[k] = toReal(values[20 + k]);
1040 td.z[k] = toReal(values[30 + k]);
1041 }
1042 creationInterface->addTrace(td);
1043 }
1044
1045
1046
1047 /**
1048 * Adds a 3dface entity that was read from the file via the creation interface.
1049 */
add3dFace(DL_CreationInterface * creationInterface)1050 void DL_Dxf::add3dFace(DL_CreationInterface* creationInterface) {
1051 DL_3dFaceData td;
1052
1053 for (int k = 0; k < 4; k++) {
1054 td.x[k] = toReal(values[10 + k]);
1055 td.y[k] = toReal(values[20 + k]);
1056 td.z[k] = toReal(values[30 + k]);
1057 }
1058 creationInterface->add3dFace(td);
1059 }
1060
1061
1062
1063 /**
1064 * Adds a solid entity (filled trace) that was read from the file via the creation interface.
1065 *
1066 * @author AHM
1067 */
addSolid(DL_CreationInterface * creationInterface)1068 void DL_Dxf::addSolid(DL_CreationInterface* creationInterface) {
1069 DL_SolidData sd;
1070
1071 for (int k = 0; k < 4; k++) {
1072 sd.x[k] = toReal(values[10 + k]);
1073 sd.y[k] = toReal(values[20 + k]);
1074 sd.z[k] = toReal(values[30 + k]);
1075 }
1076 creationInterface->addSolid(sd);
1077 }
1078
1079
1080 /**
1081 * Adds an MText entity that was read from the file via the creation interface.
1082 */
addMText(DL_CreationInterface * creationInterface)1083 void DL_Dxf::addMText(DL_CreationInterface* creationInterface) {
1084 double angle = 0.0;
1085
1086 if (values[50][0]!='\0') {
1087 if (libVersion<=0x02000200) {
1088 // wrong but compatible with dxflib <=2.0.2.0:
1089 angle = toReal(values[50], 0.0);
1090 } else {
1091 angle = (toReal(values[50], 0.0)*2*M_PI)/360.0;
1092 }
1093 } else if (values[11][0]!='\0' && values[21][0]!='\0') {
1094 double x = toReal(values[11], 0.0);
1095 double y = toReal(values[21], 0.0);
1096
1097 if (fabs(x)<1.0e-6) {
1098 if (y>0.0) {
1099 angle = M_PI/2.0;
1100 } else {
1101 angle = M_PI/2.0*3.0;
1102 }
1103 } else {
1104 angle = atan(y/x);
1105 }
1106 }
1107
1108 DL_MTextData d(
1109 // insertion point
1110 toReal(values[10], 0.0),
1111 toReal(values[20], 0.0),
1112 toReal(values[30], 0.0),
1113 // height
1114 toReal(values[40], 2.5),
1115 // width
1116 toReal(values[41], 100.0),
1117 // attachment point
1118 toInt(values[71], 1),
1119 // drawing direction
1120 toInt(values[72], 1),
1121 // line spacing style
1122 toInt(values[73], 1),
1123 // line spacing factor
1124 toReal(values[44], 1.0),
1125 // text
1126 values[1],
1127 // style
1128 values[7],
1129 // angle
1130 angle);
1131 creationInterface->addMText(d);
1132 }
1133
1134
1135
1136 /**
1137 * Handles additional MText data.
1138 */
handleMTextData(DL_CreationInterface * creationInterface)1139 bool DL_Dxf::handleMTextData(DL_CreationInterface* creationInterface) {
1140 // Special handling of text chunks for MTEXT entities:
1141 if (groupCode==3) {
1142 creationInterface->addMTextChunk(groupValue);
1143 return true;
1144 }
1145
1146 return false;
1147 }
1148
1149
1150
1151 /**
1152 * Handles additional polyline data.
1153 */
handleLWPolylineData(DL_CreationInterface *)1154 bool DL_Dxf::handleLWPolylineData(DL_CreationInterface* /*creationInterface*/) {
1155 // Allocate LWPolyline vertices (group code 90):
1156 if (groupCode==90) {
1157 maxVertices = toInt(groupValue);
1158 if (maxVertices>0) {
1159 if (vertices!=NULL) {
1160 delete[] vertices;
1161 }
1162 vertices = new double[4*maxVertices];
1163 for (int i=0; i<maxVertices; ++i) {
1164 vertices[i*4] = 0.0;
1165 vertices[i*4+1] = 0.0;
1166 vertices[i*4+2] = 0.0;
1167 vertices[i*4+3] = 0.0;
1168 }
1169 }
1170 vertexIndex=-1;
1171 return true;
1172 }
1173
1174 // Compute LWPolylines vertices (group codes 10/20/30/42):
1175 else if (groupCode==10 || groupCode==20 ||
1176 groupCode==30 || groupCode==42) {
1177
1178 if (vertexIndex<maxVertices-1 && groupCode==10) {
1179 vertexIndex++;
1180 }
1181
1182 if (groupCode<=30) {
1183 if (vertexIndex>=0 && vertexIndex<maxVertices) {
1184 vertices[4*vertexIndex + (groupCode/10-1)]
1185 = toReal(groupValue);
1186 }
1187 } else if (groupCode==42 && vertexIndex<maxVertices) {
1188 vertices[4*vertexIndex + 3] = toReal(groupValue);
1189 }
1190 return true;
1191 }
1192 return false;
1193 }
1194
1195
1196
1197 /**
1198 * Handles additional spline data.
1199 */
handleSplineData(DL_CreationInterface *)1200 bool DL_Dxf::handleSplineData(DL_CreationInterface* /*creationInterface*/) {
1201 // Allocate Spline knots (group code 72):
1202 if (groupCode==72) {
1203 maxKnots = toInt(groupValue);
1204 if (maxKnots>0) {
1205 if (knots!=NULL) {
1206 delete[] knots;
1207 }
1208 knots = new double[maxKnots];
1209 for (int i=0; i<maxKnots; ++i) {
1210 knots[i] = 0.0;
1211 }
1212 }
1213 knotIndex=-1;
1214 return true;
1215 }
1216
1217 // Allocate Spline control points (group code 73):
1218 else if (groupCode==73) {
1219 maxControlPoints = toInt(groupValue);
1220 if (maxControlPoints>0) {
1221 if (controlPoints!=NULL) {
1222 delete[] controlPoints;
1223 }
1224 controlPoints = new double[3*maxControlPoints];
1225 for (int i=0; i<maxControlPoints; ++i) {
1226 controlPoints[i*3] = 0.0;
1227 controlPoints[i*3+1] = 0.0;
1228 controlPoints[i*3+2] = 0.0;
1229 }
1230 }
1231 controlPointIndex=-1;
1232 return true;
1233 }
1234
1235 // Compute spline knot vertices (group code 40):
1236 else if (groupCode==40) {
1237 if (knotIndex<maxKnots-1) {
1238 knotIndex++;
1239 knots[knotIndex] = toReal(groupValue);
1240 }
1241 return true;
1242 }
1243
1244 // Compute spline control points (group codes 10/20/30):
1245 else if (groupCode==10 || groupCode==20 ||
1246 groupCode==30) {
1247
1248 if (controlPointIndex<maxControlPoints-1 && groupCode==10) {
1249 controlPointIndex++;
1250 }
1251
1252 if (controlPointIndex>=0 && controlPointIndex<maxControlPoints) {
1253 controlPoints[3*controlPointIndex + (groupCode/10-1)]
1254 = toReal(groupValue);
1255 }
1256 return true;
1257 }
1258 return false;
1259 }
1260
1261
1262
1263 /**
1264 * Handles additional leader data.
1265 */
handleLeaderData(DL_CreationInterface *)1266 bool DL_Dxf::handleLeaderData(DL_CreationInterface* /*creationInterface*/) {
1267 // Allocate Leader vertices (group code 76):
1268 if (groupCode==76) {
1269 maxLeaderVertices = toInt(groupValue);
1270 if (maxLeaderVertices>0) {
1271 if (leaderVertices!=NULL) {
1272 delete[] leaderVertices;
1273 }
1274 leaderVertices = new double[3*maxLeaderVertices];
1275 for (int i=0; i<maxLeaderVertices; ++i) {
1276 leaderVertices[i*3] = 0.0;
1277 leaderVertices[i*3+1] = 0.0;
1278 leaderVertices[i*3+2] = 0.0;
1279 }
1280 }
1281 leaderVertexIndex=-1;
1282 return true;
1283 }
1284
1285 // Compute Leader vertices (group codes 10/20/30):
1286 else if (groupCode==10 || groupCode==20 || groupCode==30) {
1287
1288 if (leaderVertexIndex<maxLeaderVertices-1 && groupCode==10) {
1289 leaderVertexIndex++;
1290 }
1291
1292 if (groupCode<=30) {
1293 if (leaderVertexIndex>=0 &&
1294 leaderVertexIndex<maxLeaderVertices) {
1295 leaderVertices[3*leaderVertexIndex + (groupCode/10-1)]
1296 = toReal(groupValue);
1297 }
1298 }
1299 return true;
1300 }
1301
1302 return false;
1303 }
1304
1305
1306
1307 /**
1308 * Handles additional hatch data.
1309 */
handleHatchData(DL_CreationInterface *)1310 bool DL_Dxf::handleHatchData(DL_CreationInterface* /*creationInterface*/) {
1311
1312 static int firstPolylineStatus = 0;
1313
1314 // Allocate hatch loops (group code 91):
1315 if (groupCode==91 && toInt(groupValue)>0) {
1316
1317 if (hatchLoops!=NULL) {
1318 delete[] hatchLoops;
1319 hatchLoops = NULL;
1320 }
1321 if (maxHatchEdges!=NULL) {
1322 delete[] maxHatchEdges;
1323 maxHatchEdges = NULL;
1324 }
1325 if (hatchEdgeIndex!=NULL) {
1326 delete[] hatchEdgeIndex;
1327 hatchEdgeIndex = NULL;
1328 }
1329 if (hatchEdges!=NULL) {
1330 for (int i=0; i<maxHatchLoops; ++i) {
1331 delete[] hatchEdges[i];
1332 }
1333 delete[] hatchEdges;
1334 hatchEdges = NULL;
1335 }
1336 maxHatchLoops = toInt(groupValue);
1337
1338 if (maxHatchLoops>0) {
1339 hatchLoops = new DL_HatchLoopData[maxHatchLoops];
1340 maxHatchEdges = new int[maxHatchLoops];
1341 hatchEdgeIndex = new int[maxHatchLoops];
1342 hatchEdges = new DL_HatchEdgeData*[maxHatchLoops];
1343 for (int i=0; i<maxHatchLoops; ++i) {
1344 hatchEdges[i] = NULL;
1345 maxHatchEdges[i] = 0;
1346 }
1347 hatchLoopIndex = -1;
1348 dropEdges = false;
1349 }
1350 return true;
1351 }
1352
1353 // Allocate hatch edges, group code 93
1354 if (groupCode==93 && toInt(groupValue)>0) {
1355 if (hatchLoopIndex<maxHatchLoops-1 && hatchLoops!=NULL &&
1356 maxHatchEdges!=NULL && hatchEdgeIndex!=NULL &&
1357 hatchEdges!=NULL) {
1358
1359 dropEdges = false;
1360
1361 hatchLoopIndex++;
1362 hatchLoops[hatchLoopIndex]
1363 = DL_HatchLoopData(toInt(groupValue));
1364
1365 maxHatchEdges[hatchLoopIndex] = toInt(groupValue);
1366 hatchEdgeIndex[hatchLoopIndex] = -1;
1367 hatchEdges[hatchLoopIndex]
1368 = new DL_HatchEdgeData[toInt(groupValue)];
1369 firstPolylineStatus = 0;
1370 } else {
1371 dropEdges = true;
1372 }
1373 return true;
1374 }
1375
1376 // Init hatch edge for non-polyline boundary (group code 72)
1377 if (hatchEdges!=NULL &&
1378 hatchEdgeIndex!=NULL &&
1379 maxHatchEdges!=NULL &&
1380 hatchLoopIndex>=0 &&
1381 hatchLoopIndex<maxHatchLoops &&
1382 hatchEdgeIndex[hatchLoopIndex] <
1383 maxHatchEdges[hatchLoopIndex] &&
1384 (atoi(values[92])&2)==0 && // not a polyline
1385 groupCode==72 &&
1386 !dropEdges) {
1387
1388 hatchEdgeIndex[hatchLoopIndex]++;
1389
1390 hatchEdges[hatchLoopIndex][hatchEdgeIndex[hatchLoopIndex]]
1391 .type = toInt(groupValue);
1392 hatchEdges[hatchLoopIndex][hatchEdgeIndex[hatchLoopIndex]]
1393 .defined = false;
1394
1395 return true;
1396 }
1397
1398 // Handle hatch edges for non-polyline boundaries
1399 // (group codes 10, 20, 11, 21, 40, 50, 51, 73)
1400 if (!dropEdges &&
1401 hatchEdges!=NULL &&
1402 hatchEdgeIndex!=NULL &&
1403 hatchLoopIndex>=0 &&
1404 hatchLoopIndex<maxHatchLoops &&
1405 hatchEdges[hatchLoopIndex]!=NULL &&
1406 hatchEdgeIndex[hatchLoopIndex]>=0 &&
1407 hatchEdgeIndex[hatchLoopIndex] <
1408 maxHatchEdges[hatchLoopIndex] &&
1409 ((atoi(values[92])&2)==0) && // not a polyline
1410 (groupCode==10 || groupCode==20 ||
1411 groupCode==11 || groupCode==21 ||
1412 groupCode==40 || groupCode==50 ||
1413 groupCode==51 || groupCode==73)) {
1414
1415 if (hatchEdges[hatchLoopIndex]
1416 [hatchEdgeIndex[hatchLoopIndex]].defined==false) {
1417 if (hatchEdges[hatchLoopIndex]
1418 [hatchEdgeIndex[hatchLoopIndex]].type==1) {
1419 switch (groupCode) {
1420 case 10:
1421 hatchEdges[hatchLoopIndex]
1422 [hatchEdgeIndex[hatchLoopIndex]].x1
1423 = toReal(groupValue);
1424 break;
1425 case 20:
1426 hatchEdges[hatchLoopIndex]
1427 [hatchEdgeIndex[hatchLoopIndex]].y1
1428 = toReal(groupValue);
1429 break;
1430 case 11:
1431 hatchEdges[hatchLoopIndex]
1432 [hatchEdgeIndex[hatchLoopIndex]].x2
1433 = toReal(groupValue);
1434 break;
1435 case 21:
1436 hatchEdges[hatchLoopIndex]
1437 [hatchEdgeIndex[hatchLoopIndex]].y2
1438 = toReal(groupValue);
1439 hatchEdges[hatchLoopIndex]
1440 [hatchEdgeIndex[hatchLoopIndex]].defined = true;
1441 break;
1442 default:
1443 break;
1444 }
1445 }
1446
1447 if (hatchEdges[hatchLoopIndex]
1448 [hatchEdgeIndex[hatchLoopIndex]].type==2) {
1449 switch (groupCode) {
1450 case 10:
1451 hatchEdges[hatchLoopIndex]
1452 [hatchEdgeIndex[hatchLoopIndex]].cx
1453 = toReal(groupValue);
1454 break;
1455 case 20:
1456 hatchEdges[hatchLoopIndex]
1457 [hatchEdgeIndex[hatchLoopIndex]].cy
1458 = toReal(groupValue);
1459 break;
1460 case 40:
1461 hatchEdges[hatchLoopIndex]
1462 [hatchEdgeIndex[hatchLoopIndex]].radius
1463 = toReal(groupValue);
1464 break;
1465 case 50:
1466 hatchEdges[hatchLoopIndex]
1467 [hatchEdgeIndex[hatchLoopIndex]].angle1
1468 = toReal(groupValue)/360.0*2*M_PI;
1469 break;
1470 case 51:
1471 hatchEdges[hatchLoopIndex]
1472 [hatchEdgeIndex[hatchLoopIndex]].angle2
1473 = toReal(groupValue)/360.0*2*M_PI;
1474 break;
1475 case 73:
1476 hatchEdges[hatchLoopIndex]
1477 [hatchEdgeIndex[hatchLoopIndex]].ccw
1478 = (bool)toInt(groupValue);
1479 hatchEdges[hatchLoopIndex]
1480 [hatchEdgeIndex[hatchLoopIndex]].defined = true;
1481 break;
1482 default:
1483 break;
1484 }
1485 }
1486 }
1487 return true;
1488 }
1489
1490 /*
1491 // 2003/12/31: polyline hatches can be extremely slow and are rarely used
1492 //
1493 // Handle hatch edges for polyline boundaries
1494 // (group codes 10, 20, 42)
1495 if (!dropEdges &&
1496 hatchEdges!=NULL &&
1497 hatchEdgeIndex!=NULL &&
1498 hatchLoopIndex>=0 &&
1499 hatchLoopIndex<maxHatchLoops &&
1500 hatchEdges[hatchLoopIndex]!=NULL &&
1501 //hatchEdgeIndex[hatchLoopIndex]>=0 &&
1502 hatchEdgeIndex[hatchLoopIndex] <
1503 maxHatchEdges[hatchLoopIndex] &&
1504 ((atoi(values[92])&2)==2)) { // a polyline
1505
1506 if (groupCode==10 || groupCode==20 ||
1507 groupCode==42) {
1508
1509 std::cout << " found polyline edge data: " << groupCode << "\n";
1510 std::cout << " value: " << toReal(groupValue) << "\n";
1511
1512 static double lastX = 0.0;
1513 static double lastY = 0.0;
1514 static double lastB = 0.0;
1515
1516 if (firstPolylineStatus<2) {
1517 switch (groupCode) {
1518 case 10:
1519 firstPolylineStatus++;
1520 if (firstPolylineStatus==1) {
1521 lastX = toReal(groupValue);
1522 std::cout << " firstX: " << lastX << "\n";
1523 }
1524 break;
1525
1526 case 20:
1527 lastY = toReal(groupValue);
1528 std::cout << " firstY: " << lastY << "\n";
1529 break;
1530
1531 case 42:
1532 lastB = toReal(groupValue);
1533 break;
1534
1535 default:
1536 break;
1537 }
1538
1539 if (firstPolylineStatus!=2) {
1540 return true;
1541 }
1542 }
1543
1544
1545 switch (groupCode) {
1546 case 10:
1547 hatchEdgeIndex[hatchLoopIndex]++;
1548 hatchEdges[hatchLoopIndex]
1549 [hatchEdgeIndex[hatchLoopIndex]].type = 1;
1550 hatchEdges[hatchLoopIndex]
1551 [hatchEdgeIndex[hatchLoopIndex]].x1
1552 = lastX;
1553 hatchEdges[hatchLoopIndex]
1554 [hatchEdgeIndex[hatchLoopIndex]].x2
1555 = lastX = toReal(groupValue);
1556 std::cout << " X: " << lastX << "\n";
1557 break;
1558 case 20:
1559 hatchEdges[hatchLoopIndex]
1560 [hatchEdgeIndex[hatchLoopIndex]].y1
1561 = lastY;
1562 hatchEdges[hatchLoopIndex]
1563 [hatchEdgeIndex[hatchLoopIndex]].y2
1564 = lastY = toReal(groupValue);
1565 std::cout << " Y: " << lastY << "\n";
1566 break;
1567 / *
1568 case 42: {
1569 // convert to arc:
1570 double x1 = hatchEdges[hatchLoopIndex]
1571 [hatchEdgeIndex[hatchLoopIndex]].x1;
1572 double y1 = hatchEdges[hatchLoopIndex]
1573 [hatchEdgeIndex[hatchLoopIndex]].y1;
1574 double x2 = hatchEdges[hatchLoopIndex]
1575 [hatchEdgeIndex[hatchLoopIndex]].x2;
1576 double y2 = hatchEdges[hatchLoopIndex]
1577 [hatchEdgeIndex[hatchLoopIndex]].y2;
1578
1579 double bulge = toReal(groupValue);
1580
1581 bool reversed = (bulge<0.0);
1582 double alpha = atan(bulge)*4.0;
1583 double radius;
1584 double cx;
1585 double cy;
1586 double a1;
1587 double a2;
1588 double mx = (x2+x1)/2.0;
1589 double my = (y2+y1)/2.0;
1590 double dist = sqrt(pow(x2-x1,2) + pow(y2-y1,2)) / 2.0;
1591
1592 // alpha can't be 0.0 at this point
1593 radius = fabs(dist / sin(alpha/2.0));
1594
1595 double wu = fabs(pow(radius, 2.0) - pow(dist, 2.0));
1596 double h = sqrt(wu);
1597 double angle = acos((x2-x1) / dist);
1598
1599 if (bulge>0.0) {
1600 angle+=M_PI/2.0;
1601 } else {
1602 angle-=M_PI/2.0;
1603 }
1604
1605 if (fabs(alpha)>M_PI) {
1606 h*=-1.0;
1607 }
1608
1609 cx = mx + cos(angle) * h;
1610 cy = my + sin(angle) * h;
1611
1612 a1 = hatchEdges[hatchLoopIndex]
1613 [hatchEdgeIndex[hatchLoopIndex]].type = 2;
1614 hatchEdges[hatchLoopIndex]
1615 [hatchEdgeIndex[hatchLoopIndex]].ccw = (toReal(groupValue)>0.0);
1616 hatchEdges[hatchLoopIndex]
1617 [hatchEdgeIndex[hatchLoopIndex]].cx = cx;
1618 hatchEdges[hatchLoopIndex]
1619 [hatchEdgeIndex[hatchLoopIndex]].cy = cy;
1620 hatchEdges[hatchLoopIndex]
1621 [hatchEdgeIndex[hatchLoopIndex]].radius = radius;
1622 } break;
1623 * /
1624
1625 default:
1626 break;
1627 }
1628 } else {
1629 // end polyline boundary
1630 dropEdges = true;
1631 }
1632
1633 return true;
1634 }
1635 */
1636
1637 return false;
1638 }
1639
1640
1641
1642
1643 /**
1644 * Adds an text entity that was read from the file via the creation interface.
1645 */
addText(DL_CreationInterface * creationInterface)1646 void DL_Dxf::addText(DL_CreationInterface* creationInterface) {
1647 DL_TextData d(
1648 // insertion point
1649 toReal(values[10], 0.0),
1650 toReal(values[20], 0.0),
1651 toReal(values[30], 0.0),
1652 // alignment point
1653 toReal(values[11], 0.0),
1654 toReal(values[21], 0.0),
1655 toReal(values[31], 0.0),
1656 // height
1657 toReal(values[40], 2.5),
1658 // x scale
1659 toReal(values[41], 1.0),
1660 // generation flags
1661 toInt(values[71], 0),
1662 // h just
1663 toInt(values[72], 0),
1664 // v just
1665 toInt(values[73], 0),
1666 // text
1667 values[1],
1668 // style
1669 values[7],
1670 // angle
1671 (toReal(values[50], 0.0)*2*M_PI)/360.0);
1672
1673 creationInterface->addText(d);
1674 }
1675
1676
1677
1678 /**
1679 * Adds an attrib entity that was read from the file via the creation interface.
1680 * @todo add attrib instead of normal text
1681 */
addAttrib(DL_CreationInterface * creationInterface)1682 void DL_Dxf::addAttrib(DL_CreationInterface* creationInterface) {
1683 DL_TextData d(
1684 // insertion point
1685 toReal(values[10], 0.0),
1686 toReal(values[20], 0.0),
1687 toReal(values[30], 0.0),
1688 // alignment point
1689 toReal(values[11], 0.0),
1690 toReal(values[21], 0.0),
1691 toReal(values[31], 0.0),
1692 // height
1693 toReal(values[40], 2.5),
1694 // x scale
1695 toReal(values[41], 1.0),
1696 // generation flags
1697 toInt(values[71], 0),
1698 // h just
1699 toInt(values[72], 0),
1700 // v just
1701 toInt(values[74], 0),
1702 // text
1703 values[1],
1704 // style
1705 values[7],
1706 // angle
1707 (toReal(values[50], 0.0)*2*M_PI)/360.0);
1708
1709 creationInterface->addText(d);
1710 }
1711
1712
1713
1714 /**
1715 * @return dimension data from current values.
1716 */
getDimData()1717 DL_DimensionData DL_Dxf::getDimData() {
1718 // generic dimension data:
1719 return DL_DimensionData(
1720 // def point
1721 toReal(values[10], 0.0),
1722 toReal(values[20], 0.0),
1723 toReal(values[30], 0.0),
1724 // text middle point
1725 toReal(values[11], 0.0),
1726 toReal(values[21], 0.0),
1727 toReal(values[31], 0.0),
1728 // type
1729 toInt(values[70], 0),
1730 // attachment point
1731 toInt(values[71], 5),
1732 // line sp. style
1733 toInt(values[72], 1),
1734 // line sp. factor
1735 toReal(values[41], 1.0),
1736 // text
1737 values[1],
1738 // style
1739 values[3],
1740 // angle
1741 toReal(values[53], 0.0));
1742 }
1743
1744
1745
1746 /**
1747 * Adds a linear dimension entity that was read from the file via the creation interface.
1748 */
addDimLinear(DL_CreationInterface * creationInterface)1749 void DL_Dxf::addDimLinear(DL_CreationInterface* creationInterface) {
1750 DL_DimensionData d = getDimData();
1751
1752 // horizontal / vertical / rotated dimension:
1753 DL_DimLinearData dl(
1754 // definition point 1
1755 toReal(values[13], 0.0),
1756 toReal(values[23], 0.0),
1757 toReal(values[33], 0.0),
1758 // definition point 2
1759 toReal(values[14], 0.0),
1760 toReal(values[24], 0.0),
1761 toReal(values[34], 0.0),
1762 // angle
1763 toReal(values[50], 0.0),
1764 // oblique
1765 toReal(values[52], 0.0));
1766 creationInterface->addDimLinear(d, dl);
1767 }
1768
1769
1770
1771 /**
1772 * Adds an aligned dimension entity that was read from the file via the creation interface.
1773 */
addDimAligned(DL_CreationInterface * creationInterface)1774 void DL_Dxf::addDimAligned(DL_CreationInterface* creationInterface) {
1775 DL_DimensionData d = getDimData();
1776
1777 // aligned dimension:
1778 DL_DimAlignedData da(
1779 // extension point 1
1780 toReal(values[13], 0.0),
1781 toReal(values[23], 0.0),
1782 toReal(values[33], 0.0),
1783 // extension point 2
1784 toReal(values[14], 0.0),
1785 toReal(values[24], 0.0),
1786 toReal(values[34], 0.0));
1787 creationInterface->addDimAlign(d, da);
1788 }
1789
1790
1791
1792 /**
1793 * Adds a radial dimension entity that was read from the file via the creation interface.
1794 */
addDimRadial(DL_CreationInterface * creationInterface)1795 void DL_Dxf::addDimRadial(DL_CreationInterface* creationInterface) {
1796 DL_DimensionData d = getDimData();
1797
1798 DL_DimRadialData dr(
1799 // definition point
1800 toReal(values[15], 0.0),
1801 toReal(values[25], 0.0),
1802 toReal(values[35], 0.0),
1803 // leader length:
1804 toReal(values[40], 0.0));
1805 creationInterface->addDimRadial(d, dr);
1806 }
1807
1808
1809
1810 /**
1811 * Adds a diametric dimension entity that was read from the file via the creation interface.
1812 */
addDimDiametric(DL_CreationInterface * creationInterface)1813 void DL_Dxf::addDimDiametric(DL_CreationInterface* creationInterface) {
1814 DL_DimensionData d = getDimData();
1815
1816 // diametric dimension:
1817 DL_DimDiametricData dr(
1818 // definition point
1819 toReal(values[15], 0.0),
1820 toReal(values[25], 0.0),
1821 toReal(values[35], 0.0),
1822 // leader length:
1823 toReal(values[40], 0.0));
1824 creationInterface->addDimDiametric(d, dr);
1825 }
1826
1827
1828
1829 /**
1830 * Adds an angular dimension entity that was read from the file via the creation interface.
1831 */
addDimAngular(DL_CreationInterface * creationInterface)1832 void DL_Dxf::addDimAngular(DL_CreationInterface* creationInterface) {
1833 DL_DimensionData d = getDimData();
1834
1835 // angular dimension:
1836 DL_DimAngularData da(
1837 // definition point 1
1838 toReal(values[13], 0.0),
1839 toReal(values[23], 0.0),
1840 toReal(values[33], 0.0),
1841 // definition point 2
1842 toReal(values[14], 0.0),
1843 toReal(values[24], 0.0),
1844 toReal(values[34], 0.0),
1845 // definition point 3
1846 toReal(values[15], 0.0),
1847 toReal(values[25], 0.0),
1848 toReal(values[35], 0.0),
1849 // definition point 4
1850 toReal(values[16], 0.0),
1851 toReal(values[26], 0.0),
1852 toReal(values[36], 0.0));
1853 creationInterface->addDimAngular(d, da);
1854 }
1855
1856
1857 /**
1858 * Adds an angular dimension entity that was read from the file via the creation interface.
1859 */
addDimAngular3P(DL_CreationInterface * creationInterface)1860 void DL_Dxf::addDimAngular3P(DL_CreationInterface* creationInterface) {
1861 DL_DimensionData d = getDimData();
1862
1863 // angular dimension (3P):
1864 DL_DimAngular3PData da(
1865 // definition point 1
1866 toReal(values[13], 0.0),
1867 toReal(values[23], 0.0),
1868 toReal(values[33], 0.0),
1869 // definition point 2
1870 toReal(values[14], 0.0),
1871 toReal(values[24], 0.0),
1872 toReal(values[34], 0.0),
1873 // definition point 3
1874 toReal(values[15], 0.0),
1875 toReal(values[25], 0.0),
1876 toReal(values[35], 0.0));
1877 creationInterface->addDimAngular3P(d, da);
1878 }
1879
1880
1881
1882 /**
1883 * Adds an ordinate dimension entity that was read from the file via the creation interface.
1884 */
addDimOrdinate(DL_CreationInterface * creationInterface)1885 void DL_Dxf::addDimOrdinate(DL_CreationInterface* creationInterface) {
1886 DL_DimensionData d = getDimData();
1887
1888 // ordinate dimension:
1889 DL_DimOrdinateData dl(
1890 // definition point 1
1891 toReal(values[13], 0.0),
1892 toReal(values[23], 0.0),
1893 toReal(values[33], 0.0),
1894 // definition point 2
1895 toReal(values[14], 0.0),
1896 toReal(values[24], 0.0),
1897 toReal(values[34], 0.0),
1898 (toInt(values[70])&64)==64 // true: X-type, false: Y-type
1899 );
1900 creationInterface->addDimOrdinate(d, dl);
1901 }
1902
1903
1904
1905 /**
1906 * Adds a leader entity that was read from the file via the creation interface.
1907 */
addLeader(DL_CreationInterface * creationInterface)1908 void DL_Dxf::addLeader(DL_CreationInterface* creationInterface) {
1909 // leader (arrow)
1910 DL_LeaderData le(
1911 // arrow head flag
1912 toInt(values[71], 1),
1913 // leader path type
1914 toInt(values[72], 0),
1915 // Leader creation flag
1916 toInt(values[73], 3),
1917 // Hookline direction flag
1918 toInt(values[74], 1),
1919 // Hookline flag
1920 toInt(values[75], 0),
1921 // Text annotation height
1922 toReal(values[40], 1.0),
1923 // Text annotation width
1924 toReal(values[41], 1.0),
1925 // Number of vertices in leader
1926 toInt(values[76], 0)
1927 );
1928 creationInterface->addLeader(le);
1929
1930 for (int i=0; i<maxLeaderVertices; i++) {
1931 DL_LeaderVertexData d(leaderVertices[i*3],
1932 leaderVertices[i*3+1],
1933 leaderVertices[i*3+2]);
1934
1935 creationInterface->addLeaderVertex(d);
1936 }
1937 }
1938
1939
1940
1941 /**
1942 * Adds a hatch entity that was read from the file via the creation interface.
1943 */
addHatch(DL_CreationInterface * creationInterface)1944 void DL_Dxf::addHatch(DL_CreationInterface* creationInterface) {
1945 DL_HatchData hd(toInt(values[91], 1),
1946 toInt(values[70], 0),
1947 toReal(values[41], 1.0),
1948 toReal(values[52], 0.0),
1949 values[2]);
1950 creationInterface->addHatch(hd);
1951
1952 for (int l=0; l<maxHatchLoops; l++) {
1953 DL_HatchLoopData ld(maxHatchEdges[l]);
1954 creationInterface->addHatchLoop(ld);
1955 for (int b=0; b<maxHatchEdges[l]; b++) {
1956 creationInterface->addHatchEdge(hatchEdges[l][b]);
1957 }
1958 }
1959 creationInterface->endEntity();
1960 currentEntity = DL_UNKNOWN;
1961 }
1962
1963
1964
1965 /**
1966 * Adds an image entity that was read from the file via the creation interface.
1967 */
addImage(DL_CreationInterface * creationInterface)1968 void DL_Dxf::addImage(DL_CreationInterface* creationInterface) {
1969 DL_ImageData id(// pass ref insead of name we don't have yet
1970 values[340],
1971 // ins point:
1972 toReal(values[10], 0.0),
1973 toReal(values[20], 0.0),
1974 toReal(values[30], 0.0),
1975 // u vector:
1976 toReal(values[11], 1.0),
1977 toReal(values[21], 0.0),
1978 toReal(values[31], 0.0),
1979 // v vector:
1980 toReal(values[12], 0.0),
1981 toReal(values[22], 1.0),
1982 toReal(values[32], 0.0),
1983 // image size (pixel):
1984 toInt(values[13], 1),
1985 toInt(values[23], 1),
1986 // brightness, contrast, fade
1987 toInt(values[281], 50),
1988 toInt(values[282], 50),
1989 toInt(values[283], 0));
1990
1991 creationInterface->addImage(id);
1992 creationInterface->endEntity();
1993 currentEntity = DL_UNKNOWN;
1994 }
1995
1996
1997
1998 /**
1999 * Adds an image definition that was read from the file via the creation interface.
2000 */
addImageDef(DL_CreationInterface * creationInterface)2001 void DL_Dxf::addImageDef(DL_CreationInterface* creationInterface) {
2002 DL_ImageDefData id(// handle
2003 values[5],
2004 values[1]);
2005
2006 creationInterface->linkImage(id);
2007 creationInterface->endEntity();
2008 currentEntity = DL_UNKNOWN;
2009 }
2010
2011
2012
2013 /**
2014 * Ends some special entities like hatches or old style polylines.
2015 */
endEntity(DL_CreationInterface * creationInterface)2016 void DL_Dxf::endEntity(DL_CreationInterface* creationInterface) {
2017 creationInterface->endEntity();
2018 }
2019
2020
2021 /**
2022 * Ends a sequence and notifies the creation interface.
2023 */
endSequence(DL_CreationInterface * creationInterface)2024 void DL_Dxf::endSequence(DL_CreationInterface* creationInterface) {
2025 creationInterface->endSequence();
2026 }
2027
2028
2029 /**
2030 * Converts the given string into an int.
2031 * ok is set to false if there was an error.
2032 */
stringToInt(const char * s,bool * ok)2033 int DL_Dxf::stringToInt(const char* s, bool* ok) {
2034 if (ok!=NULL) {
2035 // check string:
2036 *ok = true;
2037 int i=0;
2038 bool dot = false;
2039 do {
2040 if (s[i]=='\0') {
2041 break;
2042 } else if (s[i]=='.') {
2043 if (dot==true) {
2044 //std::cerr << "two dots\n";
2045 *ok = false;
2046 } else {
2047 dot = true;
2048 }
2049 } else if (s[i]<'0' || s[i]>'9') {
2050 //std::cerr << "NaN: '" << s[i] << "'\n";
2051 *ok = false;
2052 }
2053 i++;
2054 } while(s[i]!='\0' && *ok==true);
2055 }
2056
2057 return atoi(s);
2058 }
2059
2060
2061 /**
2062 * @brief Opens the given file for writing and returns a pointer
2063 * to the dxf writer. This pointer needs to be passed on to other
2064 * writing functions.
2065 *
2066 * @param file Full path of the file to open.
2067 *
2068 * @return Pointer to an ascii dxf writer object.
2069 */
out(const char * file,DL_Codes::version version)2070 DL_WriterA* DL_Dxf::out(const char* file, DL_Codes::version version) {
2071 char* f = new char[strlen(file)+1];
2072 strcpy(f, file);
2073 this->version = version;
2074
2075 DL_WriterA* dw = new DL_WriterA(f, version);
2076 if (dw->openFailed()) {
2077 delete dw;
2078 delete[] f;
2079 return NULL;
2080 } else {
2081 delete[] f;
2082 return dw;
2083 }
2084 }
2085
2086
2087
2088 /**
2089 * @brief Writes a DXF header to the file currently opened
2090 * by the given DXF writer object.
2091 */
writeHeader(DL_WriterA & dw)2092 void DL_Dxf::writeHeader(DL_WriterA& dw) {
2093 dw.comment("dxflib " DL_VERSION);
2094 dw.sectionHeader();
2095
2096 dw.dxfString(9, "$ACADVER");
2097 switch (version) {
2098 case DL_Codes::AC1009:
2099 dw.dxfString(1, "AC1009");
2100 break;
2101 case DL_Codes::AC1012:
2102 dw.dxfString(1, "AC1012");
2103 break;
2104 case DL_Codes::AC1014:
2105 dw.dxfString(1, "AC1014");
2106 break;
2107 case DL_Codes::AC1015:
2108 dw.dxfString(1, "AC1015");
2109 break;
2110 }
2111
2112 // Newer version require that (otherwise a*cad crashes..)
2113 if (version==VER_2000) {
2114 dw.dxfString(9, "$HANDSEED");
2115 dw.dxfHex(5, 0xFFFF);
2116 }
2117
2118 //dw.sectionEnd();
2119 }
2120
2121
2122
2123
2124 /**
2125 * Writes a point entity to the file.
2126 *
2127 * @param dw DXF writer
2128 * @param data Entity data from the file
2129 * @param attrib Attributes
2130 */
writePoint(DL_WriterA & dw,const DL_PointData & data,const DL_Attributes & attrib)2131 void DL_Dxf::writePoint(DL_WriterA& dw,
2132 const DL_PointData& data,
2133 const DL_Attributes& attrib) {
2134 dw.entity("POINT");
2135 if (version==VER_2000) {
2136 dw.dxfString(100, "AcDbEntity");
2137 dw.dxfString(100, "AcDbPoint");
2138 }
2139 dw.entityAttributes(attrib);
2140 dw.coord(POINT_COORD_CODE, data.x, data.y);
2141 }
2142
2143
2144
2145 /**
2146 * Writes a line entity to the file.
2147 *
2148 * @param dw DXF writer
2149 * @param data Entity data from the file
2150 * @param attrib Attributes
2151 */
writeLine(DL_WriterA & dw,const DL_LineData & data,const DL_Attributes & attrib)2152 void DL_Dxf::writeLine(DL_WriterA& dw,
2153 const DL_LineData& data,
2154 const DL_Attributes& attrib) {
2155 dw.entity("LINE");
2156 if (version==VER_2000) {
2157 dw.dxfString(100, "AcDbEntity");
2158 dw.dxfString(100, "AcDbLine");
2159 }
2160 dw.entityAttributes(attrib);
2161 dw.coord(LINE_START_CODE, data.x1, data.y1);
2162 dw.coord(LINE_END_CODE, data.x2, data.y2);
2163 }
2164
2165
2166
2167 /**
2168 * Writes a polyline entity to the file.
2169 *
2170 * @param dw DXF writer
2171 * @param data Entity data from the file
2172 * @param attrib Attributes
2173 * @see writeVertex
2174 */
writePolyline(DL_WriterA & dw,const DL_PolylineData & data,const DL_Attributes & attrib)2175 void DL_Dxf::writePolyline(DL_WriterA& dw,
2176 const DL_PolylineData& data,
2177 const DL_Attributes& attrib) {
2178 if (version==VER_2000) {
2179 dw.entity("LWPOLYLINE");
2180 dw.entityAttributes(attrib);
2181 dw.dxfString(100, "AcDbEntity");
2182 dw.dxfString(100, "AcDbPolyline");
2183 dw.dxfInt(90, (int)data.number);
2184 dw.dxfInt(70, data.flags);
2185 } else {
2186 dw.entity("POLYLINE");
2187 dw.entityAttributes(attrib);
2188 polylineLayer = attrib.getLayer();
2189 dw.dxfInt(66, 1);
2190 dw.dxfInt(70, data.flags);
2191 dw.coord(VERTEX_COORD_CODE, 0.0, 0.0);
2192 }
2193 }
2194
2195
2196
2197 /**
2198 * Writes a single vertex of a polyline to the file.
2199 *
2200 * @param dw DXF writer
2201 * @param data Entity data from the file
2202 * @param attrib Attributes
2203 */
writeVertex(DL_WriterA & dw,const DL_VertexData & data)2204 void DL_Dxf::writeVertex(DL_WriterA& dw,
2205 const DL_VertexData& data) {
2206
2207
2208 if (version==VER_2000) {
2209 dw.dxfReal(10, data.x);
2210 dw.dxfReal(20, data.y);
2211 if (fabs(data.bulge)>1.0e-10) {
2212 dw.dxfReal(42, data.bulge);
2213 }
2214 } else {
2215 dw.entity("VERTEX");
2216 //dw.entityAttributes(attrib);
2217 dw.dxfString(8, polylineLayer);
2218 dw.coord(VERTEX_COORD_CODE, data.x, data.y);
2219 if (fabs(data.bulge)>1.0e-10) {
2220 dw.dxfReal(42, data.bulge);
2221 }
2222 }
2223 }
2224
2225
2226
2227 /**
2228 * Writes the polyline end. Only needed for DXF R12.
2229 */
writePolylineEnd(DL_WriterA & dw)2230 void DL_Dxf::writePolylineEnd(DL_WriterA& dw) {
2231 if (version==VER_2000) {
2232 } else {
2233 dw.entity("SEQEND");
2234 }
2235 }
2236
2237
2238 /**
2239 * Writes a spline entity to the file.
2240 *
2241 * @param dw DXF writer
2242 * @param data Entity data from the file
2243 * @param attrib Attributes
2244 * @see writeControlPoint
2245 */
writeSpline(DL_WriterA & dw,const DL_SplineData & data,const DL_Attributes & attrib)2246 void DL_Dxf::writeSpline(DL_WriterA& dw,
2247 const DL_SplineData& data,
2248 const DL_Attributes& attrib) {
2249
2250 dw.entity("SPLINE");
2251 dw.entityAttributes(attrib);
2252 if (version==VER_2000) {
2253 dw.dxfString(100, "AcDbEntity");
2254 dw.dxfString(100, "AcDbSpline");
2255 }
2256 dw.dxfInt(70, data.flags);
2257 dw.dxfInt(71, data.degree);
2258 dw.dxfInt(72, data.nKnots); // number of knots
2259 dw.dxfInt(73, data.nControl); // number of control points
2260 dw.dxfInt(74, 0); // number of fit points
2261 }
2262
2263
2264
2265 /**
2266 * Writes a single control point of a spline to the file.
2267 *
2268 * @param dw DXF writer
2269 * @param data Entity data from the file
2270 * @param attrib Attributes
2271 */
writeControlPoint(DL_WriterA & dw,const DL_ControlPointData & data)2272 void DL_Dxf::writeControlPoint(DL_WriterA& dw,
2273 const DL_ControlPointData& data) {
2274
2275 dw.dxfReal(10, data.x);
2276 dw.dxfReal(20, data.y);
2277 dw.dxfReal(30, data.z);
2278 }
2279
2280
2281
2282 /**
2283 * Writes a single knot of a spline to the file.
2284 *
2285 * @param dw DXF writer
2286 * @param data Entity data from the file
2287 * @param attrib Attributes
2288 */
writeKnot(DL_WriterA & dw,const DL_KnotData & data)2289 void DL_Dxf::writeKnot(DL_WriterA& dw,
2290 const DL_KnotData& data) {
2291
2292 dw.dxfReal(40, data.k);
2293 }
2294
2295
2296
2297 /**
2298 * Writes a circle entity to the file.
2299 *
2300 * @param dw DXF writer
2301 * @param data Entity data from the file
2302 * @param attrib Attributes
2303 */
writeCircle(DL_WriterA & dw,const DL_CircleData & data,const DL_Attributes & attrib)2304 void DL_Dxf::writeCircle(DL_WriterA& dw,
2305 const DL_CircleData& data,
2306 const DL_Attributes& attrib) {
2307 dw.entity("CIRCLE");
2308 if (version==VER_2000) {
2309 dw.dxfString(100, "AcDbEntity");
2310 dw.dxfString(100, "AcDbCircle");
2311 }
2312 dw.entityAttributes(attrib);
2313 dw.coord(10, data.cx, data.cy);
2314 dw.dxfReal(40, data.radius);
2315 }
2316
2317
2318
2319 /**
2320 * Writes an arc entity to the file.
2321 *
2322 * @param dw DXF writer
2323 * @param data Entity data from the file
2324 * @param attrib Attributes
2325 */
writeArc(DL_WriterA & dw,const DL_ArcData & data,const DL_Attributes & attrib)2326 void DL_Dxf::writeArc(DL_WriterA& dw,
2327 const DL_ArcData& data,
2328 const DL_Attributes& attrib) {
2329 dw.entity("ARC");
2330 if (version==VER_2000) {
2331 dw.dxfString(100, "AcDbEntity");
2332 }
2333 dw.entityAttributes(attrib);
2334 if (version==VER_2000) {
2335 dw.dxfString(100, "AcDbCircle");
2336 }
2337 dw.coord(10, data.cx, data.cy);
2338 dw.dxfReal(40, data.radius);
2339 if (version==VER_2000) {
2340 dw.dxfString(100, "AcDbArc");
2341 }
2342 dw.dxfReal(50, data.angle1);
2343 dw.dxfReal(51, data.angle2);
2344 }
2345
2346
2347
2348 /**
2349 * Writes an ellipse entity to the file.
2350 *
2351 * @param dw DXF writer
2352 * @param data Entity data from the file
2353 * @param attrib Attributes
2354 */
writeEllipse(DL_WriterA & dw,const DL_EllipseData & data,const DL_Attributes & attrib)2355 void DL_Dxf::writeEllipse(DL_WriterA& dw,
2356 const DL_EllipseData& data,
2357 const DL_Attributes& attrib) {
2358
2359 if (version>VER_R12) {
2360 dw.entity("ELLIPSE");
2361 if (version==VER_2000) {
2362 dw.dxfString(100, "AcDbEntity");
2363 dw.dxfString(100, "AcDbEllipse");
2364 }
2365 dw.entityAttributes(attrib);
2366 dw.coord(10, data.cx, data.cy);
2367 dw.coord(11, data.mx, data.my);
2368 dw.dxfReal(40, data.ratio);
2369 dw.dxfReal(41, data.angle1);
2370 dw.dxfReal(42, data.angle2);
2371 }
2372 }
2373
2374
2375
2376 /**
2377 * Writes a solid entity to the file.
2378 *
2379 * @param dw DXF writer
2380 * @param data Entity data from the file
2381 * @param attrib Attributes
2382 */
writeSolid(DL_WriterA & dw,const DL_SolidData & data,const DL_Attributes & attrib)2383 void DL_Dxf::writeSolid(DL_WriterA& dw,
2384 const DL_SolidData& data,
2385 const DL_Attributes& attrib) {
2386 dw.entity("SOLID");
2387 if (version==VER_2000) {
2388 dw.dxfString(100, "AcDbEntity");
2389 dw.dxfString(100, "AcDbTrace");
2390 }
2391 dw.entityAttributes(attrib);
2392 dw.coord(10, data.x[0], data.y[0], data.z[0]);
2393 dw.coord(11, data.x[1], data.y[1], data.z[1]);
2394 dw.coord(12, data.x[2], data.y[2], data.z[2]);
2395 dw.coord(13, data.x[3], data.y[3], data.z[3]);
2396 dw.dxfReal(39, data.thickness);
2397 }
2398
2399
2400
2401 /**
2402 * Writes a 3d face entity to the file.
2403 *
2404 * @param dw DXF writer
2405 * @param data Entity data from the file
2406 * @param attrib Attributes
2407 */
write3dFace(DL_WriterA & dw,const DL_3dFaceData & data,const DL_Attributes & attrib)2408 void DL_Dxf::write3dFace(DL_WriterA& dw,
2409 const DL_3dFaceData& data,
2410 const DL_Attributes& attrib) {
2411 dw.entity("3DFACE");
2412 if (version==VER_2000) {
2413 dw.dxfString(100, "AcDbEntity");
2414 dw.dxfString(100, "AcDbFace");
2415 }
2416 dw.entityAttributes(attrib);
2417 dw.coord(10, data.x[0], data.y[0], data.z[0]);
2418 dw.coord(11, data.x[1], data.y[1], data.z[1]);
2419 dw.coord(12, data.x[2], data.y[2], data.z[2]);
2420 dw.coord(13, data.x[3], data.y[3], data.z[3]);
2421 }
2422
2423
2424
2425 /**
2426 * Writes an insert to the file.
2427 *
2428 * @param dw DXF writer
2429 * @param data Entity data from the file
2430 * @param attrib Attributes
2431 */
writeInsert(DL_WriterA & dw,const DL_InsertData & data,const DL_Attributes & attrib)2432 void DL_Dxf::writeInsert(DL_WriterA& dw,
2433 const DL_InsertData& data,
2434 const DL_Attributes& attrib) {
2435
2436 if (data.name.empty()) {
2437 std::cerr << "DL_Dxf::writeInsert: "
2438 << "Block name must not be empty\n";
2439 return;
2440 }
2441
2442 dw.entity("INSERT");
2443 if (version==VER_2000) {
2444 dw.dxfString(100, "AcDbEntity");
2445 dw.dxfString(100, "AcDbBlockReference");
2446 }
2447 dw.entityAttributes(attrib);
2448 dw.dxfString(2, data.name);
2449 dw.dxfReal(10, data.ipx);
2450 dw.dxfReal(20, data.ipy);
2451 dw.dxfReal(30, 0.0);
2452 if (data.sx!=1.0 || data.sy!=1.0) {
2453 dw.dxfReal(41, data.sx);
2454 dw.dxfReal(42, data.sy);
2455 dw.dxfReal(43, 1.0);
2456 }
2457 if (data.angle!=0.0) {
2458 dw.dxfReal(50, data.angle);
2459 }
2460 if (data.cols!=1 || data.rows!=1) {
2461 dw.dxfInt(70, data.cols);
2462 dw.dxfInt(71, data.rows);
2463 }
2464 if (data.colSp!=0.0 || data.rowSp!=0.0) {
2465 dw.dxfReal(44, data.colSp);
2466 dw.dxfReal(45, data.rowSp);
2467 }
2468
2469 }
2470
2471
2472
2473 /**
2474 * Writes a multi text entity to the file.
2475 *
2476 * @param dw DXF writer
2477 * @param data Entity data from the file
2478 * @param attrib Attributes
2479 */
writeMText(DL_WriterA & dw,const DL_MTextData & data,const DL_Attributes & attrib)2480 void DL_Dxf::writeMText(DL_WriterA& dw,
2481 const DL_MTextData& data,
2482 const DL_Attributes& attrib) {
2483
2484 dw.entity("MTEXT");
2485 if (version==VER_2000) {
2486 dw.dxfString(100, "AcDbEntity");
2487 dw.dxfString(100, "AcDbMText");
2488 }
2489 dw.entityAttributes(attrib);
2490 dw.dxfReal(10, data.ipx);
2491 dw.dxfReal(20, data.ipy);
2492 dw.dxfReal(30, 0.0);
2493 dw.dxfReal(40, data.height);
2494 dw.dxfReal(41, data.width);
2495
2496 dw.dxfInt(71, data.attachmentPoint);
2497 dw.dxfInt(72, data.drawingDirection);
2498
2499 // Creare text chunks of 250 characters each:
2500 int length = data.text.length();
2501 char chunk[251];
2502 int i;
2503 for (i=250; i<length; i+=250) {
2504 strncpy(chunk, &data.text.c_str()[i-250], 250);
2505 chunk[250]='\0';
2506 dw.dxfString(3, chunk);
2507 }
2508 strncpy(chunk, &data.text.c_str()[i-250], 250);
2509 chunk[250]='\0';
2510 dw.dxfString(1, chunk);
2511
2512 dw.dxfString(7, data.style);
2513
2514 // since dxflib 2.0.2.1: degrees not rad (error in autodesk dxf doc)
2515 dw.dxfReal(50, data.angle/(2.0*M_PI)*360.0);
2516
2517 dw.dxfInt(73, data.lineSpacingStyle);
2518 dw.dxfReal(44, data.lineSpacingFactor);
2519 }
2520
2521
2522
2523 /**
2524 * Writes a text entity to the file.
2525 *
2526 * @param dw DXF writer
2527 * @param data Entity data from the file
2528 * @param attrib Attributes
2529 */
writeText(DL_WriterA & dw,const DL_TextData & data,const DL_Attributes & attrib)2530 void DL_Dxf::writeText(DL_WriterA& dw,
2531 const DL_TextData& data,
2532 const DL_Attributes& attrib) {
2533
2534 dw.entity("TEXT");
2535 if (version==VER_2000) {
2536 dw.dxfString(100, "AcDbEntity");
2537 dw.dxfString(100, "AcDbText");
2538 }
2539 dw.entityAttributes(attrib);
2540 dw.dxfReal(10, data.ipx);
2541 dw.dxfReal(20, data.ipy);
2542 dw.dxfReal(30, 0.0);
2543 dw.dxfReal(40, data.height);
2544 dw.dxfString(1, data.text);
2545 dw.dxfReal(50, data.angle/(2*M_PI)*360.0);
2546 dw.dxfReal(41, data.xScaleFactor);
2547 dw.dxfString(7, data.style);
2548
2549 dw.dxfInt(71, data.textGenerationFlags);
2550 dw.dxfInt(72, data.hJustification);
2551
2552 dw.dxfReal(11, data.apx);
2553 dw.dxfReal(21, data.apy);
2554 dw.dxfReal(31, 0.0);
2555
2556 dw.dxfInt(73, data.vJustification);
2557 }
2558
2559
2560 /**
2561 * Writes an aligned dimension entity to the file.
2562 *
2563 * @param dw DXF writer
2564 * @param data Generic dimension data for from the file
2565 * @param data Specific aligned dimension data from the file
2566 * @param attrib Attributes
2567 */
writeDimAligned(DL_WriterA & dw,const DL_DimensionData & data,const DL_DimAlignedData & edata,const DL_Attributes & attrib)2568 void DL_Dxf::writeDimAligned(DL_WriterA& dw,
2569 const DL_DimensionData& data,
2570 const DL_DimAlignedData& edata,
2571 const DL_Attributes& attrib) {
2572
2573 dw.entity("DIMENSION");
2574
2575 if (version==VER_2000) {
2576 dw.dxfString(100, "AcDbEntity");
2577 }
2578 dw.entityAttributes(attrib);
2579 if (version==VER_2000) {
2580 dw.dxfString(100, "AcDbDimension");
2581 }
2582
2583 dw.dxfReal(10, data.dpx);
2584 dw.dxfReal(20, data.dpy);
2585 dw.dxfReal(30, 0.0);
2586
2587 dw.dxfReal(11, data.mpx);
2588 dw.dxfReal(21, data.mpy);
2589 dw.dxfReal(31, 0.0);
2590
2591 dw.dxfInt(70, 1);
2592 if (version>VER_R12) {
2593 dw.dxfInt(71, data.attachmentPoint);
2594 dw.dxfInt(72, data.lineSpacingStyle); // opt
2595 dw.dxfReal(41, data.lineSpacingFactor); // opt
2596 }
2597
2598 dw.dxfReal(42, data.angle);
2599
2600 dw.dxfString(1, data.text); // opt
2601 //dw.dxfString(3, data.style);
2602 dw.dxfString(3, "Standard");
2603
2604 if (version==VER_2000) {
2605 dw.dxfString(100, "AcDbAlignedDimension");
2606 }
2607
2608 dw.dxfReal(13, edata.epx1);
2609 dw.dxfReal(23, edata.epy1);
2610 dw.dxfReal(33, 0.0);
2611
2612 dw.dxfReal(14, edata.epx2);
2613 dw.dxfReal(24, edata.epy2);
2614 dw.dxfReal(34, 0.0);
2615 }
2616
2617
2618
2619 /**
2620 * Writes a linear dimension entity to the file.
2621 *
2622 * @param dw DXF writer
2623 * @param data Generic dimension data for from the file
2624 * @param data Specific linear dimension data from the file
2625 * @param attrib Attributes
2626 */
writeDimLinear(DL_WriterA & dw,const DL_DimensionData & data,const DL_DimLinearData & edata,const DL_Attributes & attrib)2627 void DL_Dxf::writeDimLinear(DL_WriterA& dw,
2628 const DL_DimensionData& data,
2629 const DL_DimLinearData& edata,
2630 const DL_Attributes& attrib) {
2631
2632 dw.entity("DIMENSION");
2633
2634 if (version==VER_2000) {
2635 dw.dxfString(100, "AcDbEntity");
2636 }
2637 dw.entityAttributes(attrib);
2638 if (version==VER_2000) {
2639 dw.dxfString(100, "AcDbDimension");
2640 }
2641
2642 dw.dxfReal(10, data.dpx);
2643 dw.dxfReal(20, data.dpy);
2644 dw.dxfReal(30, 0.0);
2645
2646 dw.dxfReal(11, data.mpx);
2647 dw.dxfReal(21, data.mpy);
2648 dw.dxfReal(31, 0.0);
2649
2650 dw.dxfInt(70, 0);
2651 if (version>VER_R12) {
2652 dw.dxfInt(71, data.attachmentPoint);
2653 dw.dxfInt(72, data.lineSpacingStyle); // opt
2654 dw.dxfReal(41, data.lineSpacingFactor); // opt
2655 }
2656
2657 dw.dxfReal(42, data.angle);
2658
2659 dw.dxfString(1, data.text); // opt
2660 //dw.dxfString(3, data.style);
2661 dw.dxfString(3, "Standard");
2662
2663 if (version==VER_2000) {
2664 dw.dxfString(100, "AcDbAlignedDimension");
2665 }
2666
2667 dw.dxfReal(13, edata.dpx1);
2668 dw.dxfReal(23, edata.dpy1);
2669 dw.dxfReal(33, 0.0);
2670
2671 dw.dxfReal(14, edata.dpx2);
2672 dw.dxfReal(24, edata.dpy2);
2673 dw.dxfReal(34, 0.0);
2674
2675 dw.dxfReal(50, edata.angle/(2.0*M_PI)*360.0);
2676
2677 if (version==VER_2000) {
2678 dw.dxfString(100, "AcDbRotatedDimension");
2679 /*
2680 dw.dxfString(1001, "ACAD");
2681 dw.dxfString(1000, "DSTYLE");
2682 dw.dxfString(1002, "{");
2683 dw.dxfInt(1070, 340);
2684 dw.dxfInt(1005, 11);
2685 dw.dxfString(1002, "}");
2686 */
2687 }
2688 }
2689
2690
2691
2692 /**
2693 * Writes a radial dimension entity to the file.
2694 *
2695 * @param dw DXF writer
2696 * @param data Generic dimension data for from the file
2697 * @param data Specific radial dimension data from the file
2698 * @param attrib Attributes
2699 */
writeDimRadial(DL_WriterA & dw,const DL_DimensionData & data,const DL_DimRadialData & edata,const DL_Attributes & attrib)2700 void DL_Dxf::writeDimRadial(DL_WriterA& dw,
2701 const DL_DimensionData& data,
2702 const DL_DimRadialData& edata,
2703 const DL_Attributes& attrib) {
2704
2705 dw.entity("DIMENSION");
2706
2707 if (version==VER_2000) {
2708 dw.dxfString(100, "AcDbEntity");
2709 }
2710 dw.entityAttributes(attrib);
2711 if (version==VER_2000) {
2712 dw.dxfString(100, "AcDbDimension");
2713 }
2714
2715 dw.dxfReal(10, data.dpx);
2716 dw.dxfReal(20, data.dpy);
2717 dw.dxfReal(30, 0.0);
2718
2719 dw.dxfReal(11, data.mpx);
2720 dw.dxfReal(21, data.mpy);
2721 dw.dxfReal(31, 0.0);
2722
2723 dw.dxfInt(70, 4);
2724 if (version>VER_R12) {
2725 dw.dxfInt(71, data.attachmentPoint);
2726 dw.dxfInt(72, data.lineSpacingStyle); // opt
2727 dw.dxfReal(41, data.lineSpacingFactor); // opt
2728 }
2729
2730 dw.dxfReal(42, data.angle);
2731
2732 dw.dxfString(1, data.text); // opt
2733 //dw.dxfString(3, data.style);
2734 dw.dxfString(3, "Standard");
2735
2736 if (version==VER_2000) {
2737 dw.dxfString(100, "AcDbRadialDimension");
2738 }
2739
2740 dw.dxfReal(15, edata.dpx);
2741 dw.dxfReal(25, edata.dpy);
2742 dw.dxfReal(35, 0.0);
2743
2744 dw.dxfReal(40, edata.leader);
2745 }
2746
2747
2748
2749 /**
2750 * Writes a diametric dimension entity to the file.
2751 *
2752 * @param dw DXF writer
2753 * @param data Generic dimension data for from the file
2754 * @param data Specific diametric dimension data from the file
2755 * @param attrib Attributes
2756 */
writeDimDiametric(DL_WriterA & dw,const DL_DimensionData & data,const DL_DimDiametricData & edata,const DL_Attributes & attrib)2757 void DL_Dxf::writeDimDiametric(DL_WriterA& dw,
2758 const DL_DimensionData& data,
2759 const DL_DimDiametricData& edata,
2760 const DL_Attributes& attrib) {
2761
2762 dw.entity("DIMENSION");
2763
2764 if (version==VER_2000) {
2765 dw.dxfString(100, "AcDbEntity");
2766 }
2767 dw.entityAttributes(attrib);
2768 if (version==VER_2000) {
2769 dw.dxfString(100, "AcDbDimension");
2770 }
2771
2772 dw.dxfReal(10, data.dpx);
2773 dw.dxfReal(20, data.dpy);
2774 dw.dxfReal(30, 0.0);
2775
2776 dw.dxfReal(11, data.mpx);
2777 dw.dxfReal(21, data.mpy);
2778 dw.dxfReal(31, 0.0);
2779
2780 dw.dxfInt(70, 3);
2781 if (version>VER_R12) {
2782 dw.dxfInt(71, data.attachmentPoint);
2783 dw.dxfInt(72, data.lineSpacingStyle); // opt
2784 dw.dxfReal(41, data.lineSpacingFactor); // opt
2785 }
2786
2787 dw.dxfReal(42, data.angle);
2788
2789 dw.dxfString(1, data.text); // opt
2790 //dw.dxfString(3, data.style);
2791 dw.dxfString(3, "Standard");
2792
2793 if (version==VER_2000) {
2794 dw.dxfString(100, "AcDbDiametricDimension");
2795 }
2796
2797 dw.dxfReal(15, edata.dpx);
2798 dw.dxfReal(25, edata.dpy);
2799 dw.dxfReal(35, 0.0);
2800
2801 dw.dxfReal(40, edata.leader);
2802 }
2803
2804
2805
2806 /**
2807 * Writes an angular dimension entity to the file.
2808 *
2809 * @param dw DXF writer
2810 * @param data Generic dimension data for from the file
2811 * @param data Specific angular dimension data from the file
2812 * @param attrib Attributes
2813 */
writeDimAngular(DL_WriterA & dw,const DL_DimensionData & data,const DL_DimAngularData & edata,const DL_Attributes & attrib)2814 void DL_Dxf::writeDimAngular(DL_WriterA& dw,
2815 const DL_DimensionData& data,
2816 const DL_DimAngularData& edata,
2817 const DL_Attributes& attrib) {
2818
2819 dw.entity("DIMENSION");
2820
2821 if (version==VER_2000) {
2822 dw.dxfString(100, "AcDbEntity");
2823 }
2824 dw.entityAttributes(attrib);
2825 if (version==VER_2000) {
2826 dw.dxfString(100, "AcDbDimension");
2827 }
2828
2829 dw.dxfReal(10, data.dpx);
2830 dw.dxfReal(20, data.dpy);
2831 dw.dxfReal(30, 0.0);
2832
2833 dw.dxfReal(11, data.mpx);
2834 dw.dxfReal(21, data.mpy);
2835 dw.dxfReal(31, 0.0);
2836
2837 dw.dxfInt(70, 2);
2838 if (version>VER_R12) {
2839 dw.dxfInt(71, data.attachmentPoint);
2840 dw.dxfInt(72, data.lineSpacingStyle); // opt
2841 dw.dxfReal(41, data.lineSpacingFactor); // opt
2842 }
2843
2844 dw.dxfReal(42, data.angle);
2845
2846 dw.dxfString(1, data.text); // opt
2847 //dw.dxfString(3, data.style);
2848 dw.dxfString(3, "Standard");
2849
2850 if (version==VER_2000) {
2851 dw.dxfString(100, "AcDb2LineAngularDimension");
2852 }
2853
2854 dw.dxfReal(13, edata.dpx1);
2855 dw.dxfReal(23, edata.dpy1);
2856 dw.dxfReal(33, 0.0);
2857
2858 dw.dxfReal(14, edata.dpx2);
2859 dw.dxfReal(24, edata.dpy2);
2860 dw.dxfReal(34, 0.0);
2861
2862 dw.dxfReal(15, edata.dpx3);
2863 dw.dxfReal(25, edata.dpy3);
2864 dw.dxfReal(35, 0.0);
2865
2866 dw.dxfReal(16, edata.dpx4);
2867 dw.dxfReal(26, edata.dpy4);
2868 dw.dxfReal(36, 0.0);
2869 }
2870
2871
2872
2873 /**
2874 * Writes an angular dimension entity (3 points version) to the file.
2875 *
2876 * @param dw DXF writer
2877 * @param data Generic dimension data for from the file
2878 * @param data Specific angular dimension data from the file
2879 * @param attrib Attributes
2880 */
writeDimAngular3P(DL_WriterA & dw,const DL_DimensionData & data,const DL_DimAngular3PData & edata,const DL_Attributes & attrib)2881 void DL_Dxf::writeDimAngular3P(DL_WriterA& dw,
2882 const DL_DimensionData& data,
2883 const DL_DimAngular3PData& edata,
2884 const DL_Attributes& attrib) {
2885
2886 dw.entity("DIMENSION");
2887
2888 if (version==VER_2000) {
2889 dw.dxfString(100, "AcDbEntity");
2890 }
2891 dw.entityAttributes(attrib);
2892 if (version==VER_2000) {
2893 dw.dxfString(100, "AcDbDimension");
2894 }
2895
2896 dw.dxfReal(10, data.dpx);
2897 dw.dxfReal(20, data.dpy);
2898 dw.dxfReal(30, 0.0);
2899
2900 dw.dxfReal(11, data.mpx);
2901 dw.dxfReal(21, data.mpy);
2902 dw.dxfReal(31, 0.0);
2903
2904 dw.dxfInt(70, 5);
2905 if (version>VER_R12) {
2906 dw.dxfInt(71, data.attachmentPoint);
2907 dw.dxfInt(72, data.lineSpacingStyle); // opt
2908 dw.dxfReal(41, data.lineSpacingFactor); // opt
2909 }
2910
2911 dw.dxfReal(42, data.angle);
2912
2913 dw.dxfString(1, data.text); // opt
2914 //dw.dxfString(3, data.style);
2915 dw.dxfString(3, "Standard");
2916
2917 if (version==VER_2000) {
2918 dw.dxfString(100, "AcDb3PointAngularDimension");
2919 }
2920
2921 dw.dxfReal(13, edata.dpx1);
2922 dw.dxfReal(23, edata.dpy1);
2923 dw.dxfReal(33, 0.0);
2924
2925 dw.dxfReal(14, edata.dpx2);
2926 dw.dxfReal(24, edata.dpy2);
2927 dw.dxfReal(34, 0.0);
2928
2929 dw.dxfReal(15, edata.dpx3);
2930 dw.dxfReal(25, edata.dpy3);
2931 dw.dxfReal(35, 0.0);
2932 }
2933
2934
2935
2936
2937 /**
2938 * Writes an ordinate dimension entity to the file.
2939 *
2940 * @param dw DXF writer
2941 * @param data Generic dimension data for from the file
2942 * @param data Specific ordinate dimension data from the file
2943 * @param attrib Attributes
2944 */
writeDimOrdinate(DL_WriterA & dw,const DL_DimensionData & data,const DL_DimOrdinateData & edata,const DL_Attributes & attrib)2945 void DL_Dxf::writeDimOrdinate(DL_WriterA& dw,
2946 const DL_DimensionData& data,
2947 const DL_DimOrdinateData& edata,
2948 const DL_Attributes& attrib) {
2949
2950 dw.entity("DIMENSION");
2951
2952 if (version==VER_2000) {
2953 dw.dxfString(100, "AcDbEntity");
2954 }
2955 dw.entityAttributes(attrib);
2956 if (version==VER_2000) {
2957 dw.dxfString(100, "AcDbDimension");
2958 }
2959
2960 dw.dxfReal(10, data.dpx);
2961 dw.dxfReal(20, data.dpy);
2962 dw.dxfReal(30, 0.0);
2963
2964 dw.dxfReal(11, data.mpx);
2965 dw.dxfReal(21, data.mpy);
2966 dw.dxfReal(31, 0.0);
2967
2968 int type = 6;
2969 if (edata.xtype) {
2970 type+=64;
2971 }
2972
2973 dw.dxfInt(70, type);
2974 if (version>VER_R12) {
2975 dw.dxfInt(71, data.attachmentPoint);
2976 dw.dxfInt(72, data.lineSpacingStyle); // opt
2977 dw.dxfReal(41, data.lineSpacingFactor); // opt
2978 }
2979
2980 dw.dxfString(1, data.text); // opt
2981 //dw.dxfString(3, data.style);
2982 dw.dxfString(3, "Standard");
2983
2984 if (version==VER_2000) {
2985 dw.dxfString(100, "AcDbOrdinateDimension");
2986 }
2987
2988 dw.dxfReal(13, edata.dpx1);
2989 dw.dxfReal(23, edata.dpy1);
2990 dw.dxfReal(33, 0.0);
2991
2992 dw.dxfReal(14, edata.dpx2);
2993 dw.dxfReal(24, edata.dpy2);
2994 dw.dxfReal(34, 0.0);
2995 }
2996
2997
2998
2999 /**
3000 * Writes a leader entity to the file.
3001 *
3002 * @param dw DXF writer
3003 * @param data Entity data from the file
3004 * @param attrib Attributes
3005 * @see writeVertex
3006 */
writeLeader(DL_WriterA & dw,const DL_LeaderData & data,const DL_Attributes & attrib)3007 void DL_Dxf::writeLeader(DL_WriterA& dw,
3008 const DL_LeaderData& data,
3009 const DL_Attributes& attrib) {
3010 if (version>VER_R12) {
3011 dw.entity("LEADER");
3012 dw.entityAttributes(attrib);
3013 if (version==VER_2000) {
3014 dw.dxfString(100, "AcDbEntity");
3015 dw.dxfString(100, "AcDbLeader");
3016 }
3017 dw.dxfString(3, "Standard");
3018 dw.dxfInt(71, data.arrowHeadFlag);
3019 dw.dxfInt(72, data.leaderPathType);
3020 dw.dxfInt(73, data.leaderCreationFlag);
3021 dw.dxfInt(74, data.hooklineDirectionFlag);
3022 dw.dxfInt(75, data.hooklineFlag);
3023 dw.dxfReal(40, data.textAnnotationHeight);
3024 dw.dxfReal(41, data.textAnnotationWidth);
3025 dw.dxfInt(76, data.number);
3026 }
3027 }
3028
3029
3030
3031 /**
3032 * Writes a single vertex of a leader to the file.
3033 *
3034 * @param dw DXF writer
3035 * @param data Entity data
3036 */
writeLeaderVertex(DL_WriterA & dw,const DL_LeaderVertexData & data)3037 void DL_Dxf::writeLeaderVertex(DL_WriterA& dw,
3038 const DL_LeaderVertexData& data) {
3039 if (version>VER_R12) {
3040 dw.dxfReal(10, data.x);
3041 dw.dxfReal(20, data.y);
3042 }
3043 }
3044
3045
3046
3047 /**
3048 * Writes the beginning of a hatch entity to the file.
3049 * This must be followed by one or more writeHatchLoop()
3050 * calls and a writeHatch2() call.
3051 *
3052 * @param dw DXF writer
3053 * @param data Entity data.
3054 * @param attrib Attributes
3055 */
writeHatch1(DL_WriterA & dw,const DL_HatchData & data,const DL_Attributes & attrib)3056 void DL_Dxf::writeHatch1(DL_WriterA& dw,
3057 const DL_HatchData& data,
3058 const DL_Attributes& attrib) {
3059
3060 dw.entity("HATCH");
3061 dw.entityAttributes(attrib);
3062 if (version==VER_2000) {
3063 dw.dxfString(100, "AcDbEntity");
3064 dw.dxfString(100, "AcDbHatch");
3065 }
3066 dw.dxfReal(10, 0.0); // elevation
3067 dw.dxfReal(20, 0.0);
3068 dw.dxfReal(30, 0.0);
3069 dw.dxfReal(210, 0.0); // extrusion dir.
3070 dw.dxfReal(220, 0.0);
3071 dw.dxfReal(230, 1.0);
3072 if (data.solid==false) {
3073 dw.dxfString(2, data.pattern);
3074 } else {
3075 dw.dxfString(2, "SOLID");
3076 }
3077 dw.dxfInt(70, (int)data.solid);
3078 dw.dxfInt(71, 0); // associative
3079 dw.dxfInt(91, data.numLoops);
3080 }
3081
3082
3083
3084 /**
3085 * Writes the end of a hatch entity to the file.
3086 *
3087 * @param dw DXF writer
3088 * @param data Entity data.
3089 * @param attrib Attributes
3090 */
writeHatch2(DL_WriterA & dw,const DL_HatchData & data,const DL_Attributes &)3091 void DL_Dxf::writeHatch2(DL_WriterA& dw,
3092 const DL_HatchData& data,
3093 const DL_Attributes& /*attrib*/) {
3094
3095 dw.dxfInt(75, 0); // odd parity
3096 dw.dxfInt(76, 1); // pattern type
3097 if (data.solid==false) {
3098 dw.dxfReal(52, data.angle);
3099 dw.dxfReal(41, data.scale);
3100 dw.dxfInt(77, 0); // not double
3101 //dw.dxfInt(78, 0);
3102 dw.dxfInt(78, 1);
3103 dw.dxfReal(53, 45.0);
3104 dw.dxfReal(43, 0.0);
3105 dw.dxfReal(44, 0.0);
3106 dw.dxfReal(45, -0.0883883476483184);
3107 dw.dxfReal(46, 0.0883883476483185);
3108 dw.dxfInt(79, 0);
3109 }
3110 dw.dxfInt(98, 0);
3111 }
3112
3113
3114
3115 /**
3116 * Writes the beginning of a hatch loop to the file. This
3117 * must happen after writing the beginning of a hatch entity.
3118 *
3119 * @param dw DXF writer
3120 * @param data Entity data.
3121 * @param attrib Attributes
3122 */
writeHatchLoop1(DL_WriterA & dw,const DL_HatchLoopData & data)3123 void DL_Dxf::writeHatchLoop1(DL_WriterA& dw,
3124 const DL_HatchLoopData& data) {
3125
3126 dw.dxfInt(92, 1);
3127 dw.dxfInt(93, data.numEdges);
3128 //dw.dxfInt(97, 0);
3129 }
3130
3131
3132
3133 /**
3134 * Writes the end of a hatch loop to the file.
3135 *
3136 * @param dw DXF writer
3137 * @param data Entity data.
3138 * @param attrib Attributes
3139 */
writeHatchLoop2(DL_WriterA & dw,const DL_HatchLoopData &)3140 void DL_Dxf::writeHatchLoop2(DL_WriterA& dw,
3141 const DL_HatchLoopData& /*data*/) {
3142
3143 dw.dxfInt(97, 0);
3144 }
3145
3146
3147 /**
3148 * Writes the beginning of a hatch entity to the file.
3149 *
3150 * @param dw DXF writer
3151 * @param data Entity data.
3152 * @param attrib Attributes
3153 */
writeHatchEdge(DL_WriterA & dw,const DL_HatchEdgeData & data)3154 void DL_Dxf::writeHatchEdge(DL_WriterA& dw,
3155 const DL_HatchEdgeData& data) {
3156
3157 dw.dxfInt(72, data.type);
3158
3159 switch (data.type) {
3160 case 1:
3161 dw.dxfReal(10, data.x1);
3162 dw.dxfReal(20, data.y1);
3163 dw.dxfReal(11, data.x2);
3164 dw.dxfReal(21, data.y2);
3165 break;
3166 case 2:
3167 dw.dxfReal(10, data.cx);
3168 dw.dxfReal(20, data.cy);
3169 dw.dxfReal(40, data.radius);
3170 dw.dxfReal(50, data.angle1/(2*M_PI)*360.0);
3171 dw.dxfReal(51, data.angle2/(2*M_PI)*360.0);
3172 dw.dxfInt(73, (int)(data.ccw));
3173 break;
3174 default:
3175 break;
3176 }
3177 }
3178
3179
3180
3181 /**
3182 * Writes an image entity.
3183 *
3184 * @return IMAGEDEF handle. Needed for the IMAGEDEF counterpart.
3185 */
writeImage(DL_WriterA & dw,const DL_ImageData & data,const DL_Attributes & attrib)3186 int DL_Dxf::writeImage(DL_WriterA& dw,
3187 const DL_ImageData& data,
3188 const DL_Attributes& attrib) {
3189
3190 /*if (data.file.empty()) {
3191 std::cerr << "DL_Dxf::writeImage: "
3192 << "Image file must not be empty\n";
3193 return;
3194 }*/
3195
3196 dw.entity("IMAGE");
3197
3198 dw.entityAttributes(attrib);
3199 if (version==VER_2000) {
3200 dw.dxfString(100, "AcDbEntity");
3201 dw.dxfString(100, "AcDbRasterImage");
3202 dw.dxfInt(90, 0);
3203 }
3204 // insertion point
3205 dw.dxfReal(10, data.ipx);
3206 dw.dxfReal(20, data.ipy);
3207 dw.dxfReal(30, 0.0);
3208
3209 // vector along bottom side (1 pixel long)
3210 dw.dxfReal(11, data.ux);
3211 dw.dxfReal(21, data.uy);
3212 dw.dxfReal(31, 0.0);
3213
3214 // vector along left side (1 pixel long)
3215 dw.dxfReal(12, data.vx);
3216 dw.dxfReal(22, data.vy);
3217 dw.dxfReal(32, 0.0);
3218
3219 // image size in pixel
3220 dw.dxfReal(13, data.width);
3221 dw.dxfReal(23, data.height);
3222
3223 // handle of IMAGEDEF object
3224 int handle = dw.incHandle();
3225 dw.dxfHex(340, handle);
3226
3227 // flags
3228 dw.dxfInt(70, 15);
3229
3230 // clipping:
3231 dw.dxfInt(280, 0);
3232
3233 // brightness, contrast, fade
3234 dw.dxfInt(281, data.brightness);
3235 dw.dxfInt(282, data.contrast);
3236 dw.dxfInt(283, data.fade);
3237
3238 return handle;
3239 }
3240
3241
3242
3243 /**
3244 * Writes an image definiition entity.
3245 */
writeImageDef(DL_WriterA & dw,int handle,const DL_ImageData & data)3246 void DL_Dxf::writeImageDef(DL_WriterA& dw,
3247 int handle,
3248 const DL_ImageData& data) {
3249
3250 /*if (data.file.empty()) {
3251 std::cerr << "DL_Dxf::writeImage: "
3252 << "Image file must not be empty\n";
3253 return;
3254 }*/
3255
3256 dw.dxfString(0, "IMAGEDEF");
3257 if (version==VER_2000) {
3258 dw.dxfHex(5, handle);
3259 }
3260
3261 if (version==VER_2000) {
3262 dw.dxfString(100, "AcDbRasterImageDef");
3263 dw.dxfInt(90, 0);
3264 }
3265 // file name:
3266 dw.dxfString(1, data.ref);
3267
3268 // image size in pixel
3269 dw.dxfReal(10, data.width);
3270 dw.dxfReal(20, data.height);
3271
3272 dw.dxfReal(11, 1.0);
3273 dw.dxfReal(21, 1.0);
3274
3275 // loaded:
3276 dw.dxfInt(280, 1);
3277 // units:
3278 dw.dxfInt(281, 0);
3279 }
3280
3281
3282 /**
3283 * Writes a layer to the file. Layers are stored in the
3284 * tables section of a DXF file.
3285 *
3286 * @param dw DXF writer
3287 * @param data Entity data from the file
3288 * @param attrib Attributes
3289 */
writeLayer(DL_WriterA & dw,const DL_LayerData & data,const DL_Attributes & attrib)3290 void DL_Dxf::writeLayer(DL_WriterA& dw,
3291 const DL_LayerData& data,
3292 const DL_Attributes& attrib) {
3293
3294 if (data.name.empty()) {
3295 std::cerr << "DL_Dxf::writeLayer: "
3296 << "Layer name must not be empty\n";
3297 return;
3298 }
3299
3300 int color = attrib.getColor();
3301 if (color>=256) {
3302 std::cerr << "Layer color cannot be " << color << ". Changed to 7.\n";
3303 color = 7;
3304 }
3305
3306 if (data.name == "0") {
3307 dw.tableLayerEntry(0x10);
3308 } else {
3309 dw.tableLayerEntry();
3310 }
3311
3312 dw.dxfString(2, data.name);
3313 dw.dxfInt(70, data.flags);
3314 dw.dxfInt(62, color);
3315
3316 dw.dxfString(6, (attrib.getLineType().length()==0 ?
3317 string("CONTINUOUS") : attrib.getLineType()));
3318
3319 if (version>=VER_2000) {
3320 // layer defpoints cannot be plotted
3321 std::string lstr = data.name;
3322 std::transform(lstr.begin(), lstr.end(), lstr.begin(), tolower);
3323 if (lstr=="defpoints") {
3324 dw.dxfInt(290, 0);
3325 }
3326 }
3327 if (version>=VER_2000 && attrib.getWidth()!=-1) {
3328 dw.dxfInt(370, attrib.getWidth());
3329 }
3330 if (version>=VER_2000) {
3331 dw.dxfHex(390, 0xF);
3332 }
3333 }
3334
3335
3336
3337 /**
3338 * Writes a line type to the file. Line types are stored in the
3339 * tables section of a DXF file.
3340 */
writeLineType(DL_WriterA & dw,const DL_LineTypeData & data)3341 void DL_Dxf::writeLineType(DL_WriterA& dw,
3342 const DL_LineTypeData& data) {
3343 //const char* description,
3344 //int elements,
3345 //double patternLength) {
3346
3347 if (data.name.empty()) {
3348 std::cerr << "DL_Dxf::writeLineType: "
3349 << "Line type name must not be empty\n";
3350 return;
3351 }
3352
3353 // ignore BYLAYER, BYBLOCK for R12
3354 if (version<VER_2000) {
3355 if (!strcasecmp(data.name.c_str(), "BYBLOCK") ||
3356 !strcasecmp(data.name.c_str(), "BYLAYER")) {
3357 return;
3358 }
3359 }
3360
3361 // write id (not for R12)
3362 if (!strcasecmp(data.name.c_str(), "BYBLOCK")) {
3363 dw.tableLineTypeEntry(0x14);
3364 } else if (!strcasecmp(data.name.c_str(), "BYLAYER")) {
3365 dw.tableLineTypeEntry(0x15);
3366 } else if (!strcasecmp(data.name.c_str(), "CONTINUOUS")) {
3367 dw.tableLineTypeEntry(0x16);
3368 } else {
3369 dw.tableLineTypeEntry();
3370 }
3371
3372 dw.dxfString(2, data.name);
3373 //if (version>=VER_2000) {
3374 dw.dxfInt(70, data.flags);
3375 //}
3376
3377 if (!strcasecmp(data.name.c_str(), "BYBLOCK")) {
3378 dw.dxfString(3, "");
3379 dw.dxfInt(72, 65);
3380 dw.dxfInt(73, 0);
3381 dw.dxfReal(40, 0.0);
3382 } else if (!strcasecmp(data.name.c_str(), "BYLAYER")) {
3383 dw.dxfString(3, "");
3384 dw.dxfInt(72, 65);
3385 dw.dxfInt(73, 0);
3386 dw.dxfReal(40, 0.0);
3387 } else if (!strcasecmp(data.name.c_str(), "CONTINUOUS")) {
3388 dw.dxfString(3, "Solid line");
3389 dw.dxfInt(72, 65);
3390 dw.dxfInt(73, 0);
3391 dw.dxfReal(40, 0.0);
3392 } else if (!strcasecmp(data.name.c_str(), "ACAD_ISO02W100")) {
3393 dw.dxfString(3, "ISO Dashed __ __ __ __ __ __ __ __ __ __ _");
3394 dw.dxfInt(72, 65);
3395 dw.dxfInt(73, 2);
3396 dw.dxfReal(40, 15.0);
3397 dw.dxfReal(49, 12.0);
3398 if (version>=VER_R13)
3399 dw.dxfInt(74, 0);
3400 dw.dxfReal(49, -3.0);
3401 if (version>=VER_R13)
3402 dw.dxfInt(74, 0);
3403 } else if (!strcasecmp(data.name.c_str(), "ACAD_ISO03W100")) {
3404 dw.dxfString(3, "ISO Dashed with Distance __ __ __ _");
3405 dw.dxfInt(72, 65);
3406 dw.dxfInt(73, 2);
3407 dw.dxfReal(40, 30.0);
3408 dw.dxfReal(49, 12.0);
3409 if (version>=VER_R13)
3410 dw.dxfInt(74, 0);
3411 dw.dxfReal(49, -18.0);
3412 if (version>=VER_R13)
3413 dw.dxfInt(74, 0);
3414 } else if (!strcasecmp(data.name.c_str(), "ACAD_ISO04W100")) {
3415 dw.dxfString(3, "ISO Long Dashed Dotted ____ . ____ . __");
3416 dw.dxfInt(72, 65);
3417 dw.dxfInt(73, 4);
3418 dw.dxfReal(40, 30.0);
3419 dw.dxfReal(49, 24.0);
3420 if (version>=VER_R13)
3421 dw.dxfInt(74, 0);
3422 dw.dxfReal(49, -3.0);
3423 if (version>=VER_R13)
3424 dw.dxfInt(74, 0);
3425 dw.dxfReal(49, 0.0);
3426 if (version>=VER_R13)
3427 dw.dxfInt(74, 0);
3428 dw.dxfReal(49, -3.0);
3429 if (version>=VER_R13)
3430 dw.dxfInt(74, 0);
3431 } else if (!strcasecmp(data.name.c_str(), "ACAD_ISO05W100")) {
3432 dw.dxfString(3, "ISO Long Dashed Double Dotted ____ .. __");
3433 dw.dxfInt(72, 65);
3434 dw.dxfInt(73, 6);
3435 dw.dxfReal(40, 33.0);
3436 dw.dxfReal(49, 24.0);
3437 if (version>=VER_R13)
3438 dw.dxfInt(74, 0);
3439 dw.dxfReal(49, -3.0);
3440 if (version>=VER_R13)
3441 dw.dxfInt(74, 0);
3442 dw.dxfReal(49, 0.0);
3443 if (version>=VER_R13)
3444 dw.dxfInt(74, 0);
3445 dw.dxfReal(49, -3.0);
3446 if (version>=VER_R13)
3447 dw.dxfInt(74, 0);
3448 dw.dxfReal(49, 0.0);
3449 if (version>=VER_R13)
3450 dw.dxfInt(74, 0);
3451 dw.dxfReal(49, -3.0);
3452 if (version>=VER_R13)
3453 dw.dxfInt(74, 0);
3454 } else if (!strcasecmp(data.name.c_str(), "BORDER")) {
3455 dw.dxfString(3, "Border __ __ . __ __ . __ __ . __ __ . __ __ .");
3456 dw.dxfInt(72, 65);
3457 dw.dxfInt(73, 6);
3458 dw.dxfReal(40, 44.45);
3459 dw.dxfReal(49, 12.7);
3460 if (version>=VER_R13)
3461 dw.dxfInt(74, 0);
3462 dw.dxfReal(49, -6.35);
3463 if (version>=VER_R13)
3464 dw.dxfInt(74, 0);
3465 dw.dxfReal(49, 12.7);
3466 if (version>=VER_R13)
3467 dw.dxfInt(74, 0);
3468 dw.dxfReal(49, -6.35);
3469 if (version>=VER_R13)
3470 dw.dxfInt(74, 0);
3471 dw.dxfReal(49, 0.0);
3472 if (version>=VER_R13)
3473 dw.dxfInt(74, 0);
3474 dw.dxfReal(49, -6.35);
3475 if (version>=VER_R13)
3476 dw.dxfInt(74, 0);
3477 } else if (!strcasecmp(data.name.c_str(), "BORDER2")) {
3478 dw.dxfString(3, "Border (.5x) __.__.__.__.__.__.__.__.__.__.__.");
3479 dw.dxfInt(72, 65);
3480 dw.dxfInt(73, 6);
3481 dw.dxfReal(40, 22.225);
3482 dw.dxfReal(49, 6.35);
3483 if (version>=VER_R13)
3484 dw.dxfInt(74, 0);
3485 dw.dxfReal(49, -3.175);
3486 if (version>=VER_R13)
3487 dw.dxfInt(74, 0);
3488 dw.dxfReal(49, 6.35);
3489 if (version>=VER_R13)
3490 dw.dxfInt(74, 0);
3491 dw.dxfReal(49, -3.175);
3492 if (version>=VER_R13)
3493 dw.dxfInt(74, 0);
3494 dw.dxfReal(49, 0.0);
3495 if (version>=VER_R13)
3496 dw.dxfInt(74, 0);
3497 dw.dxfReal(49, -3.175);
3498 if (version>=VER_R13)
3499 dw.dxfInt(74, 0);
3500 } else if (!strcasecmp(data.name.c_str(), "BORDERX2")) {
3501 dw.dxfString(3, "Border (2x) ____ ____ . ____ ____ . ___");
3502 dw.dxfInt(72, 65);
3503 dw.dxfInt(73, 6);
3504 dw.dxfReal(40, 88.9);
3505 dw.dxfReal(49, 25.4);
3506 if (version>=VER_R13)
3507 dw.dxfInt(74, 0);
3508 dw.dxfReal(49, -12.7);
3509 if (version>=VER_R13)
3510 dw.dxfInt(74, 0);
3511 dw.dxfReal(49, 25.4);
3512 if (version>=VER_R13)
3513 dw.dxfInt(74, 0);
3514 dw.dxfReal(49, -12.7);
3515 if (version>=VER_R13)
3516 dw.dxfInt(74, 0);
3517 dw.dxfReal(49, 0.0);
3518 if (version>=VER_R13)
3519 dw.dxfInt(74, 0);
3520 dw.dxfReal(49, -12.7);
3521 if (version>=VER_R13)
3522 dw.dxfInt(74, 0);
3523 } else if (!strcasecmp(data.name.c_str(), "CENTER")) {
3524 dw.dxfString(3, "Center ____ _ ____ _ ____ _ ____ _ ____ _ ____");
3525 dw.dxfInt(72, 65);
3526 dw.dxfInt(73, 4);
3527 dw.dxfReal(40, 50.8);
3528 dw.dxfReal(49, 31.75);
3529 if (version>=VER_R13)
3530 dw.dxfInt(74, 0);
3531 dw.dxfReal(49, -6.35);
3532 if (version>=VER_R13)
3533 dw.dxfInt(74, 0);
3534 dw.dxfReal(49, 6.35);
3535 if (version>=VER_R13)
3536 dw.dxfInt(74, 0);
3537 dw.dxfReal(49, -6.35);
3538 if (version>=VER_R13)
3539 dw.dxfInt(74, 0);
3540 } else if (!strcasecmp(data.name.c_str(), "CENTER2")) {
3541 dw.dxfString(3, "Center (.5x) ___ _ ___ _ ___ _ ___ _ ___ _ ___");
3542 dw.dxfInt(72, 65);
3543 dw.dxfInt(73, 4);
3544 dw.dxfReal(40, 28.575);
3545 dw.dxfReal(49, 19.05);
3546 if (version>=VER_R13)
3547 dw.dxfInt(74, 0);
3548 dw.dxfReal(49, -3.175);
3549 if (version>=VER_R13)
3550 dw.dxfInt(74, 0);
3551 dw.dxfReal(49, 3.175);
3552 if (version>=VER_R13)
3553 dw.dxfInt(74, 0);
3554 dw.dxfReal(49, -3.175);
3555 if (version>=VER_R13)
3556 dw.dxfInt(74, 0);
3557 } else if (!strcasecmp(data.name.c_str(), "CENTERX2")) {
3558 dw.dxfString(3, "Center (2x) ________ __ ________ __ _____");
3559 dw.dxfInt(72, 65);
3560 dw.dxfInt(73, 4);
3561 dw.dxfReal(40, 101.6);
3562 dw.dxfReal(49, 63.5);
3563 if (version>=VER_R13)
3564 dw.dxfInt(74, 0);
3565 dw.dxfReal(49, -12.7);
3566 if (version>=VER_R13)
3567 dw.dxfInt(74, 0);
3568 dw.dxfReal(49, 12.7);
3569 if (version>=VER_R13)
3570 dw.dxfInt(74, 0);
3571 dw.dxfReal(49, -12.7);
3572 if (version>=VER_R13)
3573 dw.dxfInt(74, 0);
3574 } else if (!strcasecmp(data.name.c_str(), "DASHDOT")) {
3575 dw.dxfString(3, "Dash dot __ . __ . __ . __ . __ . __ . __ . __");
3576 dw.dxfInt(72, 65);
3577 dw.dxfInt(73, 4);
3578 dw.dxfReal(40, 25.4);
3579 dw.dxfReal(49, 12.7);
3580 if (version>=VER_R13)
3581 dw.dxfInt(74, 0);
3582 dw.dxfReal(49, -6.35);
3583 if (version>=VER_R13)
3584 dw.dxfInt(74, 0);
3585 dw.dxfReal(49, 0.0);
3586 if (version>=VER_R13)
3587 dw.dxfInt(74, 0);
3588 dw.dxfReal(49, -6.35);
3589 if (version>=VER_R13)
3590 dw.dxfInt(74, 0);
3591 } else if (!strcasecmp(data.name.c_str(), "DASHDOT2")) {
3592 dw.dxfString(3, "Dash dot (.5x) _._._._._._._._._._._._._._._.");
3593 dw.dxfInt(72, 65);
3594 dw.dxfInt(73, 4);
3595 dw.dxfReal(40, 12.7);
3596 dw.dxfReal(49, 6.35);
3597 if (version>=VER_R13)
3598 dw.dxfInt(74, 0);
3599 dw.dxfReal(49, -3.175);
3600 if (version>=VER_R13)
3601 dw.dxfInt(74, 0);
3602 dw.dxfReal(49, 0.0);
3603 if (version>=VER_R13)
3604 dw.dxfInt(74, 0);
3605 dw.dxfReal(49, -3.175);
3606 if (version>=VER_R13)
3607 dw.dxfInt(74, 0);
3608 } else if (!strcasecmp(data.name.c_str(), "DASHDOTX2")) {
3609 dw.dxfString(3, "Dash dot (2x) ____ . ____ . ____ . ___");
3610 dw.dxfInt(72, 65);
3611 dw.dxfInt(73, 4);
3612 dw.dxfReal(40, 50.8);
3613 dw.dxfReal(49, 25.4);
3614 if (version>=VER_R13)
3615 dw.dxfInt(74, 0);
3616 dw.dxfReal(49, -12.7);
3617 if (version>=VER_R13)
3618 dw.dxfInt(74, 0);
3619 dw.dxfReal(49, 0.0);
3620 if (version>=VER_R13)
3621 dw.dxfInt(74, 0);
3622 dw.dxfReal(49, -12.7);
3623 if (version>=VER_R13)
3624 dw.dxfInt(74, 0);
3625 } else if (!strcasecmp(data.name.c_str(), "DASHED")) {
3626 dw.dxfString(3, "Dashed __ __ __ __ __ __ __ __ __ __ __ __ __ _");
3627 dw.dxfInt(72, 65);
3628 dw.dxfInt(73, 2);
3629 dw.dxfReal(40, 19.05);
3630 dw.dxfReal(49, 12.7);
3631 if (version>=VER_R13)
3632 dw.dxfInt(74, 0);
3633 dw.dxfReal(49, -6.35);
3634 if (version>=VER_R13)
3635 dw.dxfInt(74, 0);
3636 } else if (!strcasecmp(data.name.c_str(), "DASHED2")) {
3637 dw.dxfString(3, "Dashed (.5x) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _");
3638 dw.dxfInt(72, 65);
3639 dw.dxfInt(73, 2);
3640 dw.dxfReal(40, 9.525);
3641 dw.dxfReal(49, 6.35);
3642 if (version>=VER_R13)
3643 dw.dxfInt(74, 0);
3644 dw.dxfReal(49, -3.175);
3645 if (version>=VER_R13)
3646 dw.dxfInt(74, 0);
3647 } else if (!strcasecmp(data.name.c_str(), "DASHEDX2")) {
3648 dw.dxfString(3, "Dashed (2x) ____ ____ ____ ____ ____ ___");
3649 dw.dxfInt(72, 65);
3650 dw.dxfInt(73, 2);
3651 dw.dxfReal(40, 38.1);
3652 dw.dxfReal(49, 25.4);
3653 if (version>=VER_R13)
3654 dw.dxfInt(74, 0);
3655 dw.dxfReal(49, -12.7);
3656 if (version>=VER_R13)
3657 dw.dxfInt(74, 0);
3658 } else if (!strcasecmp(data.name.c_str(), "DIVIDE")) {
3659 dw.dxfString(3, "Divide ____ . . ____ . . ____ . . ____ . . ____");
3660 dw.dxfInt(72, 65);
3661 dw.dxfInt(73, 6);
3662 dw.dxfReal(40, 31.75);
3663 dw.dxfReal(49, 12.7);
3664 if (version>=VER_R13)
3665 dw.dxfInt(74, 0);
3666 dw.dxfReal(49, -6.35);
3667 if (version>=VER_R13)
3668 dw.dxfInt(74, 0);
3669 dw.dxfReal(49, 0.0);
3670 if (version>=VER_R13)
3671 dw.dxfInt(74, 0);
3672 dw.dxfReal(49, -6.35);
3673 if (version>=VER_R13)
3674 dw.dxfInt(74, 0);
3675 dw.dxfReal(49, 0.0);
3676 if (version>=VER_R13)
3677 dw.dxfInt(74, 0);
3678 dw.dxfReal(49, -6.35);
3679 if (version>=VER_R13)
3680 dw.dxfInt(74, 0);
3681 } else if (!strcasecmp(data.name.c_str(), "DIVIDE2")) {
3682 dw.dxfString(3, "Divide (.5x) __..__..__..__..__..__..__..__.._");
3683 dw.dxfInt(72, 65);
3684 dw.dxfInt(73, 6);
3685 dw.dxfReal(40, 15.875);
3686 dw.dxfReal(49, 6.35);
3687 if (version>=VER_R13)
3688 dw.dxfInt(74, 0);
3689 dw.dxfReal(49, -3.175);
3690 if (version>=VER_R13)
3691 dw.dxfInt(74, 0);
3692 dw.dxfReal(49, 0.0);
3693 if (version>=VER_R13)
3694 dw.dxfInt(74, 0);
3695 dw.dxfReal(49, -3.175);
3696 if (version>=VER_R13)
3697 dw.dxfInt(74, 0);
3698 dw.dxfReal(49, 0.0);
3699 if (version>=VER_R13)
3700 dw.dxfInt(74, 0);
3701 dw.dxfReal(49, -3.175);
3702 if (version>=VER_R13)
3703 dw.dxfInt(74, 0);
3704 } else if (!strcasecmp(data.name.c_str(), "DIVIDEX2")) {
3705 dw.dxfString(3, "Divide (2x) ________ . . ________ . . _");
3706 dw.dxfInt(72, 65);
3707 dw.dxfInt(73, 6);
3708 dw.dxfReal(40, 63.5);
3709 dw.dxfReal(49, 25.4);
3710 if (version>=VER_R13)
3711 dw.dxfInt(74, 0);
3712 dw.dxfReal(49, -12.7);
3713 if (version>=VER_R13)
3714 dw.dxfInt(74, 0);
3715 dw.dxfReal(49, 0.0);
3716 if (version>=VER_R13)
3717 dw.dxfInt(74, 0);
3718 dw.dxfReal(49, -12.7);
3719 if (version>=VER_R13)
3720 dw.dxfInt(74, 0);
3721 dw.dxfReal(49, 0.0);
3722 if (version>=VER_R13)
3723 dw.dxfInt(74, 0);
3724 dw.dxfReal(49, -12.7);
3725 if (version>=VER_R13)
3726 dw.dxfInt(74, 0);
3727 } else if (!strcasecmp(data.name.c_str(), "DOT")) {
3728 dw.dxfString(3, "Dot . . . . . . . . . . . . . . . . . . . . . .");
3729 dw.dxfInt(72, 65);
3730 dw.dxfInt(73, 2);
3731 dw.dxfReal(40, 6.35);
3732 dw.dxfReal(49, 0.0);
3733 if (version>=VER_R13)
3734 dw.dxfInt(74, 0);
3735 dw.dxfReal(49, -6.35);
3736 if (version>=VER_R13)
3737 dw.dxfInt(74, 0);
3738 } else if (!strcasecmp(data.name.c_str(), "DOT2")) {
3739 dw.dxfString(3, "Dot (.5x) .....................................");
3740 dw.dxfInt(72, 65);
3741 dw.dxfInt(73, 2);
3742 dw.dxfReal(40, 3.175);
3743 dw.dxfReal(49, 0.0);
3744 if (version>=VER_R13)
3745 dw.dxfInt(74, 0);
3746 dw.dxfReal(49, -3.175);
3747 if (version>=VER_R13)
3748 dw.dxfInt(74, 0);
3749 } else if (!strcasecmp(data.name.c_str(), "DOTX2")) {
3750 dw.dxfString(3, "Dot (2x) . . . . . . . . . . . . .");
3751 dw.dxfInt(72, 65);
3752 dw.dxfInt(73, 2);
3753 dw.dxfReal(40, 12.7);
3754 dw.dxfReal(49, 0.0);
3755 if (version>=VER_R13)
3756 dw.dxfInt(74, 0);
3757 dw.dxfReal(49, -12.7);
3758 if (version>=VER_R13)
3759 dw.dxfInt(74, 0);
3760 } else {
3761 std::cerr << "dxflib warning: DL_Dxf::writeLineType: Unknown Line Type\n";
3762 }
3763 }
3764
3765
3766
3767 /**
3768 * Writes the APPID section to the DXF file.
3769 *
3770 * @param name Application name
3771 */
writeAppid(DL_WriterA & dw,const string & name)3772 void DL_Dxf::writeAppid(DL_WriterA& dw, const string& name) {
3773 if (name.empty()) {
3774 std::cerr << "DL_Dxf::writeAppid: "
3775 << "Application name must not be empty\n";
3776 return;
3777 }
3778
3779 if (!strcasecmp(name.c_str(), "ACAD")) {
3780 dw.tableAppidEntry(0x12);
3781 } else {
3782 dw.tableAppidEntry();
3783 }
3784 dw.dxfString(2, name);
3785 dw.dxfInt(70, 0);
3786 }
3787
3788
3789
3790 /**
3791 * Writes a block's definition (no entities) to the DXF file.
3792 */
writeBlock(DL_WriterA & dw,const DL_BlockData & data)3793 void DL_Dxf::writeBlock(DL_WriterA& dw, const DL_BlockData& data) {
3794 if (data.name.empty()) {
3795 std::cerr << "DL_Dxf::writeBlock: "
3796 << "Block name must not be empty\n";
3797 return;
3798 }
3799
3800 //bool paperSpace = !strcasecmp(name, "*paper_space");
3801 //!strcasecmp(name, "*paper_space0");
3802
3803 if (!strcasecmp(data.name.c_str(), "*paper_space")) {
3804 dw.sectionBlockEntry(0x1C);
3805 } else if (!strcasecmp(data.name.c_str(), "*model_space")) {
3806 dw.sectionBlockEntry(0x20);
3807 } else if (!strcasecmp(data.name.c_str(), "*paper_space0")) {
3808 dw.sectionBlockEntry(0x24);
3809 } else {
3810 dw.sectionBlockEntry();
3811 }
3812 dw.dxfString(2, data.name);
3813 dw.dxfInt(70, 0);
3814 dw.coord(10, data.bpx, data.bpy);
3815 dw.dxfString(3, data.name);
3816 dw.dxfString(1, "");
3817 }
3818
3819
3820
3821 /**
3822 * Writes a block end.
3823 *
3824 * @param name Block name
3825 */
writeEndBlock(DL_WriterA & dw,const string & name)3826 void DL_Dxf::writeEndBlock(DL_WriterA& dw, const string& name) {
3827 if (!strcasecmp(name.c_str(), "*paper_space")) {
3828 dw.sectionBlockEntryEnd(0x1D);
3829 } else if (!strcasecmp(name.c_str(), "*model_space")) {
3830 dw.sectionBlockEntryEnd(0x21);
3831 } else if (!strcasecmp(name.c_str(), "*paper_space0")) {
3832 dw.sectionBlockEntryEnd(0x25);
3833 } else {
3834 dw.sectionBlockEntryEnd();
3835 }
3836 }
3837
3838
3839
3840 /**
3841 * Writes a viewport section. This section is needed in VER_R13.
3842 * Note that this method currently only writes a faked VPORT section
3843 * to make the file readable by Aut*cad.
3844 */
writeVPort(DL_WriterA & dw)3845 void DL_Dxf::writeVPort(DL_WriterA& dw) {
3846 dw.dxfString(0, "TABLE");
3847 dw.dxfString(2, "VPORT");
3848 if (version==VER_2000) {
3849 dw.dxfHex(5, 0x8);
3850 }
3851 //dw.dxfHex(330, 0);
3852 if (version==VER_2000) {
3853 dw.dxfString(100, "AcDbSymbolTable");
3854 }
3855 dw.dxfInt(70, 1);
3856 dw.dxfString(0, "VPORT");
3857 //dw.dxfHex(5, 0x2F);
3858 if (version==VER_2000) {
3859 dw.handle();
3860 }
3861 //dw.dxfHex(330, 8);
3862 if (version==VER_2000) {
3863 dw.dxfString(100, "AcDbSymbolTableRecord");
3864 dw.dxfString(100, "AcDbViewportTableRecord");
3865 }
3866 dw.dxfString( 2, "*Active");
3867 dw.dxfInt( 70, 0);
3868 dw.dxfReal( 10, 0.0);
3869 dw.dxfReal( 20, 0.0);
3870 dw.dxfReal( 11, 1.0);
3871 dw.dxfReal( 21, 1.0);
3872 dw.dxfReal( 12, 286.3055555555555);
3873 dw.dxfReal( 22, 148.5);
3874 dw.dxfReal( 13, 0.0);
3875 dw.dxfReal( 23, 0.0);
3876 dw.dxfReal( 14, 10.0);
3877 dw.dxfReal( 24, 10.0);
3878 dw.dxfReal( 15, 10.0);
3879 dw.dxfReal( 25, 10.0);
3880 dw.dxfReal( 16, 0.0);
3881 dw.dxfReal( 26, 0.0);
3882 dw.dxfReal( 36, 1.0);
3883 dw.dxfReal( 17, 0.0);
3884 dw.dxfReal( 27, 0.0);
3885 dw.dxfReal( 37, 0.0);
3886 dw.dxfReal( 40, 297.0);
3887 dw.dxfReal( 41, 1.92798353909465);
3888 dw.dxfReal( 42, 50.0);
3889 dw.dxfReal( 43, 0.0);
3890 dw.dxfReal( 44, 0.0);
3891 dw.dxfReal( 50, 0.0);
3892 dw.dxfReal( 51, 0.0);
3893 dw.dxfInt( 71, 0);
3894 dw.dxfInt( 72, 100);
3895 dw.dxfInt( 73, 1);
3896 dw.dxfInt( 74, 3);
3897 dw.dxfInt( 75, 1);
3898 dw.dxfInt( 76, 1);
3899 dw.dxfInt( 77, 0);
3900 dw.dxfInt( 78, 0);
3901
3902 if (version==VER_2000) {
3903 dw.dxfInt(281, 0);
3904 dw.dxfInt( 65, 1);
3905 dw.dxfReal(110, 0.0);
3906 dw.dxfReal(120, 0.0);
3907 dw.dxfReal(130, 0.0);
3908 dw.dxfReal(111, 1.0);
3909 dw.dxfReal(121, 0.0);
3910 dw.dxfReal(131, 0.0);
3911 dw.dxfReal(112, 0.0);
3912 dw.dxfReal(122, 1.0);
3913 dw.dxfReal(132, 0.0);
3914 dw.dxfInt( 79, 0);
3915 dw.dxfReal(146, 0.0);
3916 }
3917 dw.dxfString( 0, "ENDTAB");
3918 }
3919
3920
3921
3922 /**
3923 * Writes a style section. This section is needed in VER_R13.
3924 * Note that this method currently only writes a faked STYLE section
3925 * to make the file readable by Aut*cad.
3926 */
writeStyle(DL_WriterA & dw)3927 void DL_Dxf::writeStyle(DL_WriterA& dw) {
3928 dw.dxfString( 0, "TABLE");
3929 dw.dxfString( 2, "STYLE");
3930 if (version==VER_2000) {
3931 dw.dxfHex(5, 3);
3932 }
3933 //dw.dxfHex(330, 0);
3934 if (version==VER_2000) {
3935 dw.dxfString(100, "AcDbSymbolTable");
3936 }
3937 dw.dxfInt( 70, 1);
3938 dw.dxfString( 0, "STYLE");
3939 if (version==VER_2000) {
3940 dw.dxfHex(5, 0x11);
3941 }
3942 //styleHandleStd = dw.handle();
3943 //dw.dxfHex(330, 3);
3944 if (version==VER_2000) {
3945 dw.dxfString(100, "AcDbSymbolTableRecord");
3946 dw.dxfString(100, "AcDbTextStyleTableRecord");
3947 }
3948 dw.dxfString( 2, "Standard");
3949 dw.dxfInt( 70, 0);
3950 dw.dxfReal( 40, 0.0);
3951 dw.dxfReal( 41, 0.75);
3952 dw.dxfReal( 50, 0.0);
3953 dw.dxfInt( 71, 0);
3954 dw.dxfReal( 42, 2.5);
3955 dw.dxfString( 3, "txt");
3956 dw.dxfString( 4, "");
3957 dw.dxfString( 0, "ENDTAB");
3958 }
3959
3960
3961
3962 /**
3963 * Writes a view section. This section is needed in VER_R13.
3964 * Note that this method currently only writes a faked VIEW section
3965 * to make the file readable by Aut*cad.
3966 */
writeView(DL_WriterA & dw)3967 void DL_Dxf::writeView(DL_WriterA& dw) {
3968 dw.dxfString( 0, "TABLE");
3969 dw.dxfString( 2, "VIEW");
3970 if (version==VER_2000) {
3971 dw.dxfHex(5, 6);
3972 }
3973 //dw.dxfHex(330, 0);
3974 if (version==VER_2000) {
3975 dw.dxfString(100, "AcDbSymbolTable");
3976 }
3977 dw.dxfInt( 70, 0);
3978 dw.dxfString( 0, "ENDTAB");
3979 }
3980
3981
3982
3983 /**
3984 * Writes a ucs section. This section is needed in VER_R13.
3985 * Note that this method currently only writes a faked UCS section
3986 * to make the file readable by Aut*cad.
3987 */
writeUcs(DL_WriterA & dw)3988 void DL_Dxf::writeUcs(DL_WriterA& dw) {
3989 dw.dxfString( 0, "TABLE");
3990 dw.dxfString( 2, "UCS");
3991 if (version==VER_2000) {
3992 dw.dxfHex(5, 7);
3993 }
3994 //dw.dxfHex(330, 0);
3995 if (version==VER_2000) {
3996 dw.dxfString(100, "AcDbSymbolTable");
3997 }
3998 dw.dxfInt( 70, 0);
3999 dw.dxfString( 0, "ENDTAB");
4000 }
4001
4002
4003
4004 /**
4005 * Writes a dimstyle section. This section is needed in VER_R13.
4006 * Note that this method currently only writes a faked DIMSTYLE section
4007 * to make the file readable by Aut*cad.
4008 */
writeDimStyle(DL_WriterA & dw,double dimasz,double dimexe,double dimexo,double dimgap,double dimtxt)4009 void DL_Dxf::writeDimStyle(DL_WriterA& dw,
4010 double dimasz, double dimexe, double dimexo,
4011 double dimgap, double dimtxt) {
4012
4013 dw.dxfString( 0, "TABLE");
4014 dw.dxfString( 2, "DIMSTYLE");
4015 if (version==VER_2000) {
4016 dw.dxfHex(5, 0xA);
4017 dw.dxfString(100, "AcDbSymbolTable");
4018 }
4019 dw.dxfInt( 70, 1);
4020 if (version==VER_2000) {
4021 dw.dxfString(100, "AcDbDimStyleTable");
4022 dw.dxfInt( 71, 0);
4023 }
4024
4025
4026 dw.dxfString( 0, "DIMSTYLE");
4027 if (version==VER_2000) {
4028 dw.dxfHex(105, 0x27);
4029 }
4030 //dw.handle(105);
4031 //dw.dxfHex(330, 0xA);
4032 if (version==VER_2000) {
4033 dw.dxfString(100, "AcDbSymbolTableRecord");
4034 dw.dxfString(100, "AcDbDimStyleTableRecord");
4035 }
4036 dw.dxfString( 2, "Standard");
4037 if (version==VER_R12) {
4038 dw.dxfString( 3, "");
4039 dw.dxfString( 4, "");
4040 dw.dxfString( 5, "");
4041 dw.dxfString( 6, "");
4042 dw.dxfString( 7, "");
4043 dw.dxfReal( 40, 1.0);
4044 }
4045
4046 dw.dxfReal( 41, dimasz);
4047 dw.dxfReal( 42, dimexo);
4048 dw.dxfReal( 43, 3.75);
4049 dw.dxfReal( 44, dimexe);
4050 if (version==VER_R12) {
4051 dw.dxfReal( 45, 0.0);
4052 dw.dxfReal( 46, 0.0);
4053 dw.dxfReal( 47, 0.0);
4054 dw.dxfReal( 48, 0.0);
4055 }
4056 dw.dxfInt( 70, 0);
4057 if (version==VER_R12) {
4058 dw.dxfInt( 71, 0);
4059 dw.dxfInt( 72, 0);
4060 }
4061 dw.dxfInt( 73, 0);
4062 dw.dxfInt( 74, 0);
4063 if (version==VER_R12) {
4064 dw.dxfInt( 75, 0);
4065 dw.dxfInt( 76, 0);
4066 }
4067 dw.dxfInt( 77, 1);
4068 dw.dxfInt( 78, 8);
4069 dw.dxfReal(140, dimtxt);
4070 dw.dxfReal(141, 2.5);
4071 if (version==VER_R12) {
4072 dw.dxfReal(142, 0.0);
4073 }
4074 dw.dxfReal(143, 0.03937007874016);
4075 if (version==VER_R12) {
4076 dw.dxfReal(144, 1.0);
4077 dw.dxfReal(145, 0.0);
4078 dw.dxfReal(146, 1.0);
4079 }
4080 dw.dxfReal(147, dimgap);
4081 if (version==VER_R12) {
4082 dw.dxfInt(170, 0);
4083 }
4084 dw.dxfInt(171, 3);
4085 dw.dxfInt(172, 1);
4086 if (version==VER_R12) {
4087 dw.dxfInt(173, 0);
4088 dw.dxfInt(174, 0);
4089 dw.dxfInt(175, 0);
4090 dw.dxfInt(176, 0);
4091 dw.dxfInt(177, 0);
4092 dw.dxfInt(178, 0);
4093 }
4094 if (version==VER_2000) {
4095 dw.dxfInt(271, 2);
4096 dw.dxfInt(272, 2);
4097 dw.dxfInt(274, 3);
4098 dw.dxfInt(278, 44);
4099 dw.dxfInt(283, 0);
4100 dw.dxfInt(284, 8);
4101 //dw.dxfHex(340, styleHandleStd);
4102 dw.dxfHex(340, 0x11);
4103 }
4104 // * /
4105 dw.dxfString( 0, "ENDTAB");
4106 }
4107
4108
4109
4110 /**
4111 * Writes a blockrecord section. This section is needed in VER_R13.
4112 * Note that this method currently only writes a faked BLOCKRECORD section
4113 * to make the file readable by Aut*cad.
4114 */
writeBlockRecord(DL_WriterA & dw)4115 void DL_Dxf::writeBlockRecord(DL_WriterA& dw) {
4116 dw.dxfString( 0, "TABLE");
4117 dw.dxfString( 2, "BLOCK_RECORD");
4118 if (version==VER_2000) {
4119 dw.dxfHex(5, 1);
4120 }
4121 //dw.dxfHex(330, 0);
4122 if (version==VER_2000) {
4123 dw.dxfString(100, "AcDbSymbolTable");
4124 }
4125 dw.dxfInt( 70, 1);
4126
4127 dw.dxfString( 0, "BLOCK_RECORD");
4128 if (version==VER_2000) {
4129 dw.dxfHex(5, 0x1F);
4130 }
4131 //int msh = dw.handle();
4132 //dw.setModelSpaceHandle(msh);
4133 //dw.dxfHex(330, 1);
4134 if (version==VER_2000) {
4135 dw.dxfString(100, "AcDbSymbolTableRecord");
4136 dw.dxfString(100, "AcDbBlockTableRecord");
4137 }
4138 dw.dxfString( 2, "*Model_Space");
4139 dw.dxfHex(340, 0x22);
4140
4141 dw.dxfString( 0, "BLOCK_RECORD");
4142 if (version==VER_2000) {
4143 dw.dxfHex(5, 0x1B);
4144 }
4145 //int psh = dw.handle();
4146 //dw.setPaperSpaceHandle(psh);
4147 //dw.dxfHex(330, 1);
4148 if (version==VER_2000) {
4149 dw.dxfString(100, "AcDbSymbolTableRecord");
4150 dw.dxfString(100, "AcDbBlockTableRecord");
4151 }
4152 dw.dxfString( 2, "*Paper_Space");
4153 dw.dxfHex(340, 0x1E);
4154
4155 dw.dxfString( 0, "BLOCK_RECORD");
4156 if (version==VER_2000) {
4157 dw.dxfHex(5, 0x23);
4158 }
4159 //int ps0h = dw.handle();
4160 //dw.setPaperSpace0Handle(ps0h);
4161 //dw.dxfHex(330, 1);
4162 if (version==VER_2000) {
4163 dw.dxfString(100, "AcDbSymbolTableRecord");
4164 dw.dxfString(100, "AcDbBlockTableRecord");
4165 }
4166 dw.dxfString( 2, "*Paper_Space0");
4167 dw.dxfHex(340, 0x26);
4168
4169 //dw.dxfString( 0, "ENDTAB");
4170 }
4171
4172
4173
4174 /**
4175 * Writes a single block record with the given name.
4176 */
writeBlockRecord(DL_WriterA & dw,const string & name)4177 void DL_Dxf::writeBlockRecord(DL_WriterA& dw, const string& name) {
4178 dw.dxfString( 0, "BLOCK_RECORD");
4179 if (version==VER_2000) {
4180 dw.handle();
4181 }
4182 //dw->dxfHex(330, 1);
4183 if (version==VER_2000) {
4184 dw.dxfString(100, "AcDbSymbolTableRecord");
4185 dw.dxfString(100, "AcDbBlockTableRecord");
4186 }
4187 dw.dxfString( 2, name);
4188 dw.dxfHex(340, 0);
4189 }
4190
4191
4192
4193 /**
4194 * Writes a objects section. This section is needed in VER_R13.
4195 * Note that this method currently only writes a faked OBJECTS section
4196 * to make the file readable by Aut*cad.
4197 */
writeObjects(DL_WriterA & dw)4198 void DL_Dxf::writeObjects(DL_WriterA& dw) {
4199 //int dicId, dicId2, dicId3, dicId4, dicId5;
4200 //int dicId5;
4201
4202 dw.dxfString( 0, "SECTION");
4203 dw.dxfString( 2, "OBJECTS");
4204 dw.dxfString( 0, "DICTIONARY");
4205 dw.dxfHex(5, 0xC); // C
4206 //dw.dxfHex(330, 0);
4207 dw.dxfString(100, "AcDbDictionary");
4208 dw.dxfInt(280, 0);
4209 dw.dxfInt(281, 1);
4210 dw.dxfString( 3, "ACAD_GROUP");
4211 //dw.dxfHex(350, dw.getNextHandle()); // D
4212 dw.dxfHex(350, 0xD); // D
4213 dw.dxfString( 3, "ACAD_LAYOUT");
4214 dw.dxfHex(350, 0x1A);
4215 //dw.dxfHex(350, dw.getNextHandle()+0); // 1A
4216 dw.dxfString( 3, "ACAD_MLINESTYLE");
4217 dw.dxfHex(350, 0x17);
4218 //dw.dxfHex(350, dw.getNextHandle()+1); // 17
4219 dw.dxfString( 3, "ACAD_PLOTSETTINGS");
4220 dw.dxfHex(350, 0x19);
4221 //dw.dxfHex(350, dw.getNextHandle()+2); // 19
4222 dw.dxfString( 3, "ACAD_PLOTSTYLENAME");
4223 dw.dxfHex(350, 0xE);
4224 //dw.dxfHex(350, dw.getNextHandle()+3); // E
4225 dw.dxfString( 3, "AcDbVariableDictionary");
4226 dw.dxfHex(350, dw.getNextHandle()); // 2C
4227 dw.dxfString( 0, "DICTIONARY");
4228 dw.dxfHex(5, 0xD);
4229 //dw.handle(); // D
4230 //dw.dxfHex(330, 0xC);
4231 dw.dxfString(100, "AcDbDictionary");
4232 dw.dxfInt(280, 0);
4233 dw.dxfInt(281, 1);
4234 dw.dxfString( 0, "ACDBDICTIONARYWDFLT");
4235 dw.dxfHex(5, 0xE);
4236 //dicId4 = dw.handle(); // E
4237 //dw.dxfHex(330, 0xC); // C
4238 dw.dxfString(100, "AcDbDictionary");
4239 dw.dxfInt(281, 1);
4240 dw.dxfString( 3, "Normal");
4241 dw.dxfHex(350, 0xF);
4242 //dw.dxfHex(350, dw.getNextHandle()+5); // F
4243 dw.dxfString(100, "AcDbDictionaryWithDefault");
4244 dw.dxfHex(340, 0xF);
4245 //dw.dxfHex(340, dw.getNextHandle()+5); // F
4246 dw.dxfString( 0, "ACDBPLACEHOLDER");
4247 dw.dxfHex(5, 0xF);
4248 //dw.handle(); // F
4249 //dw.dxfHex(330, dicId4); // E
4250 dw.dxfString( 0, "DICTIONARY");
4251 //dicId3 = dw.handle(); // 17
4252 dw.dxfHex(5, 0x17);
4253 //dw.dxfHex(330, 0xC); // C
4254 dw.dxfString(100, "AcDbDictionary");
4255 dw.dxfInt(280, 0);
4256 dw.dxfInt(281, 1);
4257 dw.dxfString( 3, "Standard");
4258 dw.dxfHex(350, 0x18);
4259 //dw.dxfHex(350, dw.getNextHandle()+5); // 18
4260 dw.dxfString( 0, "MLINESTYLE");
4261 dw.dxfHex(5, 0x18);
4262 //dw.handle(); // 18
4263 //dw.dxfHex(330, dicId3); // 17
4264 dw.dxfString(100, "AcDbMlineStyle");
4265 dw.dxfString( 2, "STANDARD");
4266 dw.dxfInt( 70, 0);
4267 dw.dxfString( 3, "");
4268 dw.dxfInt( 62, 256);
4269 dw.dxfReal( 51, 90.0);
4270 dw.dxfReal( 52, 90.0);
4271 dw.dxfInt( 71, 2);
4272 dw.dxfReal( 49, 0.5);
4273 dw.dxfInt( 62, 256);
4274 dw.dxfString( 6, "BYLAYER");
4275 dw.dxfReal( 49, -0.5);
4276 dw.dxfInt( 62, 256);
4277 dw.dxfString( 6, "BYLAYER");
4278 dw.dxfString( 0, "DICTIONARY");
4279 dw.dxfHex(5, 0x19);
4280 //dw.handle(); // 17
4281 //dw.dxfHex(330, 0xC); // C
4282 dw.dxfString(100, "AcDbDictionary");
4283 dw.dxfInt(280, 0);
4284 dw.dxfInt(281, 1);
4285 dw.dxfString( 0, "DICTIONARY");
4286 //dicId2 = dw.handle(); // 1A
4287 dw.dxfHex(5, 0x1A);
4288 //dw.dxfHex(330, 0xC);
4289 dw.dxfString(100, "AcDbDictionary");
4290 dw.dxfInt(281, 1);
4291 dw.dxfString( 3, "Layout1");
4292 dw.dxfHex(350, 0x1E);
4293 //dw.dxfHex(350, dw.getNextHandle()+2); // 1E
4294 dw.dxfString( 3, "Layout2");
4295 dw.dxfHex(350, 0x26);
4296 //dw.dxfHex(350, dw.getNextHandle()+4); // 26
4297 dw.dxfString( 3, "Model");
4298 dw.dxfHex(350, 0x22);
4299 //dw.dxfHex(350, dw.getNextHandle()+5); // 22
4300
4301 dw.dxfString( 0, "LAYOUT");
4302 dw.dxfHex(5, 0x1E);
4303 //dw.handle(); // 1E
4304 //dw.dxfHex(330, dicId2); // 1A
4305 dw.dxfString(100, "AcDbPlotSettings");
4306 dw.dxfString( 1, "");
4307 dw.dxfString( 2, "C:\\Program Files\\AutoCAD 2002\\plotters\\DWF ePlot (optimized for plotting).pc3");
4308 dw.dxfString( 4, "");
4309 dw.dxfString( 6, "");
4310 dw.dxfReal( 40, 0.0);
4311 dw.dxfReal( 41, 0.0);
4312 dw.dxfReal( 42, 0.0);
4313 dw.dxfReal( 43, 0.0);
4314 dw.dxfReal( 44, 0.0);
4315 dw.dxfReal( 45, 0.0);
4316 dw.dxfReal( 46, 0.0);
4317 dw.dxfReal( 47, 0.0);
4318 dw.dxfReal( 48, 0.0);
4319 dw.dxfReal( 49, 0.0);
4320 dw.dxfReal(140, 0.0);
4321 dw.dxfReal(141, 0.0);
4322 dw.dxfReal(142, 1.0);
4323 dw.dxfReal(143, 1.0);
4324 dw.dxfInt( 70, 688);
4325 dw.dxfInt( 72, 0);
4326 dw.dxfInt( 73, 0);
4327 dw.dxfInt( 74, 5);
4328 dw.dxfString( 7, "");
4329 dw.dxfInt( 75, 16);
4330 dw.dxfReal(147, 1.0);
4331 dw.dxfReal(148, 0.0);
4332 dw.dxfReal(149, 0.0);
4333 dw.dxfString(100, "AcDbLayout");
4334 dw.dxfString( 1, "Layout1");
4335 dw.dxfInt( 70, 1);
4336 dw.dxfInt( 71, 1);
4337 dw.dxfReal( 10, 0.0);
4338 dw.dxfReal( 20, 0.0);
4339 dw.dxfReal( 11, 420.0);
4340 dw.dxfReal( 21, 297.0);
4341 dw.dxfReal( 12, 0.0);
4342 dw.dxfReal( 22, 0.0);
4343 dw.dxfReal( 32, 0.0);
4344 dw.dxfReal( 14, 1.000000000000000E+20);
4345 dw.dxfReal( 24, 1.000000000000000E+20);
4346 dw.dxfReal( 34, 1.000000000000000E+20);
4347 dw.dxfReal( 15, -1.000000000000000E+20);
4348 dw.dxfReal( 25, -1.000000000000000E+20);
4349 dw.dxfReal( 35, -1.000000000000000E+20);
4350 dw.dxfReal(146, 0.0);
4351 dw.dxfReal( 13, 0.0);
4352 dw.dxfReal( 23, 0.0);
4353 dw.dxfReal( 33, 0.0);
4354 dw.dxfReal( 16, 1.0);
4355 dw.dxfReal( 26, 0.0);
4356 dw.dxfReal( 36, 0.0);
4357 dw.dxfReal( 17, 0.0);
4358 dw.dxfReal( 27, 1.0);
4359 dw.dxfReal( 37, 0.0);
4360 dw.dxfInt( 76, 0);
4361 //dw.dxfHex(330, dw.getPaperSpaceHandle()); // 1B
4362 dw.dxfHex(330, 0x1B);
4363 dw.dxfString( 0, "LAYOUT");
4364 dw.dxfHex(5, 0x22);
4365 //dw.handle(); // 22
4366 //dw.dxfHex(330, dicId2); // 1A
4367 dw.dxfString(100, "AcDbPlotSettings");
4368 dw.dxfString( 1, "");
4369 dw.dxfString( 2, "C:\\Program Files\\AutoCAD 2002\\plotters\\DWF ePlot (optimized for plotting).pc3");
4370 dw.dxfString( 4, "");
4371 dw.dxfString( 6, "");
4372 dw.dxfReal( 40, 0.0);
4373 dw.dxfReal( 41, 0.0);
4374 dw.dxfReal( 42, 0.0);
4375 dw.dxfReal( 43, 0.0);
4376 dw.dxfReal( 44, 0.0);
4377 dw.dxfReal( 45, 0.0);
4378 dw.dxfReal( 46, 0.0);
4379 dw.dxfReal( 47, 0.0);
4380 dw.dxfReal( 48, 0.0);
4381 dw.dxfReal( 49, 0.0);
4382 dw.dxfReal(140, 0.0);
4383 dw.dxfReal(141, 0.0);
4384 dw.dxfReal(142, 1.0);
4385 dw.dxfReal(143, 1.0);
4386 dw.dxfInt( 70, 1712);
4387 dw.dxfInt( 72, 0);
4388 dw.dxfInt( 73, 0);
4389 dw.dxfInt( 74, 0);
4390 dw.dxfString( 7, "");
4391 dw.dxfInt( 75, 0);
4392 dw.dxfReal(147, 1.0);
4393 dw.dxfReal(148, 0.0);
4394 dw.dxfReal(149, 0.0);
4395 dw.dxfString(100, "AcDbLayout");
4396 dw.dxfString( 1, "Model");
4397 dw.dxfInt( 70, 1);
4398 dw.dxfInt( 71, 0);
4399 dw.dxfReal( 10, 0.0);
4400 dw.dxfReal( 20, 0.0);
4401 dw.dxfReal( 11, 12.0);
4402 dw.dxfReal( 21, 9.0);
4403 dw.dxfReal( 12, 0.0);
4404 dw.dxfReal( 22, 0.0);
4405 dw.dxfReal( 32, 0.0);
4406 dw.dxfReal( 14, 0.0);
4407 dw.dxfReal( 24, 0.0);
4408 dw.dxfReal( 34, 0.0);
4409 dw.dxfReal( 15, 0.0);
4410 dw.dxfReal( 25, 0.0);
4411 dw.dxfReal( 35, 0.0);
4412 dw.dxfReal(146, 0.0);
4413 dw.dxfReal( 13, 0.0);
4414 dw.dxfReal( 23, 0.0);
4415 dw.dxfReal( 33, 0.0);
4416 dw.dxfReal( 16, 1.0);
4417 dw.dxfReal( 26, 0.0);
4418 dw.dxfReal( 36, 0.0);
4419 dw.dxfReal( 17, 0.0);
4420 dw.dxfReal( 27, 1.0);
4421 dw.dxfReal( 37, 0.0);
4422 dw.dxfInt( 76, 0);
4423 //dw.dxfHex(330, dw.getModelSpaceHandle()); // 1F
4424 dw.dxfHex(330, 0x1F);
4425 dw.dxfString( 0, "LAYOUT");
4426 //dw.handle(); // 26
4427 dw.dxfHex(5, 0x26);
4428 //dw.dxfHex(330, dicId2); // 1A
4429 dw.dxfString(100, "AcDbPlotSettings");
4430 dw.dxfString( 1, "");
4431 dw.dxfString( 2, "C:\\Program Files\\AutoCAD 2002\\plotters\\DWF ePlot (optimized for plotting).pc3");
4432 dw.dxfString( 4, "");
4433 dw.dxfString( 6, "");
4434 dw.dxfReal( 40, 0.0);
4435 dw.dxfReal( 41, 0.0);
4436 dw.dxfReal( 42, 0.0);
4437 dw.dxfReal( 43, 0.0);
4438 dw.dxfReal( 44, 0.0);
4439 dw.dxfReal( 45, 0.0);
4440 dw.dxfReal( 46, 0.0);
4441 dw.dxfReal( 47, 0.0);
4442 dw.dxfReal( 48, 0.0);
4443 dw.dxfReal( 49, 0.0);
4444 dw.dxfReal(140, 0.0);
4445 dw.dxfReal(141, 0.0);
4446 dw.dxfReal(142, 1.0);
4447 dw.dxfReal(143, 1.0);
4448 dw.dxfInt( 70, 688);
4449 dw.dxfInt( 72, 0);
4450 dw.dxfInt( 73, 0);
4451 dw.dxfInt( 74, 5);
4452 dw.dxfString( 7, "");
4453 dw.dxfInt( 75, 16);
4454 dw.dxfReal(147, 1.0);
4455 dw.dxfReal(148, 0.0);
4456 dw.dxfReal(149, 0.0);
4457 dw.dxfString(100, "AcDbLayout");
4458 dw.dxfString( 1, "Layout2");
4459 dw.dxfInt( 70, 1);
4460 dw.dxfInt( 71, 2);
4461 dw.dxfReal( 10, 0.0);
4462 dw.dxfReal( 20, 0.0);
4463 dw.dxfReal( 11, 12.0);
4464 dw.dxfReal( 21, 9.0);
4465 dw.dxfReal( 12, 0.0);
4466 dw.dxfReal( 22, 0.0);
4467 dw.dxfReal( 32, 0.0);
4468 dw.dxfReal( 14, 0.0);
4469 dw.dxfReal( 24, 0.0);
4470 dw.dxfReal( 34, 0.0);
4471 dw.dxfReal( 15, 0.0);
4472 dw.dxfReal( 25, 0.0);
4473 dw.dxfReal( 35, 0.0);
4474 dw.dxfReal(146, 0.0);
4475 dw.dxfReal( 13, 0.0);
4476 dw.dxfReal( 23, 0.0);
4477 dw.dxfReal( 33, 0.0);
4478 dw.dxfReal( 16, 1.0);
4479 dw.dxfReal( 26, 0.0);
4480 dw.dxfReal( 36, 0.0);
4481 dw.dxfReal( 17, 0.0);
4482 dw.dxfReal( 27, 1.0);
4483 dw.dxfReal( 37, 0.0);
4484 dw.dxfInt( 76, 0);
4485 //dw.dxfHex(330, dw.getPaperSpace0Handle()); // 23
4486 dw.dxfHex(330, 0x23);
4487 dw.dxfString( 0, "DICTIONARY");
4488 //dw.dxfHex(5, 0x2C);
4489 //dicId5 =
4490 dw.handle(); // 2C
4491 //dw.dxfHex(330, 0xC); // C
4492 dw.dxfString(100, "AcDbDictionary");
4493 dw.dxfInt(281, 1);
4494 dw.dxfString( 3, "DIMASSOC");
4495 //dw.dxfHex(350, 0x2F);
4496 dw.dxfHex(350, dw.getNextHandle()+1); // 2E
4497 dw.dxfString( 3, "HIDETEXT");
4498 //dw.dxfHex(350, 0x2E);
4499 dw.dxfHex(350, dw.getNextHandle()); // 2D
4500 dw.dxfString( 0, "DICTIONARYVAR");
4501 //dw.dxfHex(5, 0x2E);
4502 dw.handle(); // 2E
4503 //dw.dxfHex(330, dicId5); // 2C
4504 dw.dxfString(100, "DictionaryVariables");
4505 dw.dxfInt(280, 0);
4506 dw.dxfInt( 1, 2);
4507 dw.dxfString( 0, "DICTIONARYVAR");
4508 //dw.dxfHex(5, 0x2D);
4509 dw.handle(); // 2D
4510 //dw.dxfHex(330, dicId5); // 2C
4511 dw.dxfString(100, "DictionaryVariables");
4512 dw.dxfInt(280, 0);
4513 dw.dxfInt( 1, 1);
4514 }
4515
4516
4517 /**
4518 * Writes the end of the objects section. This section is needed in VER_R13.
4519 * Note that this method currently only writes a faked OBJECTS section
4520 * to make the file readable by Aut*cad.
4521 */
writeObjectsEnd(DL_WriterA & dw)4522 void DL_Dxf::writeObjectsEnd(DL_WriterA& dw) {
4523 dw.dxfString( 0, "ENDSEC");
4524 }
4525
4526
4527
4528 /**
4529 * Writes a comment to the DXF file.
4530 */
writeComment(DL_WriterA & dw,const string & comment)4531 void DL_Dxf::writeComment(DL_WriterA& dw, const string& comment) {
4532 dw.dxfString(999, comment);
4533 }
4534
4535
4536 /**
4537 * Checks if the given variable is known by the given DXF version.
4538 */
checkVariable(const char * var,DL_Codes::version version)4539 bool DL_Dxf::checkVariable(const char* var, DL_Codes::version version) {
4540 if (version>=VER_2000) {
4541 return true;
4542 } else if (version==VER_R12) {
4543 // these are all the variables recognized by dxf r12:
4544 if (!strcmp(var, "$ACADVER")) {
4545 return true;
4546 }
4547 if (!strcmp(var, "$ACADVER")) {
4548 return true;
4549 }
4550 if (!strcmp(var, "$ANGBASE")) {
4551 return true;
4552 }
4553 if (!strcmp(var, "$ANGDIR")) {
4554 return true;
4555 }
4556 if (!strcmp(var, "$ATTDIA")) {
4557 return true;
4558 }
4559 if (!strcmp(var, "$ATTMODE")) {
4560 return true;
4561 }
4562 if (!strcmp(var, "$ATTREQ")) {
4563 return true;
4564 }
4565 if (!strcmp(var, "$AUNITS")) {
4566 return true;
4567 }
4568 if (!strcmp(var, "$AUPREC")) {
4569 return true;
4570 }
4571 if (!strcmp(var, "$AXISMODE")) {
4572 return true;
4573 }
4574 if (!strcmp(var, "$AXISUNIT")) {
4575 return true;
4576 }
4577 if (!strcmp(var, "$BLIPMODE")) {
4578 return true;
4579 }
4580 if (!strcmp(var, "$CECOLOR")) {
4581 return true;
4582 }
4583 if (!strcmp(var, "$CELTYPE")) {
4584 return true;
4585 }
4586 if (!strcmp(var, "$CHAMFERA")) {
4587 return true;
4588 }
4589 if (!strcmp(var, "$CHAMFERB")) {
4590 return true;
4591 }
4592 if (!strcmp(var, "$CLAYER")) {
4593 return true;
4594 }
4595 if (!strcmp(var, "$COORDS")) {
4596 return true;
4597 }
4598 if (!strcmp(var, "$DIMALT")) {
4599 return true;
4600 }
4601 if (!strcmp(var, "$DIMALTD")) {
4602 return true;
4603 }
4604 if (!strcmp(var, "$DIMALTF")) {
4605 return true;
4606 }
4607 if (!strcmp(var, "$DIMAPOST")) {
4608 return true;
4609 }
4610 if (!strcmp(var, "$DIMASO")) {
4611 return true;
4612 }
4613 if (!strcmp(var, "$DIMASZ")) {
4614 return true;
4615 }
4616 if (!strcmp(var, "$DIMBLK")) {
4617 return true;
4618 }
4619 if (!strcmp(var, "$DIMBLK1")) {
4620 return true;
4621 }
4622 if (!strcmp(var, "$DIMBLK2")) {
4623 return true;
4624 }
4625 if (!strcmp(var, "$DIMCEN")) {
4626 return true;
4627 }
4628 if (!strcmp(var, "$DIMCLRD")) {
4629 return true;
4630 }
4631 if (!strcmp(var, "$DIMCLRE")) {
4632 return true;
4633 }
4634 if (!strcmp(var, "$DIMCLRT")) {
4635 return true;
4636 }
4637 if (!strcmp(var, "$DIMDLE")) {
4638 return true;
4639 }
4640 if (!strcmp(var, "$DIMDLI")) {
4641 return true;
4642 }
4643 if (!strcmp(var, "$DIMEXE")) {
4644 return true;
4645 }
4646 if (!strcmp(var, "$DIMEXO")) {
4647 return true;
4648 }
4649 if (!strcmp(var, "$DIMGAP")) {
4650 return true;
4651 }
4652 if (!strcmp(var, "$DIMLFAC")) {
4653 return true;
4654 }
4655 if (!strcmp(var, "$DIMLIM")) {
4656 return true;
4657 }
4658 if (!strcmp(var, "$DIMPOST")) {
4659 return true;
4660 }
4661 if (!strcmp(var, "$DIMRND")) {
4662 return true;
4663 }
4664 if (!strcmp(var, "$DIMSAH")) {
4665 return true;
4666 }
4667 if (!strcmp(var, "$DIMSCALE")) {
4668 return true;
4669 }
4670 if (!strcmp(var, "$DIMSE1")) {
4671 return true;
4672 }
4673 if (!strcmp(var, "$DIMSE2")) {
4674 return true;
4675 }
4676 if (!strcmp(var, "$DIMSHO")) {
4677 return true;
4678 }
4679 if (!strcmp(var, "$DIMSOXD")) {
4680 return true;
4681 }
4682 if (!strcmp(var, "$DIMSTYLE")) {
4683 return true;
4684 }
4685 if (!strcmp(var, "$DIMTAD")) {
4686 return true;
4687 }
4688 if (!strcmp(var, "$DIMTFAC")) {
4689 return true;
4690 }
4691 if (!strcmp(var, "$DIMTIH")) {
4692 return true;
4693 }
4694 if (!strcmp(var, "$DIMTIX")) {
4695 return true;
4696 }
4697 if (!strcmp(var, "$DIMTM")) {
4698 return true;
4699 }
4700 if (!strcmp(var, "$DIMTOFL")) {
4701 return true;
4702 }
4703 if (!strcmp(var, "$DIMTOH")) {
4704 return true;
4705 }
4706 if (!strcmp(var, "$DIMTOL")) {
4707 return true;
4708 }
4709 if (!strcmp(var, "$DIMTP")) {
4710 return true;
4711 }
4712 if (!strcmp(var, "$DIMTSZ")) {
4713 return true;
4714 }
4715 if (!strcmp(var, "$DIMTVP")) {
4716 return true;
4717 }
4718 if (!strcmp(var, "$DIMTXT")) {
4719 return true;
4720 }
4721 if (!strcmp(var, "$DIMZIN")) {
4722 return true;
4723 }
4724 if (!strcmp(var, "$DWGCODEPAGE")) {
4725 return true;
4726 }
4727 if (!strcmp(var, "$DRAGMODE")) {
4728 return true;
4729 }
4730 if (!strcmp(var, "$ELEVATION")) {
4731 return true;
4732 }
4733 if (!strcmp(var, "$EXTMAX")) {
4734 return true;
4735 }
4736 if (!strcmp(var, "$EXTMIN")) {
4737 return true;
4738 }
4739 if (!strcmp(var, "$FILLETRAD")) {
4740 return true;
4741 }
4742 if (!strcmp(var, "$FILLMODE")) {
4743 return true;
4744 }
4745 if (!strcmp(var, "$HANDLING")) {
4746 return true;
4747 }
4748 if (!strcmp(var, "$HANDSEED")) {
4749 return true;
4750 }
4751 if (!strcmp(var, "$INSBASE")) {
4752 return true;
4753 }
4754 if (!strcmp(var, "$LIMCHECK")) {
4755 return true;
4756 }
4757 if (!strcmp(var, "$LIMMAX")) {
4758 return true;
4759 }
4760 if (!strcmp(var, "$LIMMIN")) {
4761 return true;
4762 }
4763 if (!strcmp(var, "$LTSCALE")) {
4764 return true;
4765 }
4766 if (!strcmp(var, "$LUNITS")) {
4767 return true;
4768 }
4769 if (!strcmp(var, "$LUPREC")) {
4770 return true;
4771 }
4772 if (!strcmp(var, "$MAXACTVP")) {
4773 return true;
4774 }
4775 if (!strcmp(var, "$MENU")) {
4776 return true;
4777 }
4778 if (!strcmp(var, "$MIRRTEXT")) {
4779 return true;
4780 }
4781 if (!strcmp(var, "$ORTHOMODE")) {
4782 return true;
4783 }
4784 if (!strcmp(var, "$OSMODE")) {
4785 return true;
4786 }
4787 if (!strcmp(var, "$PDMODE")) {
4788 return true;
4789 }
4790 if (!strcmp(var, "$PDSIZE")) {
4791 return true;
4792 }
4793 if (!strcmp(var, "$PELEVATION")) {
4794 return true;
4795 }
4796 if (!strcmp(var, "$PEXTMAX")) {
4797 return true;
4798 }
4799 if (!strcmp(var, "$PEXTMIN")) {
4800 return true;
4801 }
4802 if (!strcmp(var, "$PLIMCHECK")) {
4803 return true;
4804 }
4805 if (!strcmp(var, "$PLIMMAX")) {
4806 return true;
4807 }
4808 if (!strcmp(var, "$PLIMMIN")) {
4809 return true;
4810 }
4811 if (!strcmp(var, "$PLINEGEN")) {
4812 return true;
4813 }
4814 if (!strcmp(var, "$PLINEWID")) {
4815 return true;
4816 }
4817 if (!strcmp(var, "$PSLTSCALE")) {
4818 return true;
4819 }
4820 if (!strcmp(var, "$PUCSNAME")) {
4821 return true;
4822 }
4823 if (!strcmp(var, "$PUCSORG")) {
4824 return true;
4825 }
4826 if (!strcmp(var, "$PUCSXDIR")) {
4827 return true;
4828 }
4829 if (!strcmp(var, "$PUCSYDIR")) {
4830 return true;
4831 }
4832 if (!strcmp(var, "$QTEXTMODE")) {
4833 return true;
4834 }
4835 if (!strcmp(var, "$REGENMODE")) {
4836 return true;
4837 }
4838 if (!strcmp(var, "$SHADEDGE")) {
4839 return true;
4840 }
4841 if (!strcmp(var, "$SHADEDIF")) {
4842 return true;
4843 }
4844 if (!strcmp(var, "$SKETCHINC")) {
4845 return true;
4846 }
4847 if (!strcmp(var, "$SKPOLY")) {
4848 return true;
4849 }
4850 if (!strcmp(var, "$SPLFRAME")) {
4851 return true;
4852 }
4853 if (!strcmp(var, "$SPLINESEGS")) {
4854 return true;
4855 }
4856 if (!strcmp(var, "$SPLINETYPE")) {
4857 return true;
4858 }
4859 if (!strcmp(var, "$SURFTAB1")) {
4860 return true;
4861 }
4862 if (!strcmp(var, "$SURFTAB2")) {
4863 return true;
4864 }
4865 if (!strcmp(var, "$SURFTYPE")) {
4866 return true;
4867 }
4868 if (!strcmp(var, "$SURFU")) {
4869 return true;
4870 }
4871 if (!strcmp(var, "$SURFV")) {
4872 return true;
4873 }
4874 if (!strcmp(var, "$TDCREATE")) {
4875 return true;
4876 }
4877 if (!strcmp(var, "$TDINDWG")) {
4878 return true;
4879 }
4880 if (!strcmp(var, "$TDUPDATE")) {
4881 return true;
4882 }
4883 if (!strcmp(var, "$TDUSRTIMER")) {
4884 return true;
4885 }
4886 if (!strcmp(var, "$TEXTSIZE")) {
4887 return true;
4888 }
4889 if (!strcmp(var, "$TEXTSTYLE")) {
4890 return true;
4891 }
4892 if (!strcmp(var, "$THICKNESS")) {
4893 return true;
4894 }
4895 if (!strcmp(var, "$TILEMODE")) {
4896 return true;
4897 }
4898 if (!strcmp(var, "$TRACEWID")) {
4899 return true;
4900 }
4901 if (!strcmp(var, "$UCSNAME")) {
4902 return true;
4903 }
4904 if (!strcmp(var, "$UCSORG")) {
4905 return true;
4906 }
4907 if (!strcmp(var, "$UCSXDIR")) {
4908 return true;
4909 }
4910 if (!strcmp(var, "$UCSYDIR")) {
4911 return true;
4912 }
4913 if (!strcmp(var, "$UNITMODE")) {
4914 return true;
4915 }
4916 if (!strcmp(var, "$USERI1")) {
4917 return true;
4918 }
4919 if (!strcmp(var, "$USERR1")) {
4920 return true;
4921 }
4922 if (!strcmp(var, "$USRTIMER")) {
4923 return true;
4924 }
4925 if (!strcmp(var, "$VISRETAIN")) {
4926 return true;
4927 }
4928 if (!strcmp(var, "$WORLDVIEW")) {
4929 return true;
4930 }
4931 if (!strcmp(var, "$FASTZOOM")) {
4932 return true;
4933 }
4934 if (!strcmp(var, "$GRIDMODE")) {
4935 return true;
4936 }
4937 if (!strcmp(var, "$GRIDUNIT")) {
4938 return true;
4939 }
4940 if (!strcmp(var, "$SNAPANG")) {
4941 return true;
4942 }
4943 if (!strcmp(var, "$SNAPBASE")) {
4944 return true;
4945 }
4946 if (!strcmp(var, "$SNAPISOPAIR")) {
4947 return true;
4948 }
4949 if (!strcmp(var, "$SNAPMODE")) {
4950 return true;
4951 }
4952 if (!strcmp(var, "$SNAPSTYLE")) {
4953 return true;
4954 }
4955 if (!strcmp(var, "$SNAPUNIT")) {
4956 return true;
4957 }
4958 if (!strcmp(var, "$VIEWCTR")) {
4959 return true;
4960 }
4961 if (!strcmp(var, "$VIEWDIR")) {
4962 return true;
4963 }
4964 if (!strcmp(var, "$VIEWSIZE")) {
4965 return true;
4966 }
4967 return false;
4968 }
4969
4970 return false;
4971 }
4972
4973
4974
4975 /**
4976 * @returns the library version as int (4 bytes, each byte one version number).
4977 * e.g. if str = "2.0.2.0" getLibVersion returns 0x02000200
4978 */
getLibVersion(const char * str)4979 int DL_Dxf::getLibVersion(const char* str) {
4980 int d[4];
4981 int idx = 0;
4982 char v[4][5];
4983 int ret = 0;
4984
4985 for (unsigned int i=0; i<strlen(str) && idx<3; ++i) {
4986 if (str[i]=='.') {
4987 d[idx] = i;
4988 idx++;
4989 }
4990 }
4991
4992 if (idx==3) {
4993 d[3] = strlen(str);
4994
4995 strncpy(v[0], str, d[0]);
4996 v[0][d[0]] = '\0';
4997
4998 strncpy(v[1], &str[d[0]+1], d[1]-d[0]-1);
4999 v[1][d[1]-d[0]-1] = '\0';
5000
5001 strncpy(v[2], &str[d[1]+1], d[2]-d[1]-1);
5002 v[2][d[2]-d[1]-1] = '\0';
5003
5004 strncpy(v[3], &str[d[2]+1], d[3]-d[2]-1);
5005 v[3][d[3]-d[2]-1] = '\0';
5006
5007 ret = (atoi(v[0])<<(3*8)) +
5008 (atoi(v[1])<<(2*8)) +
5009 (atoi(v[2])<<(1*8)) +
5010 (atoi(v[3])<<(0*8));
5011
5012 return ret;
5013 } else {
5014 std::cerr << "DL_Dxf::getLibVersion: invalid version number: " << str << "\n";
5015 return 0;
5016 }
5017 }
5018
5019
5020
5021 /**
5022 * Some test routines.
5023 */
test()5024 void DL_Dxf::test() {
5025 char* buf1;
5026 char* buf2;
5027 char* buf3;
5028 char* buf4;
5029 char* buf5;
5030 char* buf6;
5031
5032 buf1 = new char[10];
5033 buf2 = new char[10];
5034 buf3 = new char[10];
5035 buf4 = new char[10];
5036 buf5 = new char[10];
5037 buf6 = new char[10];
5038
5039 strcpy(buf1, " 10\n");
5040 strcpy(buf2, "10");
5041 strcpy(buf3, "10\n");
5042 strcpy(buf4, " 10 \n");
5043 strcpy(buf5, " 10 \r");
5044 strcpy(buf6, "\t10 \n");
5045
5046 std::cout << "1 buf1: '" << buf1 << "'\n";
5047 stripWhiteSpace(&buf1);
5048 std::cout << "2 buf1: '" << buf1 << "'\n";
5049 //assert(!strcmp(buf1, "10"));
5050
5051 std::cout << "1 buf2: '" << buf2 << "'\n";
5052 stripWhiteSpace(&buf2);
5053 std::cout << "2 buf2: '" << buf2 << "'\n";
5054
5055 std::cout << "1 buf3: '" << buf3 << "'\n";
5056 stripWhiteSpace(&buf3);
5057 std::cout << "2 buf3: '" << buf3 << "'\n";
5058
5059 std::cout << "1 buf4: '" << buf4 << "'\n";
5060 stripWhiteSpace(&buf4);
5061 std::cout << "2 buf4: '" << buf4 << "'\n";
5062
5063 std::cout << "1 buf5: '" << buf5 << "'\n";
5064 stripWhiteSpace(&buf5);
5065 std::cout << "2 buf5: '" << buf5 << "'\n";
5066
5067 std::cout << "1 buf6: '" << buf6 << "'\n";
5068 stripWhiteSpace(&buf6);
5069 std::cout << "2 buf6: '" << buf6 << "'\n";
5070
5071 }
5072
5073
5074