1 /****************************************************************************
2 ** $Id: dl_dxf.cpp 2398 2005-06-06 18:12:14Z andrew $
4 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
6 ** This file is part of the dxflib project.
8 ** This file may be distributed and/or modified under the terms of the
9 ** GNU General Public License version 2 as published by the Free Software
10 ** Foundation and appearing in the file LICENSE.GPL included in the
11 ** packaging of this file.
13 ** Licensees holding valid dxflib Professional Edition licenses may use
14 ** this file in accordance with the dxflib Commercial License
15 ** Agreement provided with the Software.
17 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
18 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 ** See http://www.ribbonsoft.com for further details.
22 ** Contact info@ribbonsoft.com if any conditions of this licensing are
25 **********************************************************************/
35 #include "dl_attributes.h"
37 #include "dl_creationinterface.h"
38 #include "dl_writer_ascii.h"
42 * Default constructor.
58 controlPointIndex = 0;
60 leaderVertices = NULL;
61 maxLeaderVertices = 0;
62 leaderVertexIndex = 0;
69 hatchEdgeIndex = NULL;
87 if (controlPoints!=NULL) {
88 delete[] controlPoints;
90 if (leaderVertices!=NULL) {
91 delete[] leaderVertices;
93 if (hatchLoops!=NULL) {
96 if (hatchEdges!=NULL) {
97 for (int i=0; i<maxHatchLoops; ++i) {
98 if (hatchEdges[i]!=NULL) {
99 delete[] hatchEdges[i];
104 if (maxHatchEdges!=NULL) {
105 delete[] maxHatchEdges;
107 if (hatchEdgeIndex!=NULL) {
108 delete[] hatchEdgeIndex;
115 * @brief Reads the given file and calls the appropriate functions in
116 * the given creation interface for every entity found in the file.
119 * Path and name of file to read
120 * @param creationInterface
121 * Pointer to the class which takes care of the entities in the file.
123 * @retval true If \p file could be opened.
124 * @retval false If \p file could not be opened.
126 bool DL_Dxf::in(const string& file, DL_CreationInterface* creationInterface) {
129 currentEntity = DL_UNKNOWN;
130 int errorCounter = 0;
132 fp = fopen(file.c_str(), "rt");
134 while (readDxfGroups(fp, creationInterface, &errorCounter)) {}
136 if (errorCounter>0) {
137 std::cerr << "DXF Filter: There have been " << errorCounter <<
138 " errors. The drawing might be incomplete / incorrect.\n";
149 * Reads a DXF file from an existing stream.
151 * @param stream The string stream.
152 * @param creationInterface
153 * Pointer to the class which takes care of the entities in the file.
155 * @retval true If \p file could be opened.
156 * @retval false If \p file could not be opened.
159 bool DL_Dxf::in(std::stringstream& stream,
160 DL_CreationInterface* creationInterface) {
162 int errorCounter = 0;
166 currentEntity = DL_UNKNOWN;
167 while (readDxfGroups(stream, creationInterface, &errorCounter)) {}
168 if (errorCounter>0) {
169 std::cerr << "DXF Filter: There have been " << errorCounter <<
170 " errors. The drawing might be incomplete / incorrect.\n";
181 * @brief Reads a group couplet from a DXF file. Calls another function
184 * A group couplet consists of two lines that represent a single
185 * piece of data. An integer constant on the first line indicates
186 * the type of data. The value is on the next line.\n
188 * This function reads a couplet, determines the type of data, and
189 * passes the value to the the appropriate handler function of
190 * \p creationInterface.\n
192 * \p fp is advanced so that the next call to \p readDXFGroups() reads
193 * the next couplet in the file.
195 * @param fp Handle of input file
196 * @param creationInterface Handle of class which processes entities
199 * @retval true If EOF not reached.
200 * @retval false If EOF reached.
202 bool DL_Dxf::readDxfGroups(FILE *fp, DL_CreationInterface* creationInterface,
208 // Read one group of the DXF file and chop the lines:
209 if (DL_Dxf::getChoppedLine(groupCodeTmp, DL_DXF_MAXLINE, fp) &&
210 DL_Dxf::getChoppedLine(groupValue, DL_DXF_MAXLINE, fp) ) {
212 groupCode = (unsigned int)stringToInt(groupCodeTmp, &ok);
215 //std::cerr << groupCode << "\n";
216 //std::cerr << groupValue << "\n";
218 processDXFGroup(creationInterface, groupCode, groupValue);
220 std::cerr << "DXF read error: Line: " << line << "\n";
221 if (errorCounter!=NULL) {
225 std::cerr << "DXF read error: trying to fix..\n";
226 // drop a line to sync:
227 DL_Dxf::getChoppedLine(groupCodeTmp, DL_DXF_MAXLINE, fp);
237 * Same as above but for stringstreams.
240 bool DL_Dxf::readDxfGroups(std::stringstream& stream,
241 DL_CreationInterface* creationInterface,
247 // Read one group of the DXF file and chop the lines:
248 if (DL_Dxf::getChoppedLine(groupCodeTmp, DL_DXF_MAXLINE, stream) &&
249 DL_Dxf::getChoppedLine(groupValue, DL_DXF_MAXLINE, stream) ) {
251 groupCode = (unsigned int)stringToInt(groupCodeTmp, &ok);
254 //std::cout << groupCode << "\n";
255 //std::cout << groupValue << "\n";
257 processDXFGroup(creationInterface, groupCode, groupValue);
259 std::cerr << "DXF read error: Line: " << line << "\n";
260 if (errorCounter!=NULL) {
264 std::cerr << "DXF read error: trying to fix..\n";
265 // drop a line to sync:
266 DL_Dxf::getChoppedLine(groupCodeTmp, DL_DXF_MAXLINE, stream);
269 return !stream.eof();
276 * @brief Reads line from file & strips whitespace at start and newline
280 * Pointer to character array that chopped line will be returned in.
281 * @param size Size of \p s. (Including space for NULL.)
283 * Handle of input file.
285 * @retval true if line could be read
286 * @retval false if \p fp is already at end of file
288 * @todo Change function to use safer FreeBSD strl* functions
289 * @todo Is it a problem if line is blank (i.e., newline only)?
290 * Then, when function returns, (s==NULL).
292 bool DL_Dxf::getChoppedLine(char *s, unsigned int size, FILE *fp) {
294 // The whole line in the file. Includes space for NULL.
295 char* wholeLine = new char[size];
296 // Only the useful part of the line
299 line = fgets(wholeLine, size, fp);
301 if (line!=NULL && line[0] != '\0') { // Evaluates to fgets() retval
302 // line == wholeLine at this point.
303 // Both guaranteed to be NULL terminated.
305 // Strip leading whitespace and trailing CR/LF.
306 stripWhiteSpace(&line);
308 strncpy(s, line, size);
310 // s should always be NULL terminated, because:
311 assert(size > strlen(line));
314 delete[] wholeLine; // Done with wholeLine
326 * Same as above but for stringstreams.
329 bool DL_Dxf::getChoppedLine(char *s, unsigned int size,
330 std::stringstream& stream) {
333 // Only the useful part of the line
334 stream.getline(s, size);
336 assert(size > strlen(s));
348 * @brief Strips leading whitespace and trailing Carriage Return (CR)
349 * and Line Feed (LF) from NULL terminated string.
351 * @param s Input and output.
352 * NULL terminates string.
354 * @retval true if \p s is non-NULL
355 * @retval false if \p s is NULL
357 bool DL_Dxf::stripWhiteSpace(char** s) {
358 // last non-NULL char:
359 int lastChar = strlen(*s) - 1;
360 //std::cout << "lastChar: " << lastChar << "\n";
362 // Is last character CR or LF?
363 while ( (lastChar >= 0) &&
364 (((*s)[lastChar] == 10) || ((*s)[lastChar] == 13) ||
365 ((*s)[lastChar] == ' ' || ((*s)[lastChar] == '\t'))) ) {
366 (*s)[lastChar] = '\0';
370 // Skip whitespace, excluding \n, at beginning of line
371 while ((*s)[0]==' ' || (*s)[0]=='\t') {
375 return ((*s) ? true : false);
381 * Processes a group (pair of group code and value).
383 * @param creationInterface Handle to class that creates entities and
384 * other CAD data from DXF group codes
386 * @param groupCode Constant indicating the data type of the group.
387 * @param groupValue The data value.
389 * @retval true if done processing current entity and new entity begun
390 * @retval false if not done processing current entity
392 bool DL_Dxf::processDXFGroup(DL_CreationInterface* creationInterface,
393 int groupCode, const char *groupValue) {
396 //std::cout << "DL_Dxf::processDXFGroup: " << groupCode << ": "
397 //<< groupValue << "\n";
399 // Init on first call
401 for (int i=0; i<DL_DXF_MAXGROUPCODE; ++i) {
404 settingValue[0] = '\0';
408 // Indicates comment or dxflib version:
409 if (groupCode==999) {
410 //std::cout << "999: " << groupValue << "\n";
411 if (groupValue!=NULL) {
412 if (!strncmp(groupValue, "dxflib", 6)) {
413 //std::cout << "dxflib version found" << "\n";
414 libVersion = getLibVersion(&groupValue[7]);
419 // Indicates start of new entity or var
420 else if (groupCode==0 || groupCode==9) {
422 // If new entity is encountered, the last one must be complete
423 // prepare attributes which can be used for most entities:
424 char name[DL_DXF_MAXLINE+1];
425 if ((values[8])[0]!='\0') {
426 strcpy(name, values[8]);
428 // defaults to layer '0':
434 // Compatibillity with qcad1:
435 if ((values[39])[0]!='\0' &&
436 (values[370])[0]=='\0') {
437 width = toInt(values[39], -1);
439 // since autocad 2002:
440 else if ((values[370])[0]!='\0') {
441 width = toInt(values[370], -1);
443 // default to BYLAYER:
449 color = toInt(values[62], 256);
451 char linetype[DL_DXF_MAXLINE+1];
452 strcpy(linetype, toString(values[6], "BYLAYER"));
454 attrib = DL_Attributes(values[8], // layer
457 linetype); // linetype
458 creationInterface->setAttributes(attrib);
460 creationInterface->setExtrusion(toReal(values[210], 0.0),
461 toReal(values[220], 0.0),
462 toReal(values[230], 1.0),
463 toReal(values[30], 0.0));
465 // Add the last entity via creationInterface
466 switch (currentEntity) {
468 addSetting(creationInterface);
472 addLayer(creationInterface);
476 addBlock(creationInterface);
480 endBlock(creationInterface);
483 case DL_ENTITY_POINT:
484 addPoint(creationInterface);
488 addLine(creationInterface);
491 case DL_ENTITY_POLYLINE:
492 //bulge = toReal(values[42]);
494 case DL_ENTITY_LWPOLYLINE:
495 addPolyline(creationInterface);
498 case DL_ENTITY_VERTEX:
499 addVertex(creationInterface);
502 case DL_ENTITY_SPLINE:
503 addSpline(creationInterface);
507 addArc(creationInterface);
510 case DL_ENTITY_CIRCLE:
511 addCircle(creationInterface);
514 case DL_ENTITY_ELLIPSE:
515 addEllipse(creationInterface);
518 case DL_ENTITY_INSERT:
519 addInsert(creationInterface);
522 case DL_ENTITY_MTEXT:
523 addMText(creationInterface);
527 addText(creationInterface);
530 case DL_ENTITY_ATTRIB:
531 addAttrib(creationInterface);
534 case DL_ENTITY_DIMENSION: {
535 int type = (toInt(values[70], 0)&0x07);
539 addDimLinear(creationInterface);
543 addDimAligned(creationInterface);
547 addDimAngular(creationInterface);
551 addDimDiametric(creationInterface);
555 addDimRadial(creationInterface);
559 addDimAngular3P(creationInterface);
568 case DL_ENTITY_LEADER:
569 addLeader(creationInterface);
572 case DL_ENTITY_HATCH:
573 addHatch(creationInterface);
576 case DL_ENTITY_IMAGE:
577 addImage(creationInterface);
580 case DL_ENTITY_IMAGEDEF:
581 addImageDef(creationInterface);
584 case DL_ENTITY_TRACE:
585 addTrace(creationInterface);
588 case DL_ENTITY_SOLID:
589 addSolid(creationInterface);
592 case DL_ENTITY_SEQEND:
593 endSequence(creationInterface);
601 // reset all values (they are not persistent and only this
602 // way we can detect default values for unstored settings)
603 for (int i=0; i<DL_DXF_MAXGROUPCODE; ++i) {
606 settingValue[0] = '\0';
607 settingKey[0] = '\0';
610 // Last DXF entity or setting has been handled
611 // Now determine what the next entity or setting type is
613 int prevEntity = currentEntity;
615 // Read DXF settings:
616 if (groupValue[0]=='$') {
617 currentEntity = DL_SETTING;
618 strncpy(settingKey, groupValue, DL_DXF_MAXLINE);
619 settingKey[DL_DXF_MAXLINE] = '\0';
622 else if (!strcmp(groupValue, "LAYER")) {
623 currentEntity = DL_LAYER;
627 else if (!strcmp(groupValue, "BLOCK")) {
628 currentEntity = DL_BLOCK;
629 } else if (!strcmp(groupValue, "ENDBLK")) {
630 currentEntity = DL_ENDBLK;
634 else if (!strcmp(groupValue, "POINT")) {
635 currentEntity = DL_ENTITY_POINT;
636 } else if (!strcmp(groupValue, "LINE")) {
637 currentEntity = DL_ENTITY_LINE;
638 } else if (!strcmp(groupValue, "POLYLINE")) {
639 currentEntity = DL_ENTITY_POLYLINE;
640 } else if (!strcmp(groupValue, "LWPOLYLINE")) {
641 currentEntity = DL_ENTITY_LWPOLYLINE;
642 } else if (!strcmp(groupValue, "VERTEX")) {
643 currentEntity = DL_ENTITY_VERTEX;
644 } else if (!strcmp(groupValue, "SPLINE")) {
645 currentEntity = DL_ENTITY_SPLINE;
646 } else if (!strcmp(groupValue, "ARC")) {
647 currentEntity = DL_ENTITY_ARC;
648 } else if (!strcmp(groupValue, "ELLIPSE")) {
649 currentEntity = DL_ENTITY_ELLIPSE;
650 } else if (!strcmp(groupValue, "CIRCLE")) {
651 currentEntity = DL_ENTITY_CIRCLE;
652 } else if (!strcmp(groupValue, "INSERT")) {
653 currentEntity = DL_ENTITY_INSERT;
654 } else if (!strcmp(groupValue, "TEXT")) {
655 currentEntity = DL_ENTITY_TEXT;
656 } else if (!strcmp(groupValue, "MTEXT")) {
657 currentEntity = DL_ENTITY_MTEXT;
658 } else if (!strcmp(groupValue, "ATTRIB")) {
659 currentEntity = DL_ENTITY_ATTRIB;
660 } else if (!strcmp(groupValue, "DIMENSION")) {
661 currentEntity = DL_ENTITY_DIMENSION;
662 } else if (!strcmp(groupValue, "LEADER")) {
663 currentEntity = DL_ENTITY_LEADER;
664 } else if (!strcmp(groupValue, "HATCH")) {
665 currentEntity = DL_ENTITY_HATCH;
666 } else if (!strcmp(groupValue, "IMAGE")) {
667 currentEntity = DL_ENTITY_IMAGE;
668 } else if (!strcmp(groupValue, "IMAGEDEF")) {
669 currentEntity = DL_ENTITY_IMAGEDEF;
670 } else if (!strcmp(groupValue, "TRACE")) {
671 currentEntity = DL_ENTITY_TRACE;
672 } else if (!strcmp(groupValue, "SOLID")) {
673 currentEntity = DL_ENTITY_SOLID;
674 } else if (!strcmp(groupValue, "SEQEND")) {
675 currentEntity = DL_ENTITY_SEQEND;
677 currentEntity = DL_UNKNOWN;
680 // end of old style POLYLINE entity
681 if (prevEntity==DL_ENTITY_VERTEX && currentEntity!=DL_ENTITY_VERTEX) {
682 endEntity(creationInterface);
688 // Group code does not indicate start of new entity or setting,
689 // so this group must be continuation of data for the current
691 if (groupCode<DL_DXF_MAXGROUPCODE) {
693 bool handled = false;
695 switch (currentEntity) {
696 case DL_ENTITY_MTEXT:
697 handled = handleMTextData(creationInterface);
700 case DL_ENTITY_LWPOLYLINE:
701 handled = handleLWPolylineData(creationInterface);
704 case DL_ENTITY_SPLINE:
705 handled = handleSplineData(creationInterface);
708 case DL_ENTITY_LEADER:
709 handled = handleLeaderData(creationInterface);
712 case DL_ENTITY_HATCH:
713 handled = handleHatchData(creationInterface);
721 // Normal group / value pair:
722 strncpy(values[groupCode], groupValue, DL_DXF_MAXLINE);
723 values[groupCode][DL_DXF_MAXLINE] = '\0';
735 * Adds a variable from the DXF file.
737 void DL_Dxf::addSetting(DL_CreationInterface* creationInterface) {
739 for (int i=0; i<=380; ++i) {
740 if (values[i][0]!='\0') {
748 creationInterface->setVariableString(settingKey,
752 else if (c>=10 && c<=39) {
754 creationInterface->setVariableVector(
757 toReal(values[c+10]),
758 toReal(values[c+20]),
763 else if (c>=40 && c<=59) {
764 creationInterface->setVariableDouble(settingKey,
769 else if (c>=60 && c<=99) {
770 creationInterface->setVariableInt(settingKey,
776 creationInterface->setVariableString(settingKey,
785 * Adds a layer that was read from the file via the creation interface.
787 void DL_Dxf::addLayer(DL_CreationInterface* creationInterface) {
788 // correct some impossible attributes for layers:
789 attrib = creationInterface->getAttributes();
790 if (attrib.getColor()==256 || attrib.getColor()==0) {
793 if (attrib.getWidth()<0) {
796 if (!strcasecmp(attrib.getLineType().c_str(), "BYLAYER") ||
797 !strcasecmp(attrib.getLineType().c_str(), "BYBLOCK")) {
798 attrib.setLineType("CONTINUOUS");
802 creationInterface->addLayer(DL_LayerData(values[2],
809 * Adds a block that was read from the file via the creation interface.
811 void DL_Dxf::addBlock(DL_CreationInterface* creationInterface) {
822 creationInterface->addBlock(d);
828 * Ends a block that was read from the file via the creation interface.
830 void DL_Dxf::endBlock(DL_CreationInterface* creationInterface) {
831 creationInterface->endBlock();
837 * Adds a point entity that was read from the file via the creation interface.
839 void DL_Dxf::addPoint(DL_CreationInterface* creationInterface) {
840 DL_PointData d(toReal(values[10]),
843 creationInterface->addPoint(d);
849 * Adds a line entity that was read from the file via the creation interface.
851 void DL_Dxf::addLine(DL_CreationInterface* creationInterface) {
852 DL_LineData d(toReal(values[10]),
859 creationInterface->addLine(d);
865 * Adds a polyline entity that was read from the file via the creation interface.
867 void DL_Dxf::addPolyline(DL_CreationInterface* creationInterface) {
868 DL_PolylineData pd(maxVertices, toInt(values[71], 0), toInt(values[72], 0), toInt(values[70], 0));
869 creationInterface->addPolyline(pd);
871 if (currentEntity==DL_ENTITY_LWPOLYLINE) {
872 for (int i=0; i<maxVertices; i++) {
873 DL_VertexData d(vertices[i*4],
878 creationInterface->addVertex(d);
880 creationInterface->endEntity();
887 * Adds a polyline vertex entity that was read from the file
888 * via the creation interface.
890 void DL_Dxf::addVertex(DL_CreationInterface* creationInterface) {
891 DL_VertexData d(toReal(values[10]),
897 //bulge = toReal(values[42]);
899 creationInterface->addVertex(d);
905 * Adds a spline entity that was read from the file via the creation interface.
907 void DL_Dxf::addSpline(DL_CreationInterface* creationInterface) {
908 DL_SplineData sd(toInt(values[71], 3), toInt(values[72], 0),
909 toInt(values[73], 0), toInt(values[70], 4));
910 creationInterface->addSpline(sd);
912 for (int i=0; i<maxControlPoints; i++) {
913 DL_ControlPointData d(controlPoints[i*3],
914 controlPoints[i*3+1],
915 controlPoints[i*3+2]);
917 creationInterface->addControlPoint(d);
924 * Adds a knot to the previously added spline.
927 void DL_Dxf::addKnot(DL_CreationInterface* creationInterface) {
928 std::cout << "DL_Dxf::addKnot\n";
935 * Adds a control point to the previously added spline.
938 void DL_Dxf::addControlPoint(DL_CreationInterface* creationInterface) {
939 std::cout << "DL_Dxf::addControlPoint\n";
946 * Adds an arc entity that was read from the file via the creation interface.
948 void DL_Dxf::addArc(DL_CreationInterface* creationInterface) {
949 DL_ArcData d(toReal(values[10]),
956 creationInterface->addArc(d);
962 * Adds a circle entity that was read from the file via the creation interface.
964 void DL_Dxf::addCircle(DL_CreationInterface* creationInterface) {
965 DL_CircleData d(toReal(values[10]),
970 creationInterface->addCircle(d);
976 * Adds an ellipse entity that was read from the file via the creation interface.
978 void DL_Dxf::addEllipse(DL_CreationInterface* creationInterface) {
979 DL_EllipseData d(toReal(values[10]),
985 toReal(values[40], 1.0),
986 toReal(values[41], 0.0),
987 toReal(values[42], 2*M_PI));
989 creationInterface->addEllipse(d);
995 * Adds an insert entity that was read from the file via the creation interface.
997 void DL_Dxf::addInsert(DL_CreationInterface* creationInterface) {
998 DL_InsertData d(values[2],
1000 toReal(values[10], 0.0),
1001 toReal(values[20], 0.0),
1002 toReal(values[30], 0.0),
1004 toReal(values[41], 1.0),
1005 toReal(values[42], 1.0),
1006 toReal(values[43], 1.0),
1008 toReal(values[50], 0.0),
1010 toInt(values[70], 1),
1011 toInt(values[71], 1),
1013 toReal(values[44], 0.0),
1014 toReal(values[45], 0.0));
1016 creationInterface->addInsert(d);
1021 * Adds a trace entity (4 edge closed polyline) that was read from the file via the creation interface.
1025 void DL_Dxf::addTrace(DL_CreationInterface* creationInterface) {
1028 for (int k = 0; k < 4; k++) {
1029 td.x[k] = toReal(values[10 + k]);
1030 td.y[k] = toReal(values[20 + k]);
1031 td.z[k] = toReal(values[30 + k]);
1033 creationInterface->addTrace(td);
1037 * Adds a solid entity (filled trace) that was read from the file via the creation interface.
1041 void DL_Dxf::addSolid(DL_CreationInterface* creationInterface) {
1044 for (int k = 0; k < 4; k++) {
1045 sd.x[k] = toReal(values[10 + k]);
1046 sd.y[k] = toReal(values[20 + k]);
1047 sd.z[k] = toReal(values[30 + k]);
1049 creationInterface->addSolid(sd);
1054 * Adds an MText entity that was read from the file via the creation interface.
1056 void DL_Dxf::addMText(DL_CreationInterface* creationInterface) {
1059 if (values[50][0]!='\0') {
1060 if (libVersion<=0x02000200) {
1061 // wrong but compatible with dxflib <=2.0.2.0:
1062 angle = toReal(values[50], 0.0);
1064 angle = (toReal(values[50], 0.0)*2*M_PI)/360.0;
1066 } else if (values[11][0]!='\0' && values[21][0]!='\0') {
1067 double x = toReal(values[11], 0.0);
1068 double y = toReal(values[21], 0.0);
1070 if (fabs(x)<1.0e-6) {
1074 angle = M_PI/2.0*3.0;
1083 toReal(values[10], 0.0),
1084 toReal(values[20], 0.0),
1085 toReal(values[30], 0.0),
1087 toReal(values[40], 2.5),
1089 toReal(values[41], 100.0),
1091 toInt(values[71], 1),
1092 // drawing direction
1093 toInt(values[72], 1),
1094 // line spacing style
1095 toInt(values[73], 1),
1096 // line spacing factor
1097 toReal(values[44], 1.0),
1104 creationInterface->addMText(d);
1110 * Handles additional MText data.
1112 bool DL_Dxf::handleMTextData(DL_CreationInterface* creationInterface) {
1113 // Special handling of text chunks for MTEXT entities:
1115 creationInterface->addMTextChunk(groupValue);
1125 * Handles additional polyline data.
1127 bool DL_Dxf::handleLWPolylineData(DL_CreationInterface* /*creationInterface*/) {
1128 // Allocate LWPolyline vertices (group code 90):
1129 if (groupCode==90) {
1130 maxVertices = toInt(groupValue);
1131 if (maxVertices>0) {
1132 if (vertices!=NULL) {
1135 vertices = new double[4*maxVertices];
1136 for (int i=0; i<maxVertices; ++i) {
1137 vertices[i*4] = 0.0;
1138 vertices[i*4+1] = 0.0;
1139 vertices[i*4+2] = 0.0;
1140 vertices[i*4+3] = 0.0;
1147 // Compute LWPolylines vertices (group codes 10/20/30/42):
1148 else if (groupCode==10 || groupCode==20 ||
1149 groupCode==30 || groupCode==42) {
1151 if (vertexIndex<maxVertices-1 && groupCode==10) {
1155 if (groupCode<=30) {
1156 if (vertexIndex>=0 && vertexIndex<maxVertices) {
1157 vertices[4*vertexIndex + (groupCode/10-1)]
1158 = toReal(groupValue);
1160 } else if (groupCode==42 && vertexIndex<maxVertices) {
1161 vertices[4*vertexIndex + 3] = toReal(groupValue);
1171 * Handles additional spline data.
1173 bool DL_Dxf::handleSplineData(DL_CreationInterface* /*creationInterface*/) {
1174 // Allocate Spline knots (group code 72):
1175 if (groupCode==72) {
1176 maxKnots = toInt(groupValue);
1181 knots = new double[maxKnots];
1182 for (int i=0; i<maxKnots; ++i) {
1190 // Allocate Spline control points (group code 73):
1191 else if (groupCode==73) {
1192 maxControlPoints = toInt(groupValue);
1193 if (maxControlPoints>0) {
1194 if (controlPoints!=NULL) {
1195 delete[] controlPoints;
1197 controlPoints = new double[3*maxControlPoints];
1198 for (int i=0; i<maxControlPoints; ++i) {
1199 controlPoints[i*3] = 0.0;
1200 controlPoints[i*3+1] = 0.0;
1201 controlPoints[i*3+2] = 0.0;
1204 controlPointIndex=-1;
1208 // Compute spline knot vertices (group code 40):
1209 else if (groupCode==40) {
1210 if (knotIndex<maxKnots-1) {
1212 knots[knotIndex] = toReal(groupValue);
1217 // Compute spline control points (group codes 10/20/30):
1218 else if (groupCode==10 || groupCode==20 ||
1221 if (controlPointIndex<maxControlPoints-1 && groupCode==10) {
1222 controlPointIndex++;
1225 if (controlPointIndex>=0 && controlPointIndex<maxControlPoints) {
1226 controlPoints[3*controlPointIndex + (groupCode/10-1)]
1227 = toReal(groupValue);
1237 * Handles additional leader data.
1239 bool DL_Dxf::handleLeaderData(DL_CreationInterface* /*creationInterface*/) {
1240 // Allocate Leader vertices (group code 76):
1241 if (groupCode==76) {
1242 maxLeaderVertices = toInt(groupValue);
1243 if (maxLeaderVertices>0) {
1244 if (leaderVertices!=NULL) {
1245 delete[] leaderVertices;
1247 leaderVertices = new double[3*maxLeaderVertices];
1248 for (int i=0; i<maxLeaderVertices; ++i) {
1249 leaderVertices[i*3] = 0.0;
1250 leaderVertices[i*3+1] = 0.0;
1251 leaderVertices[i*3+2] = 0.0;
1254 leaderVertexIndex=-1;
1258 // Compute Leader vertices (group codes 10/20/30):
1259 else if (groupCode==10 || groupCode==20 || groupCode==30) {
1261 if (leaderVertexIndex<maxLeaderVertices-1 && groupCode==10) {
1262 leaderVertexIndex++;
1265 if (groupCode<=30) {
1266 if (leaderVertexIndex>=0 &&
1267 leaderVertexIndex<maxLeaderVertices) {
1268 leaderVertices[3*leaderVertexIndex + (groupCode/10-1)]
1269 = toReal(groupValue);
1281 * Handles additional hatch data.
1283 bool DL_Dxf::handleHatchData(DL_CreationInterface* /*creationInterface*/) {
1285 static int firstPolylineStatus = 0;
1287 // Allocate hatch loops (group code 91):
1288 if (groupCode==91 && toInt(groupValue)>0) {
1290 //std::cout << "allocating " << toInt(groupValue) << " loops\n";
1292 if (hatchLoops!=NULL) {
1293 delete[] hatchLoops;
1296 if (maxHatchEdges!=NULL) {
1297 delete[] maxHatchEdges;
1298 maxHatchEdges = NULL;
1300 if (hatchEdgeIndex!=NULL) {
1301 delete[] hatchEdgeIndex;
1302 hatchEdgeIndex = NULL;
1304 if (hatchEdges!=NULL) {
1305 for (int i=0; i<maxHatchLoops; ++i) {
1306 delete[] hatchEdges[i];
1308 delete[] hatchEdges;
1311 maxHatchLoops = toInt(groupValue);
1313 //std::cout << "maxHatchLoops: " << maxHatchLoops << "\n";
1315 if (maxHatchLoops>0) {
1316 hatchLoops = new DL_HatchLoopData[maxHatchLoops];
1317 maxHatchEdges = new int[maxHatchLoops];
1318 hatchEdgeIndex = new int[maxHatchLoops];
1319 hatchEdges = new DL_HatchEdgeData*[maxHatchLoops];
1320 //std::cout << "new hatchEdges[" << maxHatchLoops << "]\n";
1321 for (int i=0; i<maxHatchLoops; ++i) {
1322 hatchEdges[i] = NULL;
1323 //std::cout << "hatchEdges[" << i << "] = NULL\n";
1324 maxHatchEdges[i] = 0;
1326 hatchLoopIndex = -1;
1329 //std::cout << "done\n";
1333 // Allocate hatch edges, group code 93
1334 if (groupCode==93 && toInt(groupValue)>0) {
1335 if (hatchLoopIndex<maxHatchLoops-1 && hatchLoops!=NULL &&
1336 maxHatchEdges!=NULL && hatchEdgeIndex!=NULL &&
1339 //std::cout << " allocating " << toInt(groupValue) << " edges\n";
1343 hatchLoops[hatchLoopIndex]
1344 = DL_HatchLoopData(toInt(groupValue));
1346 maxHatchEdges[hatchLoopIndex] = toInt(groupValue);
1347 hatchEdgeIndex[hatchLoopIndex] = -1;
1348 hatchEdges[hatchLoopIndex]
1349 = new DL_HatchEdgeData[toInt(groupValue)];
1351 //std::cout << "hatchEdges[" << hatchLoopIndex << "] = new "
1352 // << toInt(groupValue) << "\n";
1353 firstPolylineStatus = 0;
1355 //std::cout << "dropping " << toInt(groupValue) << " edges\n";
1358 //std::cout << "done\n";
1362 // Init hatch edge for non-polyline boundary (group code 72)
1363 if (hatchEdges!=NULL &&
1364 hatchEdgeIndex!=NULL &&
1365 maxHatchEdges!=NULL &&
1366 hatchLoopIndex>=0 &&
1367 hatchLoopIndex<maxHatchLoops &&
1368 hatchEdgeIndex[hatchLoopIndex] <
1369 maxHatchEdges[hatchLoopIndex] &&
1370 (atoi(values[92])&2)==0 && // not a polyline
1374 //std::cout << "Init hatch edge for non-polyline boundary\n";
1375 //std::cout << "hatchLoopIndex: " << hatchLoopIndex << "\n";
1376 //std::cout << "maxHatchLoops: " << maxHatchLoops << "\n";
1378 hatchEdgeIndex[hatchLoopIndex]++;
1380 //std::cout << " init edge: type: "
1381 //<< toInt(groupValue)
1382 //<< " index: " << hatchEdgeIndex[hatchLoopIndex] << "\n";
1384 hatchEdges[hatchLoopIndex][hatchEdgeIndex[hatchLoopIndex]]
1385 .type = toInt(groupValue);
1386 hatchEdges[hatchLoopIndex][hatchEdgeIndex[hatchLoopIndex]]
1389 //std::cout << "done\n";
1393 // Handle hatch edges for non-polyline boundaries
1394 // (group codes 10, 20, 11, 21, 40, 50, 51, 73)
1397 hatchEdgeIndex!=NULL &&
1398 hatchLoopIndex>=0 &&
1399 hatchLoopIndex<maxHatchLoops &&
1400 hatchEdges[hatchLoopIndex]!=NULL &&
1401 hatchEdgeIndex[hatchLoopIndex]>=0 &&
1402 hatchEdgeIndex[hatchLoopIndex] <
1403 maxHatchEdges[hatchLoopIndex] &&
1404 ((atoi(values[92])&2)==0) && // not a polyline
1405 (groupCode==10 || groupCode==20 ||
1406 groupCode==11 || groupCode==21 ||
1407 groupCode==40 || groupCode==50 ||
1408 groupCode==51 || groupCode==73)) {
1410 //std::cout << "Handle hatch edge for non-polyline boundary\n";
1411 //std::cout << " found edge data: " << groupCode << "\n";
1412 //std::cout << " value: " << toReal(groupValue) << "\n";
1415 //std::cout << " defined: "
1416 // << (int)hatchEdges[hatchLoopIndex]
1417 // [hatchEdgeIndex[hatchLoopIndex]].defined << "\n";
1419 //std::cout << "92 flag: '" << values[92] << "'\n";
1420 //std::cout << "92 flag (int): '" << atoi(values[92]) << "'\n";
1422 if (hatchEdges[hatchLoopIndex]
1423 [hatchEdgeIndex[hatchLoopIndex]].defined==false) {
1424 if (hatchEdges[hatchLoopIndex]
1425 [hatchEdgeIndex[hatchLoopIndex]].type==1) {
1426 switch (groupCode) {
1428 hatchEdges[hatchLoopIndex]
1429 [hatchEdgeIndex[hatchLoopIndex]].x1
1430 = toReal(groupValue);
1433 hatchEdges[hatchLoopIndex]
1434 [hatchEdgeIndex[hatchLoopIndex]].y1
1435 = toReal(groupValue);
1438 hatchEdges[hatchLoopIndex]
1439 [hatchEdgeIndex[hatchLoopIndex]].x2
1440 = toReal(groupValue);
1443 hatchEdges[hatchLoopIndex]
1444 [hatchEdgeIndex[hatchLoopIndex]].y2
1445 = toReal(groupValue);
1446 hatchEdges[hatchLoopIndex]
1447 [hatchEdgeIndex[hatchLoopIndex]].defined = true;
1454 if (hatchEdges[hatchLoopIndex]
1455 [hatchEdgeIndex[hatchLoopIndex]].type==2) {
1456 switch (groupCode) {
1458 hatchEdges[hatchLoopIndex]
1459 [hatchEdgeIndex[hatchLoopIndex]].cx
1460 = toReal(groupValue);
1463 hatchEdges[hatchLoopIndex]
1464 [hatchEdgeIndex[hatchLoopIndex]].cy
1465 = toReal(groupValue);
1468 hatchEdges[hatchLoopIndex]
1469 [hatchEdgeIndex[hatchLoopIndex]].radius
1470 = toReal(groupValue);
1473 hatchEdges[hatchLoopIndex]
1474 [hatchEdgeIndex[hatchLoopIndex]].angle1
1475 = toReal(groupValue)/360.0*2*M_PI;
1478 hatchEdges[hatchLoopIndex]
1479 [hatchEdgeIndex[hatchLoopIndex]].angle2
1480 = toReal(groupValue)/360.0*2*M_PI;
1483 hatchEdges[hatchLoopIndex]
1484 [hatchEdgeIndex[hatchLoopIndex]].ccw
1485 = (bool)toInt(groupValue);
1486 hatchEdges[hatchLoopIndex]
1487 [hatchEdgeIndex[hatchLoopIndex]].defined = true;
1498 // 2003/12/31: polyline hatches can be extremely slow and are rarely used
1500 // Handle hatch edges for polyline boundaries
1501 // (group codes 10, 20, 42)
1504 hatchEdgeIndex!=NULL &&
1505 hatchLoopIndex>=0 &&
1506 hatchLoopIndex<maxHatchLoops &&
1507 hatchEdges[hatchLoopIndex]!=NULL &&
1508 //hatchEdgeIndex[hatchLoopIndex]>=0 &&
1509 hatchEdgeIndex[hatchLoopIndex] <
1510 maxHatchEdges[hatchLoopIndex] &&
1511 ((atoi(values[92])&2)==2)) { // a polyline
1513 if (groupCode==10 || groupCode==20 ||
1516 std::cout << " found polyline edge data: " << groupCode << "\n";
1517 std::cout << " value: " << toReal(groupValue) << "\n";
1519 static double lastX = 0.0;
1520 static double lastY = 0.0;
1521 static double lastB = 0.0;
1523 if (firstPolylineStatus<2) {
1524 switch (groupCode) {
1526 firstPolylineStatus++;
1527 if (firstPolylineStatus==1) {
1528 lastX = toReal(groupValue);
1529 std::cout << " firstX: " << lastX << "\n";
1534 lastY = toReal(groupValue);
1535 std::cout << " firstY: " << lastY << "\n";
1539 lastB = toReal(groupValue);
1546 if (firstPolylineStatus!=2) {
1552 switch (groupCode) {
1554 hatchEdgeIndex[hatchLoopIndex]++;
1555 hatchEdges[hatchLoopIndex]
1556 [hatchEdgeIndex[hatchLoopIndex]].type = 1;
1557 hatchEdges[hatchLoopIndex]
1558 [hatchEdgeIndex[hatchLoopIndex]].x1
1560 hatchEdges[hatchLoopIndex]
1561 [hatchEdgeIndex[hatchLoopIndex]].x2
1562 = lastX = toReal(groupValue);
1563 std::cout << " X: " << lastX << "\n";
1566 hatchEdges[hatchLoopIndex]
1567 [hatchEdgeIndex[hatchLoopIndex]].y1
1569 hatchEdges[hatchLoopIndex]
1570 [hatchEdgeIndex[hatchLoopIndex]].y2
1571 = lastY = toReal(groupValue);
1572 std::cout << " Y: " << lastY << "\n";
1577 double x1 = hatchEdges[hatchLoopIndex]
1578 [hatchEdgeIndex[hatchLoopIndex]].x1;
1579 double y1 = hatchEdges[hatchLoopIndex]
1580 [hatchEdgeIndex[hatchLoopIndex]].y1;
1581 double x2 = hatchEdges[hatchLoopIndex]
1582 [hatchEdgeIndex[hatchLoopIndex]].x2;
1583 double y2 = hatchEdges[hatchLoopIndex]
1584 [hatchEdgeIndex[hatchLoopIndex]].y2;
1586 double bulge = toReal(groupValue);
1588 bool reversed = (bulge<0.0);
1589 double alpha = atan(bulge)*4.0;
1595 double mx = (x2+x1)/2.0;
1596 double my = (y2+y1)/2.0;
1597 double dist = sqrt(pow(x2-x1,2) + pow(y2-y1,2)) / 2.0;
1599 // alpha can't be 0.0 at this point
1600 radius = fabs(dist / sin(alpha/2.0));
1602 double wu = fabs(pow(radius, 2.0) - pow(dist, 2.0));
1603 double h = sqrt(wu);
1604 double angle = acos((x2-x1) / dist);
1612 if (fabs(alpha)>M_PI) {
1616 cx = mx + cos(angle) * h;
1617 cy = my + sin(angle) * h;
1619 a1 = hatchEdges[hatchLoopIndex]
1620 [hatchEdgeIndex[hatchLoopIndex]].type = 2;
1621 hatchEdges[hatchLoopIndex]
1622 [hatchEdgeIndex[hatchLoopIndex]].ccw = (toReal(groupValue)>0.0);
1623 hatchEdges[hatchLoopIndex]
1624 [hatchEdgeIndex[hatchLoopIndex]].cx = cx;
1625 hatchEdges[hatchLoopIndex]
1626 [hatchEdgeIndex[hatchLoopIndex]].cy = cy;
1627 hatchEdges[hatchLoopIndex]
1628 [hatchEdgeIndex[hatchLoopIndex]].radius = radius;
1636 // end polyline boundary
1651 * Adds an text entity that was read from the file via the creation interface.
1653 void DL_Dxf::addText(DL_CreationInterface* creationInterface) {
1656 toReal(values[10], 0.0),
1657 toReal(values[20], 0.0),
1658 toReal(values[30], 0.0),
1660 toReal(values[11], 0.0),
1661 toReal(values[21], 0.0),
1662 toReal(values[31], 0.0),
1664 toReal(values[40], 2.5),
1666 toReal(values[41], 1.0),
1668 toInt(values[71], 0),
1670 toInt(values[72], 0),
1672 toInt(values[73], 0),
1678 (toReal(values[50], 0.0)*2*M_PI)/360.0);
1680 creationInterface->addText(d);
1686 * Adds an attrib entity that was read from the file via the creation interface.
1687 * @todo add attrib instead of normal text
1689 void DL_Dxf::addAttrib(DL_CreationInterface* creationInterface) {
1692 toReal(values[10], 0.0),
1693 toReal(values[20], 0.0),
1694 toReal(values[30], 0.0),
1696 toReal(values[11], 0.0),
1697 toReal(values[21], 0.0),
1698 toReal(values[31], 0.0),
1700 toReal(values[40], 2.5),
1702 toReal(values[41], 1.0),
1704 toInt(values[71], 0),
1706 toInt(values[72], 0),
1708 toInt(values[74], 0),
1714 (toReal(values[50], 0.0)*2*M_PI)/360.0);
1716 creationInterface->addText(d);
1722 * @return dimension data from current values.
1724 DL_DimensionData DL_Dxf::getDimData() {
1725 // generic dimension data:
1726 return DL_DimensionData(
1728 toReal(values[10], 0.0),
1729 toReal(values[20], 0.0),
1730 toReal(values[30], 0.0),
1731 // text middle point
1732 toReal(values[11], 0.0),
1733 toReal(values[21], 0.0),
1734 toReal(values[31], 0.0),
1736 toInt(values[70], 0),
1738 toInt(values[71], 5),
1740 toInt(values[72], 1),
1742 toReal(values[41], 1.0),
1748 toReal(values[53], 0.0));
1754 * Adds a linear dimension entity that was read from the file via the creation interface.
1756 void DL_Dxf::addDimLinear(DL_CreationInterface* creationInterface) {
1757 DL_DimensionData d = getDimData();
1759 // horizontal / vertical / rotated dimension:
1760 DL_DimLinearData dl(
1761 // definition point 1
1762 toReal(values[13], 0.0),
1763 toReal(values[23], 0.0),
1764 toReal(values[33], 0.0),
1765 // definition point 2
1766 toReal(values[14], 0.0),
1767 toReal(values[24], 0.0),
1768 toReal(values[34], 0.0),
1770 toReal(values[50], 0.0),
1772 toReal(values[52], 0.0));
1773 creationInterface->addDimLinear(d, dl);
1779 * Adds an aligned dimension entity that was read from the file via the creation interface.
1781 void DL_Dxf::addDimAligned(DL_CreationInterface* creationInterface) {
1782 DL_DimensionData d = getDimData();
1784 // aligned dimension:
1785 DL_DimAlignedData da(
1786 // extension point 1
1787 toReal(values[13], 0.0),
1788 toReal(values[23], 0.0),
1789 toReal(values[33], 0.0),
1790 // extension point 2
1791 toReal(values[14], 0.0),
1792 toReal(values[24], 0.0),
1793 toReal(values[34], 0.0));
1794 creationInterface->addDimAlign(d, da);
1800 * Adds a radial dimension entity that was read from the file via the creation interface.
1802 void DL_Dxf::addDimRadial(DL_CreationInterface* creationInterface) {
1803 DL_DimensionData d = getDimData();
1805 DL_DimRadialData dr(
1807 toReal(values[15], 0.0),
1808 toReal(values[25], 0.0),
1809 toReal(values[35], 0.0),
1811 toReal(values[40], 0.0));
1812 creationInterface->addDimRadial(d, dr);
1818 * Adds a diametric dimension entity that was read from the file via the creation interface.
1820 void DL_Dxf::addDimDiametric(DL_CreationInterface* creationInterface) {
1821 DL_DimensionData d = getDimData();
1823 // diametric dimension:
1824 DL_DimDiametricData dr(
1826 toReal(values[15], 0.0),
1827 toReal(values[25], 0.0),
1828 toReal(values[35], 0.0),
1830 toReal(values[40], 0.0));
1831 creationInterface->addDimDiametric(d, dr);
1837 * Adds an angular dimension entity that was read from the file via the creation interface.
1839 void DL_Dxf::addDimAngular(DL_CreationInterface* creationInterface) {
1840 DL_DimensionData d = getDimData();
1842 // angular dimension:
1843 DL_DimAngularData da(
1844 // definition point 1
1845 toReal(values[13], 0.0),
1846 toReal(values[23], 0.0),
1847 toReal(values[33], 0.0),
1848 // definition point 2
1849 toReal(values[14], 0.0),
1850 toReal(values[24], 0.0),
1851 toReal(values[34], 0.0),
1852 // definition point 3
1853 toReal(values[15], 0.0),
1854 toReal(values[25], 0.0),
1855 toReal(values[35], 0.0),
1856 // definition point 4
1857 toReal(values[16], 0.0),
1858 toReal(values[26], 0.0),
1859 toReal(values[36], 0.0));
1860 creationInterface->addDimAngular(d, da);
1865 * Adds an angular dimension entity that was read from the file via the creation interface.
1867 void DL_Dxf::addDimAngular3P(DL_CreationInterface* creationInterface) {
1868 DL_DimensionData d = getDimData();
1870 // angular dimension (3P):
1871 DL_DimAngular3PData da(
1872 // definition point 1
1873 toReal(values[13], 0.0),
1874 toReal(values[23], 0.0),
1875 toReal(values[33], 0.0),
1876 // definition point 2
1877 toReal(values[14], 0.0),
1878 toReal(values[24], 0.0),
1879 toReal(values[34], 0.0),
1880 // definition point 3
1881 toReal(values[15], 0.0),
1882 toReal(values[25], 0.0),
1883 toReal(values[35], 0.0));
1884 creationInterface->addDimAngular3P(d, da);
1890 * Adds a leader entity that was read from the file via the creation interface.
1892 void DL_Dxf::addLeader(DL_CreationInterface* creationInterface) {
1896 toInt(values[71], 1),
1898 toInt(values[72], 0),
1899 // Leader creation flag
1900 toInt(values[73], 3),
1901 // Hookline direction flag
1902 toInt(values[74], 1),
1904 toInt(values[75], 0),
1905 // Text annotation height
1906 toReal(values[40], 1.0),
1907 // Text annotation width
1908 toReal(values[41], 1.0),
1909 // Number of vertices in leader
1910 toInt(values[76], 0)
1912 creationInterface->addLeader(le);
1914 for (int i=0; i<maxLeaderVertices; i++) {
1915 DL_LeaderVertexData d(leaderVertices[i*3],
1916 leaderVertices[i*3+1],
1917 leaderVertices[i*3+2]);
1919 creationInterface->addLeaderVertex(d);
1926 * Adds a hatch entity that was read from the file via the creation interface.
1928 void DL_Dxf::addHatch(DL_CreationInterface* creationInterface) {
1929 DL_HatchData hd(toInt(values[91], 1),
1930 toInt(values[70], 0),
1931 toReal(values[41], 1.0),
1932 toReal(values[52], 0.0),
1934 creationInterface->addHatch(hd);
1936 for (int l=0; l<maxHatchLoops; l++) {
1937 DL_HatchLoopData ld(maxHatchEdges[l]);
1938 creationInterface->addHatchLoop(ld);
1939 for (int b=0; b<maxHatchEdges[l]; b++) {
1940 creationInterface->addHatchEdge(hatchEdges[l][b]);
1943 creationInterface->endEntity();
1944 currentEntity = DL_UNKNOWN;
1950 * Adds an image entity that was read from the file via the creation interface.
1952 void DL_Dxf::addImage(DL_CreationInterface* creationInterface) {
1953 DL_ImageData id(// pass ref insead of name we don't have yet
1956 toReal(values[10], 0.0),
1957 toReal(values[20], 0.0),
1958 toReal(values[30], 0.0),
1960 toReal(values[11], 1.0),
1961 toReal(values[21], 0.0),
1962 toReal(values[31], 0.0),
1964 toReal(values[12], 0.0),
1965 toReal(values[22], 1.0),
1966 toReal(values[32], 0.0),
1967 // image size (pixel):
1968 toInt(values[13], 1),
1969 toInt(values[23], 1),
1970 // brightness, contrast, fade
1971 toInt(values[281], 50),
1972 toInt(values[282], 50),
1973 toInt(values[283], 0));
1975 creationInterface->addImage(id);
1976 creationInterface->endEntity();
1977 currentEntity = DL_UNKNOWN;
1983 * Adds an image definition that was read from the file via the creation interface.
1985 void DL_Dxf::addImageDef(DL_CreationInterface* creationInterface) {
1986 DL_ImageDefData id(// handle
1990 creationInterface->linkImage(id);
1991 creationInterface->endEntity();
1992 currentEntity = DL_UNKNOWN;
1998 * Ends some special entities like hatches or old style polylines.
2000 void DL_Dxf::endEntity(DL_CreationInterface* creationInterface) {
2001 creationInterface->endEntity();
2006 * Ends a sequence and notifies the creation interface.
2008 void DL_Dxf::endSequence(DL_CreationInterface* creationInterface) {
2009 creationInterface->endSequence();
2014 * Converts the given string into an int.
2015 * ok is set to false if there was an error.
2017 int DL_Dxf::stringToInt(const char* s, bool* ok) {
2026 } else if (s[i]=='.') {
2028 //std::cerr << "two dots\n";
2033 } else if (s[i]<'0' || s[i]>'9') {
2034 //std::cerr << "NaN: '" << s[i] << "'\n";
2038 } while(s[i]!='\0' && *ok==true);
2046 * @brief Opens the given file for writing and returns a pointer
2047 * to the dxf writer. This pointer needs to be passed on to other
2048 * writing functions.
2050 * @param file Full path of the file to open.
2052 * @return Pointer to an ascii dxf writer object.
2054 DL_WriterA* DL_Dxf::out(const char* file, DL_Codes::version version) {
2055 char* f = new char[strlen(file)+1];
2057 this->version = version;
2059 DL_WriterA* dw = new DL_WriterA(f, version);
2060 if (dw->openFailed()) {
2071 * @brief Writes a DXF header to the file currently opened
2072 * by the given DXF writer object.
2074 void DL_Dxf::writeHeader(DL_WriterA& dw) {
2075 dw.comment("dxflib " DL_VERSION);
2078 dw.dxfString(9, "$ACADVER");
2080 case DL_Codes::AC1009:
2081 dw.dxfString(1, "AC1009");
2083 case DL_Codes::AC1012:
2084 dw.dxfString(1, "AC1012");
2086 case DL_Codes::AC1014:
2087 dw.dxfString(1, "AC1014");
2089 case DL_Codes::AC1015:
2090 dw.dxfString(1, "AC1015");
2094 // Newer version require that (otherwise a*cad crashes..)
2095 if (version==VER_2000) {
2096 dw.dxfString(9, "$HANDSEED");
2097 dw.dxfHex(5, 0xFFFF);
2107 * Writes a point entity to the file.
2109 * @param dw DXF writer
2110 * @param data Entity data from the file
2111 * @param attrib Attributes
2113 void DL_Dxf::writePoint(DL_WriterA& dw,
2114 const DL_PointData& data,
2115 const DL_Attributes& attrib) {
2117 if (version==VER_2000) {
2118 dw.dxfString(100, "AcDbEntity");
2119 dw.dxfString(100, "AcDbPoint");
2121 dw.entityAttributes(attrib);
2122 dw.coord(POINT_COORD_CODE, data.x, data.y);
2128 * Writes a line entity to the file.
2130 * @param dw DXF writer
2131 * @param data Entity data from the file
2132 * @param attrib Attributes
2134 void DL_Dxf::writeLine(DL_WriterA& dw,
2135 const DL_LineData& data,
2136 const DL_Attributes& attrib) {
2138 if (version==VER_2000) {
2139 dw.dxfString(100, "AcDbEntity");
2140 dw.dxfString(100, "AcDbLine");
2142 dw.entityAttributes(attrib);
2143 dw.coord(LINE_START_CODE, data.x1, data.y1);
2144 dw.coord(LINE_END_CODE, data.x2, data.y2);
2150 * Writes a polyline entity to the file.
2152 * @param dw DXF writer
2153 * @param data Entity data from the file
2154 * @param attrib Attributes
2157 void DL_Dxf::writePolyline(DL_WriterA& dw,
2158 const DL_PolylineData& data,
2159 const DL_Attributes& attrib) {
2160 if (version==VER_2000) {
2161 dw.entity("LWPOLYLINE");
2162 dw.entityAttributes(attrib);
2163 dw.dxfString(100, "AcDbEntity");
2164 dw.dxfString(100, "AcDbPolyline");
2165 dw.dxfInt(90, (int)data.number);
2166 dw.dxfInt(70, data.flags);
2168 dw.entity("POLYLINE");
2169 dw.entityAttributes(attrib);
2170 polylineLayer = attrib.getLayer();
2172 dw.dxfInt(70, data.flags);
2173 dw.coord(VERTEX_COORD_CODE, 0.0, 0.0);
2180 * Writes a single vertex of a polyline to the file.
2182 * @param dw DXF writer
2183 * @param data Entity data from the file
2184 * @param attrib Attributes
2186 void DL_Dxf::writeVertex(DL_WriterA& dw,
2187 const DL_VertexData& data) {
2190 if (version==VER_2000) {
2191 dw.dxfReal(10, data.x);
2192 dw.dxfReal(20, data.y);
2193 if (fabs(data.bulge)>1.0e-10) {
2194 dw.dxfReal(42, data.bulge);
2197 dw.entity("VERTEX");
2198 //dw.entityAttributes(attrib);
2199 dw.dxfString(8, polylineLayer);
2200 dw.coord(VERTEX_COORD_CODE, data.x, data.y);
2201 if (fabs(data.bulge)>1.0e-10) {
2202 dw.dxfReal(42, data.bulge);
2210 * Writes the polyline end. Only needed for DXF R12.
2212 void DL_Dxf::writePolylineEnd(DL_WriterA& dw) {
2213 if (version==VER_2000) {
2215 dw.entity("SEQEND");
2221 * Writes a spline entity to the file.
2223 * @param dw DXF writer
2224 * @param data Entity data from the file
2225 * @param attrib Attributes
2226 * @see writeControlPoint
2228 void DL_Dxf::writeSpline(DL_WriterA& dw,
2229 const DL_SplineData& data,
2230 const DL_Attributes& attrib) {
2232 dw.entity("SPLINE");
2233 dw.entityAttributes(attrib);
2234 if (version==VER_2000) {
2235 dw.dxfString(100, "AcDbEntity");
2236 dw.dxfString(100, "AcDbSpline");
2238 dw.dxfInt(70, data.flags);
2239 dw.dxfInt(71, data.degree);
2240 dw.dxfInt(72, data.nKnots); // number of knots
2241 dw.dxfInt(73, data.nControl); // number of control points
2242 dw.dxfInt(74, 0); // number of fit points
2248 * Writes a single control point of a spline to the file.
2250 * @param dw DXF writer
2251 * @param data Entity data from the file
2252 * @param attrib Attributes
2254 void DL_Dxf::writeControlPoint(DL_WriterA& dw,
2255 const DL_ControlPointData& data) {
2257 dw.dxfReal(10, data.x);
2258 dw.dxfReal(20, data.y);
2259 dw.dxfReal(30, data.z);
2265 * Writes a single knot of a spline to the file.
2267 * @param dw DXF writer
2268 * @param data Entity data from the file
2269 * @param attrib Attributes
2271 void DL_Dxf::writeKnot(DL_WriterA& dw,
2272 const DL_KnotData& data) {
2274 dw.dxfReal(40, data.k);
2280 * Writes a circle entity to the file.
2282 * @param dw DXF writer
2283 * @param data Entity data from the file
2284 * @param attrib Attributes
2286 void DL_Dxf::writeCircle(DL_WriterA& dw,
2287 const DL_CircleData& data,
2288 const DL_Attributes& attrib) {
2289 dw.entity("CIRCLE");
2290 if (version==VER_2000) {
2291 dw.dxfString(100, "AcDbEntity");
2292 dw.dxfString(100, "AcDbCircle");
2294 dw.entityAttributes(attrib);
2295 dw.coord(10, data.cx, data.cy);
2296 dw.dxfReal(40, data.radius);
2302 * Writes an arc entity to the file.
2304 * @param dw DXF writer
2305 * @param data Entity data from the file
2306 * @param attrib Attributes
2308 void DL_Dxf::writeArc(DL_WriterA& dw,
2309 const DL_ArcData& data,
2310 const DL_Attributes& attrib) {
2312 if (version==VER_2000) {
2313 dw.dxfString(100, "AcDbEntity");
2315 dw.entityAttributes(attrib);
2316 if (version==VER_2000) {
2317 dw.dxfString(100, "AcDbCircle");
2319 dw.coord(10, data.cx, data.cy);
2320 dw.dxfReal(40, data.radius);
2321 if (version==VER_2000) {
2322 dw.dxfString(100, "AcDbArc");
2324 dw.dxfReal(50, data.angle1);
2325 dw.dxfReal(51, data.angle2);
2331 * Writes an ellipse entity to the file.
2333 * @param dw DXF writer
2334 * @param data Entity data from the file
2335 * @param attrib Attributes
2337 void DL_Dxf::writeEllipse(DL_WriterA& dw,
2338 const DL_EllipseData& data,
2339 const DL_Attributes& attrib) {
2341 if (version>VER_R12) {
2342 dw.entity("ELLIPSE");
2343 if (version==VER_2000) {
2344 dw.dxfString(100, "AcDbEntity");
2345 dw.dxfString(100, "AcDbEllipse");
2347 dw.entityAttributes(attrib);
2348 dw.coord(10, data.cx, data.cy);
2349 dw.coord(11, data.mx, data.my);
2350 dw.dxfReal(40, data.ratio);
2351 dw.dxfReal(41, data.angle1);
2352 dw.dxfReal(42, data.angle2);
2359 * Writes an insert to the file.
2361 * @param dw DXF writer
2362 * @param data Entity data from the file
2363 * @param attrib Attributes
2365 void DL_Dxf::writeInsert(DL_WriterA& dw,
2366 const DL_InsertData& data,
2367 const DL_Attributes& attrib) {
2369 if (data.name.empty()) {
2370 std::cerr << "DL_Dxf::writeInsert: "
2371 << "Block name must not be empty\n";
2375 dw.entity("INSERT");
2376 if (version==VER_2000) {
2377 dw.dxfString(100, "AcDbEntity");
2378 dw.dxfString(100, "AcDbBlockReference");
2380 dw.entityAttributes(attrib);
2381 dw.dxfString(2, data.name);
2382 dw.dxfReal(10, data.ipx);
2383 dw.dxfReal(20, data.ipy);
2384 dw.dxfReal(30, 0.0);
2385 if (data.sx!=1.0 || data.sy!=1.0) {
2386 dw.dxfReal(41, data.sx);
2387 dw.dxfReal(42, data.sy);
2388 dw.dxfReal(43, 1.0);
2390 if (data.angle!=0.0) {
2391 dw.dxfReal(50, data.angle);
2393 if (data.cols!=1 || data.rows!=1) {
2394 dw.dxfInt(70, data.cols);
2395 dw.dxfInt(71, data.rows);
2397 if (data.colSp!=0.0 || data.rowSp!=0.0) {
2398 dw.dxfReal(44, data.colSp);
2399 dw.dxfReal(45, data.rowSp);
2407 * Writes a multi text entity to the file.
2409 * @param dw DXF writer
2410 * @param data Entity data from the file
2411 * @param attrib Attributes
2413 void DL_Dxf::writeMText(DL_WriterA& dw,
2414 const DL_MTextData& data,
2415 const DL_Attributes& attrib) {
2418 if (version==VER_2000) {
2419 dw.dxfString(100, "AcDbEntity");
2420 dw.dxfString(100, "AcDbMText");
2422 dw.entityAttributes(attrib);
2423 dw.dxfReal(10, data.ipx);
2424 dw.dxfReal(20, data.ipy);
2425 dw.dxfReal(30, 0.0);
2426 dw.dxfReal(40, data.height);
2427 dw.dxfReal(41, data.width);
2429 dw.dxfInt(71, data.attachmentPoint);
2430 dw.dxfInt(72, data.drawingDirection);
2432 // Creare text chunks of 250 characters each:
2433 int length = data.text.length();
2436 for (i=250; i<length; i+=250) {
2437 strncpy(chunk, &data.text.c_str()[i-250], 250);
2439 dw.dxfString(3, chunk);
2441 strncpy(chunk, &data.text.c_str()[i-250], 250);
2443 dw.dxfString(1, chunk);
2445 dw.dxfString(7, data.style);
2447 // since dxflib 2.0.2.1: degrees not rad (error in autodesk dxf doc)
2448 dw.dxfReal(50, data.angle/(2.0*M_PI)*360.0);
2450 dw.dxfInt(73, data.lineSpacingStyle);
2451 dw.dxfReal(44, data.lineSpacingFactor);
2457 * Writes a text entity to the file.
2459 * @param dw DXF writer
2460 * @param data Entity data from the file
2461 * @param attrib Attributes
2463 void DL_Dxf::writeText(DL_WriterA& dw,
2464 const DL_TextData& data,
2465 const DL_Attributes& attrib) {
2468 if (version==VER_2000) {
2469 dw.dxfString(100, "AcDbEntity");
2470 dw.dxfString(100, "AcDbText");
2472 dw.entityAttributes(attrib);
2473 dw.dxfReal(10, data.ipx);
2474 dw.dxfReal(20, data.ipy);
2475 dw.dxfReal(30, 0.0);
2476 dw.dxfReal(40, data.height);
2477 dw.dxfString(1, data.text);
2478 dw.dxfReal(50, data.angle/(2*M_PI)*360.0);
2479 dw.dxfReal(41, data.xScaleFactor);
2480 dw.dxfString(7, data.style);
2482 dw.dxfInt(71, data.textGenerationFlags);
2483 dw.dxfInt(72, data.hJustification);
2485 dw.dxfReal(11, data.apx);
2486 dw.dxfReal(21, data.apy);
2487 dw.dxfReal(31, 0.0);
2489 dw.dxfInt(73, data.vJustification);
2494 * Writes an aligned dimension entity to the file.
2496 * @param dw DXF writer
2497 * @param data Generic dimension data for from the file
2498 * @param data Specific aligned dimension data from the file
2499 * @param attrib Attributes
2501 void DL_Dxf::writeDimAligned(DL_WriterA& dw,
2502 const DL_DimensionData& data,
2503 const DL_DimAlignedData& edata,
2504 const DL_Attributes& attrib) {
2506 dw.entity("DIMENSION");
2508 if (version==VER_2000) {
2509 dw.dxfString(100, "AcDbEntity");
2511 dw.entityAttributes(attrib);
2512 if (version==VER_2000) {
2513 dw.dxfString(100, "AcDbDimension");
2516 dw.dxfReal(10, data.dpx);
2517 dw.dxfReal(20, data.dpy);
2518 dw.dxfReal(30, 0.0);
2520 dw.dxfReal(11, data.mpx);
2521 dw.dxfReal(21, data.mpy);
2522 dw.dxfReal(31, 0.0);
2525 if (version>VER_R12) {
2526 dw.dxfInt(71, data.attachmentPoint);
2527 dw.dxfInt(72, data.lineSpacingStyle); // opt
2528 dw.dxfReal(41, data.lineSpacingFactor); // opt
2531 dw.dxfReal(42, data.angle);
2533 dw.dxfString(1, data.text); // opt
2534 //dw.dxfString(3, data.style);
2535 dw.dxfString(3, "Standard");
2537 if (version==VER_2000) {
2538 dw.dxfString(100, "AcDbAlignedDimension");
2541 dw.dxfReal(13, edata.epx1);
2542 dw.dxfReal(23, edata.epy1);
2543 dw.dxfReal(33, 0.0);
2545 dw.dxfReal(14, edata.epx2);
2546 dw.dxfReal(24, edata.epy2);
2547 dw.dxfReal(34, 0.0);
2553 * Writes a linear dimension entity to the file.
2555 * @param dw DXF writer
2556 * @param data Generic dimension data for from the file
2557 * @param data Specific linear dimension data from the file
2558 * @param attrib Attributes
2560 void DL_Dxf::writeDimLinear(DL_WriterA& dw,
2561 const DL_DimensionData& data,
2562 const DL_DimLinearData& edata,
2563 const DL_Attributes& attrib) {
2565 dw.entity("DIMENSION");
2567 if (version==VER_2000) {
2568 dw.dxfString(100, "AcDbEntity");
2570 dw.entityAttributes(attrib);
2571 if (version==VER_2000) {
2572 dw.dxfString(100, "AcDbDimension");
2575 dw.dxfReal(10, data.dpx);
2576 dw.dxfReal(20, data.dpy);
2577 dw.dxfReal(30, 0.0);
2579 dw.dxfReal(11, data.mpx);
2580 dw.dxfReal(21, data.mpy);
2581 dw.dxfReal(31, 0.0);
2584 if (version>VER_R12) {
2585 dw.dxfInt(71, data.attachmentPoint);
2586 dw.dxfInt(72, data.lineSpacingStyle); // opt
2587 dw.dxfReal(41, data.lineSpacingFactor); // opt
2590 dw.dxfReal(42, data.angle);
2592 dw.dxfString(1, data.text); // opt
2593 //dw.dxfString(3, data.style);
2594 dw.dxfString(3, "Standard");
2596 if (version==VER_2000) {
2597 dw.dxfString(100, "AcDbAlignedDimension");
2600 dw.dxfReal(13, edata.dpx1);
2601 dw.dxfReal(23, edata.dpy1);
2602 dw.dxfReal(33, 0.0);
2604 dw.dxfReal(14, edata.dpx2);
2605 dw.dxfReal(24, edata.dpy2);
2606 dw.dxfReal(34, 0.0);
2608 dw.dxfReal(50, edata.angle/(2.0*M_PI)*360.0);
2610 if (version==VER_2000) {
2611 dw.dxfString(100, "AcDbRotatedDimension");
2613 dw.dxfString(1001, "ACAD");
2614 dw.dxfString(1000, "DSTYLE");
2615 dw.dxfString(1002, "{");
2616 dw.dxfInt(1070, 340);
2617 dw.dxfInt(1005, 11);
2618 dw.dxfString(1002, "}");
2626 * Writes a radial dimension entity to the file.
2628 * @param dw DXF writer
2629 * @param data Generic dimension data for from the file
2630 * @param data Specific radial dimension data from the file
2631 * @param attrib Attributes
2633 void DL_Dxf::writeDimRadial(DL_WriterA& dw,
2634 const DL_DimensionData& data,
2635 const DL_DimRadialData& edata,
2636 const DL_Attributes& attrib) {
2638 dw.entity("DIMENSION");
2640 if (version==VER_2000) {
2641 dw.dxfString(100, "AcDbEntity");
2643 dw.entityAttributes(attrib);
2644 if (version==VER_2000) {
2645 dw.dxfString(100, "AcDbDimension");
2648 dw.dxfReal(10, data.dpx);
2649 dw.dxfReal(20, data.dpy);
2650 dw.dxfReal(30, 0.0);
2652 dw.dxfReal(11, data.mpx);
2653 dw.dxfReal(21, data.mpy);
2654 dw.dxfReal(31, 0.0);
2657 if (version>VER_R12) {
2658 dw.dxfInt(71, data.attachmentPoint);
2659 dw.dxfInt(72, data.lineSpacingStyle); // opt
2660 dw.dxfReal(41, data.lineSpacingFactor); // opt
2663 dw.dxfReal(42, data.angle);
2665 dw.dxfString(1, data.text); // opt
2666 //dw.dxfString(3, data.style);
2667 dw.dxfString(3, "Standard");
2669 if (version==VER_2000) {
2670 dw.dxfString(100, "AcDbRadialDimension");
2673 dw.dxfReal(15, edata.dpx);
2674 dw.dxfReal(25, edata.dpy);
2675 dw.dxfReal(35, 0.0);
2677 dw.dxfReal(40, edata.leader);
2683 * Writes a diametric dimension entity to the file.
2685 * @param dw DXF writer
2686 * @param data Generic dimension data for from the file
2687 * @param data Specific diametric dimension data from the file
2688 * @param attrib Attributes
2690 void DL_Dxf::writeDimDiametric(DL_WriterA& dw,
2691 const DL_DimensionData& data,
2692 const DL_DimDiametricData& edata,
2693 const DL_Attributes& attrib) {
2695 dw.entity("DIMENSION");
2697 if (version==VER_2000) {
2698 dw.dxfString(100, "AcDbEntity");
2700 dw.entityAttributes(attrib);
2701 if (version==VER_2000) {
2702 dw.dxfString(100, "AcDbDimension");
2705 dw.dxfReal(10, data.dpx);
2706 dw.dxfReal(20, data.dpy);
2707 dw.dxfReal(30, 0.0);
2709 dw.dxfReal(11, data.mpx);
2710 dw.dxfReal(21, data.mpy);
2711 dw.dxfReal(31, 0.0);
2714 if (version>VER_R12) {
2715 dw.dxfInt(71, data.attachmentPoint);
2716 dw.dxfInt(72, data.lineSpacingStyle); // opt
2717 dw.dxfReal(41, data.lineSpacingFactor); // opt
2720 dw.dxfReal(42, data.angle);
2722 dw.dxfString(1, data.text); // opt
2723 //dw.dxfString(3, data.style);
2724 dw.dxfString(3, "Standard");
2726 if (version==VER_2000) {
2727 dw.dxfString(100, "AcDbDiametricDimension");
2730 dw.dxfReal(15, edata.dpx);
2731 dw.dxfReal(25, edata.dpy);
2732 dw.dxfReal(35, 0.0);
2734 dw.dxfReal(40, edata.leader);
2740 * Writes an angular dimension entity to the file.
2742 * @param dw DXF writer
2743 * @param data Generic dimension data for from the file
2744 * @param data Specific angular dimension data from the file
2745 * @param attrib Attributes
2747 void DL_Dxf::writeDimAngular(DL_WriterA& dw,
2748 const DL_DimensionData& data,
2749 const DL_DimAngularData& edata,
2750 const DL_Attributes& attrib) {
2752 dw.entity("DIMENSION");
2754 if (version==VER_2000) {
2755 dw.dxfString(100, "AcDbEntity");
2757 dw.entityAttributes(attrib);
2758 if (version==VER_2000) {
2759 dw.dxfString(100, "AcDbDimension");
2762 dw.dxfReal(10, data.dpx);
2763 dw.dxfReal(20, data.dpy);
2764 dw.dxfReal(30, 0.0);
2766 dw.dxfReal(11, data.mpx);
2767 dw.dxfReal(21, data.mpy);
2768 dw.dxfReal(31, 0.0);
2771 if (version>VER_R12) {
2772 dw.dxfInt(71, data.attachmentPoint);
2773 dw.dxfInt(72, data.lineSpacingStyle); // opt
2774 dw.dxfReal(41, data.lineSpacingFactor); // opt
2777 dw.dxfReal(42, data.angle);
2779 dw.dxfString(1, data.text); // opt
2780 //dw.dxfString(3, data.style);
2781 dw.dxfString(3, "Standard");
2783 if (version==VER_2000) {
2784 dw.dxfString(100, "AcDb2LineAngularDimension");
2787 dw.dxfReal(13, edata.dpx1);
2788 dw.dxfReal(23, edata.dpy1);
2789 dw.dxfReal(33, 0.0);
2791 dw.dxfReal(14, edata.dpx2);
2792 dw.dxfReal(24, edata.dpy2);
2793 dw.dxfReal(34, 0.0);
2795 dw.dxfReal(15, edata.dpx3);
2796 dw.dxfReal(25, edata.dpy3);
2797 dw.dxfReal(35, 0.0);
2799 dw.dxfReal(16, edata.dpx4);
2800 dw.dxfReal(26, edata.dpy4);
2801 dw.dxfReal(36, 0.0);
2807 * Writes an angular dimension entity (3 points version) to the file.
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
2814 void DL_Dxf::writeDimAngular3P(DL_WriterA& dw,
2815 const DL_DimensionData& data,
2816 const DL_DimAngular3PData& edata,
2817 const DL_Attributes& attrib) {
2819 dw.entity("DIMENSION");
2821 if (version==VER_2000) {
2822 dw.dxfString(100, "AcDbEntity");
2824 dw.entityAttributes(attrib);
2825 if (version==VER_2000) {
2826 dw.dxfString(100, "AcDbDimension");
2829 dw.dxfReal(10, data.dpx);
2830 dw.dxfReal(20, data.dpy);
2831 dw.dxfReal(30, 0.0);
2833 dw.dxfReal(11, data.mpx);
2834 dw.dxfReal(21, data.mpy);
2835 dw.dxfReal(31, 0.0);
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
2844 dw.dxfReal(42, data.angle);
2846 dw.dxfString(1, data.text); // opt
2847 //dw.dxfString(3, data.style);
2848 dw.dxfString(3, "Standard");
2850 if (version==VER_2000) {
2851 dw.dxfString(100, "AcDb3PointAngularDimension");
2854 dw.dxfReal(13, edata.dpx1);
2855 dw.dxfReal(23, edata.dpy1);
2856 dw.dxfReal(33, 0.0);
2858 dw.dxfReal(14, edata.dpx2);
2859 dw.dxfReal(24, edata.dpy2);
2860 dw.dxfReal(34, 0.0);
2862 dw.dxfReal(15, edata.dpx3);
2863 dw.dxfReal(25, edata.dpy3);
2864 dw.dxfReal(35, 0.0);
2870 * Writes a leader entity to the file.
2872 * @param dw DXF writer
2873 * @param data Entity data from the file
2874 * @param attrib Attributes
2877 void DL_Dxf::writeLeader(DL_WriterA& dw,
2878 const DL_LeaderData& data,
2879 const DL_Attributes& attrib) {
2880 if (version>VER_R12) {
2881 dw.entity("LEADER");
2882 dw.entityAttributes(attrib);
2883 if (version==VER_2000) {
2884 dw.dxfString(100, "AcDbEntity");
2885 dw.dxfString(100, "AcDbLeader");
2887 dw.dxfString(3, "Standard");
2888 dw.dxfInt(71, data.arrowHeadFlag);
2889 dw.dxfInt(72, data.leaderPathType);
2890 dw.dxfInt(73, data.leaderCreationFlag);
2891 dw.dxfInt(74, data.hooklineDirectionFlag);
2892 dw.dxfInt(75, data.hooklineFlag);
2893 dw.dxfReal(40, data.textAnnotationHeight);
2894 dw.dxfReal(41, data.textAnnotationWidth);
2895 dw.dxfInt(76, data.number);
2902 * Writes a single vertex of a leader to the file.
2904 * @param dw DXF writer
2905 * @param data Entity data
2907 void DL_Dxf::writeLeaderVertex(DL_WriterA& dw,
2908 const DL_LeaderVertexData& data) {
2909 if (version>VER_R12) {
2910 dw.dxfReal(10, data.x);
2911 dw.dxfReal(20, data.y);
2918 * Writes the beginning of a hatch entity to the file.
2919 * This must be followed by one or more writeHatchLoop()
2920 * calls and a writeHatch2() call.
2922 * @param dw DXF writer
2923 * @param data Entity data.
2924 * @param attrib Attributes
2926 void DL_Dxf::writeHatch1(DL_WriterA& dw,
2927 const DL_HatchData& data,
2928 const DL_Attributes& attrib) {
2931 dw.entityAttributes(attrib);
2932 if (version==VER_2000) {
2933 dw.dxfString(100, "AcDbEntity");
2934 dw.dxfString(100, "AcDbHatch");
2936 dw.dxfReal(10, 0.0); // elevation
2937 dw.dxfReal(20, 0.0);
2938 dw.dxfReal(30, 0.0);
2939 dw.dxfReal(210, 0.0); // extrusion dir.
2940 dw.dxfReal(220, 0.0);
2941 dw.dxfReal(230, 1.0);
2942 if (data.solid==false) {
2943 dw.dxfString(2, data.pattern);
2945 dw.dxfString(2, "SOLID");
2947 dw.dxfInt(70, (int)data.solid);
2948 dw.dxfInt(71, 0); // associative
2949 dw.dxfInt(91, data.numLoops);
2955 * Writes the end of a hatch entity to the file.
2957 * @param dw DXF writer
2958 * @param data Entity data.
2959 * @param attrib Attributes
2961 void DL_Dxf::writeHatch2(DL_WriterA& dw,
2962 const DL_HatchData& data,
2963 const DL_Attributes& /*attrib*/) {
2965 dw.dxfInt(75, 0); // odd parity
2966 dw.dxfInt(76, 1); // pattern type
2967 if (data.solid==false) {
2968 dw.dxfReal(52, data.angle);
2969 dw.dxfReal(41, data.scale);
2970 dw.dxfInt(77, 0); // not double
2973 dw.dxfReal(53, 45.0);
2974 dw.dxfReal(43, 0.0);
2975 dw.dxfReal(44, 0.0);
2976 dw.dxfReal(45, -0.0883883476483184);
2977 dw.dxfReal(46, 0.0883883476483185);
2986 * Writes the beginning of a hatch loop to the file. This
2987 * must happen after writing the beginning of a hatch entity.
2989 * @param dw DXF writer
2990 * @param data Entity data.
2991 * @param attrib Attributes
2993 void DL_Dxf::writeHatchLoop1(DL_WriterA& dw,
2994 const DL_HatchLoopData& data) {
2997 dw.dxfInt(93, data.numEdges);
3004 * Writes the end of a hatch loop to the file.
3006 * @param dw DXF writer
3007 * @param data Entity data.
3008 * @param attrib Attributes
3010 void DL_Dxf::writeHatchLoop2(DL_WriterA& dw,
3011 const DL_HatchLoopData& /*data*/) {
3018 * Writes the beginning of a hatch entity to the file.
3020 * @param dw DXF writer
3021 * @param data Entity data.
3022 * @param attrib Attributes
3024 void DL_Dxf::writeHatchEdge(DL_WriterA& dw,
3025 const DL_HatchEdgeData& data) {
3027 dw.dxfInt(72, data.type);
3029 switch (data.type) {
3031 dw.dxfReal(10, data.x1);
3032 dw.dxfReal(20, data.y1);
3033 dw.dxfReal(11, data.x2);
3034 dw.dxfReal(21, data.y2);
3037 dw.dxfReal(10, data.cx);
3038 dw.dxfReal(20, data.cy);
3039 dw.dxfReal(40, data.radius);
3040 dw.dxfReal(50, data.angle1/(2*M_PI)*360.0);
3041 dw.dxfReal(51, data.angle2/(2*M_PI)*360.0);
3042 dw.dxfInt(73, (int)(data.ccw));
3052 * Writes an image entity.
3054 * @return IMAGEDEF handle. Needed for the IMAGEDEF counterpart.
3056 int DL_Dxf::writeImage(DL_WriterA& dw,
3057 const DL_ImageData& data,
3058 const DL_Attributes& attrib) {
3060 /*if (data.file.empty()) {
3061 std::cerr << "DL_Dxf::writeImage: "
3062 << "Image file must not be empty\n";
3068 dw.entityAttributes(attrib);
3069 if (version==VER_2000) {
3070 dw.dxfString(100, "AcDbEntity");
3071 dw.dxfString(100, "AcDbRasterImage");
3075 dw.dxfReal(10, data.ipx);
3076 dw.dxfReal(20, data.ipy);
3077 dw.dxfReal(30, 0.0);
3079 // vector along bottom side (1 pixel long)
3080 dw.dxfReal(11, data.ux);
3081 dw.dxfReal(21, data.uy);
3082 dw.dxfReal(31, 0.0);
3084 // vector along left side (1 pixel long)
3085 dw.dxfReal(12, data.vx);
3086 dw.dxfReal(22, data.vy);
3087 dw.dxfReal(32, 0.0);
3089 // image size in pixel
3090 dw.dxfReal(13, data.width);
3091 dw.dxfReal(23, data.height);
3093 // handle of IMAGEDEF object
3094 int handle = dw.incHandle();
3095 dw.dxfHex(340, handle);
3103 // brightness, contrast, fade
3104 dw.dxfInt(281, data.brightness);
3105 dw.dxfInt(282, data.contrast);
3106 dw.dxfInt(283, data.fade);
3114 * Writes an image definiition entity.
3116 void DL_Dxf::writeImageDef(DL_WriterA& dw,
3118 const DL_ImageData& data) {
3120 /*if (data.file.empty()) {
3121 std::cerr << "DL_Dxf::writeImage: "
3122 << "Image file must not be empty\n";
3126 dw.dxfString(0, "IMAGEDEF");
3127 if (version==VER_2000) {
3128 dw.dxfHex(5, handle);
3131 if (version==VER_2000) {
3132 dw.dxfString(100, "AcDbRasterImageDef");
3136 dw.dxfString(1, data.ref);
3138 // image size in pixel
3139 dw.dxfReal(10, data.width);
3140 dw.dxfReal(20, data.height);
3142 dw.dxfReal(11, 1.0);
3143 dw.dxfReal(21, 1.0);
3153 * Writes a layer to the file. Layers are stored in the
3154 * tables section of a DXF file.
3156 * @param dw DXF writer
3157 * @param data Entity data from the file
3158 * @param attrib Attributes
3160 void DL_Dxf::writeLayer(DL_WriterA& dw,
3161 const DL_LayerData& data,
3162 const DL_Attributes& attrib) {
3164 if (data.name.empty()) {
3165 std::cerr << "DL_Dxf::writeLayer: "
3166 << "Layer name must not be empty\n";
3170 int color = attrib.getColor();
3171 if (color<=0 || color>=256) {
3172 std::cerr << "Layer color cannot be " << color << ". Changed to 7.\n";
3176 if (data.name == "0") {
3177 dw.tableLayerEntry(0x10);
3179 dw.tableLayerEntry();
3182 dw.dxfString(2, data.name);
3183 dw.dxfInt(70, data.flags);
3184 dw.dxfInt(62, color);
3186 dw.dxfString(6, (attrib.getLineType().length()==0 ?
3187 string("CONTINUOUS") : attrib.getLineType()));
3189 if (version>=VER_2000) {
3190 // layer defpoints cannot be plotted
3191 std::string lstr = data.name;
3192 std::transform(lstr.begin(), lstr.end(), lstr.begin(), tolower);
3193 if (lstr=="defpoints") {
3197 if (version>=VER_2000 && attrib.getWidth()!=-1) {
3198 dw.dxfInt(370, attrib.getWidth());
3200 if (version>=VER_2000) {
3201 dw.dxfHex(390, 0xF);
3208 * Writes a line type to the file. Line types are stored in the
3209 * tables section of a DXF file.
3211 void DL_Dxf::writeLineType(DL_WriterA& dw,
3212 const DL_LineTypeData& data) {
3213 //const char* description,
3215 //double patternLength) {
3217 if (data.name.empty()) {
3218 std::cerr << "DL_Dxf::writeLineType: "
3219 << "Line type name must not be empty\n";
3223 // ignore BYLAYER, BYBLOCK for R12
3224 if (version<VER_2000) {
3225 if (!strcasecmp(data.name.c_str(), "BYBLOCK") ||
3226 !strcasecmp(data.name.c_str(), "BYLAYER")) {
3231 // write id (not for R12)
3232 if (!strcasecmp(data.name.c_str(), "BYBLOCK")) {
3233 dw.tableLineTypeEntry(0x14);
3234 } else if (!strcasecmp(data.name.c_str(), "BYLAYER")) {
3235 dw.tableLineTypeEntry(0x15);
3236 } else if (!strcasecmp(data.name.c_str(), "CONTINUOUS")) {
3237 dw.tableLineTypeEntry(0x16);
3239 dw.tableLineTypeEntry();
3242 dw.dxfString(2, data.name);
3243 //if (version>=VER_2000) {
3244 dw.dxfInt(70, data.flags);
3247 if (!strcasecmp(data.name.c_str(), "BYBLOCK")) {
3248 dw.dxfString(3, "");
3251 dw.dxfReal(40, 0.0);
3252 } else if (!strcasecmp(data.name.c_str(), "BYLAYER")) {
3253 dw.dxfString(3, "");
3256 dw.dxfReal(40, 0.0);
3257 } else if (!strcasecmp(data.name.c_str(), "CONTINUOUS")) {
3258 dw.dxfString(3, "Solid line");
3261 dw.dxfReal(40, 0.0);
3262 } else if (!strcasecmp(data.name.c_str(), "ACAD_ISO02W100")) {
3263 dw.dxfString(3, "ISO Dashed __ __ __ __ __ __ __ __ __ __ _");
3266 dw.dxfReal(40, 15.0);
3267 dw.dxfReal(49, 12.0);
3268 if (version>=VER_R13)
3270 dw.dxfReal(49, -3.0);
3271 if (version>=VER_R13)
3273 } else if (!strcasecmp(data.name.c_str(), "ACAD_ISO03W100")) {
3274 dw.dxfString(3, "ISO Dashed with Distance __ __ __ _");
3277 dw.dxfReal(40, 30.0);
3278 dw.dxfReal(49, 12.0);
3279 if (version>=VER_R13)
3281 dw.dxfReal(49, -18.0);
3282 if (version>=VER_R13)
3284 } else if (!strcasecmp(data.name.c_str(), "ACAD_ISO04W100")) {
3285 dw.dxfString(3, "ISO Long Dashed Dotted ____ . ____ . __");
3288 dw.dxfReal(40, 30.0);
3289 dw.dxfReal(49, 24.0);
3290 if (version>=VER_R13)
3292 dw.dxfReal(49, -3.0);
3293 if (version>=VER_R13)
3295 dw.dxfReal(49, 0.0);
3296 if (version>=VER_R13)
3298 dw.dxfReal(49, -3.0);
3299 if (version>=VER_R13)
3301 } else if (!strcasecmp(data.name.c_str(), "ACAD_ISO05W100")) {
3302 dw.dxfString(3, "ISO Long Dashed Double Dotted ____ .. __");
3305 dw.dxfReal(40, 33.0);
3306 dw.dxfReal(49, 24.0);
3307 if (version>=VER_R13)
3309 dw.dxfReal(49, -3.0);
3310 if (version>=VER_R13)
3312 dw.dxfReal(49, 0.0);
3313 if (version>=VER_R13)
3315 dw.dxfReal(49, -3.0);
3316 if (version>=VER_R13)
3318 dw.dxfReal(49, 0.0);
3319 if (version>=VER_R13)
3321 dw.dxfReal(49, -3.0);
3322 if (version>=VER_R13)
3324 } else if (!strcasecmp(data.name.c_str(), "BORDER")) {
3325 dw.dxfString(3, "Border __ __ . __ __ . __ __ . __ __ . __ __ .");
3328 dw.dxfReal(40, 44.45);
3329 dw.dxfReal(49, 12.7);
3330 if (version>=VER_R13)
3332 dw.dxfReal(49, -6.35);
3333 if (version>=VER_R13)
3335 dw.dxfReal(49, 12.7);
3336 if (version>=VER_R13)
3338 dw.dxfReal(49, -6.35);
3339 if (version>=VER_R13)
3341 dw.dxfReal(49, 0.0);
3342 if (version>=VER_R13)
3344 dw.dxfReal(49, -6.35);
3345 if (version>=VER_R13)
3347 } else if (!strcasecmp(data.name.c_str(), "BORDER2")) {
3348 dw.dxfString(3, "Border (.5x) __.__.__.__.__.__.__.__.__.__.__.");
3351 dw.dxfReal(40, 22.225);
3352 dw.dxfReal(49, 6.35);
3353 if (version>=VER_R13)
3355 dw.dxfReal(49, -3.175);
3356 if (version>=VER_R13)
3358 dw.dxfReal(49, 6.35);
3359 if (version>=VER_R13)
3361 dw.dxfReal(49, -3.175);
3362 if (version>=VER_R13)
3364 dw.dxfReal(49, 0.0);
3365 if (version>=VER_R13)
3367 dw.dxfReal(49, -3.175);
3368 if (version>=VER_R13)
3370 } else if (!strcasecmp(data.name.c_str(), "BORDERX2")) {
3371 dw.dxfString(3, "Border (2x) ____ ____ . ____ ____ . ___");
3374 dw.dxfReal(40, 88.9);
3375 dw.dxfReal(49, 25.4);
3376 if (version>=VER_R13)
3378 dw.dxfReal(49, -12.7);
3379 if (version>=VER_R13)
3381 dw.dxfReal(49, 25.4);
3382 if (version>=VER_R13)
3384 dw.dxfReal(49, -12.7);
3385 if (version>=VER_R13)
3387 dw.dxfReal(49, 0.0);
3388 if (version>=VER_R13)
3390 dw.dxfReal(49, -12.7);
3391 if (version>=VER_R13)
3393 } else if (!strcasecmp(data.name.c_str(), "CENTER")) {
3394 dw.dxfString(3, "Center ____ _ ____ _ ____ _ ____ _ ____ _ ____");
3397 dw.dxfReal(40, 50.8);
3398 dw.dxfReal(49, 31.75);
3399 if (version>=VER_R13)
3401 dw.dxfReal(49, -6.35);
3402 if (version>=VER_R13)
3404 dw.dxfReal(49, 6.35);
3405 if (version>=VER_R13)
3407 dw.dxfReal(49, -6.35);
3408 if (version>=VER_R13)
3410 } else if (!strcasecmp(data.name.c_str(), "CENTER2")) {
3411 dw.dxfString(3, "Center (.5x) ___ _ ___ _ ___ _ ___ _ ___ _ ___");
3414 dw.dxfReal(40, 28.575);
3415 dw.dxfReal(49, 19.05);
3416 if (version>=VER_R13)
3418 dw.dxfReal(49, -3.175);
3419 if (version>=VER_R13)
3421 dw.dxfReal(49, 3.175);
3422 if (version>=VER_R13)
3424 dw.dxfReal(49, -3.175);
3425 if (version>=VER_R13)
3427 } else if (!strcasecmp(data.name.c_str(), "CENTERX2")) {
3428 dw.dxfString(3, "Center (2x) ________ __ ________ __ _____");
3431 dw.dxfReal(40, 101.6);
3432 dw.dxfReal(49, 63.5);
3433 if (version>=VER_R13)
3435 dw.dxfReal(49, -12.7);
3436 if (version>=VER_R13)
3438 dw.dxfReal(49, 12.7);
3439 if (version>=VER_R13)
3441 dw.dxfReal(49, -12.7);
3442 if (version>=VER_R13)
3444 } else if (!strcasecmp(data.name.c_str(), "DASHDOT")) {
3445 dw.dxfString(3, "Dash dot __ . __ . __ . __ . __ . __ . __ . __");
3448 dw.dxfReal(40, 25.4);
3449 dw.dxfReal(49, 12.7);
3450 if (version>=VER_R13)
3452 dw.dxfReal(49, -6.35);
3453 if (version>=VER_R13)
3455 dw.dxfReal(49, 0.0);
3456 if (version>=VER_R13)
3458 dw.dxfReal(49, -6.35);
3459 if (version>=VER_R13)
3461 } else if (!strcasecmp(data.name.c_str(), "DASHDOT2")) {
3462 dw.dxfString(3, "Dash dot (.5x) _._._._._._._._._._._._._._._.");
3465 dw.dxfReal(40, 12.7);
3466 dw.dxfReal(49, 6.35);
3467 if (version>=VER_R13)
3469 dw.dxfReal(49, -3.175);
3470 if (version>=VER_R13)
3472 dw.dxfReal(49, 0.0);
3473 if (version>=VER_R13)
3475 dw.dxfReal(49, -3.175);
3476 if (version>=VER_R13)
3478 } else if (!strcasecmp(data.name.c_str(), "DASHDOTX2")) {
3479 dw.dxfString(3, "Dash dot (2x) ____ . ____ . ____ . ___");
3482 dw.dxfReal(40, 50.8);
3483 dw.dxfReal(49, 25.4);
3484 if (version>=VER_R13)
3486 dw.dxfReal(49, -12.7);
3487 if (version>=VER_R13)
3489 dw.dxfReal(49, 0.0);
3490 if (version>=VER_R13)
3492 dw.dxfReal(49, -12.7);
3493 if (version>=VER_R13)
3495 } else if (!strcasecmp(data.name.c_str(), "DASHED")) {
3496 dw.dxfString(3, "Dashed __ __ __ __ __ __ __ __ __ __ __ __ __ _");
3499 dw.dxfReal(40, 19.05);
3500 dw.dxfReal(49, 12.7);
3501 if (version>=VER_R13)
3503 dw.dxfReal(49, -6.35);
3504 if (version>=VER_R13)
3506 } else if (!strcasecmp(data.name.c_str(), "DASHED2")) {
3507 dw.dxfString(3, "Dashed (.5x) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _");
3510 dw.dxfReal(40, 9.525);
3511 dw.dxfReal(49, 6.35);
3512 if (version>=VER_R13)
3514 dw.dxfReal(49, -3.175);
3515 if (version>=VER_R13)
3517 } else if (!strcasecmp(data.name.c_str(), "DASHEDX2")) {
3518 dw.dxfString(3, "Dashed (2x) ____ ____ ____ ____ ____ ___");
3521 dw.dxfReal(40, 38.1);
3522 dw.dxfReal(49, 25.4);
3523 if (version>=VER_R13)
3525 dw.dxfReal(49, -12.7);
3526 if (version>=VER_R13)
3528 } else if (!strcasecmp(data.name.c_str(), "DIVIDE")) {
3529 dw.dxfString(3, "Divide ____ . . ____ . . ____ . . ____ . . ____");
3532 dw.dxfReal(40, 31.75);
3533 dw.dxfReal(49, 12.7);
3534 if (version>=VER_R13)
3536 dw.dxfReal(49, -6.35);
3537 if (version>=VER_R13)
3539 dw.dxfReal(49, 0.0);
3540 if (version>=VER_R13)
3542 dw.dxfReal(49, -6.35);
3543 if (version>=VER_R13)
3545 dw.dxfReal(49, 0.0);
3546 if (version>=VER_R13)
3548 dw.dxfReal(49, -6.35);
3549 if (version>=VER_R13)
3551 } else if (!strcasecmp(data.name.c_str(), "DIVIDE2")) {
3552 dw.dxfString(3, "Divide (.5x) __..__..__..__..__..__..__..__.._");
3555 dw.dxfReal(40, 15.875);
3556 dw.dxfReal(49, 6.35);
3557 if (version>=VER_R13)
3559 dw.dxfReal(49, -3.175);
3560 if (version>=VER_R13)
3562 dw.dxfReal(49, 0.0);
3563 if (version>=VER_R13)
3565 dw.dxfReal(49, -3.175);
3566 if (version>=VER_R13)
3568 dw.dxfReal(49, 0.0);
3569 if (version>=VER_R13)
3571 dw.dxfReal(49, -3.175);
3572 if (version>=VER_R13)
3574 } else if (!strcasecmp(data.name.c_str(), "DIVIDEX2")) {
3575 dw.dxfString(3, "Divide (2x) ________ . . ________ . . _");
3578 dw.dxfReal(40, 63.5);
3579 dw.dxfReal(49, 25.4);
3580 if (version>=VER_R13)
3582 dw.dxfReal(49, -12.7);
3583 if (version>=VER_R13)
3585 dw.dxfReal(49, 0.0);
3586 if (version>=VER_R13)
3588 dw.dxfReal(49, -12.7);
3589 if (version>=VER_R13)
3591 dw.dxfReal(49, 0.0);
3592 if (version>=VER_R13)
3594 dw.dxfReal(49, -12.7);
3595 if (version>=VER_R13)
3597 } else if (!strcasecmp(data.name.c_str(), "DOT")) {
3598 dw.dxfString(3, "Dot . . . . . . . . . . . . . . . . . . . . . .");
3601 dw.dxfReal(40, 6.35);
3602 dw.dxfReal(49, 0.0);
3603 if (version>=VER_R13)
3605 dw.dxfReal(49, -6.35);
3606 if (version>=VER_R13)
3608 } else if (!strcasecmp(data.name.c_str(), "DOT2")) {
3609 dw.dxfString(3, "Dot (.5x) .....................................");
3612 dw.dxfReal(40, 3.175);
3613 dw.dxfReal(49, 0.0);
3614 if (version>=VER_R13)
3616 dw.dxfReal(49, -3.175);
3617 if (version>=VER_R13)
3619 } else if (!strcasecmp(data.name.c_str(), "DOTX2")) {
3620 dw.dxfString(3, "Dot (2x) . . . . . . . . . . . . .");
3623 dw.dxfReal(40, 12.7);
3624 dw.dxfReal(49, 0.0);
3625 if (version>=VER_R13)
3627 dw.dxfReal(49, -12.7);
3628 if (version>=VER_R13)
3631 std::cerr << "dxflib warning: DL_Dxf::writeLineType: Unknown Line Type\n";
3638 * Writes the APPID section to the DXF file.
3640 * @param name Application name
3642 void DL_Dxf::writeAppid(DL_WriterA& dw, const string& name) {
3644 std::cerr << "DL_Dxf::writeAppid: "
3645 << "Application name must not be empty\n";
3649 if (!strcasecmp(name.c_str(), "ACAD")) {
3650 dw.tableAppidEntry(0x12);
3652 dw.tableAppidEntry();
3654 dw.dxfString(2, name);
3661 * Writes a block's definition (no entities) to the DXF file.
3663 void DL_Dxf::writeBlock(DL_WriterA& dw, const DL_BlockData& data) {
3664 if (data.name.empty()) {
3665 std::cerr << "DL_Dxf::writeBlock: "
3666 << "Block name must not be empty\n";
3670 //bool paperSpace = !strcasecmp(name, "*paper_space");
3671 //!strcasecmp(name, "*paper_space0");
3673 if (!strcasecmp(data.name.c_str(), "*paper_space")) {
3674 dw.sectionBlockEntry(0x1C);
3675 } else if (!strcasecmp(data.name.c_str(), "*model_space")) {
3676 dw.sectionBlockEntry(0x20);
3677 } else if (!strcasecmp(data.name.c_str(), "*paper_space0")) {
3678 dw.sectionBlockEntry(0x24);
3680 dw.sectionBlockEntry();
3682 dw.dxfString(2, data.name);
3684 dw.coord(10, data.bpx, data.bpy);
3685 dw.dxfString(3, data.name);
3686 dw.dxfString(1, "");
3692 * Writes a block end.
3694 * @param name Block name
3696 void DL_Dxf::writeEndBlock(DL_WriterA& dw, const string& name) {
3697 if (!strcasecmp(name.c_str(), "*paper_space")) {
3698 dw.sectionBlockEntryEnd(0x1D);
3699 } else if (!strcasecmp(name.c_str(), "*model_space")) {
3700 dw.sectionBlockEntryEnd(0x21);
3701 } else if (!strcasecmp(name.c_str(), "*paper_space0")) {
3702 dw.sectionBlockEntryEnd(0x25);
3704 dw.sectionBlockEntryEnd();
3711 * Writes a viewport section. This section is needed in VER_R13.
3712 * Note that this method currently only writes a faked VPORT section
3713 * to make the file readable by Aut*cad.
3715 void DL_Dxf::writeVPort(DL_WriterA& dw) {
3716 dw.dxfString(0, "TABLE");
3717 dw.dxfString(2, "VPORT");
3718 if (version==VER_2000) {
3721 //dw.dxfHex(330, 0);
3722 if (version==VER_2000) {
3723 dw.dxfString(100, "AcDbSymbolTable");
3726 dw.dxfString(0, "VPORT");
3727 //dw.dxfHex(5, 0x2F);
3728 if (version==VER_2000) {
3731 //dw.dxfHex(330, 8);
3732 if (version==VER_2000) {
3733 dw.dxfString(100, "AcDbSymbolTableRecord");
3734 dw.dxfString(100, "AcDbViewportTableRecord");
3736 dw.dxfString( 2, "*Active");
3738 dw.dxfReal( 10, 0.0);
3739 dw.dxfReal( 20, 0.0);
3740 dw.dxfReal( 11, 1.0);
3741 dw.dxfReal( 21, 1.0);
3742 dw.dxfReal( 12, 286.3055555555555);
3743 dw.dxfReal( 22, 148.5);
3744 dw.dxfReal( 13, 0.0);
3745 dw.dxfReal( 23, 0.0);
3746 dw.dxfReal( 14, 10.0);
3747 dw.dxfReal( 24, 10.0);
3748 dw.dxfReal( 15, 10.0);
3749 dw.dxfReal( 25, 10.0);
3750 dw.dxfReal( 16, 0.0);
3751 dw.dxfReal( 26, 0.0);
3752 dw.dxfReal( 36, 1.0);
3753 dw.dxfReal( 17, 0.0);
3754 dw.dxfReal( 27, 0.0);
3755 dw.dxfReal( 37, 0.0);
3756 dw.dxfReal( 40, 297.0);
3757 dw.dxfReal( 41, 1.92798353909465);
3758 dw.dxfReal( 42, 50.0);
3759 dw.dxfReal( 43, 0.0);
3760 dw.dxfReal( 44, 0.0);
3761 dw.dxfReal( 50, 0.0);
3762 dw.dxfReal( 51, 0.0);
3764 dw.dxfInt( 72, 100);
3772 if (version==VER_2000) {
3775 dw.dxfReal(110, 0.0);
3776 dw.dxfReal(120, 0.0);
3777 dw.dxfReal(130, 0.0);
3778 dw.dxfReal(111, 1.0);
3779 dw.dxfReal(121, 0.0);
3780 dw.dxfReal(131, 0.0);
3781 dw.dxfReal(112, 0.0);
3782 dw.dxfReal(122, 1.0);
3783 dw.dxfReal(132, 0.0);
3785 dw.dxfReal(146, 0.0);
3787 dw.dxfString( 0, "ENDTAB");
3793 * Writes a style section. This section is needed in VER_R13.
3794 * Note that this method currently only writes a faked STYLE section
3795 * to make the file readable by Aut*cad.
3797 void DL_Dxf::writeStyle(DL_WriterA& dw) {
3798 dw.dxfString( 0, "TABLE");
3799 dw.dxfString( 2, "STYLE");
3800 if (version==VER_2000) {
3803 //dw.dxfHex(330, 0);
3804 if (version==VER_2000) {
3805 dw.dxfString(100, "AcDbSymbolTable");
3808 dw.dxfString( 0, "STYLE");
3809 if (version==VER_2000) {
3812 //styleHandleStd = dw.handle();
3813 //dw.dxfHex(330, 3);
3814 if (version==VER_2000) {
3815 dw.dxfString(100, "AcDbSymbolTableRecord");
3816 dw.dxfString(100, "AcDbTextStyleTableRecord");
3818 dw.dxfString( 2, "Standard");
3820 dw.dxfReal( 40, 0.0);
3821 dw.dxfReal( 41, 0.75);
3822 dw.dxfReal( 50, 0.0);
3824 dw.dxfReal( 42, 2.5);
3825 dw.dxfString( 3, "txt");
3826 dw.dxfString( 4, "");
3827 dw.dxfString( 0, "ENDTAB");
3833 * Writes a view section. This section is needed in VER_R13.
3834 * Note that this method currently only writes a faked VIEW section
3835 * to make the file readable by Aut*cad.
3837 void DL_Dxf::writeView(DL_WriterA& dw) {
3838 dw.dxfString( 0, "TABLE");
3839 dw.dxfString( 2, "VIEW");
3840 if (version==VER_2000) {
3843 //dw.dxfHex(330, 0);
3844 if (version==VER_2000) {
3845 dw.dxfString(100, "AcDbSymbolTable");
3848 dw.dxfString( 0, "ENDTAB");
3854 * Writes a ucs section. This section is needed in VER_R13.
3855 * Note that this method currently only writes a faked UCS section
3856 * to make the file readable by Aut*cad.
3858 void DL_Dxf::writeUcs(DL_WriterA& dw) {
3859 dw.dxfString( 0, "TABLE");
3860 dw.dxfString( 2, "UCS");
3861 if (version==VER_2000) {
3864 //dw.dxfHex(330, 0);
3865 if (version==VER_2000) {
3866 dw.dxfString(100, "AcDbSymbolTable");
3869 dw.dxfString( 0, "ENDTAB");
3875 * Writes a dimstyle section. This section is needed in VER_R13.
3876 * Note that this method currently only writes a faked DIMSTYLE section
3877 * to make the file readable by Aut*cad.
3879 void DL_Dxf::writeDimStyle(DL_WriterA& dw,
3880 double dimasz, double dimexe, double dimexo,
3881 double dimgap, double dimtxt) {
3883 dw.dxfString( 0, "TABLE");
3884 dw.dxfString( 2, "DIMSTYLE");
3885 if (version==VER_2000) {
3887 dw.dxfString(100, "AcDbSymbolTable");
3890 if (version==VER_2000) {
3891 dw.dxfString(100, "AcDbDimStyleTable");
3896 dw.dxfString( 0, "DIMSTYLE");
3897 if (version==VER_2000) {
3898 dw.dxfHex(105, 0x27);
3901 //dw.dxfHex(330, 0xA);
3902 if (version==VER_2000) {
3903 dw.dxfString(100, "AcDbSymbolTableRecord");
3904 dw.dxfString(100, "AcDbDimStyleTableRecord");
3906 dw.dxfString( 2, "Standard");
3907 if (version==VER_R12) {
3908 dw.dxfString( 3, "");
3909 dw.dxfString( 4, "");
3910 dw.dxfString( 5, "");
3911 dw.dxfString( 6, "");
3912 dw.dxfString( 7, "");
3913 dw.dxfReal( 40, 1.0);
3916 dw.dxfReal( 41, dimasz);
3917 dw.dxfReal( 42, dimexo);
3918 dw.dxfReal( 43, 3.75);
3919 dw.dxfReal( 44, dimexe);
3920 if (version==VER_R12) {
3921 dw.dxfReal( 45, 0.0);
3922 dw.dxfReal( 46, 0.0);
3923 dw.dxfReal( 47, 0.0);
3924 dw.dxfReal( 48, 0.0);
3927 if (version==VER_R12) {
3933 if (version==VER_R12) {
3939 dw.dxfReal(140, dimtxt);
3940 dw.dxfReal(141, 2.5);
3941 if (version==VER_R12) {
3942 dw.dxfReal(142, 0.0);
3944 dw.dxfReal(143, 0.03937007874016);
3945 if (version==VER_R12) {
3946 dw.dxfReal(144, 1.0);
3947 dw.dxfReal(145, 0.0);
3948 dw.dxfReal(146, 1.0);
3950 dw.dxfReal(147, dimgap);
3951 if (version==VER_R12) {
3956 if (version==VER_R12) {
3964 if (version==VER_2000) {
3971 //dw.dxfHex(340, styleHandleStd);
3972 dw.dxfHex(340, 0x11);
3975 dw.dxfString( 0, "ENDTAB");
3981 * Writes a blockrecord section. This section is needed in VER_R13.
3982 * Note that this method currently only writes a faked BLOCKRECORD section
3983 * to make the file readable by Aut*cad.
3985 void DL_Dxf::writeBlockRecord(DL_WriterA& dw) {
3986 dw.dxfString( 0, "TABLE");
3987 dw.dxfString( 2, "BLOCK_RECORD");
3988 if (version==VER_2000) {
3991 //dw.dxfHex(330, 0);
3992 if (version==VER_2000) {
3993 dw.dxfString(100, "AcDbSymbolTable");
3997 dw.dxfString( 0, "BLOCK_RECORD");
3998 if (version==VER_2000) {
4001 //int msh = dw.handle();
4002 //dw.setModelSpaceHandle(msh);
4003 //dw.dxfHex(330, 1);
4004 if (version==VER_2000) {
4005 dw.dxfString(100, "AcDbSymbolTableRecord");
4006 dw.dxfString(100, "AcDbBlockTableRecord");
4008 dw.dxfString( 2, "*Model_Space");
4009 dw.dxfHex(340, 0x22);
4011 dw.dxfString( 0, "BLOCK_RECORD");
4012 if (version==VER_2000) {
4015 //int psh = dw.handle();
4016 //dw.setPaperSpaceHandle(psh);
4017 //dw.dxfHex(330, 1);
4018 if (version==VER_2000) {
4019 dw.dxfString(100, "AcDbSymbolTableRecord");
4020 dw.dxfString(100, "AcDbBlockTableRecord");
4022 dw.dxfString( 2, "*Paper_Space");
4023 dw.dxfHex(340, 0x1E);
4025 dw.dxfString( 0, "BLOCK_RECORD");
4026 if (version==VER_2000) {
4029 //int ps0h = dw.handle();
4030 //dw.setPaperSpace0Handle(ps0h);
4031 //dw.dxfHex(330, 1);
4032 if (version==VER_2000) {
4033 dw.dxfString(100, "AcDbSymbolTableRecord");
4034 dw.dxfString(100, "AcDbBlockTableRecord");
4036 dw.dxfString( 2, "*Paper_Space0");
4037 dw.dxfHex(340, 0x26);
4039 //dw.dxfString( 0, "ENDTAB");
4045 * Writes a single block record with the given name.
4047 void DL_Dxf::writeBlockRecord(DL_WriterA& dw, const string& name) {
4048 dw.dxfString( 0, "BLOCK_RECORD");
4049 if (version==VER_2000) {
4052 //dw->dxfHex(330, 1);
4053 if (version==VER_2000) {
4054 dw.dxfString(100, "AcDbSymbolTableRecord");
4055 dw.dxfString(100, "AcDbBlockTableRecord");
4057 dw.dxfString( 2, name);
4064 * Writes a objects section. This section is needed in VER_R13.
4065 * Note that this method currently only writes a faked OBJECTS section
4066 * to make the file readable by Aut*cad.
4068 void DL_Dxf::writeObjects(DL_WriterA& dw) {
4069 //int dicId, dicId2, dicId3, dicId4, dicId5;
4072 dw.dxfString( 0, "SECTION");
4073 dw.dxfString( 2, "OBJECTS");
4074 dw.dxfString( 0, "DICTIONARY");
4075 dw.dxfHex(5, 0xC); // C
4076 //dw.dxfHex(330, 0);
4077 dw.dxfString(100, "AcDbDictionary");
4080 dw.dxfString( 3, "ACAD_GROUP");
4081 //dw.dxfHex(350, dw.getNextHandle()); // D
4082 dw.dxfHex(350, 0xD); // D
4083 dw.dxfString( 3, "ACAD_LAYOUT");
4084 dw.dxfHex(350, 0x1A);
4085 //dw.dxfHex(350, dw.getNextHandle()+0); // 1A
4086 dw.dxfString( 3, "ACAD_MLINESTYLE");
4087 dw.dxfHex(350, 0x17);
4088 //dw.dxfHex(350, dw.getNextHandle()+1); // 17
4089 dw.dxfString( 3, "ACAD_PLOTSETTINGS");
4090 dw.dxfHex(350, 0x19);
4091 //dw.dxfHex(350, dw.getNextHandle()+2); // 19
4092 dw.dxfString( 3, "ACAD_PLOTSTYLENAME");
4093 dw.dxfHex(350, 0xE);
4094 //dw.dxfHex(350, dw.getNextHandle()+3); // E
4095 dw.dxfString( 3, "AcDbVariableDictionary");
4096 dw.dxfHex(350, dw.getNextHandle()); // 2C
4097 dw.dxfString( 0, "DICTIONARY");
4100 //dw.dxfHex(330, 0xC);
4101 dw.dxfString(100, "AcDbDictionary");
4104 dw.dxfString( 0, "ACDBDICTIONARYWDFLT");
4106 //dicId4 = dw.handle(); // E
4107 //dw.dxfHex(330, 0xC); // C
4108 dw.dxfString(100, "AcDbDictionary");
4110 dw.dxfString( 3, "Normal");
4111 dw.dxfHex(350, 0xF);
4112 //dw.dxfHex(350, dw.getNextHandle()+5); // F
4113 dw.dxfString(100, "AcDbDictionaryWithDefault");
4114 dw.dxfHex(340, 0xF);
4115 //dw.dxfHex(340, dw.getNextHandle()+5); // F
4116 dw.dxfString( 0, "ACDBPLACEHOLDER");
4119 //dw.dxfHex(330, dicId4); // E
4120 dw.dxfString( 0, "DICTIONARY");
4121 //dicId3 = dw.handle(); // 17
4123 //dw.dxfHex(330, 0xC); // C
4124 dw.dxfString(100, "AcDbDictionary");
4127 dw.dxfString( 3, "Standard");
4128 dw.dxfHex(350, 0x18);
4129 //dw.dxfHex(350, dw.getNextHandle()+5); // 18
4130 dw.dxfString( 0, "MLINESTYLE");
4132 //dw.handle(); // 18
4133 //dw.dxfHex(330, dicId3); // 17
4134 dw.dxfString(100, "AcDbMlineStyle");
4135 dw.dxfString( 2, "STANDARD");
4137 dw.dxfString( 3, "");
4138 dw.dxfInt( 62, 256);
4139 dw.dxfReal( 51, 90.0);
4140 dw.dxfReal( 52, 90.0);
4142 dw.dxfReal( 49, 0.5);
4143 dw.dxfInt( 62, 256);
4144 dw.dxfString( 6, "BYLAYER");
4145 dw.dxfReal( 49, -0.5);
4146 dw.dxfInt( 62, 256);
4147 dw.dxfString( 6, "BYLAYER");
4148 dw.dxfString( 0, "DICTIONARY");
4150 //dw.handle(); // 17
4151 //dw.dxfHex(330, 0xC); // C
4152 dw.dxfString(100, "AcDbDictionary");
4155 dw.dxfString( 0, "DICTIONARY");
4156 //dicId2 = dw.handle(); // 1A
4158 //dw.dxfHex(330, 0xC);
4159 dw.dxfString(100, "AcDbDictionary");
4161 dw.dxfString( 3, "Layout1");
4162 dw.dxfHex(350, 0x1E);
4163 //dw.dxfHex(350, dw.getNextHandle()+2); // 1E
4164 dw.dxfString( 3, "Layout2");
4165 dw.dxfHex(350, 0x26);
4166 //dw.dxfHex(350, dw.getNextHandle()+4); // 26
4167 dw.dxfString( 3, "Model");
4168 dw.dxfHex(350, 0x22);
4169 //dw.dxfHex(350, dw.getNextHandle()+5); // 22
4171 dw.dxfString( 0, "LAYOUT");
4173 //dw.handle(); // 1E
4174 //dw.dxfHex(330, dicId2); // 1A
4175 dw.dxfString(100, "AcDbPlotSettings");
4176 dw.dxfString( 1, "");
4177 dw.dxfString( 2, "C:\\Program Files\\AutoCAD 2002\\plotters\\DWF ePlot (optimized for plotting).pc3");
4178 dw.dxfString( 4, "");
4179 dw.dxfString( 6, "");
4180 dw.dxfReal( 40, 0.0);
4181 dw.dxfReal( 41, 0.0);
4182 dw.dxfReal( 42, 0.0);
4183 dw.dxfReal( 43, 0.0);
4184 dw.dxfReal( 44, 0.0);
4185 dw.dxfReal( 45, 0.0);
4186 dw.dxfReal( 46, 0.0);
4187 dw.dxfReal( 47, 0.0);
4188 dw.dxfReal( 48, 0.0);
4189 dw.dxfReal( 49, 0.0);
4190 dw.dxfReal(140, 0.0);
4191 dw.dxfReal(141, 0.0);
4192 dw.dxfReal(142, 1.0);
4193 dw.dxfReal(143, 1.0);
4194 dw.dxfInt( 70, 688);
4198 dw.dxfString( 7, "");
4200 dw.dxfReal(147, 1.0);
4201 dw.dxfReal(148, 0.0);
4202 dw.dxfReal(149, 0.0);
4203 dw.dxfString(100, "AcDbLayout");
4204 dw.dxfString( 1, "Layout1");
4207 dw.dxfReal( 10, 0.0);
4208 dw.dxfReal( 20, 0.0);
4209 dw.dxfReal( 11, 420.0);
4210 dw.dxfReal( 21, 297.0);
4211 dw.dxfReal( 12, 0.0);
4212 dw.dxfReal( 22, 0.0);
4213 dw.dxfReal( 32, 0.0);
4214 dw.dxfReal( 14, 1.000000000000000E+20);
4215 dw.dxfReal( 24, 1.000000000000000E+20);
4216 dw.dxfReal( 34, 1.000000000000000E+20);
4217 dw.dxfReal( 15, -1.000000000000000E+20);
4218 dw.dxfReal( 25, -1.000000000000000E+20);
4219 dw.dxfReal( 35, -1.000000000000000E+20);
4220 dw.dxfReal(146, 0.0);
4221 dw.dxfReal( 13, 0.0);
4222 dw.dxfReal( 23, 0.0);
4223 dw.dxfReal( 33, 0.0);
4224 dw.dxfReal( 16, 1.0);
4225 dw.dxfReal( 26, 0.0);
4226 dw.dxfReal( 36, 0.0);
4227 dw.dxfReal( 17, 0.0);
4228 dw.dxfReal( 27, 1.0);
4229 dw.dxfReal( 37, 0.0);
4231 //dw.dxfHex(330, dw.getPaperSpaceHandle()); // 1B
4232 dw.dxfHex(330, 0x1B);
4233 dw.dxfString( 0, "LAYOUT");
4235 //dw.handle(); // 22
4236 //dw.dxfHex(330, dicId2); // 1A
4237 dw.dxfString(100, "AcDbPlotSettings");
4238 dw.dxfString( 1, "");
4239 dw.dxfString( 2, "C:\\Program Files\\AutoCAD 2002\\plotters\\DWF ePlot (optimized for plotting).pc3");
4240 dw.dxfString( 4, "");
4241 dw.dxfString( 6, "");
4242 dw.dxfReal( 40, 0.0);
4243 dw.dxfReal( 41, 0.0);
4244 dw.dxfReal( 42, 0.0);
4245 dw.dxfReal( 43, 0.0);
4246 dw.dxfReal( 44, 0.0);
4247 dw.dxfReal( 45, 0.0);
4248 dw.dxfReal( 46, 0.0);
4249 dw.dxfReal( 47, 0.0);
4250 dw.dxfReal( 48, 0.0);
4251 dw.dxfReal( 49, 0.0);
4252 dw.dxfReal(140, 0.0);
4253 dw.dxfReal(141, 0.0);
4254 dw.dxfReal(142, 1.0);
4255 dw.dxfReal(143, 1.0);
4256 dw.dxfInt( 70, 1712);
4260 dw.dxfString( 7, "");
4262 dw.dxfReal(147, 1.0);
4263 dw.dxfReal(148, 0.0);
4264 dw.dxfReal(149, 0.0);
4265 dw.dxfString(100, "AcDbLayout");
4266 dw.dxfString( 1, "Model");
4269 dw.dxfReal( 10, 0.0);
4270 dw.dxfReal( 20, 0.0);
4271 dw.dxfReal( 11, 12.0);
4272 dw.dxfReal( 21, 9.0);
4273 dw.dxfReal( 12, 0.0);
4274 dw.dxfReal( 22, 0.0);
4275 dw.dxfReal( 32, 0.0);
4276 dw.dxfReal( 14, 0.0);
4277 dw.dxfReal( 24, 0.0);
4278 dw.dxfReal( 34, 0.0);
4279 dw.dxfReal( 15, 0.0);
4280 dw.dxfReal( 25, 0.0);
4281 dw.dxfReal( 35, 0.0);
4282 dw.dxfReal(146, 0.0);
4283 dw.dxfReal( 13, 0.0);
4284 dw.dxfReal( 23, 0.0);
4285 dw.dxfReal( 33, 0.0);
4286 dw.dxfReal( 16, 1.0);
4287 dw.dxfReal( 26, 0.0);
4288 dw.dxfReal( 36, 0.0);
4289 dw.dxfReal( 17, 0.0);
4290 dw.dxfReal( 27, 1.0);
4291 dw.dxfReal( 37, 0.0);
4293 //dw.dxfHex(330, dw.getModelSpaceHandle()); // 1F
4294 dw.dxfHex(330, 0x1F);
4295 dw.dxfString( 0, "LAYOUT");
4296 //dw.handle(); // 26
4298 //dw.dxfHex(330, dicId2); // 1A
4299 dw.dxfString(100, "AcDbPlotSettings");
4300 dw.dxfString( 1, "");
4301 dw.dxfString( 2, "C:\\Program Files\\AutoCAD 2002\\plotters\\DWF ePlot (optimized for plotting).pc3");
4302 dw.dxfString( 4, "");
4303 dw.dxfString( 6, "");
4304 dw.dxfReal( 40, 0.0);
4305 dw.dxfReal( 41, 0.0);
4306 dw.dxfReal( 42, 0.0);
4307 dw.dxfReal( 43, 0.0);
4308 dw.dxfReal( 44, 0.0);
4309 dw.dxfReal( 45, 0.0);
4310 dw.dxfReal( 46, 0.0);
4311 dw.dxfReal( 47, 0.0);
4312 dw.dxfReal( 48, 0.0);
4313 dw.dxfReal( 49, 0.0);
4314 dw.dxfReal(140, 0.0);
4315 dw.dxfReal(141, 0.0);
4316 dw.dxfReal(142, 1.0);
4317 dw.dxfReal(143, 1.0);
4318 dw.dxfInt( 70, 688);
4322 dw.dxfString( 7, "");
4324 dw.dxfReal(147, 1.0);
4325 dw.dxfReal(148, 0.0);
4326 dw.dxfReal(149, 0.0);
4327 dw.dxfString(100, "AcDbLayout");
4328 dw.dxfString( 1, "Layout2");
4331 dw.dxfReal( 10, 0.0);
4332 dw.dxfReal( 20, 0.0);
4333 dw.dxfReal( 11, 12.0);
4334 dw.dxfReal( 21, 9.0);
4335 dw.dxfReal( 12, 0.0);
4336 dw.dxfReal( 22, 0.0);
4337 dw.dxfReal( 32, 0.0);
4338 dw.dxfReal( 14, 0.0);
4339 dw.dxfReal( 24, 0.0);
4340 dw.dxfReal( 34, 0.0);
4341 dw.dxfReal( 15, 0.0);
4342 dw.dxfReal( 25, 0.0);
4343 dw.dxfReal( 35, 0.0);
4344 dw.dxfReal(146, 0.0);
4345 dw.dxfReal( 13, 0.0);
4346 dw.dxfReal( 23, 0.0);
4347 dw.dxfReal( 33, 0.0);
4348 dw.dxfReal( 16, 1.0);
4349 dw.dxfReal( 26, 0.0);
4350 dw.dxfReal( 36, 0.0);
4351 dw.dxfReal( 17, 0.0);
4352 dw.dxfReal( 27, 1.0);
4353 dw.dxfReal( 37, 0.0);
4355 //dw.dxfHex(330, dw.getPaperSpace0Handle()); // 23
4356 dw.dxfHex(330, 0x23);
4357 dw.dxfString( 0, "DICTIONARY");
4358 //dw.dxfHex(5, 0x2C);
4361 //dw.dxfHex(330, 0xC); // C
4362 dw.dxfString(100, "AcDbDictionary");
4364 dw.dxfString( 3, "DIMASSOC");
4365 //dw.dxfHex(350, 0x2F);
4366 dw.dxfHex(350, dw.getNextHandle()+1); // 2E
4367 dw.dxfString( 3, "HIDETEXT");
4368 //dw.dxfHex(350, 0x2E);
4369 dw.dxfHex(350, dw.getNextHandle()); // 2D
4370 dw.dxfString( 0, "DICTIONARYVAR");
4371 //dw.dxfHex(5, 0x2E);
4373 //dw.dxfHex(330, dicId5); // 2C
4374 dw.dxfString(100, "DictionaryVariables");
4377 dw.dxfString( 0, "DICTIONARYVAR");
4378 //dw.dxfHex(5, 0x2D);
4380 //dw.dxfHex(330, dicId5); // 2C
4381 dw.dxfString(100, "DictionaryVariables");
4388 * Writes the end of the objects section. This section is needed in VER_R13.
4389 * Note that this method currently only writes a faked OBJECTS section
4390 * to make the file readable by Aut*cad.
4392 void DL_Dxf::writeObjectsEnd(DL_WriterA& dw) {
4393 dw.dxfString( 0, "ENDSEC");
4399 * Checks if the given variable is known by the given DXF version.
4401 bool DL_Dxf::checkVariable(const char* var, DL_Codes::version version) {
4402 if (version>=VER_2000) {
4404 } else if (version==VER_R12) {
4405 // these are all the variables recognized by dxf r12:
4406 if (!strcmp(var, "$ACADVER")) {
4409 if (!strcmp(var, "$ACADVER")) {
4412 if (!strcmp(var, "$ANGBASE")) {
4415 if (!strcmp(var, "$ANGDIR")) {
4418 if (!strcmp(var, "$ATTDIA")) {
4421 if (!strcmp(var, "$ATTMODE")) {
4424 if (!strcmp(var, "$ATTREQ")) {
4427 if (!strcmp(var, "$AUNITS")) {
4430 if (!strcmp(var, "$AUPREC")) {
4433 if (!strcmp(var, "$AXISMODE")) {
4436 if (!strcmp(var, "$AXISUNIT")) {
4439 if (!strcmp(var, "$BLIPMODE")) {
4442 if (!strcmp(var, "$CECOLOR")) {
4445 if (!strcmp(var, "$CELTYPE")) {
4448 if (!strcmp(var, "$CHAMFERA")) {
4451 if (!strcmp(var, "$CHAMFERB")) {
4454 if (!strcmp(var, "$CLAYER")) {
4457 if (!strcmp(var, "$COORDS")) {
4460 if (!strcmp(var, "$DIMALT")) {
4463 if (!strcmp(var, "$DIMALTD")) {
4466 if (!strcmp(var, "$DIMALTF")) {
4469 if (!strcmp(var, "$DIMAPOST")) {
4472 if (!strcmp(var, "$DIMASO")) {
4475 if (!strcmp(var, "$DIMASZ")) {
4478 if (!strcmp(var, "$DIMBLK")) {
4481 if (!strcmp(var, "$DIMBLK1")) {
4484 if (!strcmp(var, "$DIMBLK2")) {
4487 if (!strcmp(var, "$DIMCEN")) {
4490 if (!strcmp(var, "$DIMCLRD")) {
4493 if (!strcmp(var, "$DIMCLRE")) {
4496 if (!strcmp(var, "$DIMCLRT")) {
4499 if (!strcmp(var, "$DIMDLE")) {
4502 if (!strcmp(var, "$DIMDLI")) {
4505 if (!strcmp(var, "$DIMEXE")) {
4508 if (!strcmp(var, "$DIMEXO")) {
4511 if (!strcmp(var, "$DIMGAP")) {
4514 if (!strcmp(var, "$DIMLFAC")) {
4517 if (!strcmp(var, "$DIMLIM")) {
4520 if (!strcmp(var, "$DIMPOST")) {
4523 if (!strcmp(var, "$DIMRND")) {
4526 if (!strcmp(var, "$DIMSAH")) {
4529 if (!strcmp(var, "$DIMSCALE")) {
4532 if (!strcmp(var, "$DIMSE1")) {
4535 if (!strcmp(var, "$DIMSE2")) {
4538 if (!strcmp(var, "$DIMSHO")) {
4541 if (!strcmp(var, "$DIMSOXD")) {
4544 if (!strcmp(var, "$DIMSTYLE")) {
4547 if (!strcmp(var, "$DIMTAD")) {
4550 if (!strcmp(var, "$DIMTFAC")) {
4553 if (!strcmp(var, "$DIMTIH")) {
4556 if (!strcmp(var, "$DIMTIX")) {
4559 if (!strcmp(var, "$DIMTM")) {
4562 if (!strcmp(var, "$DIMTOFL")) {
4565 if (!strcmp(var, "$DIMTOH")) {
4568 if (!strcmp(var, "$DIMTOL")) {
4571 if (!strcmp(var, "$DIMTP")) {
4574 if (!strcmp(var, "$DIMTSZ")) {
4577 if (!strcmp(var, "$DIMTVP")) {
4580 if (!strcmp(var, "$DIMTXT")) {
4583 if (!strcmp(var, "$DIMZIN")) {
4586 if (!strcmp(var, "$DWGCODEPAGE")) {
4589 if (!strcmp(var, "$DRAGMODE")) {
4592 if (!strcmp(var, "$ELEVATION")) {
4595 if (!strcmp(var, "$EXTMAX")) {
4598 if (!strcmp(var, "$EXTMIN")) {
4601 if (!strcmp(var, "$FILLETRAD")) {
4604 if (!strcmp(var, "$FILLMODE")) {
4607 if (!strcmp(var, "$HANDLING")) {
4610 if (!strcmp(var, "$HANDSEED")) {
4613 if (!strcmp(var, "$INSBASE")) {
4616 if (!strcmp(var, "$LIMCHECK")) {
4619 if (!strcmp(var, "$LIMMAX")) {
4622 if (!strcmp(var, "$LIMMIN")) {
4625 if (!strcmp(var, "$LTSCALE")) {
4628 if (!strcmp(var, "$LUNITS")) {
4631 if (!strcmp(var, "$LUPREC")) {
4634 if (!strcmp(var, "$MAXACTVP")) {
4637 if (!strcmp(var, "$MENU")) {
4640 if (!strcmp(var, "$MIRRTEXT")) {
4643 if (!strcmp(var, "$ORTHOMODE")) {
4646 if (!strcmp(var, "$OSMODE")) {
4649 if (!strcmp(var, "$PDMODE")) {
4652 if (!strcmp(var, "$PDSIZE")) {
4655 if (!strcmp(var, "$PELEVATION")) {
4658 if (!strcmp(var, "$PEXTMAX")) {
4661 if (!strcmp(var, "$PEXTMIN")) {
4664 if (!strcmp(var, "$PLIMCHECK")) {
4667 if (!strcmp(var, "$PLIMMAX")) {
4670 if (!strcmp(var, "$PLIMMIN")) {
4673 if (!strcmp(var, "$PLINEGEN")) {
4676 if (!strcmp(var, "$PLINEWID")) {
4679 if (!strcmp(var, "$PSLTSCALE")) {
4682 if (!strcmp(var, "$PUCSNAME")) {
4685 if (!strcmp(var, "$PUCSORG")) {
4688 if (!strcmp(var, "$PUCSXDIR")) {
4691 if (!strcmp(var, "$PUCSYDIR")) {
4694 if (!strcmp(var, "$QTEXTMODE")) {
4697 if (!strcmp(var, "$REGENMODE")) {
4700 if (!strcmp(var, "$SHADEDGE")) {
4703 if (!strcmp(var, "$SHADEDIF")) {
4706 if (!strcmp(var, "$SKETCHINC")) {
4709 if (!strcmp(var, "$SKPOLY")) {
4712 if (!strcmp(var, "$SPLFRAME")) {
4715 if (!strcmp(var, "$SPLINESEGS")) {
4718 if (!strcmp(var, "$SPLINETYPE")) {
4721 if (!strcmp(var, "$SURFTAB1")) {
4724 if (!strcmp(var, "$SURFTAB2")) {
4727 if (!strcmp(var, "$SURFTYPE")) {
4730 if (!strcmp(var, "$SURFU")) {
4733 if (!strcmp(var, "$SURFV")) {
4736 if (!strcmp(var, "$TDCREATE")) {
4739 if (!strcmp(var, "$TDINDWG")) {
4742 if (!strcmp(var, "$TDUPDATE")) {
4745 if (!strcmp(var, "$TDUSRTIMER")) {
4748 if (!strcmp(var, "$TEXTSIZE")) {
4751 if (!strcmp(var, "$TEXTSTYLE")) {
4754 if (!strcmp(var, "$THICKNESS")) {
4757 if (!strcmp(var, "$TILEMODE")) {
4760 if (!strcmp(var, "$TRACEWID")) {
4763 if (!strcmp(var, "$UCSNAME")) {
4766 if (!strcmp(var, "$UCSORG")) {
4769 if (!strcmp(var, "$UCSXDIR")) {
4772 if (!strcmp(var, "$UCSYDIR")) {
4775 if (!strcmp(var, "$UNITMODE")) {
4778 if (!strcmp(var, "$USERI1")) {
4781 if (!strcmp(var, "$USERR1")) {
4784 if (!strcmp(var, "$USRTIMER")) {
4787 if (!strcmp(var, "$VISRETAIN")) {
4790 if (!strcmp(var, "$WORLDVIEW")) {
4793 if (!strcmp(var, "$FASTZOOM")) {
4796 if (!strcmp(var, "$GRIDMODE")) {
4799 if (!strcmp(var, "$GRIDUNIT")) {
4802 if (!strcmp(var, "$SNAPANG")) {
4805 if (!strcmp(var, "$SNAPBASE")) {
4808 if (!strcmp(var, "$SNAPISOPAIR")) {
4811 if (!strcmp(var, "$SNAPMODE")) {
4814 if (!strcmp(var, "$SNAPSTYLE")) {
4817 if (!strcmp(var, "$SNAPUNIT")) {
4820 if (!strcmp(var, "$VIEWCTR")) {
4823 if (!strcmp(var, "$VIEWDIR")) {
4826 if (!strcmp(var, "$VIEWSIZE")) {
4838 * @returns the library version as int (4 bytes, each byte one version number).
4839 * e.g. if str = "2.0.2.0" getLibVersion returns 0x02000200
4841 int DL_Dxf::getLibVersion(const char* str) {
4847 for (unsigned int i=0; i<strlen(str) && idx<3; ++i) {
4857 strncpy(v[0], str, d[0]);
4859 //std::cout << "v[0]: " << atoi(v[0]) << "\n";
4861 strncpy(v[1], &str[d[0]+1], d[1]-d[0]-1);
4862 v[1][d[1]-d[0]-1] = '\0';
4863 //std::cout << "v[1]: " << atoi(v[1]) << "\n";
4865 strncpy(v[2], &str[d[1]+1], d[2]-d[1]-1);
4866 v[2][d[2]-d[1]-1] = '\0';
4867 //std::cout << "v[2]: " << atoi(v[2]) << "\n";
4869 strncpy(v[3], &str[d[2]+1], d[3]-d[2]-1);
4870 v[3][d[3]-d[2]-1] = '\0';
4871 //std::cout << "v[3]: " << atoi(v[3]) << "\n";
4873 ret = (atoi(v[0])<<(3*8)) +
4874 (atoi(v[1])<<(2*8)) +
4875 (atoi(v[2])<<(1*8)) +
4876 (atoi(v[3])<<(0*8));
4880 std::cerr << "DL_Dxf::getLibVersion: invalid version number: " << str << "\n";
4888 * Some test routines.
4890 void DL_Dxf::test() {
4898 buf1 = new char[10];
4899 buf2 = new char[10];
4900 buf3 = new char[10];
4901 buf4 = new char[10];
4902 buf5 = new char[10];
4903 buf6 = new char[10];
4905 strcpy(buf1, " 10\n");
4907 strcpy(buf3, "10\n");
4908 strcpy(buf4, " 10 \n");
4909 strcpy(buf5, " 10 \r");
4910 strcpy(buf6, "\t10 \n");
4912 std::cout << "1 buf1: '" << buf1 << "'\n";
4913 stripWhiteSpace(&buf1);
4914 std::cout << "2 buf1: '" << buf1 << "'\n";
4915 //assert(!strcmp(buf1, "10"));
4917 std::cout << "1 buf2: '" << buf2 << "'\n";
4918 stripWhiteSpace(&buf2);
4919 std::cout << "2 buf2: '" << buf2 << "'\n";
4921 std::cout << "1 buf3: '" << buf3 << "'\n";
4922 stripWhiteSpace(&buf3);
4923 std::cout << "2 buf3: '" << buf3 << "'\n";
4925 std::cout << "1 buf4: '" << buf4 << "'\n";
4926 stripWhiteSpace(&buf4);
4927 std::cout << "2 buf4: '" << buf4 << "'\n";
4929 std::cout << "1 buf5: '" << buf5 << "'\n";
4930 stripWhiteSpace(&buf5);
4931 std::cout << "2 buf5: '" << buf5 << "'\n";
4933 std::cout << "1 buf6: '" << buf6 << "'\n";
4934 stripWhiteSpace(&buf6);
4935 std::cout << "2 buf6: '" << buf6 << "'\n";