1
/****************************************************************************
2
** $Id: dl_dxf.cpp 8865 2008-02-04 18:54:02Z 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;
85
if (controlPoints!=NULL) {
86
delete[] controlPoints;
88
if (leaderVertices!=NULL) {
89
delete[] leaderVertices;
91
if (hatchLoops!=NULL) {
94
if (hatchEdges!=NULL) {
95
for (int i=0; i<maxHatchLoops; ++i) {
96
if (hatchEdges[i]!=NULL) {
97
delete[] hatchEdges[i];
102
if (maxHatchEdges!=NULL) {
103
delete[] maxHatchEdges;
105
if (hatchEdgeIndex!=NULL) {
106
delete[] hatchEdgeIndex;
113
* @brief Reads the given file and calls the appropriate functions in
114
* the given creation interface for every entity found in the file.
117
* Path and name of file to read
118
* @param creationInterface
119
* Pointer to the class which takes care of the entities in the file.
121
* @retval true If \p file could be opened.
122
* @retval false If \p file could not be opened.
124
bool DL_Dxf::in(const string& file, DL_CreationInterface* creationInterface) {
127
currentEntity = DL_UNKNOWN;
128
int errorCounter = 0;
130
fp = fopen(file.c_str(), "rt");
132
while (readDxfGroups(fp, creationInterface, &errorCounter)) {}
134
if (errorCounter>0) {
135
std::cerr << "DXF Filter: There have been " << errorCounter <<
136
" errors. The drawing might be incomplete / incorrect.\n";
147
* Reads a DXF file from an existing stream.
149
* @param stream The string stream.
150
* @param creationInterface
151
* Pointer to the class which takes care of the entities in the file.
153
* @retval true If \p file could be opened.
154
* @retval false If \p file could not be opened.
157
bool DL_Dxf::in(std::stringstream& stream,
158
DL_CreationInterface* creationInterface) {
160
int errorCounter = 0;
164
currentEntity = DL_UNKNOWN;
165
while (readDxfGroups(stream, creationInterface, &errorCounter)) {}
166
if (errorCounter>0) {
167
std::cerr << "DXF Filter: There have been " << errorCounter <<
168
" errors. The drawing might be incomplete / incorrect.\n";
179
* @brief Reads a group couplet from a DXF file. Calls another function
182
* A group couplet consists of two lines that represent a single
183
* piece of data. An integer constant on the first line indicates
184
* the type of data. The value is on the next line.\n
186
* This function reads a couplet, determines the type of data, and
187
* passes the value to the the appropriate handler function of
188
* \p creationInterface.\n
190
* \p fp is advanced so that the next call to \p readDXFGroups() reads
191
* the next couplet in the file.
193
* @param fp Handle of input file
194
* @param creationInterface Handle of class which processes entities
197
* @retval true If EOF not reached.
198
* @retval false If EOF reached.
200
bool DL_Dxf::readDxfGroups(FILE *fp, DL_CreationInterface* creationInterface,
206
// Read one group of the DXF file and chop the lines:
207
if (DL_Dxf::getChoppedLine(groupCodeTmp, DL_DXF_MAXLINE, fp) &&
208
DL_Dxf::getChoppedLine(groupValue, DL_DXF_MAXLINE, fp) ) {
210
groupCode = (unsigned int)stringToInt(groupCodeTmp, &ok);
213
//std::cerr << groupCode << "\n";
214
//std::cerr << groupValue << "\n";
216
processDXFGroup(creationInterface, groupCode, groupValue);
218
std::cerr << "DXF read error: Line: " << line << "\n";
219
if (errorCounter!=NULL) {
223
std::cerr << "DXF read error: trying to fix..\n";
224
// drop a line to sync:
225
DL_Dxf::getChoppedLine(groupCodeTmp, DL_DXF_MAXLINE, fp);
235
* Same as above but for stringstreams.
238
bool DL_Dxf::readDxfGroups(std::stringstream& stream,
239
DL_CreationInterface* creationInterface,
245
// Read one group of the DXF file and chop the lines:
246
if (DL_Dxf::getChoppedLine(groupCodeTmp, DL_DXF_MAXLINE, stream) &&
247
DL_Dxf::getChoppedLine(groupValue, DL_DXF_MAXLINE, stream) ) {
249
groupCode = (unsigned int)stringToInt(groupCodeTmp, &ok);
252
//std::cout << "group code: " << groupCode << "\n";
253
//std::cout << "group value: " << groupValue << "\n";
255
processDXFGroup(creationInterface, groupCode, groupValue);
257
std::cerr << "DXF read error: Line: " << line << "\n";
258
if (errorCounter!=NULL) {
262
//std::cerr << "DXF read error: trying to fix..\n";
263
// drop a line to sync:
264
//DL_Dxf::getChoppedLine(groupCodeTmp, DL_DXF_MAXLINE, stream);
267
return !stream.eof();
274
* @brief Reads line from file & strips whitespace at start and newline
278
* Pointer to character array that chopped line will be returned in.
279
* @param size Size of \p s. (Including space for NULL.)
281
* Handle of input file.
283
* @retval true if line could be read
284
* @retval false if \p fp is already at end of file
286
* @todo Change function to use safer FreeBSD strl* functions
287
* @todo Is it a problem if line is blank (i.e., newline only)?
288
* Then, when function returns, (s==NULL).
290
bool DL_Dxf::getChoppedLine(char *s, unsigned int size, FILE *fp) {
292
// The whole line in the file. Includes space for NULL.
293
char* wholeLine = new char[size];
294
// Only the useful part of the line
297
line = fgets(wholeLine, size, fp);
299
if (line!=NULL && line[0] != '\0') { // Evaluates to fgets() retval
300
// line == wholeLine at this point.
301
// Both guaranteed to be NULL terminated.
303
// Strip leading whitespace and trailing CR/LF.
304
stripWhiteSpace(&line);
306
strncpy(s, line, size);
308
// s should always be NULL terminated, because:
309
assert(size > strlen(line));
312
delete[] wholeLine; // Done with wholeLine
324
* Same as above but for stringstreams.
327
bool DL_Dxf::getChoppedLine(char *s, unsigned int size,
328
std::stringstream& stream) {
331
// Only the useful part of the line
332
char* line = new char[size+1];
333
char* oriLine = line;
334
stream.getline(line, size);
335
stripWhiteSpace(&line);
336
strncpy(s, line, size);
338
assert(size > strlen(s));
351
* @brief Strips leading whitespace and trailing Carriage Return (CR)
352
* and Line Feed (LF) from NULL terminated string.
354
* @param s Input and output.
355
* NULL terminates string.
357
* @retval true if \p s is non-NULL
358
* @retval false if \p s is NULL
360
bool DL_Dxf::stripWhiteSpace(char** s) {
361
// last non-NULL char:
362
int lastChar = strlen(*s) - 1;
364
// Is last character CR or LF?
365
while ( (lastChar >= 0) &&
366
(((*s)[lastChar] == 10) || ((*s)[lastChar] == 13) ||
367
((*s)[lastChar] == ' ' || ((*s)[lastChar] == '\t'))) ) {
368
(*s)[lastChar] = '\0';
372
// Skip whitespace, excluding \n, at beginning of line
373
while ((*s)[0]==' ' || (*s)[0]=='\t') {
377
return ((*s) ? true : false);
383
* Processes a group (pair of group code and value).
385
* @param creationInterface Handle to class that creates entities and
386
* other CAD data from DXF group codes
388
* @param groupCode Constant indicating the data type of the group.
389
* @param groupValue The data value.
391
* @retval true if done processing current entity and new entity begun
392
* @retval false if not done processing current entity
394
bool DL_Dxf::processDXFGroup(DL_CreationInterface* creationInterface,
395
int groupCode, const char *groupValue) {
397
// Init on first call
399
for (int i=0; i<DL_DXF_MAXGROUPCODE; ++i) {
402
settingValue[0] = '\0';
406
// Indicates comment or dxflib version:
407
if (groupCode==999) {
408
if (groupValue!=NULL) {
409
if (!strncmp(groupValue, "dxflib", 6)) {
410
libVersion = getLibVersion(&groupValue[7]);
413
addComment(creationInterface, groupValue);
417
// Indicates start of new entity or var
418
else if (groupCode==0 || groupCode==9) {
420
// If new entity is encountered, the last one must be complete
421
// prepare attributes which can be used for most entities:
422
char name[DL_DXF_MAXLINE+1];
423
if ((values[8])[0]!='\0') {
424
strcpy(name, values[8]);
426
// defaults to layer '0':
432
// Compatibillity with qcad1:
433
if ((values[39])[0]!='\0' &&
434
(values[370])[0]=='\0') {
435
width = toInt(values[39], -1);
437
// since autocad 2002:
438
else if ((values[370])[0]!='\0') {
439
width = toInt(values[370], -1);
441
// default to BYLAYER:
447
color = toInt(values[62], 256);
449
char linetype[DL_DXF_MAXLINE+1];
450
strcpy(linetype, toString(values[6], "BYLAYER"));
452
attrib = DL_Attributes(values[8], // layer
455
linetype); // linetype
456
creationInterface->setAttributes(attrib);
458
creationInterface->setExtrusion(toReal(values[210], 0.0),
459
toReal(values[220], 0.0),
460
toReal(values[230], 1.0),
461
toReal(values[30], 0.0));
463
// Add the last entity via creationInterface
464
switch (currentEntity) {
466
addSetting(creationInterface);
470
addLayer(creationInterface);
474
addBlock(creationInterface);
478
endBlock(creationInterface);
481
case DL_ENTITY_POINT:
482
addPoint(creationInterface);
486
addLine(creationInterface);
489
case DL_ENTITY_POLYLINE:
490
//bulge = toReal(values[42]);
492
case DL_ENTITY_LWPOLYLINE:
493
addPolyline(creationInterface);
496
case DL_ENTITY_VERTEX:
497
addVertex(creationInterface);
500
case DL_ENTITY_SPLINE:
501
addSpline(creationInterface);
505
addArc(creationInterface);
508
case DL_ENTITY_CIRCLE:
509
addCircle(creationInterface);
512
case DL_ENTITY_ELLIPSE:
513
addEllipse(creationInterface);
516
case DL_ENTITY_INSERT:
517
addInsert(creationInterface);
520
case DL_ENTITY_MTEXT:
521
addMText(creationInterface);
525
addText(creationInterface);
528
case DL_ENTITY_ATTRIB:
529
addAttrib(creationInterface);
532
case DL_ENTITY_DIMENSION: {
533
int type = (toInt(values[70], 0)&0x07);
537
addDimLinear(creationInterface);
541
addDimAligned(creationInterface);
545
addDimAngular(creationInterface);
549
addDimDiametric(creationInterface);
553
addDimRadial(creationInterface);
557
addDimAngular3P(creationInterface);
561
addDimOrdinate(creationInterface);
570
case DL_ENTITY_LEADER:
571
addLeader(creationInterface);
574
case DL_ENTITY_HATCH:
575
addHatch(creationInterface);
578
case DL_ENTITY_IMAGE:
579
addImage(creationInterface);
582
case DL_ENTITY_IMAGEDEF:
583
addImageDef(creationInterface);
586
case DL_ENTITY_TRACE:
587
addTrace(creationInterface);
590
case DL_ENTITY_3DFACE:
591
add3dFace(creationInterface);
594
case DL_ENTITY_SOLID:
595
addSolid(creationInterface);
598
case DL_ENTITY_SEQEND:
599
endSequence(creationInterface);
607
// reset all values (they are not persistent and only this
608
// way we can detect default values for unstored settings)
609
for (int i=0; i<DL_DXF_MAXGROUPCODE; ++i) {
612
settingValue[0] = '\0';
613
settingKey[0] = '\0';
616
// Last DXF entity or setting has been handled
617
// Now determine what the next entity or setting type is
619
int prevEntity = currentEntity;
621
// Read DXF settings:
622
if (groupValue[0]=='$') {
623
currentEntity = DL_SETTING;
624
strncpy(settingKey, groupValue, DL_DXF_MAXLINE);
625
settingKey[DL_DXF_MAXLINE] = '\0';
628
else if (!strcmp(groupValue, "LAYER")) {
629
currentEntity = DL_LAYER;
633
else if (!strcmp(groupValue, "BLOCK")) {
634
currentEntity = DL_BLOCK;
635
} else if (!strcmp(groupValue, "ENDBLK")) {
636
currentEntity = DL_ENDBLK;
640
else if (!strcmp(groupValue, "POINT")) {
641
currentEntity = DL_ENTITY_POINT;
642
} else if (!strcmp(groupValue, "LINE")) {
643
currentEntity = DL_ENTITY_LINE;
644
} else if (!strcmp(groupValue, "POLYLINE")) {
645
currentEntity = DL_ENTITY_POLYLINE;
646
} else if (!strcmp(groupValue, "LWPOLYLINE")) {
647
currentEntity = DL_ENTITY_LWPOLYLINE;
648
} else if (!strcmp(groupValue, "VERTEX")) {
649
currentEntity = DL_ENTITY_VERTEX;
650
} else if (!strcmp(groupValue, "SPLINE")) {
651
currentEntity = DL_ENTITY_SPLINE;
652
} else if (!strcmp(groupValue, "ARC")) {
653
currentEntity = DL_ENTITY_ARC;
654
} else if (!strcmp(groupValue, "ELLIPSE")) {
655
currentEntity = DL_ENTITY_ELLIPSE;
656
} else if (!strcmp(groupValue, "CIRCLE")) {
657
currentEntity = DL_ENTITY_CIRCLE;
658
} else if (!strcmp(groupValue, "INSERT")) {
659
currentEntity = DL_ENTITY_INSERT;
660
} else if (!strcmp(groupValue, "TEXT")) {
661
currentEntity = DL_ENTITY_TEXT;
662
} else if (!strcmp(groupValue, "MTEXT")) {
663
currentEntity = DL_ENTITY_MTEXT;
664
} else if (!strcmp(groupValue, "ATTRIB")) {
665
currentEntity = DL_ENTITY_ATTRIB;
666
} else if (!strcmp(groupValue, "DIMENSION")) {
667
currentEntity = DL_ENTITY_DIMENSION;
668
} else if (!strcmp(groupValue, "LEADER")) {
669
currentEntity = DL_ENTITY_LEADER;
670
} else if (!strcmp(groupValue, "HATCH")) {
671
currentEntity = DL_ENTITY_HATCH;
672
} else if (!strcmp(groupValue, "IMAGE")) {
673
currentEntity = DL_ENTITY_IMAGE;
674
} else if (!strcmp(groupValue, "IMAGEDEF")) {
675
currentEntity = DL_ENTITY_IMAGEDEF;
676
} else if (!strcmp(groupValue, "TRACE")) {
677
currentEntity = DL_ENTITY_TRACE;
678
} else if (!strcmp(groupValue, "SOLID")) {
679
currentEntity = DL_ENTITY_SOLID;
680
} else if (!strcmp(groupValue, "3DFACE")) {
681
currentEntity = DL_ENTITY_3DFACE;
682
} else if (!strcmp(groupValue, "SEQEND")) {
683
currentEntity = DL_ENTITY_SEQEND;
685
currentEntity = DL_UNKNOWN;
688
// end of old style POLYLINE entity
689
if (prevEntity==DL_ENTITY_VERTEX && currentEntity!=DL_ENTITY_VERTEX) {
690
endEntity(creationInterface);
696
// Group code does not indicate start of new entity or setting,
697
// so this group must be continuation of data for the current
699
if (groupCode<DL_DXF_MAXGROUPCODE) {
701
bool handled = false;
703
switch (currentEntity) {
704
case DL_ENTITY_MTEXT:
705
handled = handleMTextData(creationInterface);
708
case DL_ENTITY_LWPOLYLINE:
709
handled = handleLWPolylineData(creationInterface);
712
case DL_ENTITY_SPLINE:
713
handled = handleSplineData(creationInterface);
716
case DL_ENTITY_LEADER:
717
handled = handleLeaderData(creationInterface);
720
case DL_ENTITY_HATCH:
721
handled = handleHatchData(creationInterface);
729
// Normal group / value pair:
730
strncpy(values[groupCode], groupValue, DL_DXF_MAXLINE);
731
values[groupCode][DL_DXF_MAXLINE] = '\0';
743
* Adds a comment from the DXF file.
745
void DL_Dxf::addComment(DL_CreationInterface* creationInterface, const char* comment) {
746
creationInterface->addComment(comment);
752
* Adds a variable from the DXF file.
754
void DL_Dxf::addSetting(DL_CreationInterface* creationInterface) {
756
for (int i=0; i<=380; ++i) {
757
if (values[i][0]!='\0') {
765
creationInterface->setVariableString(settingKey,
769
else if (c>=10 && c<=39) {
771
creationInterface->setVariableVector(
774
toReal(values[c+10]),
775
toReal(values[c+20]),
780
else if (c>=40 && c<=59) {
781
creationInterface->setVariableDouble(settingKey,
786
else if (c>=60 && c<=99) {
787
creationInterface->setVariableInt(settingKey,
793
creationInterface->setVariableString(settingKey,
802
* Adds a layer that was read from the file via the creation interface.
804
void DL_Dxf::addLayer(DL_CreationInterface* creationInterface) {
805
// correct some impossible attributes for layers:
806
attrib = creationInterface->getAttributes();
807
if (attrib.getColor()==256 || attrib.getColor()==0) {
810
if (attrib.getWidth()<0) {
813
if (!strcasecmp(attrib.getLineType().c_str(), "BYLAYER") ||
814
!strcasecmp(attrib.getLineType().c_str(), "BYBLOCK")) {
815
attrib.setLineType("CONTINUOUS");
819
creationInterface->addLayer(DL_LayerData(values[2],
826
* Adds a block that was read from the file via the creation interface.
828
void DL_Dxf::addBlock(DL_CreationInterface* creationInterface) {
839
creationInterface->addBlock(d);
845
* Ends a block that was read from the file via the creation interface.
847
void DL_Dxf::endBlock(DL_CreationInterface* creationInterface) {
848
creationInterface->endBlock();
854
* Adds a point entity that was read from the file via the creation interface.
856
void DL_Dxf::addPoint(DL_CreationInterface* creationInterface) {
857
DL_PointData d(toReal(values[10]),
860
creationInterface->addPoint(d);
866
* Adds a line entity that was read from the file via the creation interface.
868
void DL_Dxf::addLine(DL_CreationInterface* creationInterface) {
869
DL_LineData d(toReal(values[10]),
876
creationInterface->addLine(d);
882
* Adds a polyline entity that was read from the file via the creation interface.
884
void DL_Dxf::addPolyline(DL_CreationInterface* creationInterface) {
885
DL_PolylineData pd(maxVertices, toInt(values[71], 0), toInt(values[72], 0), toInt(values[70], 0));
886
creationInterface->addPolyline(pd);
888
if (currentEntity==DL_ENTITY_LWPOLYLINE) {
889
for (int i=0; i<maxVertices; i++) {
890
DL_VertexData d(vertices[i*4],
895
creationInterface->addVertex(d);
897
creationInterface->endEntity();
904
* Adds a polyline vertex entity that was read from the file
905
* via the creation interface.
907
void DL_Dxf::addVertex(DL_CreationInterface* creationInterface) {
908
DL_VertexData d(toReal(values[10]),
914
//bulge = toReal(values[42]);
916
creationInterface->addVertex(d);
922
* Adds a spline entity that was read from the file via the creation interface.
924
void DL_Dxf::addSpline(DL_CreationInterface* creationInterface) {
925
DL_SplineData sd(toInt(values[71], 3),
928
toInt(values[70], 4));
929
/*DL_SplineData sd(toInt(values[71], 3), toInt(values[72], 0),
930
toInt(values[73], 0), toInt(values[70], 4));*/
931
creationInterface->addSpline(sd);
934
for (i=0; i<maxControlPoints; i++) {
935
DL_ControlPointData d(controlPoints[i*3],
936
controlPoints[i*3+1],
937
controlPoints[i*3+2]);
939
creationInterface->addControlPoint(d);
941
for (i=0; i<maxKnots; i++) {
942
DL_KnotData k(knots[i]);
944
creationInterface->addKnot(k);
951
* Adds an arc entity that was read from the file via the creation interface.
953
void DL_Dxf::addArc(DL_CreationInterface* creationInterface) {
954
DL_ArcData d(toReal(values[10]),
961
creationInterface->addArc(d);
967
* Adds a circle entity that was read from the file via the creation interface.
969
void DL_Dxf::addCircle(DL_CreationInterface* creationInterface) {
970
DL_CircleData d(toReal(values[10]),
975
creationInterface->addCircle(d);
981
* Adds an ellipse entity that was read from the file via the creation interface.
983
void DL_Dxf::addEllipse(DL_CreationInterface* creationInterface) {
984
DL_EllipseData d(toReal(values[10]),
990
toReal(values[40], 1.0),
991
toReal(values[41], 0.0),
992
toReal(values[42], 2*M_PI));
994
creationInterface->addEllipse(d);
1000
* Adds an insert entity that was read from the file via the creation interface.
1002
void DL_Dxf::addInsert(DL_CreationInterface* creationInterface) {
1003
DL_InsertData d(values[2],
1005
toReal(values[10], 0.0),
1006
toReal(values[20], 0.0),
1007
toReal(values[30], 0.0),
1009
toReal(values[41], 1.0),
1010
toReal(values[42], 1.0),
1011
toReal(values[43], 1.0),
1013
toReal(values[50], 0.0),
1015
toInt(values[70], 1),
1016
toInt(values[71], 1),
1018
toReal(values[44], 0.0),
1019
toReal(values[45], 0.0));
1021
creationInterface->addInsert(d);
1027
* Adds a trace entity (4 edge closed polyline) that was read from the file via the creation interface.
1031
void DL_Dxf::addTrace(DL_CreationInterface* creationInterface) {
1034
for (int k = 0; k < 4; k++) {
1035
td.x[k] = toReal(values[10 + k]);
1036
td.y[k] = toReal(values[20 + k]);
1037
td.z[k] = toReal(values[30 + k]);
1039
creationInterface->addTrace(td);
1045
* Adds a 3dface entity that was read from the file via the creation interface.
1047
void DL_Dxf::add3dFace(DL_CreationInterface* creationInterface) {
1050
for (int k = 0; k < 4; k++) {
1051
td.x[k] = toReal(values[10 + k]);
1052
td.y[k] = toReal(values[20 + k]);
1053
td.z[k] = toReal(values[30 + k]);
1055
creationInterface->add3dFace(td);
1061
* Adds a solid entity (filled trace) that was read from the file via the creation interface.
1065
void DL_Dxf::addSolid(DL_CreationInterface* creationInterface) {
1068
for (int k = 0; k < 4; k++) {
1069
sd.x[k] = toReal(values[10 + k]);
1070
sd.y[k] = toReal(values[20 + k]);
1071
sd.z[k] = toReal(values[30 + k]);
1073
creationInterface->addSolid(sd);
1078
* Adds an MText entity that was read from the file via the creation interface.
1080
void DL_Dxf::addMText(DL_CreationInterface* creationInterface) {
1083
if (values[50][0]!='\0') {
1084
if (libVersion<=0x02000200) {
1085
// wrong but compatible with dxflib <=2.0.2.0:
1086
angle = toReal(values[50], 0.0);
1088
angle = (toReal(values[50], 0.0)*2*M_PI)/360.0;
1090
} else if (values[11][0]!='\0' && values[21][0]!='\0') {
1091
double x = toReal(values[11], 0.0);
1092
double y = toReal(values[21], 0.0);
1094
if (fabs(x)<1.0e-6) {
1098
angle = M_PI/2.0*3.0;
1107
toReal(values[10], 0.0),
1108
toReal(values[20], 0.0),
1109
toReal(values[30], 0.0),
1111
toReal(values[40], 2.5),
1113
toReal(values[41], 100.0),
1115
toInt(values[71], 1),
1116
// drawing direction
1117
toInt(values[72], 1),
1118
// line spacing style
1119
toInt(values[73], 1),
1120
// line spacing factor
1121
toReal(values[44], 1.0),
1128
creationInterface->addMText(d);
1134
* Handles additional MText data.
1136
bool DL_Dxf::handleMTextData(DL_CreationInterface* creationInterface) {
1137
// Special handling of text chunks for MTEXT entities:
1139
creationInterface->addMTextChunk(groupValue);
1149
* Handles additional polyline data.
1151
bool DL_Dxf::handleLWPolylineData(DL_CreationInterface* /*creationInterface*/) {
1152
// Allocate LWPolyline vertices (group code 90):
1153
if (groupCode==90) {
1154
maxVertices = toInt(groupValue);
1155
if (maxVertices>0) {
1156
if (vertices!=NULL) {
1159
vertices = new double[4*maxVertices];
1160
for (int i=0; i<maxVertices; ++i) {
1161
vertices[i*4] = 0.0;
1162
vertices[i*4+1] = 0.0;
1163
vertices[i*4+2] = 0.0;
1164
vertices[i*4+3] = 0.0;
1171
// Compute LWPolylines vertices (group codes 10/20/30/42):
1172
else if (groupCode==10 || groupCode==20 ||
1173
groupCode==30 || groupCode==42) {
1175
if (vertexIndex<maxVertices-1 && groupCode==10) {
1179
if (groupCode<=30) {
1180
if (vertexIndex>=0 && vertexIndex<maxVertices) {
1181
vertices[4*vertexIndex + (groupCode/10-1)]
1182
= toReal(groupValue);
1184
} else if (groupCode==42 && vertexIndex<maxVertices) {
1185
vertices[4*vertexIndex + 3] = toReal(groupValue);
1195
* Handles additional spline data.
1197
bool DL_Dxf::handleSplineData(DL_CreationInterface* /*creationInterface*/) {
1198
// Allocate Spline knots (group code 72):
1199
if (groupCode==72) {
1200
maxKnots = toInt(groupValue);
1205
knots = new double[maxKnots];
1206
for (int i=0; i<maxKnots; ++i) {
1214
// Allocate Spline control points (group code 73):
1215
else if (groupCode==73) {
1216
maxControlPoints = toInt(groupValue);
1217
if (maxControlPoints>0) {
1218
if (controlPoints!=NULL) {
1219
delete[] controlPoints;
1221
controlPoints = new double[3*maxControlPoints];
1222
for (int i=0; i<maxControlPoints; ++i) {
1223
controlPoints[i*3] = 0.0;
1224
controlPoints[i*3+1] = 0.0;
1225
controlPoints[i*3+2] = 0.0;
1228
controlPointIndex=-1;
1232
// Compute spline knot vertices (group code 40):
1233
else if (groupCode==40) {
1234
if (knotIndex<maxKnots-1) {
1236
knots[knotIndex] = toReal(groupValue);
1241
// Compute spline control points (group codes 10/20/30):
1242
else if (groupCode==10 || groupCode==20 ||
1245
if (controlPointIndex<maxControlPoints-1 && groupCode==10) {
1246
controlPointIndex++;
1249
if (controlPointIndex>=0 && controlPointIndex<maxControlPoints) {
1250
controlPoints[3*controlPointIndex + (groupCode/10-1)]
1251
= toReal(groupValue);
1261
* Handles additional leader data.
1263
bool DL_Dxf::handleLeaderData(DL_CreationInterface* /*creationInterface*/) {
1264
// Allocate Leader vertices (group code 76):
1265
if (groupCode==76) {
1266
maxLeaderVertices = toInt(groupValue);
1267
if (maxLeaderVertices>0) {
1268
if (leaderVertices!=NULL) {
1269
delete[] leaderVertices;
1271
leaderVertices = new double[3*maxLeaderVertices];
1272
for (int i=0; i<maxLeaderVertices; ++i) {
1273
leaderVertices[i*3] = 0.0;
1274
leaderVertices[i*3+1] = 0.0;
1275
leaderVertices[i*3+2] = 0.0;
1278
leaderVertexIndex=-1;
1282
// Compute Leader vertices (group codes 10/20/30):
1283
else if (groupCode==10 || groupCode==20 || groupCode==30) {
1285
if (leaderVertexIndex<maxLeaderVertices-1 && groupCode==10) {
1286
leaderVertexIndex++;
1289
if (groupCode<=30) {
1290
if (leaderVertexIndex>=0 &&
1291
leaderVertexIndex<maxLeaderVertices) {
1292
leaderVertices[3*leaderVertexIndex + (groupCode/10-1)]
1293
= toReal(groupValue);
1305
* Handles additional hatch data.
1307
bool DL_Dxf::handleHatchData(DL_CreationInterface* /*creationInterface*/) {
1309
static int firstPolylineStatus = 0;
1311
// Allocate hatch loops (group code 91):
1312
if (groupCode==91 && toInt(groupValue)>0) {
1314
if (hatchLoops!=NULL) {
1315
delete[] hatchLoops;
1318
if (maxHatchEdges!=NULL) {
1319
delete[] maxHatchEdges;
1320
maxHatchEdges = NULL;
1322
if (hatchEdgeIndex!=NULL) {
1323
delete[] hatchEdgeIndex;
1324
hatchEdgeIndex = NULL;
1326
if (hatchEdges!=NULL) {
1327
for (int i=0; i<maxHatchLoops; ++i) {
1328
delete[] hatchEdges[i];
1330
delete[] hatchEdges;
1333
maxHatchLoops = toInt(groupValue);
1335
if (maxHatchLoops>0) {
1336
hatchLoops = new DL_HatchLoopData[maxHatchLoops];
1337
maxHatchEdges = new int[maxHatchLoops];
1338
hatchEdgeIndex = new int[maxHatchLoops];
1339
hatchEdges = new DL_HatchEdgeData*[maxHatchLoops];
1340
for (int i=0; i<maxHatchLoops; ++i) {
1341
hatchEdges[i] = NULL;
1342
maxHatchEdges[i] = 0;
1344
hatchLoopIndex = -1;
1350
// Allocate hatch edges, group code 93
1351
if (groupCode==93 && toInt(groupValue)>0) {
1352
if (hatchLoopIndex<maxHatchLoops-1 && hatchLoops!=NULL &&
1353
maxHatchEdges!=NULL && hatchEdgeIndex!=NULL &&
1359
hatchLoops[hatchLoopIndex]
1360
= DL_HatchLoopData(toInt(groupValue));
1362
maxHatchEdges[hatchLoopIndex] = toInt(groupValue);
1363
hatchEdgeIndex[hatchLoopIndex] = -1;
1364
hatchEdges[hatchLoopIndex]
1365
= new DL_HatchEdgeData[toInt(groupValue)];
1366
firstPolylineStatus = 0;
1373
// Init hatch edge for non-polyline boundary (group code 72)
1374
if (hatchEdges!=NULL &&
1375
hatchEdgeIndex!=NULL &&
1376
maxHatchEdges!=NULL &&
1377
hatchLoopIndex>=0 &&
1378
hatchLoopIndex<maxHatchLoops &&
1379
hatchEdgeIndex[hatchLoopIndex] <
1380
maxHatchEdges[hatchLoopIndex] &&
1381
(atoi(values[92])&2)==0 && // not a polyline
1385
hatchEdgeIndex[hatchLoopIndex]++;
1387
hatchEdges[hatchLoopIndex][hatchEdgeIndex[hatchLoopIndex]]
1388
.type = toInt(groupValue);
1389
hatchEdges[hatchLoopIndex][hatchEdgeIndex[hatchLoopIndex]]
1395
// Handle hatch edges for non-polyline boundaries
1396
// (group codes 10, 20, 11, 21, 40, 50, 51, 73)
1399
hatchEdgeIndex!=NULL &&
1400
hatchLoopIndex>=0 &&
1401
hatchLoopIndex<maxHatchLoops &&
1402
hatchEdges[hatchLoopIndex]!=NULL &&
1403
hatchEdgeIndex[hatchLoopIndex]>=0 &&
1404
hatchEdgeIndex[hatchLoopIndex] <
1405
maxHatchEdges[hatchLoopIndex] &&
1406
((atoi(values[92])&2)==0) && // not a polyline
1407
(groupCode==10 || groupCode==20 ||
1408
groupCode==11 || groupCode==21 ||
1409
groupCode==40 || groupCode==50 ||
1410
groupCode==51 || groupCode==73)) {
1412
if (hatchEdges[hatchLoopIndex]
1413
[hatchEdgeIndex[hatchLoopIndex]].defined==false) {
1414
if (hatchEdges[hatchLoopIndex]
1415
[hatchEdgeIndex[hatchLoopIndex]].type==1) {
1416
switch (groupCode) {
1418
hatchEdges[hatchLoopIndex]
1419
[hatchEdgeIndex[hatchLoopIndex]].x1
1420
= toReal(groupValue);
1423
hatchEdges[hatchLoopIndex]
1424
[hatchEdgeIndex[hatchLoopIndex]].y1
1425
= toReal(groupValue);
1428
hatchEdges[hatchLoopIndex]
1429
[hatchEdgeIndex[hatchLoopIndex]].x2
1430
= toReal(groupValue);
1433
hatchEdges[hatchLoopIndex]
1434
[hatchEdgeIndex[hatchLoopIndex]].y2
1435
= toReal(groupValue);
1436
hatchEdges[hatchLoopIndex]
1437
[hatchEdgeIndex[hatchLoopIndex]].defined = true;
1444
if (hatchEdges[hatchLoopIndex]
1445
[hatchEdgeIndex[hatchLoopIndex]].type==2) {
1446
switch (groupCode) {
1448
hatchEdges[hatchLoopIndex]
1449
[hatchEdgeIndex[hatchLoopIndex]].cx
1450
= toReal(groupValue);
1453
hatchEdges[hatchLoopIndex]
1454
[hatchEdgeIndex[hatchLoopIndex]].cy
1455
= toReal(groupValue);
1458
hatchEdges[hatchLoopIndex]
1459
[hatchEdgeIndex[hatchLoopIndex]].radius
1460
= toReal(groupValue);
1463
hatchEdges[hatchLoopIndex]
1464
[hatchEdgeIndex[hatchLoopIndex]].angle1
1465
= toReal(groupValue)/360.0*2*M_PI;
1468
hatchEdges[hatchLoopIndex]
1469
[hatchEdgeIndex[hatchLoopIndex]].angle2
1470
= toReal(groupValue)/360.0*2*M_PI;
1473
hatchEdges[hatchLoopIndex]
1474
[hatchEdgeIndex[hatchLoopIndex]].ccw
1475
= (bool)toInt(groupValue);
1476
hatchEdges[hatchLoopIndex]
1477
[hatchEdgeIndex[hatchLoopIndex]].defined = true;
1488
// 2003/12/31: polyline hatches can be extremely slow and are rarely used
1490
// Handle hatch edges for polyline boundaries
1491
// (group codes 10, 20, 42)
1494
hatchEdgeIndex!=NULL &&
1495
hatchLoopIndex>=0 &&
1496
hatchLoopIndex<maxHatchLoops &&
1497
hatchEdges[hatchLoopIndex]!=NULL &&
1498
//hatchEdgeIndex[hatchLoopIndex]>=0 &&
1499
hatchEdgeIndex[hatchLoopIndex] <
1500
maxHatchEdges[hatchLoopIndex] &&
1501
((atoi(values[92])&2)==2)) { // a polyline
1503
if (groupCode==10 || groupCode==20 ||
1506
std::cout << " found polyline edge data: " << groupCode << "\n";
1507
std::cout << " value: " << toReal(groupValue) << "\n";
1509
static double lastX = 0.0;
1510
static double lastY = 0.0;
1511
static double lastB = 0.0;
1513
if (firstPolylineStatus<2) {
1514
switch (groupCode) {
1516
firstPolylineStatus++;
1517
if (firstPolylineStatus==1) {
1518
lastX = toReal(groupValue);
1519
std::cout << " firstX: " << lastX << "\n";
1524
lastY = toReal(groupValue);
1525
std::cout << " firstY: " << lastY << "\n";
1529
lastB = toReal(groupValue);
1536
if (firstPolylineStatus!=2) {
1542
switch (groupCode) {
1544
hatchEdgeIndex[hatchLoopIndex]++;
1545
hatchEdges[hatchLoopIndex]
1546
[hatchEdgeIndex[hatchLoopIndex]].type = 1;
1547
hatchEdges[hatchLoopIndex]
1548
[hatchEdgeIndex[hatchLoopIndex]].x1
1550
hatchEdges[hatchLoopIndex]
1551
[hatchEdgeIndex[hatchLoopIndex]].x2
1552
= lastX = toReal(groupValue);
1553
std::cout << " X: " << lastX << "\n";
1556
hatchEdges[hatchLoopIndex]
1557
[hatchEdgeIndex[hatchLoopIndex]].y1
1559
hatchEdges[hatchLoopIndex]
1560
[hatchEdgeIndex[hatchLoopIndex]].y2
1561
= lastY = toReal(groupValue);
1562
std::cout << " Y: " << lastY << "\n";
1567
double x1 = hatchEdges[hatchLoopIndex]
1568
[hatchEdgeIndex[hatchLoopIndex]].x1;
1569
double y1 = hatchEdges[hatchLoopIndex]
1570
[hatchEdgeIndex[hatchLoopIndex]].y1;
1571
double x2 = hatchEdges[hatchLoopIndex]
1572
[hatchEdgeIndex[hatchLoopIndex]].x2;
1573
double y2 = hatchEdges[hatchLoopIndex]
1574
[hatchEdgeIndex[hatchLoopIndex]].y2;
1576
double bulge = toReal(groupValue);
1578
bool reversed = (bulge<0.0);
1579
double alpha = atan(bulge)*4.0;
1585
double mx = (x2+x1)/2.0;
1586
double my = (y2+y1)/2.0;
1587
double dist = sqrt(pow(x2-x1,2) + pow(y2-y1,2)) / 2.0;
1589
// alpha can't be 0.0 at this point
1590
radius = fabs(dist / sin(alpha/2.0));
1592
double wu = fabs(pow(radius, 2.0) - pow(dist, 2.0));
1593
double h = sqrt(wu);
1594
double angle = acos((x2-x1) / dist);
1602
if (fabs(alpha)>M_PI) {
1606
cx = mx + cos(angle) * h;
1607
cy = my + sin(angle) * h;
1609
a1 = hatchEdges[hatchLoopIndex]
1610
[hatchEdgeIndex[hatchLoopIndex]].type = 2;
1611
hatchEdges[hatchLoopIndex]
1612
[hatchEdgeIndex[hatchLoopIndex]].ccw = (toReal(groupValue)>0.0);
1613
hatchEdges[hatchLoopIndex]
1614
[hatchEdgeIndex[hatchLoopIndex]].cx = cx;
1615
hatchEdges[hatchLoopIndex]
1616
[hatchEdgeIndex[hatchLoopIndex]].cy = cy;
1617
hatchEdges[hatchLoopIndex]
1618
[hatchEdgeIndex[hatchLoopIndex]].radius = radius;
1626
// end polyline boundary
1641
* Adds an text entity that was read from the file via the creation interface.
1643
void DL_Dxf::addText(DL_CreationInterface* creationInterface) {
1646
toReal(values[10], 0.0),
1647
toReal(values[20], 0.0),
1648
toReal(values[30], 0.0),
1650
toReal(values[11], 0.0),
1651
toReal(values[21], 0.0),
1652
toReal(values[31], 0.0),
1654
toReal(values[40], 2.5),
1656
toReal(values[41], 1.0),
1658
toInt(values[71], 0),
1660
toInt(values[72], 0),
1662
toInt(values[73], 0),
1668
(toReal(values[50], 0.0)*2*M_PI)/360.0);
1670
creationInterface->addText(d);
1676
* Adds an attrib entity that was read from the file via the creation interface.
1677
* @todo add attrib instead of normal text
1679
void DL_Dxf::addAttrib(DL_CreationInterface* creationInterface) {
1682
toReal(values[10], 0.0),
1683
toReal(values[20], 0.0),
1684
toReal(values[30], 0.0),
1686
toReal(values[11], 0.0),
1687
toReal(values[21], 0.0),
1688
toReal(values[31], 0.0),
1690
toReal(values[40], 2.5),
1692
toReal(values[41], 1.0),
1694
toInt(values[71], 0),
1696
toInt(values[72], 0),
1698
toInt(values[74], 0),
1704
(toReal(values[50], 0.0)*2*M_PI)/360.0);
1706
creationInterface->addText(d);
1712
* @return dimension data from current values.
1714
DL_DimensionData DL_Dxf::getDimData() {
1715
// generic dimension data:
1716
return DL_DimensionData(
1718
toReal(values[10], 0.0),
1719
toReal(values[20], 0.0),
1720
toReal(values[30], 0.0),
1721
// text middle point
1722
toReal(values[11], 0.0),
1723
toReal(values[21], 0.0),
1724
toReal(values[31], 0.0),
1726
toInt(values[70], 0),
1728
toInt(values[71], 5),
1730
toInt(values[72], 1),
1732
toReal(values[41], 1.0),
1738
toReal(values[53], 0.0));
1744
* Adds a linear dimension entity that was read from the file via the creation interface.
1746
void DL_Dxf::addDimLinear(DL_CreationInterface* creationInterface) {
1747
DL_DimensionData d = getDimData();
1749
// horizontal / vertical / rotated dimension:
1750
DL_DimLinearData dl(
1751
// definition point 1
1752
toReal(values[13], 0.0),
1753
toReal(values[23], 0.0),
1754
toReal(values[33], 0.0),
1755
// definition point 2
1756
toReal(values[14], 0.0),
1757
toReal(values[24], 0.0),
1758
toReal(values[34], 0.0),
1760
toReal(values[50], 0.0),
1762
toReal(values[52], 0.0));
1763
creationInterface->addDimLinear(d, dl);
1769
* Adds an aligned dimension entity that was read from the file via the creation interface.
1771
void DL_Dxf::addDimAligned(DL_CreationInterface* creationInterface) {
1772
DL_DimensionData d = getDimData();
1774
// aligned dimension:
1775
DL_DimAlignedData da(
1776
// extension point 1
1777
toReal(values[13], 0.0),
1778
toReal(values[23], 0.0),
1779
toReal(values[33], 0.0),
1780
// extension point 2
1781
toReal(values[14], 0.0),
1782
toReal(values[24], 0.0),
1783
toReal(values[34], 0.0));
1784
creationInterface->addDimAlign(d, da);
1790
* Adds a radial dimension entity that was read from the file via the creation interface.
1792
void DL_Dxf::addDimRadial(DL_CreationInterface* creationInterface) {
1793
DL_DimensionData d = getDimData();
1795
DL_DimRadialData dr(
1797
toReal(values[15], 0.0),
1798
toReal(values[25], 0.0),
1799
toReal(values[35], 0.0),
1801
toReal(values[40], 0.0));
1802
creationInterface->addDimRadial(d, dr);
1808
* Adds a diametric dimension entity that was read from the file via the creation interface.
1810
void DL_Dxf::addDimDiametric(DL_CreationInterface* creationInterface) {
1811
DL_DimensionData d = getDimData();
1813
// diametric dimension:
1814
DL_DimDiametricData dr(
1816
toReal(values[15], 0.0),
1817
toReal(values[25], 0.0),
1818
toReal(values[35], 0.0),
1820
toReal(values[40], 0.0));
1821
creationInterface->addDimDiametric(d, dr);
1827
* Adds an angular dimension entity that was read from the file via the creation interface.
1829
void DL_Dxf::addDimAngular(DL_CreationInterface* creationInterface) {
1830
DL_DimensionData d = getDimData();
1832
// angular dimension:
1833
DL_DimAngularData da(
1834
// definition point 1
1835
toReal(values[13], 0.0),
1836
toReal(values[23], 0.0),
1837
toReal(values[33], 0.0),
1838
// definition point 2
1839
toReal(values[14], 0.0),
1840
toReal(values[24], 0.0),
1841
toReal(values[34], 0.0),
1842
// definition point 3
1843
toReal(values[15], 0.0),
1844
toReal(values[25], 0.0),
1845
toReal(values[35], 0.0),
1846
// definition point 4
1847
toReal(values[16], 0.0),
1848
toReal(values[26], 0.0),
1849
toReal(values[36], 0.0));
1850
creationInterface->addDimAngular(d, da);
1855
* Adds an angular dimension entity that was read from the file via the creation interface.
1857
void DL_Dxf::addDimAngular3P(DL_CreationInterface* creationInterface) {
1858
DL_DimensionData d = getDimData();
1860
// angular dimension (3P):
1861
DL_DimAngular3PData da(
1862
// definition point 1
1863
toReal(values[13], 0.0),
1864
toReal(values[23], 0.0),
1865
toReal(values[33], 0.0),
1866
// definition point 2
1867
toReal(values[14], 0.0),
1868
toReal(values[24], 0.0),
1869
toReal(values[34], 0.0),
1870
// definition point 3
1871
toReal(values[15], 0.0),
1872
toReal(values[25], 0.0),
1873
toReal(values[35], 0.0));
1874
creationInterface->addDimAngular3P(d, da);
1880
* Adds an ordinate dimension entity that was read from the file via the creation interface.
1882
void DL_Dxf::addDimOrdinate(DL_CreationInterface* creationInterface) {
1883
DL_DimensionData d = getDimData();
1885
// ordinate dimension:
1886
DL_DimOrdinateData dl(
1887
// definition point 1
1888
toReal(values[13], 0.0),
1889
toReal(values[23], 0.0),
1890
toReal(values[33], 0.0),
1891
// definition point 2
1892
toReal(values[14], 0.0),
1893
toReal(values[24], 0.0),
1894
toReal(values[34], 0.0),
1895
(toInt(values[70])&64)==64 // true: X-type, false: Y-type
1897
creationInterface->addDimOrdinate(d, dl);
1903
* Adds a leader entity that was read from the file via the creation interface.
1905
void DL_Dxf::addLeader(DL_CreationInterface* creationInterface) {
1909
toInt(values[71], 1),
1911
toInt(values[72], 0),
1912
// Leader creation flag
1913
toInt(values[73], 3),
1914
// Hookline direction flag
1915
toInt(values[74], 1),
1917
toInt(values[75], 0),
1918
// Text annotation height
1919
toReal(values[40], 1.0),
1920
// Text annotation width
1921
toReal(values[41], 1.0),
1922
// Number of vertices in leader
1923
toInt(values[76], 0)
1925
creationInterface->addLeader(le);
1927
for (int i=0; i<maxLeaderVertices; i++) {
1928
DL_LeaderVertexData d(leaderVertices[i*3],
1929
leaderVertices[i*3+1],
1930
leaderVertices[i*3+2]);
1932
creationInterface->addLeaderVertex(d);
1939
* Adds a hatch entity that was read from the file via the creation interface.
1941
void DL_Dxf::addHatch(DL_CreationInterface* creationInterface) {
1942
DL_HatchData hd(toInt(values[91], 1),
1943
toInt(values[70], 0),
1944
toReal(values[41], 1.0),
1945
toReal(values[52], 0.0),
1947
creationInterface->addHatch(hd);
1949
for (int l=0; l<maxHatchLoops; l++) {
1950
DL_HatchLoopData ld(maxHatchEdges[l]);
1951
creationInterface->addHatchLoop(ld);
1952
for (int b=0; b<maxHatchEdges[l]; b++) {
1953
creationInterface->addHatchEdge(hatchEdges[l][b]);
1956
creationInterface->endEntity();
1957
currentEntity = DL_UNKNOWN;
1963
* Adds an image entity that was read from the file via the creation interface.
1965
void DL_Dxf::addImage(DL_CreationInterface* creationInterface) {
1966
DL_ImageData id(// pass ref insead of name we don't have yet
1969
toReal(values[10], 0.0),
1970
toReal(values[20], 0.0),
1971
toReal(values[30], 0.0),
1973
toReal(values[11], 1.0),
1974
toReal(values[21], 0.0),
1975
toReal(values[31], 0.0),
1977
toReal(values[12], 0.0),
1978
toReal(values[22], 1.0),
1979
toReal(values[32], 0.0),
1980
// image size (pixel):
1981
toInt(values[13], 1),
1982
toInt(values[23], 1),
1983
// brightness, contrast, fade
1984
toInt(values[281], 50),
1985
toInt(values[282], 50),
1986
toInt(values[283], 0));
1988
creationInterface->addImage(id);
1989
creationInterface->endEntity();
1990
currentEntity = DL_UNKNOWN;
1996
* Adds an image definition that was read from the file via the creation interface.
1998
void DL_Dxf::addImageDef(DL_CreationInterface* creationInterface) {
1999
DL_ImageDefData id(// handle
2003
creationInterface->linkImage(id);
2004
creationInterface->endEntity();
2005
currentEntity = DL_UNKNOWN;
2011
* Ends some special entities like hatches or old style polylines.
2013
void DL_Dxf::endEntity(DL_CreationInterface* creationInterface) {
2014
creationInterface->endEntity();
2019
* Ends a sequence and notifies the creation interface.
2021
void DL_Dxf::endSequence(DL_CreationInterface* creationInterface) {
2022
creationInterface->endSequence();
2027
* Converts the given string into an int.
2028
* ok is set to false if there was an error.
2030
int DL_Dxf::stringToInt(const char* s, bool* ok) {
2039
} else if (s[i]=='.') {
2041
//std::cerr << "two dots\n";
2046
} else if (s[i]<'0' || s[i]>'9') {
2047
//std::cerr << "NaN: '" << s[i] << "'\n";
2051
} while(s[i]!='\0' && *ok==true);
2059
* @brief Opens the given file for writing and returns a pointer
2060
* to the dxf writer. This pointer needs to be passed on to other
2061
* writing functions.
2063
* @param file Full path of the file to open.
2065
* @return Pointer to an ascii dxf writer object.
2067
DL_WriterA* DL_Dxf::out(const char* file, DL_Codes::version version) {
2068
char* f = new char[strlen(file)+1];
2070
this->version = version;
2072
DL_WriterA* dw = new DL_WriterA(f, version);
2073
if (dw->openFailed()) {
2086
* @brief Writes a DXF header to the file currently opened
2087
* by the given DXF writer object.
2089
void DL_Dxf::writeHeader(DL_WriterA& dw) {
2090
dw.comment("dxflib " DL_VERSION);
2093
dw.dxfString(9, "$ACADVER");
2095
case DL_Codes::AC1009:
2096
dw.dxfString(1, "AC1009");
2098
case DL_Codes::AC1012:
2099
dw.dxfString(1, "AC1012");
2101
case DL_Codes::AC1014:
2102
dw.dxfString(1, "AC1014");
2104
case DL_Codes::AC1015:
2105
dw.dxfString(1, "AC1015");
2109
// Newer version require that (otherwise a*cad crashes..)
2110
if (version==VER_2000) {
2111
dw.dxfString(9, "$HANDSEED");
2112
dw.dxfHex(5, 0xFFFF);
2122
* Writes a point entity to the file.
2124
* @param dw DXF writer
2125
* @param data Entity data from the file
2126
* @param attrib Attributes
2128
void DL_Dxf::writePoint(DL_WriterA& dw,
2129
const DL_PointData& data,
2130
const DL_Attributes& attrib) {
2132
if (version==VER_2000) {
2133
dw.dxfString(100, "AcDbEntity");
2134
dw.dxfString(100, "AcDbPoint");
2136
dw.entityAttributes(attrib);
2137
dw.coord(POINT_COORD_CODE, data.x, data.y);
2143
* Writes a line entity to the file.
2145
* @param dw DXF writer
2146
* @param data Entity data from the file
2147
* @param attrib Attributes
2149
void DL_Dxf::writeLine(DL_WriterA& dw,
2150
const DL_LineData& data,
2151
const DL_Attributes& attrib) {
2153
if (version==VER_2000) {
2154
dw.dxfString(100, "AcDbEntity");
2155
dw.dxfString(100, "AcDbLine");
2157
dw.entityAttributes(attrib);
2158
dw.coord(LINE_START_CODE, data.x1, data.y1);
2159
dw.coord(LINE_END_CODE, data.x2, data.y2);
2165
* Writes a polyline entity to the file.
2167
* @param dw DXF writer
2168
* @param data Entity data from the file
2169
* @param attrib Attributes
2172
void DL_Dxf::writePolyline(DL_WriterA& dw,
2173
const DL_PolylineData& data,
2174
const DL_Attributes& attrib) {
2175
if (version==VER_2000) {
2176
dw.entity("LWPOLYLINE");
2177
dw.entityAttributes(attrib);
2178
dw.dxfString(100, "AcDbEntity");
2179
dw.dxfString(100, "AcDbPolyline");
2180
dw.dxfInt(90, (int)data.number);
2181
dw.dxfInt(70, data.flags);
2183
dw.entity("POLYLINE");
2184
dw.entityAttributes(attrib);
2185
polylineLayer = attrib.getLayer();
2187
dw.dxfInt(70, data.flags);
2188
dw.coord(VERTEX_COORD_CODE, 0.0, 0.0);
2195
* Writes a single vertex of a polyline to the file.
2197
* @param dw DXF writer
2198
* @param data Entity data from the file
2199
* @param attrib Attributes
2201
void DL_Dxf::writeVertex(DL_WriterA& dw,
2202
const DL_VertexData& data) {
2205
if (version==VER_2000) {
2206
dw.dxfReal(10, data.x);
2207
dw.dxfReal(20, data.y);
2208
if (fabs(data.bulge)>1.0e-10) {
2209
dw.dxfReal(42, data.bulge);
2212
dw.entity("VERTEX");
2213
//dw.entityAttributes(attrib);
2214
dw.dxfString(8, polylineLayer);
2215
dw.coord(VERTEX_COORD_CODE, data.x, data.y);
2216
if (fabs(data.bulge)>1.0e-10) {
2217
dw.dxfReal(42, data.bulge);
2225
* Writes the polyline end. Only needed for DXF R12.
2227
void DL_Dxf::writePolylineEnd(DL_WriterA& dw) {
2228
if (version==VER_2000) {
2230
dw.entity("SEQEND");
2236
* Writes a spline entity to the file.
2238
* @param dw DXF writer
2239
* @param data Entity data from the file
2240
* @param attrib Attributes
2241
* @see writeControlPoint
2243
void DL_Dxf::writeSpline(DL_WriterA& dw,
2244
const DL_SplineData& data,
2245
const DL_Attributes& attrib) {
2247
dw.entity("SPLINE");
2248
dw.entityAttributes(attrib);
2249
if (version==VER_2000) {
2250
dw.dxfString(100, "AcDbEntity");
2251
dw.dxfString(100, "AcDbSpline");
2253
dw.dxfInt(70, data.flags);
2254
dw.dxfInt(71, data.degree);
2255
dw.dxfInt(72, data.nKnots); // number of knots
2256
dw.dxfInt(73, data.nControl); // number of control points
2257
dw.dxfInt(74, 0); // number of fit points
2263
* Writes a single control point of a spline to the file.
2265
* @param dw DXF writer
2266
* @param data Entity data from the file
2267
* @param attrib Attributes
2269
void DL_Dxf::writeControlPoint(DL_WriterA& dw,
2270
const DL_ControlPointData& data) {
2272
dw.dxfReal(10, data.x);
2273
dw.dxfReal(20, data.y);
2274
dw.dxfReal(30, data.z);
2280
* Writes a single knot of a spline to the file.
2282
* @param dw DXF writer
2283
* @param data Entity data from the file
2284
* @param attrib Attributes
2286
void DL_Dxf::writeKnot(DL_WriterA& dw,
2287
const DL_KnotData& data) {
2289
dw.dxfReal(40, data.k);
2295
* Writes a circle entity to the file.
2297
* @param dw DXF writer
2298
* @param data Entity data from the file
2299
* @param attrib Attributes
2301
void DL_Dxf::writeCircle(DL_WriterA& dw,
2302
const DL_CircleData& data,
2303
const DL_Attributes& attrib) {
2304
dw.entity("CIRCLE");
2305
if (version==VER_2000) {
2306
dw.dxfString(100, "AcDbEntity");
2307
dw.dxfString(100, "AcDbCircle");
2309
dw.entityAttributes(attrib);
2310
dw.coord(10, data.cx, data.cy);
2311
dw.dxfReal(40, data.radius);
2317
* Writes an arc entity to the file.
2319
* @param dw DXF writer
2320
* @param data Entity data from the file
2321
* @param attrib Attributes
2323
void DL_Dxf::writeArc(DL_WriterA& dw,
2324
const DL_ArcData& data,
2325
const DL_Attributes& attrib) {
2327
if (version==VER_2000) {
2328
dw.dxfString(100, "AcDbEntity");
2330
dw.entityAttributes(attrib);
2331
if (version==VER_2000) {
2332
dw.dxfString(100, "AcDbCircle");
2334
dw.coord(10, data.cx, data.cy);
2335
dw.dxfReal(40, data.radius);
2336
if (version==VER_2000) {
2337
dw.dxfString(100, "AcDbArc");
2339
dw.dxfReal(50, data.angle1);
2340
dw.dxfReal(51, data.angle2);
2346
* Writes an ellipse entity to the file.
2348
* @param dw DXF writer
2349
* @param data Entity data from the file
2350
* @param attrib Attributes
2352
void DL_Dxf::writeEllipse(DL_WriterA& dw,
2353
const DL_EllipseData& data,
2354
const DL_Attributes& attrib) {
2356
if (version>VER_R12) {
2357
dw.entity("ELLIPSE");
2358
if (version==VER_2000) {
2359
dw.dxfString(100, "AcDbEntity");
2360
dw.dxfString(100, "AcDbEllipse");
2362
dw.entityAttributes(attrib);
2363
dw.coord(10, data.cx, data.cy);
2364
dw.coord(11, data.mx, data.my);
2365
dw.dxfReal(40, data.ratio);
2366
dw.dxfReal(41, data.angle1);
2367
dw.dxfReal(42, data.angle2);
2374
* Writes a solid entity to the file.
2376
* @param dw DXF writer
2377
* @param data Entity data from the file
2378
* @param attrib Attributes
2380
void DL_Dxf::writeSolid(DL_WriterA& dw,
2381
const DL_SolidData& data,
2382
const DL_Attributes& attrib) {
2384
if (version==VER_2000) {
2385
dw.dxfString(100, "AcDbEntity");
2386
dw.dxfString(100, "AcDbTrace");
2388
dw.entityAttributes(attrib);
2389
dw.coord(10, data.x[0], data.y[0], data.z[0]);
2390
dw.coord(11, data.x[1], data.y[1], data.z[1]);
2391
dw.coord(12, data.x[2], data.y[2], data.z[2]);
2392
dw.coord(13, data.x[3], data.y[3], data.z[3]);
2393
dw.dxfReal(39, data.thickness);
2399
* Writes a 3d face entity to the file.
2401
* @param dw DXF writer
2402
* @param data Entity data from the file
2403
* @param attrib Attributes
2405
void DL_Dxf::write3dFace(DL_WriterA& dw,
2406
const DL_3dFaceData& data,
2407
const DL_Attributes& attrib) {
2408
dw.entity("3DFACE");
2409
if (version==VER_2000) {
2410
dw.dxfString(100, "AcDbEntity");
2411
dw.dxfString(100, "AcDbFace");
2413
dw.entityAttributes(attrib);
2414
dw.coord(10, data.x[0], data.y[0], data.z[0]);
2415
dw.coord(11, data.x[1], data.y[1], data.z[1]);
2416
dw.coord(12, data.x[2], data.y[2], data.z[2]);
2417
dw.coord(13, data.x[3], data.y[3], data.z[3]);
2423
* Writes an insert to the file.
2425
* @param dw DXF writer
2426
* @param data Entity data from the file
2427
* @param attrib Attributes
2429
void DL_Dxf::writeInsert(DL_WriterA& dw,
2430
const DL_InsertData& data,
2431
const DL_Attributes& attrib) {
2433
if (data.name.empty()) {
2434
std::cerr << "DL_Dxf::writeInsert: "
2435
<< "Block name must not be empty\n";
2439
dw.entity("INSERT");
2440
if (version==VER_2000) {
2441
dw.dxfString(100, "AcDbEntity");
2442
dw.dxfString(100, "AcDbBlockReference");
2444
dw.entityAttributes(attrib);
2445
dw.dxfString(2, data.name);
2446
dw.dxfReal(10, data.ipx);
2447
dw.dxfReal(20, data.ipy);
2448
dw.dxfReal(30, 0.0);
2449
if (data.sx!=1.0 || data.sy!=1.0) {
2450
dw.dxfReal(41, data.sx);
2451
dw.dxfReal(42, data.sy);
2452
dw.dxfReal(43, 1.0);
2454
if (data.angle!=0.0) {
2455
dw.dxfReal(50, data.angle);
2457
if (data.cols!=1 || data.rows!=1) {
2458
dw.dxfInt(70, data.cols);
2459
dw.dxfInt(71, data.rows);
2461
if (data.colSp!=0.0 || data.rowSp!=0.0) {
2462
dw.dxfReal(44, data.colSp);
2463
dw.dxfReal(45, data.rowSp);
2471
* Writes a multi text entity to the file.
2473
* @param dw DXF writer
2474
* @param data Entity data from the file
2475
* @param attrib Attributes
2477
void DL_Dxf::writeMText(DL_WriterA& dw,
2478
const DL_MTextData& data,
2479
const DL_Attributes& attrib) {
2482
if (version==VER_2000) {
2483
dw.dxfString(100, "AcDbEntity");
2484
dw.dxfString(100, "AcDbMText");
2486
dw.entityAttributes(attrib);
2487
dw.dxfReal(10, data.ipx);
2488
dw.dxfReal(20, data.ipy);
2489
dw.dxfReal(30, 0.0);
2490
dw.dxfReal(40, data.height);
2491
dw.dxfReal(41, data.width);
2493
dw.dxfInt(71, data.attachmentPoint);
2494
dw.dxfInt(72, data.drawingDirection);
2496
// Creare text chunks of 250 characters each:
2497
int length = data.text.length();
2500
for (i=250; i<length; i+=250) {
2501
strncpy(chunk, &data.text.c_str()[i-250], 250);
2503
dw.dxfString(3, chunk);
2505
strncpy(chunk, &data.text.c_str()[i-250], 250);
2507
dw.dxfString(1, chunk);
2509
dw.dxfString(7, data.style);
2511
// since dxflib 2.0.2.1: degrees not rad (error in autodesk dxf doc)
2512
dw.dxfReal(50, data.angle/(2.0*M_PI)*360.0);
2514
dw.dxfInt(73, data.lineSpacingStyle);
2515
dw.dxfReal(44, data.lineSpacingFactor);
2521
* Writes a text entity to the file.
2523
* @param dw DXF writer
2524
* @param data Entity data from the file
2525
* @param attrib Attributes
2527
void DL_Dxf::writeText(DL_WriterA& dw,
2528
const DL_TextData& data,
2529
const DL_Attributes& attrib) {
2532
if (version==VER_2000) {
2533
dw.dxfString(100, "AcDbEntity");
2534
dw.dxfString(100, "AcDbText");
2536
dw.entityAttributes(attrib);
2537
dw.dxfReal(10, data.ipx);
2538
dw.dxfReal(20, data.ipy);
2539
dw.dxfReal(30, 0.0);
2540
dw.dxfReal(40, data.height);
2541
dw.dxfString(1, data.text);
2542
dw.dxfReal(50, data.angle/(2*M_PI)*360.0);
2543
dw.dxfReal(41, data.xScaleFactor);
2544
dw.dxfString(7, data.style);
2546
dw.dxfInt(71, data.textGenerationFlags);
2547
dw.dxfInt(72, data.hJustification);
2549
dw.dxfReal(11, data.apx);
2550
dw.dxfReal(21, data.apy);
2551
dw.dxfReal(31, 0.0);
2553
dw.dxfInt(73, data.vJustification);
2558
* Writes an aligned dimension entity to the file.
2560
* @param dw DXF writer
2561
* @param data Generic dimension data for from the file
2562
* @param data Specific aligned dimension data from the file
2563
* @param attrib Attributes
2565
void DL_Dxf::writeDimAligned(DL_WriterA& dw,
2566
const DL_DimensionData& data,
2567
const DL_DimAlignedData& edata,
2568
const DL_Attributes& attrib) {
2570
dw.entity("DIMENSION");
2572
if (version==VER_2000) {
2573
dw.dxfString(100, "AcDbEntity");
2575
dw.entityAttributes(attrib);
2576
if (version==VER_2000) {
2577
dw.dxfString(100, "AcDbDimension");
2580
dw.dxfReal(10, data.dpx);
2581
dw.dxfReal(20, data.dpy);
2582
dw.dxfReal(30, 0.0);
2584
dw.dxfReal(11, data.mpx);
2585
dw.dxfReal(21, data.mpy);
2586
dw.dxfReal(31, 0.0);
2589
if (version>VER_R12) {
2590
dw.dxfInt(71, data.attachmentPoint);
2591
dw.dxfInt(72, data.lineSpacingStyle); // opt
2592
dw.dxfReal(41, data.lineSpacingFactor); // opt
2595
dw.dxfReal(42, data.angle);
2597
dw.dxfString(1, data.text); // opt
2598
//dw.dxfString(3, data.style);
2599
dw.dxfString(3, "Standard");
2601
if (version==VER_2000) {
2602
dw.dxfString(100, "AcDbAlignedDimension");
2605
dw.dxfReal(13, edata.epx1);
2606
dw.dxfReal(23, edata.epy1);
2607
dw.dxfReal(33, 0.0);
2609
dw.dxfReal(14, edata.epx2);
2610
dw.dxfReal(24, edata.epy2);
2611
dw.dxfReal(34, 0.0);
2617
* Writes a linear dimension entity to the file.
2619
* @param dw DXF writer
2620
* @param data Generic dimension data for from the file
2621
* @param data Specific linear dimension data from the file
2622
* @param attrib Attributes
2624
void DL_Dxf::writeDimLinear(DL_WriterA& dw,
2625
const DL_DimensionData& data,
2626
const DL_DimLinearData& edata,
2627
const DL_Attributes& attrib) {
2629
dw.entity("DIMENSION");
2631
if (version==VER_2000) {
2632
dw.dxfString(100, "AcDbEntity");
2634
dw.entityAttributes(attrib);
2635
if (version==VER_2000) {
2636
dw.dxfString(100, "AcDbDimension");
2639
dw.dxfReal(10, data.dpx);
2640
dw.dxfReal(20, data.dpy);
2641
dw.dxfReal(30, 0.0);
2643
dw.dxfReal(11, data.mpx);
2644
dw.dxfReal(21, data.mpy);
2645
dw.dxfReal(31, 0.0);
2648
if (version>VER_R12) {
2649
dw.dxfInt(71, data.attachmentPoint);
2650
dw.dxfInt(72, data.lineSpacingStyle); // opt
2651
dw.dxfReal(41, data.lineSpacingFactor); // opt
2654
dw.dxfReal(42, data.angle);
2656
dw.dxfString(1, data.text); // opt
2657
//dw.dxfString(3, data.style);
2658
dw.dxfString(3, "Standard");
2660
if (version==VER_2000) {
2661
dw.dxfString(100, "AcDbAlignedDimension");
2664
dw.dxfReal(13, edata.dpx1);
2665
dw.dxfReal(23, edata.dpy1);
2666
dw.dxfReal(33, 0.0);
2668
dw.dxfReal(14, edata.dpx2);
2669
dw.dxfReal(24, edata.dpy2);
2670
dw.dxfReal(34, 0.0);
2672
dw.dxfReal(50, edata.angle/(2.0*M_PI)*360.0);
2674
if (version==VER_2000) {
2675
dw.dxfString(100, "AcDbRotatedDimension");
2677
dw.dxfString(1001, "ACAD");
2678
dw.dxfString(1000, "DSTYLE");
2679
dw.dxfString(1002, "{");
2680
dw.dxfInt(1070, 340);
2681
dw.dxfInt(1005, 11);
2682
dw.dxfString(1002, "}");
2690
* Writes a radial dimension entity to the file.
2692
* @param dw DXF writer
2693
* @param data Generic dimension data for from the file
2694
* @param data Specific radial dimension data from the file
2695
* @param attrib Attributes
2697
void DL_Dxf::writeDimRadial(DL_WriterA& dw,
2698
const DL_DimensionData& data,
2699
const DL_DimRadialData& edata,
2700
const DL_Attributes& attrib) {
2702
dw.entity("DIMENSION");
2704
if (version==VER_2000) {
2705
dw.dxfString(100, "AcDbEntity");
2707
dw.entityAttributes(attrib);
2708
if (version==VER_2000) {
2709
dw.dxfString(100, "AcDbDimension");
2712
dw.dxfReal(10, data.dpx);
2713
dw.dxfReal(20, data.dpy);
2714
dw.dxfReal(30, 0.0);
2716
dw.dxfReal(11, data.mpx);
2717
dw.dxfReal(21, data.mpy);
2718
dw.dxfReal(31, 0.0);
2721
if (version>VER_R12) {
2722
dw.dxfInt(71, data.attachmentPoint);
2723
dw.dxfInt(72, data.lineSpacingStyle); // opt
2724
dw.dxfReal(41, data.lineSpacingFactor); // opt
2727
dw.dxfReal(42, data.angle);
2729
dw.dxfString(1, data.text); // opt
2730
//dw.dxfString(3, data.style);
2731
dw.dxfString(3, "Standard");
2733
if (version==VER_2000) {
2734
dw.dxfString(100, "AcDbRadialDimension");
2737
dw.dxfReal(15, edata.dpx);
2738
dw.dxfReal(25, edata.dpy);
2739
dw.dxfReal(35, 0.0);
2741
dw.dxfReal(40, edata.leader);
2747
* Writes a diametric dimension entity to the file.
2749
* @param dw DXF writer
2750
* @param data Generic dimension data for from the file
2751
* @param data Specific diametric dimension data from the file
2752
* @param attrib Attributes
2754
void DL_Dxf::writeDimDiametric(DL_WriterA& dw,
2755
const DL_DimensionData& data,
2756
const DL_DimDiametricData& edata,
2757
const DL_Attributes& attrib) {
2759
dw.entity("DIMENSION");
2761
if (version==VER_2000) {
2762
dw.dxfString(100, "AcDbEntity");
2764
dw.entityAttributes(attrib);
2765
if (version==VER_2000) {
2766
dw.dxfString(100, "AcDbDimension");
2769
dw.dxfReal(10, data.dpx);
2770
dw.dxfReal(20, data.dpy);
2771
dw.dxfReal(30, 0.0);
2773
dw.dxfReal(11, data.mpx);
2774
dw.dxfReal(21, data.mpy);
2775
dw.dxfReal(31, 0.0);
2778
if (version>VER_R12) {
2779
dw.dxfInt(71, data.attachmentPoint);
2780
dw.dxfInt(72, data.lineSpacingStyle); // opt
2781
dw.dxfReal(41, data.lineSpacingFactor); // opt
2784
dw.dxfReal(42, data.angle);
2786
dw.dxfString(1, data.text); // opt
2787
//dw.dxfString(3, data.style);
2788
dw.dxfString(3, "Standard");
2790
if (version==VER_2000) {
2791
dw.dxfString(100, "AcDbDiametricDimension");
2794
dw.dxfReal(15, edata.dpx);
2795
dw.dxfReal(25, edata.dpy);
2796
dw.dxfReal(35, 0.0);
2798
dw.dxfReal(40, edata.leader);
2804
* Writes an angular dimension entity to the file.
2806
* @param dw DXF writer
2807
* @param data Generic dimension data for from the file
2808
* @param data Specific angular dimension data from the file
2809
* @param attrib Attributes
2811
void DL_Dxf::writeDimAngular(DL_WriterA& dw,
2812
const DL_DimensionData& data,
2813
const DL_DimAngularData& edata,
2814
const DL_Attributes& attrib) {
2816
dw.entity("DIMENSION");
2818
if (version==VER_2000) {
2819
dw.dxfString(100, "AcDbEntity");
2821
dw.entityAttributes(attrib);
2822
if (version==VER_2000) {
2823
dw.dxfString(100, "AcDbDimension");
2826
dw.dxfReal(10, data.dpx);
2827
dw.dxfReal(20, data.dpy);
2828
dw.dxfReal(30, 0.0);
2830
dw.dxfReal(11, data.mpx);
2831
dw.dxfReal(21, data.mpy);
2832
dw.dxfReal(31, 0.0);
2835
if (version>VER_R12) {
2836
dw.dxfInt(71, data.attachmentPoint);
2837
dw.dxfInt(72, data.lineSpacingStyle); // opt
2838
dw.dxfReal(41, data.lineSpacingFactor); // opt
2841
dw.dxfReal(42, data.angle);
2843
dw.dxfString(1, data.text); // opt
2844
//dw.dxfString(3, data.style);
2845
dw.dxfString(3, "Standard");
2847
if (version==VER_2000) {
2848
dw.dxfString(100, "AcDb2LineAngularDimension");
2851
dw.dxfReal(13, edata.dpx1);
2852
dw.dxfReal(23, edata.dpy1);
2853
dw.dxfReal(33, 0.0);
2855
dw.dxfReal(14, edata.dpx2);
2856
dw.dxfReal(24, edata.dpy2);
2857
dw.dxfReal(34, 0.0);
2859
dw.dxfReal(15, edata.dpx3);
2860
dw.dxfReal(25, edata.dpy3);
2861
dw.dxfReal(35, 0.0);
2863
dw.dxfReal(16, edata.dpx4);
2864
dw.dxfReal(26, edata.dpy4);
2865
dw.dxfReal(36, 0.0);
2871
* Writes an angular dimension entity (3 points version) to the file.
2873
* @param dw DXF writer
2874
* @param data Generic dimension data for from the file
2875
* @param data Specific angular dimension data from the file
2876
* @param attrib Attributes
2878
void DL_Dxf::writeDimAngular3P(DL_WriterA& dw,
2879
const DL_DimensionData& data,
2880
const DL_DimAngular3PData& edata,
2881
const DL_Attributes& attrib) {
2883
dw.entity("DIMENSION");
2885
if (version==VER_2000) {
2886
dw.dxfString(100, "AcDbEntity");
2888
dw.entityAttributes(attrib);
2889
if (version==VER_2000) {
2890
dw.dxfString(100, "AcDbDimension");
2893
dw.dxfReal(10, data.dpx);
2894
dw.dxfReal(20, data.dpy);
2895
dw.dxfReal(30, 0.0);
2897
dw.dxfReal(11, data.mpx);
2898
dw.dxfReal(21, data.mpy);
2899
dw.dxfReal(31, 0.0);
2902
if (version>VER_R12) {
2903
dw.dxfInt(71, data.attachmentPoint);
2904
dw.dxfInt(72, data.lineSpacingStyle); // opt
2905
dw.dxfReal(41, data.lineSpacingFactor); // opt
2908
dw.dxfReal(42, data.angle);
2910
dw.dxfString(1, data.text); // opt
2911
//dw.dxfString(3, data.style);
2912
dw.dxfString(3, "Standard");
2914
if (version==VER_2000) {
2915
dw.dxfString(100, "AcDb3PointAngularDimension");
2918
dw.dxfReal(13, edata.dpx1);
2919
dw.dxfReal(23, edata.dpy1);
2920
dw.dxfReal(33, 0.0);
2922
dw.dxfReal(14, edata.dpx2);
2923
dw.dxfReal(24, edata.dpy2);
2924
dw.dxfReal(34, 0.0);
2926
dw.dxfReal(15, edata.dpx3);
2927
dw.dxfReal(25, edata.dpy3);
2928
dw.dxfReal(35, 0.0);
2935
* Writes an ordinate dimension entity to the file.
2937
* @param dw DXF writer
2938
* @param data Generic dimension data for from the file
2939
* @param data Specific ordinate dimension data from the file
2940
* @param attrib Attributes
2942
void DL_Dxf::writeDimOrdinate(DL_WriterA& dw,
2943
const DL_DimensionData& data,
2944
const DL_DimOrdinateData& edata,
2945
const DL_Attributes& attrib) {
2947
dw.entity("DIMENSION");
2949
if (version==VER_2000) {
2950
dw.dxfString(100, "AcDbEntity");
2952
dw.entityAttributes(attrib);
2953
if (version==VER_2000) {
2954
dw.dxfString(100, "AcDbDimension");
2957
dw.dxfReal(10, data.dpx);
2958
dw.dxfReal(20, data.dpy);
2959
dw.dxfReal(30, 0.0);
2961
dw.dxfReal(11, data.mpx);
2962
dw.dxfReal(21, data.mpy);
2963
dw.dxfReal(31, 0.0);
2970
dw.dxfInt(70, type);
2971
if (version>VER_R12) {
2972
dw.dxfInt(71, data.attachmentPoint);
2973
dw.dxfInt(72, data.lineSpacingStyle); // opt
2974
dw.dxfReal(41, data.lineSpacingFactor); // opt
2977
dw.dxfString(1, data.text); // opt
2978
//dw.dxfString(3, data.style);
2979
dw.dxfString(3, "Standard");
2981
if (version==VER_2000) {
2982
dw.dxfString(100, "AcDbOrdinateDimension");
2985
dw.dxfReal(13, edata.dpx1);
2986
dw.dxfReal(23, edata.dpy1);
2987
dw.dxfReal(33, 0.0);
2989
dw.dxfReal(14, edata.dpx2);
2990
dw.dxfReal(24, edata.dpy2);
2991
dw.dxfReal(34, 0.0);
2997
* Writes a leader entity to the file.
2999
* @param dw DXF writer
3000
* @param data Entity data from the file
3001
* @param attrib Attributes
3004
void DL_Dxf::writeLeader(DL_WriterA& dw,
3005
const DL_LeaderData& data,
3006
const DL_Attributes& attrib) {
3007
if (version>VER_R12) {
3008
dw.entity("LEADER");
3009
dw.entityAttributes(attrib);
3010
if (version==VER_2000) {
3011
dw.dxfString(100, "AcDbEntity");
3012
dw.dxfString(100, "AcDbLeader");
3014
dw.dxfString(3, "Standard");
3015
dw.dxfInt(71, data.arrowHeadFlag);
3016
dw.dxfInt(72, data.leaderPathType);
3017
dw.dxfInt(73, data.leaderCreationFlag);
3018
dw.dxfInt(74, data.hooklineDirectionFlag);
3019
dw.dxfInt(75, data.hooklineFlag);
3020
dw.dxfReal(40, data.textAnnotationHeight);
3021
dw.dxfReal(41, data.textAnnotationWidth);
3022
dw.dxfInt(76, data.number);
3029
* Writes a single vertex of a leader to the file.
3031
* @param dw DXF writer
3032
* @param data Entity data
3034
void DL_Dxf::writeLeaderVertex(DL_WriterA& dw,
3035
const DL_LeaderVertexData& data) {
3036
if (version>VER_R12) {
3037
dw.dxfReal(10, data.x);
3038
dw.dxfReal(20, data.y);
3045
* Writes the beginning of a hatch entity to the file.
3046
* This must be followed by one or more writeHatchLoop()
3047
* calls and a writeHatch2() call.
3049
* @param dw DXF writer
3050
* @param data Entity data.
3051
* @param attrib Attributes
3053
void DL_Dxf::writeHatch1(DL_WriterA& dw,
3054
const DL_HatchData& data,
3055
const DL_Attributes& attrib) {
3058
dw.entityAttributes(attrib);
3059
if (version==VER_2000) {
3060
dw.dxfString(100, "AcDbEntity");
3061
dw.dxfString(100, "AcDbHatch");
3063
dw.dxfReal(10, 0.0); // elevation
3064
dw.dxfReal(20, 0.0);
3065
dw.dxfReal(30, 0.0);
3066
dw.dxfReal(210, 0.0); // extrusion dir.
3067
dw.dxfReal(220, 0.0);
3068
dw.dxfReal(230, 1.0);
3069
if (data.solid==false) {
3070
dw.dxfString(2, data.pattern);
3072
dw.dxfString(2, "SOLID");
3074
dw.dxfInt(70, (int)data.solid);
3075
dw.dxfInt(71, 0); // associative
3076
dw.dxfInt(91, data.numLoops);
3082
* Writes the end of a hatch entity to the file.
3084
* @param dw DXF writer
3085
* @param data Entity data.
3086
* @param attrib Attributes
3088
void DL_Dxf::writeHatch2(DL_WriterA& dw,
3089
const DL_HatchData& data,
3090
const DL_Attributes& /*attrib*/) {
3092
dw.dxfInt(75, 0); // odd parity
3093
dw.dxfInt(76, 1); // pattern type
3094
if (data.solid==false) {
3095
dw.dxfReal(52, data.angle);
3096
dw.dxfReal(41, data.scale);
3097
dw.dxfInt(77, 0); // not double
3100
dw.dxfReal(53, 45.0);
3101
dw.dxfReal(43, 0.0);
3102
dw.dxfReal(44, 0.0);
3103
dw.dxfReal(45, -0.0883883476483184);
3104
dw.dxfReal(46, 0.0883883476483185);
3113
* Writes the beginning of a hatch loop to the file. This
3114
* must happen after writing the beginning of a hatch entity.
3116
* @param dw DXF writer
3117
* @param data Entity data.
3118
* @param attrib Attributes
3120
void DL_Dxf::writeHatchLoop1(DL_WriterA& dw,
3121
const DL_HatchLoopData& data) {
3124
dw.dxfInt(93, data.numEdges);
3131
* Writes the end of a hatch loop to the file.
3133
* @param dw DXF writer
3134
* @param data Entity data.
3135
* @param attrib Attributes
3137
void DL_Dxf::writeHatchLoop2(DL_WriterA& dw,
3138
const DL_HatchLoopData& /*data*/) {
3145
* Writes the beginning of a hatch entity to the file.
3147
* @param dw DXF writer
3148
* @param data Entity data.
3149
* @param attrib Attributes
3151
void DL_Dxf::writeHatchEdge(DL_WriterA& dw,
3152
const DL_HatchEdgeData& data) {
3154
dw.dxfInt(72, data.type);
3156
switch (data.type) {
3158
dw.dxfReal(10, data.x1);
3159
dw.dxfReal(20, data.y1);
3160
dw.dxfReal(11, data.x2);
3161
dw.dxfReal(21, data.y2);
3164
dw.dxfReal(10, data.cx);
3165
dw.dxfReal(20, data.cy);
3166
dw.dxfReal(40, data.radius);
3167
dw.dxfReal(50, data.angle1/(2*M_PI)*360.0);
3168
dw.dxfReal(51, data.angle2/(2*M_PI)*360.0);
3169
dw.dxfInt(73, (int)(data.ccw));
3179
* Writes an image entity.
3181
* @return IMAGEDEF handle. Needed for the IMAGEDEF counterpart.
3183
int DL_Dxf::writeImage(DL_WriterA& dw,
3184
const DL_ImageData& data,
3185
const DL_Attributes& attrib) {
3187
/*if (data.file.empty()) {
3188
std::cerr << "DL_Dxf::writeImage: "
3189
<< "Image file must not be empty\n";
3195
dw.entityAttributes(attrib);
3196
if (version==VER_2000) {
3197
dw.dxfString(100, "AcDbEntity");
3198
dw.dxfString(100, "AcDbRasterImage");
3202
dw.dxfReal(10, data.ipx);
3203
dw.dxfReal(20, data.ipy);
3204
dw.dxfReal(30, 0.0);
3206
// vector along bottom side (1 pixel long)
3207
dw.dxfReal(11, data.ux);
3208
dw.dxfReal(21, data.uy);
3209
dw.dxfReal(31, 0.0);
3211
// vector along left side (1 pixel long)
3212
dw.dxfReal(12, data.vx);
3213
dw.dxfReal(22, data.vy);
3214
dw.dxfReal(32, 0.0);
3216
// image size in pixel
3217
dw.dxfReal(13, data.width);
3218
dw.dxfReal(23, data.height);
3220
// handle of IMAGEDEF object
3221
int handle = dw.incHandle();
3222
dw.dxfHex(340, handle);
3230
// brightness, contrast, fade
3231
dw.dxfInt(281, data.brightness);
3232
dw.dxfInt(282, data.contrast);
3233
dw.dxfInt(283, data.fade);
3241
* Writes an image definiition entity.
3243
void DL_Dxf::writeImageDef(DL_WriterA& dw,
3245
const DL_ImageData& data) {
3247
/*if (data.file.empty()) {
3248
std::cerr << "DL_Dxf::writeImage: "
3249
<< "Image file must not be empty\n";
3253
dw.dxfString(0, "IMAGEDEF");
3254
if (version==VER_2000) {
3255
dw.dxfHex(5, handle);
3258
if (version==VER_2000) {
3259
dw.dxfString(100, "AcDbRasterImageDef");
3263
dw.dxfString(1, data.ref);
3265
// image size in pixel
3266
dw.dxfReal(10, data.width);
3267
dw.dxfReal(20, data.height);
3269
dw.dxfReal(11, 1.0);
3270
dw.dxfReal(21, 1.0);
3280
* Writes a layer to the file. Layers are stored in the
3281
* tables section of a DXF file.
3283
* @param dw DXF writer
3284
* @param data Entity data from the file
3285
* @param attrib Attributes
3287
void DL_Dxf::writeLayer(DL_WriterA& dw,
3288
const DL_LayerData& data,
3289
const DL_Attributes& attrib) {
3291
if (data.name.empty()) {
3292
std::cerr << "DL_Dxf::writeLayer: "
3293
<< "Layer name must not be empty\n";
3297
int color = attrib.getColor();
3299
std::cerr << "Layer color cannot be " << color << ". Changed to 7.\n";
3303
if (data.name == "0") {
3304
dw.tableLayerEntry(0x10);
3306
dw.tableLayerEntry();
3309
dw.dxfString(2, data.name);
3310
dw.dxfInt(70, data.flags);
3311
dw.dxfInt(62, color);
3313
dw.dxfString(6, (attrib.getLineType().length()==0 ?
3314
string("CONTINUOUS") : attrib.getLineType()));
3316
if (version>=VER_2000) {
3317
// layer defpoints cannot be plotted
3318
std::string lstr = data.name;
3319
std::transform(lstr.begin(), lstr.end(), lstr.begin(), tolower);
3320
if (lstr=="defpoints") {
3324
if (version>=VER_2000 && attrib.getWidth()!=-1) {
3325
dw.dxfInt(370, attrib.getWidth());
3327
if (version>=VER_2000) {
3328
dw.dxfHex(390, 0xF);
3335
* Writes a line type to the file. Line types are stored in the
3336
* tables section of a DXF file.
3338
void DL_Dxf::writeLineType(DL_WriterA& dw,
3339
const DL_LineTypeData& data) {
3340
//const char* description,
3342
//double patternLength) {
3344
if (data.name.empty()) {
3345
std::cerr << "DL_Dxf::writeLineType: "
3346
<< "Line type name must not be empty\n";
3350
// ignore BYLAYER, BYBLOCK for R12
3351
if (version<VER_2000) {
3352
if (!strcasecmp(data.name.c_str(), "BYBLOCK") ||
3353
!strcasecmp(data.name.c_str(), "BYLAYER")) {
3358
// write id (not for R12)
3359
if (!strcasecmp(data.name.c_str(), "BYBLOCK")) {
3360
dw.tableLineTypeEntry(0x14);
3361
} else if (!strcasecmp(data.name.c_str(), "BYLAYER")) {
3362
dw.tableLineTypeEntry(0x15);
3363
} else if (!strcasecmp(data.name.c_str(), "CONTINUOUS")) {
3364
dw.tableLineTypeEntry(0x16);
3366
dw.tableLineTypeEntry();
3369
dw.dxfString(2, data.name);
3370
//if (version>=VER_2000) {
3371
dw.dxfInt(70, data.flags);
3374
if (!strcasecmp(data.name.c_str(), "BYBLOCK")) {
3375
dw.dxfString(3, "");
3378
dw.dxfReal(40, 0.0);
3379
} else if (!strcasecmp(data.name.c_str(), "BYLAYER")) {
3380
dw.dxfString(3, "");
3383
dw.dxfReal(40, 0.0);
3384
} else if (!strcasecmp(data.name.c_str(), "CONTINUOUS")) {
3385
dw.dxfString(3, "Solid line");
3388
dw.dxfReal(40, 0.0);
3389
} else if (!strcasecmp(data.name.c_str(), "ACAD_ISO02W100")) {
3390
dw.dxfString(3, "ISO Dashed __ __ __ __ __ __ __ __ __ __ _");
3393
dw.dxfReal(40, 15.0);
3394
dw.dxfReal(49, 12.0);
3395
if (version>=VER_R13)
3397
dw.dxfReal(49, -3.0);
3398
if (version>=VER_R13)
3400
} else if (!strcasecmp(data.name.c_str(), "ACAD_ISO03W100")) {
3401
dw.dxfString(3, "ISO Dashed with Distance __ __ __ _");
3404
dw.dxfReal(40, 30.0);
3405
dw.dxfReal(49, 12.0);
3406
if (version>=VER_R13)
3408
dw.dxfReal(49, -18.0);
3409
if (version>=VER_R13)
3411
} else if (!strcasecmp(data.name.c_str(), "ACAD_ISO04W100")) {
3412
dw.dxfString(3, "ISO Long Dashed Dotted ____ . ____ . __");
3415
dw.dxfReal(40, 30.0);
3416
dw.dxfReal(49, 24.0);
3417
if (version>=VER_R13)
3419
dw.dxfReal(49, -3.0);
3420
if (version>=VER_R13)
3422
dw.dxfReal(49, 0.0);
3423
if (version>=VER_R13)
3425
dw.dxfReal(49, -3.0);
3426
if (version>=VER_R13)
3428
} else if (!strcasecmp(data.name.c_str(), "ACAD_ISO05W100")) {
3429
dw.dxfString(3, "ISO Long Dashed Double Dotted ____ .. __");
3432
dw.dxfReal(40, 33.0);
3433
dw.dxfReal(49, 24.0);
3434
if (version>=VER_R13)
3436
dw.dxfReal(49, -3.0);
3437
if (version>=VER_R13)
3439
dw.dxfReal(49, 0.0);
3440
if (version>=VER_R13)
3442
dw.dxfReal(49, -3.0);
3443
if (version>=VER_R13)
3445
dw.dxfReal(49, 0.0);
3446
if (version>=VER_R13)
3448
dw.dxfReal(49, -3.0);
3449
if (version>=VER_R13)
3451
} else if (!strcasecmp(data.name.c_str(), "BORDER")) {
3452
dw.dxfString(3, "Border __ __ . __ __ . __ __ . __ __ . __ __ .");
3455
dw.dxfReal(40, 44.45);
3456
dw.dxfReal(49, 12.7);
3457
if (version>=VER_R13)
3459
dw.dxfReal(49, -6.35);
3460
if (version>=VER_R13)
3462
dw.dxfReal(49, 12.7);
3463
if (version>=VER_R13)
3465
dw.dxfReal(49, -6.35);
3466
if (version>=VER_R13)
3468
dw.dxfReal(49, 0.0);
3469
if (version>=VER_R13)
3471
dw.dxfReal(49, -6.35);
3472
if (version>=VER_R13)
3474
} else if (!strcasecmp(data.name.c_str(), "BORDER2")) {
3475
dw.dxfString(3, "Border (.5x) __.__.__.__.__.__.__.__.__.__.__.");
3478
dw.dxfReal(40, 22.225);
3479
dw.dxfReal(49, 6.35);
3480
if (version>=VER_R13)
3482
dw.dxfReal(49, -3.175);
3483
if (version>=VER_R13)
3485
dw.dxfReal(49, 6.35);
3486
if (version>=VER_R13)
3488
dw.dxfReal(49, -3.175);
3489
if (version>=VER_R13)
3491
dw.dxfReal(49, 0.0);
3492
if (version>=VER_R13)
3494
dw.dxfReal(49, -3.175);
3495
if (version>=VER_R13)
3497
} else if (!strcasecmp(data.name.c_str(), "BORDERX2")) {
3498
dw.dxfString(3, "Border (2x) ____ ____ . ____ ____ . ___");
3501
dw.dxfReal(40, 88.9);
3502
dw.dxfReal(49, 25.4);
3503
if (version>=VER_R13)
3505
dw.dxfReal(49, -12.7);
3506
if (version>=VER_R13)
3508
dw.dxfReal(49, 25.4);
3509
if (version>=VER_R13)
3511
dw.dxfReal(49, -12.7);
3512
if (version>=VER_R13)
3514
dw.dxfReal(49, 0.0);
3515
if (version>=VER_R13)
3517
dw.dxfReal(49, -12.7);
3518
if (version>=VER_R13)
3520
} else if (!strcasecmp(data.name.c_str(), "CENTER")) {
3521
dw.dxfString(3, "Center ____ _ ____ _ ____ _ ____ _ ____ _ ____");
3524
dw.dxfReal(40, 50.8);
3525
dw.dxfReal(49, 31.75);
3526
if (version>=VER_R13)
3528
dw.dxfReal(49, -6.35);
3529
if (version>=VER_R13)
3531
dw.dxfReal(49, 6.35);
3532
if (version>=VER_R13)
3534
dw.dxfReal(49, -6.35);
3535
if (version>=VER_R13)
3537
} else if (!strcasecmp(data.name.c_str(), "CENTER2")) {
3538
dw.dxfString(3, "Center (.5x) ___ _ ___ _ ___ _ ___ _ ___ _ ___");
3541
dw.dxfReal(40, 28.575);
3542
dw.dxfReal(49, 19.05);
3543
if (version>=VER_R13)
3545
dw.dxfReal(49, -3.175);
3546
if (version>=VER_R13)
3548
dw.dxfReal(49, 3.175);
3549
if (version>=VER_R13)
3551
dw.dxfReal(49, -3.175);
3552
if (version>=VER_R13)
3554
} else if (!strcasecmp(data.name.c_str(), "CENTERX2")) {
3555
dw.dxfString(3, "Center (2x) ________ __ ________ __ _____");
3558
dw.dxfReal(40, 101.6);
3559
dw.dxfReal(49, 63.5);
3560
if (version>=VER_R13)
3562
dw.dxfReal(49, -12.7);
3563
if (version>=VER_R13)
3565
dw.dxfReal(49, 12.7);
3566
if (version>=VER_R13)
3568
dw.dxfReal(49, -12.7);
3569
if (version>=VER_R13)
3571
} else if (!strcasecmp(data.name.c_str(), "DASHDOT")) {
3572
dw.dxfString(3, "Dash dot __ . __ . __ . __ . __ . __ . __ . __");
3575
dw.dxfReal(40, 25.4);
3576
dw.dxfReal(49, 12.7);
3577
if (version>=VER_R13)
3579
dw.dxfReal(49, -6.35);
3580
if (version>=VER_R13)
3582
dw.dxfReal(49, 0.0);
3583
if (version>=VER_R13)
3585
dw.dxfReal(49, -6.35);
3586
if (version>=VER_R13)
3588
} else if (!strcasecmp(data.name.c_str(), "DASHDOT2")) {
3589
dw.dxfString(3, "Dash dot (.5x) _._._._._._._._._._._._._._._.");
3592
dw.dxfReal(40, 12.7);
3593
dw.dxfReal(49, 6.35);
3594
if (version>=VER_R13)
3596
dw.dxfReal(49, -3.175);
3597
if (version>=VER_R13)
3599
dw.dxfReal(49, 0.0);
3600
if (version>=VER_R13)
3602
dw.dxfReal(49, -3.175);
3603
if (version>=VER_R13)
3605
} else if (!strcasecmp(data.name.c_str(), "DASHDOTX2")) {
3606
dw.dxfString(3, "Dash dot (2x) ____ . ____ . ____ . ___");
3609
dw.dxfReal(40, 50.8);
3610
dw.dxfReal(49, 25.4);
3611
if (version>=VER_R13)
3613
dw.dxfReal(49, -12.7);
3614
if (version>=VER_R13)
3616
dw.dxfReal(49, 0.0);
3617
if (version>=VER_R13)
3619
dw.dxfReal(49, -12.7);
3620
if (version>=VER_R13)
3622
} else if (!strcasecmp(data.name.c_str(), "DASHED")) {
3623
dw.dxfString(3, "Dashed __ __ __ __ __ __ __ __ __ __ __ __ __ _");
3626
dw.dxfReal(40, 19.05);
3627
dw.dxfReal(49, 12.7);
3628
if (version>=VER_R13)
3630
dw.dxfReal(49, -6.35);
3631
if (version>=VER_R13)
3633
} else if (!strcasecmp(data.name.c_str(), "DASHED2")) {
3634
dw.dxfString(3, "Dashed (.5x) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _");
3637
dw.dxfReal(40, 9.525);
3638
dw.dxfReal(49, 6.35);
3639
if (version>=VER_R13)
3641
dw.dxfReal(49, -3.175);
3642
if (version>=VER_R13)
3644
} else if (!strcasecmp(data.name.c_str(), "DASHEDX2")) {
3645
dw.dxfString(3, "Dashed (2x) ____ ____ ____ ____ ____ ___");
3648
dw.dxfReal(40, 38.1);
3649
dw.dxfReal(49, 25.4);
3650
if (version>=VER_R13)
3652
dw.dxfReal(49, -12.7);
3653
if (version>=VER_R13)
3655
} else if (!strcasecmp(data.name.c_str(), "DIVIDE")) {
3656
dw.dxfString(3, "Divide ____ . . ____ . . ____ . . ____ . . ____");
3659
dw.dxfReal(40, 31.75);
3660
dw.dxfReal(49, 12.7);
3661
if (version>=VER_R13)
3663
dw.dxfReal(49, -6.35);
3664
if (version>=VER_R13)
3666
dw.dxfReal(49, 0.0);
3667
if (version>=VER_R13)
3669
dw.dxfReal(49, -6.35);
3670
if (version>=VER_R13)
3672
dw.dxfReal(49, 0.0);
3673
if (version>=VER_R13)
3675
dw.dxfReal(49, -6.35);
3676
if (version>=VER_R13)
3678
} else if (!strcasecmp(data.name.c_str(), "DIVIDE2")) {
3679
dw.dxfString(3, "Divide (.5x) __..__..__..__..__..__..__..__.._");
3682
dw.dxfReal(40, 15.875);
3683
dw.dxfReal(49, 6.35);
3684
if (version>=VER_R13)
3686
dw.dxfReal(49, -3.175);
3687
if (version>=VER_R13)
3689
dw.dxfReal(49, 0.0);
3690
if (version>=VER_R13)
3692
dw.dxfReal(49, -3.175);
3693
if (version>=VER_R13)
3695
dw.dxfReal(49, 0.0);
3696
if (version>=VER_R13)
3698
dw.dxfReal(49, -3.175);
3699
if (version>=VER_R13)
3701
} else if (!strcasecmp(data.name.c_str(), "DIVIDEX2")) {
3702
dw.dxfString(3, "Divide (2x) ________ . . ________ . . _");
3705
dw.dxfReal(40, 63.5);
3706
dw.dxfReal(49, 25.4);
3707
if (version>=VER_R13)
3709
dw.dxfReal(49, -12.7);
3710
if (version>=VER_R13)
3712
dw.dxfReal(49, 0.0);
3713
if (version>=VER_R13)
3715
dw.dxfReal(49, -12.7);
3716
if (version>=VER_R13)
3718
dw.dxfReal(49, 0.0);
3719
if (version>=VER_R13)
3721
dw.dxfReal(49, -12.7);
3722
if (version>=VER_R13)
3724
} else if (!strcasecmp(data.name.c_str(), "DOT")) {
3725
dw.dxfString(3, "Dot . . . . . . . . . . . . . . . . . . . . . .");
3728
dw.dxfReal(40, 6.35);
3729
dw.dxfReal(49, 0.0);
3730
if (version>=VER_R13)
3732
dw.dxfReal(49, -6.35);
3733
if (version>=VER_R13)
3735
} else if (!strcasecmp(data.name.c_str(), "DOT2")) {
3736
dw.dxfString(3, "Dot (.5x) .....................................");
3739
dw.dxfReal(40, 3.175);
3740
dw.dxfReal(49, 0.0);
3741
if (version>=VER_R13)
3743
dw.dxfReal(49, -3.175);
3744
if (version>=VER_R13)
3746
} else if (!strcasecmp(data.name.c_str(), "DOTX2")) {
3747
dw.dxfString(3, "Dot (2x) . . . . . . . . . . . . .");
3750
dw.dxfReal(40, 12.7);
3751
dw.dxfReal(49, 0.0);
3752
if (version>=VER_R13)
3754
dw.dxfReal(49, -12.7);
3755
if (version>=VER_R13)
3758
std::cerr << "dxflib warning: DL_Dxf::writeLineType: Unknown Line Type\n";
3765
* Writes the APPID section to the DXF file.
3767
* @param name Application name
3769
void DL_Dxf::writeAppid(DL_WriterA& dw, const string& name) {
3771
std::cerr << "DL_Dxf::writeAppid: "
3772
<< "Application name must not be empty\n";
3776
if (!strcasecmp(name.c_str(), "ACAD")) {
3777
dw.tableAppidEntry(0x12);
3779
dw.tableAppidEntry();
3781
dw.dxfString(2, name);
3788
* Writes a block's definition (no entities) to the DXF file.
3790
void DL_Dxf::writeBlock(DL_WriterA& dw, const DL_BlockData& data) {
3791
if (data.name.empty()) {
3792
std::cerr << "DL_Dxf::writeBlock: "
3793
<< "Block name must not be empty\n";
3797
//bool paperSpace = !strcasecmp(name, "*paper_space");
3798
//!strcasecmp(name, "*paper_space0");
3800
if (!strcasecmp(data.name.c_str(), "*paper_space")) {
3801
dw.sectionBlockEntry(0x1C);
3802
} else if (!strcasecmp(data.name.c_str(), "*model_space")) {
3803
dw.sectionBlockEntry(0x20);
3804
} else if (!strcasecmp(data.name.c_str(), "*paper_space0")) {
3805
dw.sectionBlockEntry(0x24);
3807
dw.sectionBlockEntry();
3809
dw.dxfString(2, data.name);
3811
dw.coord(10, data.bpx, data.bpy);
3812
dw.dxfString(3, data.name);
3813
dw.dxfString(1, "");
3819
* Writes a block end.
3821
* @param name Block name
3823
void DL_Dxf::writeEndBlock(DL_WriterA& dw, const string& name) {
3824
if (!strcasecmp(name.c_str(), "*paper_space")) {
3825
dw.sectionBlockEntryEnd(0x1D);
3826
} else if (!strcasecmp(name.c_str(), "*model_space")) {
3827
dw.sectionBlockEntryEnd(0x21);
3828
} else if (!strcasecmp(name.c_str(), "*paper_space0")) {
3829
dw.sectionBlockEntryEnd(0x25);
3831
dw.sectionBlockEntryEnd();
3838
* Writes a viewport section. This section is needed in VER_R13.
3839
* Note that this method currently only writes a faked VPORT section
3840
* to make the file readable by Aut*cad.
3842
void DL_Dxf::writeVPort(DL_WriterA& dw) {
3843
dw.dxfString(0, "TABLE");
3844
dw.dxfString(2, "VPORT");
3845
if (version==VER_2000) {
3848
//dw.dxfHex(330, 0);
3849
if (version==VER_2000) {
3850
dw.dxfString(100, "AcDbSymbolTable");
3853
dw.dxfString(0, "VPORT");
3854
//dw.dxfHex(5, 0x2F);
3855
if (version==VER_2000) {
3858
//dw.dxfHex(330, 8);
3859
if (version==VER_2000) {
3860
dw.dxfString(100, "AcDbSymbolTableRecord");
3861
dw.dxfString(100, "AcDbViewportTableRecord");
3863
dw.dxfString( 2, "*Active");
3865
dw.dxfReal( 10, 0.0);
3866
dw.dxfReal( 20, 0.0);
3867
dw.dxfReal( 11, 1.0);
3868
dw.dxfReal( 21, 1.0);
3869
dw.dxfReal( 12, 286.3055555555555);
3870
dw.dxfReal( 22, 148.5);
3871
dw.dxfReal( 13, 0.0);
3872
dw.dxfReal( 23, 0.0);
3873
dw.dxfReal( 14, 10.0);
3874
dw.dxfReal( 24, 10.0);
3875
dw.dxfReal( 15, 10.0);
3876
dw.dxfReal( 25, 10.0);
3877
dw.dxfReal( 16, 0.0);
3878
dw.dxfReal( 26, 0.0);
3879
dw.dxfReal( 36, 1.0);
3880
dw.dxfReal( 17, 0.0);
3881
dw.dxfReal( 27, 0.0);
3882
dw.dxfReal( 37, 0.0);
3883
dw.dxfReal( 40, 297.0);
3884
dw.dxfReal( 41, 1.92798353909465);
3885
dw.dxfReal( 42, 50.0);
3886
dw.dxfReal( 43, 0.0);
3887
dw.dxfReal( 44, 0.0);
3888
dw.dxfReal( 50, 0.0);
3889
dw.dxfReal( 51, 0.0);
3891
dw.dxfInt( 72, 100);
3899
if (version==VER_2000) {
3902
dw.dxfReal(110, 0.0);
3903
dw.dxfReal(120, 0.0);
3904
dw.dxfReal(130, 0.0);
3905
dw.dxfReal(111, 1.0);
3906
dw.dxfReal(121, 0.0);
3907
dw.dxfReal(131, 0.0);
3908
dw.dxfReal(112, 0.0);
3909
dw.dxfReal(122, 1.0);
3910
dw.dxfReal(132, 0.0);
3912
dw.dxfReal(146, 0.0);
3914
dw.dxfString( 0, "ENDTAB");
3920
* Writes a style section. This section is needed in VER_R13.
3921
* Note that this method currently only writes a faked STYLE section
3922
* to make the file readable by Aut*cad.
3924
void DL_Dxf::writeStyle(DL_WriterA& dw) {
3925
dw.dxfString( 0, "TABLE");
3926
dw.dxfString( 2, "STYLE");
3927
if (version==VER_2000) {
3930
//dw.dxfHex(330, 0);
3931
if (version==VER_2000) {
3932
dw.dxfString(100, "AcDbSymbolTable");
3935
dw.dxfString( 0, "STYLE");
3936
if (version==VER_2000) {
3939
//styleHandleStd = dw.handle();
3940
//dw.dxfHex(330, 3);
3941
if (version==VER_2000) {
3942
dw.dxfString(100, "AcDbSymbolTableRecord");
3943
dw.dxfString(100, "AcDbTextStyleTableRecord");
3945
dw.dxfString( 2, "Standard");
3947
dw.dxfReal( 40, 0.0);
3948
dw.dxfReal( 41, 0.75);
3949
dw.dxfReal( 50, 0.0);
3951
dw.dxfReal( 42, 2.5);
3952
dw.dxfString( 3, "txt");
3953
dw.dxfString( 4, "");
3954
dw.dxfString( 0, "ENDTAB");
3960
* Writes a view section. This section is needed in VER_R13.
3961
* Note that this method currently only writes a faked VIEW section
3962
* to make the file readable by Aut*cad.
3964
void DL_Dxf::writeView(DL_WriterA& dw) {
3965
dw.dxfString( 0, "TABLE");
3966
dw.dxfString( 2, "VIEW");
3967
if (version==VER_2000) {
3970
//dw.dxfHex(330, 0);
3971
if (version==VER_2000) {
3972
dw.dxfString(100, "AcDbSymbolTable");
3975
dw.dxfString( 0, "ENDTAB");
3981
* Writes a ucs section. This section is needed in VER_R13.
3982
* Note that this method currently only writes a faked UCS section
3983
* to make the file readable by Aut*cad.
3985
void DL_Dxf::writeUcs(DL_WriterA& dw) {
3986
dw.dxfString( 0, "TABLE");
3987
dw.dxfString( 2, "UCS");
3988
if (version==VER_2000) {
3991
//dw.dxfHex(330, 0);
3992
if (version==VER_2000) {
3993
dw.dxfString(100, "AcDbSymbolTable");
3996
dw.dxfString( 0, "ENDTAB");
4002
* Writes a dimstyle section. This section is needed in VER_R13.
4003
* Note that this method currently only writes a faked DIMSTYLE section
4004
* to make the file readable by Aut*cad.
4006
void DL_Dxf::writeDimStyle(DL_WriterA& dw,
4007
double dimasz, double dimexe, double dimexo,
4008
double dimgap, double dimtxt) {
4010
dw.dxfString( 0, "TABLE");
4011
dw.dxfString( 2, "DIMSTYLE");
4012
if (version==VER_2000) {
4014
dw.dxfString(100, "AcDbSymbolTable");
4017
if (version==VER_2000) {
4018
dw.dxfString(100, "AcDbDimStyleTable");
4023
dw.dxfString( 0, "DIMSTYLE");
4024
if (version==VER_2000) {
4025
dw.dxfHex(105, 0x27);
4028
//dw.dxfHex(330, 0xA);
4029
if (version==VER_2000) {
4030
dw.dxfString(100, "AcDbSymbolTableRecord");
4031
dw.dxfString(100, "AcDbDimStyleTableRecord");
4033
dw.dxfString( 2, "Standard");
4034
if (version==VER_R12) {
4035
dw.dxfString( 3, "");
4036
dw.dxfString( 4, "");
4037
dw.dxfString( 5, "");
4038
dw.dxfString( 6, "");
4039
dw.dxfString( 7, "");
4040
dw.dxfReal( 40, 1.0);
4043
dw.dxfReal( 41, dimasz);
4044
dw.dxfReal( 42, dimexo);
4045
dw.dxfReal( 43, 3.75);
4046
dw.dxfReal( 44, dimexe);
4047
if (version==VER_R12) {
4048
dw.dxfReal( 45, 0.0);
4049
dw.dxfReal( 46, 0.0);
4050
dw.dxfReal( 47, 0.0);
4051
dw.dxfReal( 48, 0.0);
4054
if (version==VER_R12) {
4060
if (version==VER_R12) {
4066
dw.dxfReal(140, dimtxt);
4067
dw.dxfReal(141, 2.5);
4068
if (version==VER_R12) {
4069
dw.dxfReal(142, 0.0);
4071
dw.dxfReal(143, 0.03937007874016);
4072
if (version==VER_R12) {
4073
dw.dxfReal(144, 1.0);
4074
dw.dxfReal(145, 0.0);
4075
dw.dxfReal(146, 1.0);
4077
dw.dxfReal(147, dimgap);
4078
if (version==VER_R12) {
4083
if (version==VER_R12) {
4091
if (version==VER_2000) {
4098
//dw.dxfHex(340, styleHandleStd);
4099
dw.dxfHex(340, 0x11);
4102
dw.dxfString( 0, "ENDTAB");
4108
* Writes a blockrecord section. This section is needed in VER_R13.
4109
* Note that this method currently only writes a faked BLOCKRECORD section
4110
* to make the file readable by Aut*cad.
4112
void DL_Dxf::writeBlockRecord(DL_WriterA& dw) {
4113
dw.dxfString( 0, "TABLE");
4114
dw.dxfString( 2, "BLOCK_RECORD");
4115
if (version==VER_2000) {
4118
//dw.dxfHex(330, 0);
4119
if (version==VER_2000) {
4120
dw.dxfString(100, "AcDbSymbolTable");
4124
dw.dxfString( 0, "BLOCK_RECORD");
4125
if (version==VER_2000) {
4128
//int msh = dw.handle();
4129
//dw.setModelSpaceHandle(msh);
4130
//dw.dxfHex(330, 1);
4131
if (version==VER_2000) {
4132
dw.dxfString(100, "AcDbSymbolTableRecord");
4133
dw.dxfString(100, "AcDbBlockTableRecord");
4135
dw.dxfString( 2, "*Model_Space");
4136
dw.dxfHex(340, 0x22);
4138
dw.dxfString( 0, "BLOCK_RECORD");
4139
if (version==VER_2000) {
4142
//int psh = dw.handle();
4143
//dw.setPaperSpaceHandle(psh);
4144
//dw.dxfHex(330, 1);
4145
if (version==VER_2000) {
4146
dw.dxfString(100, "AcDbSymbolTableRecord");
4147
dw.dxfString(100, "AcDbBlockTableRecord");
4149
dw.dxfString( 2, "*Paper_Space");
4150
dw.dxfHex(340, 0x1E);
4152
dw.dxfString( 0, "BLOCK_RECORD");
4153
if (version==VER_2000) {
4156
//int ps0h = dw.handle();
4157
//dw.setPaperSpace0Handle(ps0h);
4158
//dw.dxfHex(330, 1);
4159
if (version==VER_2000) {
4160
dw.dxfString(100, "AcDbSymbolTableRecord");
4161
dw.dxfString(100, "AcDbBlockTableRecord");
4163
dw.dxfString( 2, "*Paper_Space0");
4164
dw.dxfHex(340, 0x26);
4166
//dw.dxfString( 0, "ENDTAB");
4172
* Writes a single block record with the given name.
4174
void DL_Dxf::writeBlockRecord(DL_WriterA& dw, const string& name) {
4175
dw.dxfString( 0, "BLOCK_RECORD");
4176
if (version==VER_2000) {
4179
//dw->dxfHex(330, 1);
4180
if (version==VER_2000) {
4181
dw.dxfString(100, "AcDbSymbolTableRecord");
4182
dw.dxfString(100, "AcDbBlockTableRecord");
4184
dw.dxfString( 2, name);
4191
* Writes a objects section. This section is needed in VER_R13.
4192
* Note that this method currently only writes a faked OBJECTS section
4193
* to make the file readable by Aut*cad.
4195
void DL_Dxf::writeObjects(DL_WriterA& dw) {
4196
//int dicId, dicId2, dicId3, dicId4, dicId5;
4199
dw.dxfString( 0, "SECTION");
4200
dw.dxfString( 2, "OBJECTS");
4201
dw.dxfString( 0, "DICTIONARY");
4202
dw.dxfHex(5, 0xC); // C
4203
//dw.dxfHex(330, 0);
4204
dw.dxfString(100, "AcDbDictionary");
4207
dw.dxfString( 3, "ACAD_GROUP");
4208
//dw.dxfHex(350, dw.getNextHandle()); // D
4209
dw.dxfHex(350, 0xD); // D
4210
dw.dxfString( 3, "ACAD_LAYOUT");
4211
dw.dxfHex(350, 0x1A);
4212
//dw.dxfHex(350, dw.getNextHandle()+0); // 1A
4213
dw.dxfString( 3, "ACAD_MLINESTYLE");
4214
dw.dxfHex(350, 0x17);
4215
//dw.dxfHex(350, dw.getNextHandle()+1); // 17
4216
dw.dxfString( 3, "ACAD_PLOTSETTINGS");
4217
dw.dxfHex(350, 0x19);
4218
//dw.dxfHex(350, dw.getNextHandle()+2); // 19
4219
dw.dxfString( 3, "ACAD_PLOTSTYLENAME");
4220
dw.dxfHex(350, 0xE);
4221
//dw.dxfHex(350, dw.getNextHandle()+3); // E
4222
dw.dxfString( 3, "AcDbVariableDictionary");
4223
dw.dxfHex(350, dw.getNextHandle()); // 2C
4224
dw.dxfString( 0, "DICTIONARY");
4227
//dw.dxfHex(330, 0xC);
4228
dw.dxfString(100, "AcDbDictionary");
4231
dw.dxfString( 0, "ACDBDICTIONARYWDFLT");
4233
//dicId4 = dw.handle(); // E
4234
//dw.dxfHex(330, 0xC); // C
4235
dw.dxfString(100, "AcDbDictionary");
4237
dw.dxfString( 3, "Normal");
4238
dw.dxfHex(350, 0xF);
4239
//dw.dxfHex(350, dw.getNextHandle()+5); // F
4240
dw.dxfString(100, "AcDbDictionaryWithDefault");
4241
dw.dxfHex(340, 0xF);
4242
//dw.dxfHex(340, dw.getNextHandle()+5); // F
4243
dw.dxfString( 0, "ACDBPLACEHOLDER");
4246
//dw.dxfHex(330, dicId4); // E
4247
dw.dxfString( 0, "DICTIONARY");
4248
//dicId3 = dw.handle(); // 17
4250
//dw.dxfHex(330, 0xC); // C
4251
dw.dxfString(100, "AcDbDictionary");
4254
dw.dxfString( 3, "Standard");
4255
dw.dxfHex(350, 0x18);
4256
//dw.dxfHex(350, dw.getNextHandle()+5); // 18
4257
dw.dxfString( 0, "MLINESTYLE");
4259
//dw.handle(); // 18
4260
//dw.dxfHex(330, dicId3); // 17
4261
dw.dxfString(100, "AcDbMlineStyle");
4262
dw.dxfString( 2, "STANDARD");
4264
dw.dxfString( 3, "");
4265
dw.dxfInt( 62, 256);
4266
dw.dxfReal( 51, 90.0);
4267
dw.dxfReal( 52, 90.0);
4269
dw.dxfReal( 49, 0.5);
4270
dw.dxfInt( 62, 256);
4271
dw.dxfString( 6, "BYLAYER");
4272
dw.dxfReal( 49, -0.5);
4273
dw.dxfInt( 62, 256);
4274
dw.dxfString( 6, "BYLAYER");
4275
dw.dxfString( 0, "DICTIONARY");
4277
//dw.handle(); // 17
4278
//dw.dxfHex(330, 0xC); // C
4279
dw.dxfString(100, "AcDbDictionary");
4282
dw.dxfString( 0, "DICTIONARY");
4283
//dicId2 = dw.handle(); // 1A
4285
//dw.dxfHex(330, 0xC);
4286
dw.dxfString(100, "AcDbDictionary");
4288
dw.dxfString( 3, "Layout1");
4289
dw.dxfHex(350, 0x1E);
4290
//dw.dxfHex(350, dw.getNextHandle()+2); // 1E
4291
dw.dxfString( 3, "Layout2");
4292
dw.dxfHex(350, 0x26);
4293
//dw.dxfHex(350, dw.getNextHandle()+4); // 26
4294
dw.dxfString( 3, "Model");
4295
dw.dxfHex(350, 0x22);
4296
//dw.dxfHex(350, dw.getNextHandle()+5); // 22
4298
dw.dxfString( 0, "LAYOUT");
4300
//dw.handle(); // 1E
4301
//dw.dxfHex(330, dicId2); // 1A
4302
dw.dxfString(100, "AcDbPlotSettings");
4303
dw.dxfString( 1, "");
4304
dw.dxfString( 2, "C:\\Program Files\\AutoCAD 2002\\plotters\\DWF ePlot (optimized for plotting).pc3");
4305
dw.dxfString( 4, "");
4306
dw.dxfString( 6, "");
4307
dw.dxfReal( 40, 0.0);
4308
dw.dxfReal( 41, 0.0);
4309
dw.dxfReal( 42, 0.0);
4310
dw.dxfReal( 43, 0.0);
4311
dw.dxfReal( 44, 0.0);
4312
dw.dxfReal( 45, 0.0);
4313
dw.dxfReal( 46, 0.0);
4314
dw.dxfReal( 47, 0.0);
4315
dw.dxfReal( 48, 0.0);
4316
dw.dxfReal( 49, 0.0);
4317
dw.dxfReal(140, 0.0);
4318
dw.dxfReal(141, 0.0);
4319
dw.dxfReal(142, 1.0);
4320
dw.dxfReal(143, 1.0);
4321
dw.dxfInt( 70, 688);
4325
dw.dxfString( 7, "");
4327
dw.dxfReal(147, 1.0);
4328
dw.dxfReal(148, 0.0);
4329
dw.dxfReal(149, 0.0);
4330
dw.dxfString(100, "AcDbLayout");
4331
dw.dxfString( 1, "Layout1");
4334
dw.dxfReal( 10, 0.0);
4335
dw.dxfReal( 20, 0.0);
4336
dw.dxfReal( 11, 420.0);
4337
dw.dxfReal( 21, 297.0);
4338
dw.dxfReal( 12, 0.0);
4339
dw.dxfReal( 22, 0.0);
4340
dw.dxfReal( 32, 0.0);
4341
dw.dxfReal( 14, 1.000000000000000E+20);
4342
dw.dxfReal( 24, 1.000000000000000E+20);
4343
dw.dxfReal( 34, 1.000000000000000E+20);
4344
dw.dxfReal( 15, -1.000000000000000E+20);
4345
dw.dxfReal( 25, -1.000000000000000E+20);
4346
dw.dxfReal( 35, -1.000000000000000E+20);
4347
dw.dxfReal(146, 0.0);
4348
dw.dxfReal( 13, 0.0);
4349
dw.dxfReal( 23, 0.0);
4350
dw.dxfReal( 33, 0.0);
4351
dw.dxfReal( 16, 1.0);
4352
dw.dxfReal( 26, 0.0);
4353
dw.dxfReal( 36, 0.0);
4354
dw.dxfReal( 17, 0.0);
4355
dw.dxfReal( 27, 1.0);
4356
dw.dxfReal( 37, 0.0);
4358
//dw.dxfHex(330, dw.getPaperSpaceHandle()); // 1B
4359
dw.dxfHex(330, 0x1B);
4360
dw.dxfString( 0, "LAYOUT");
4362
//dw.handle(); // 22
4363
//dw.dxfHex(330, dicId2); // 1A
4364
dw.dxfString(100, "AcDbPlotSettings");
4365
dw.dxfString( 1, "");
4366
dw.dxfString( 2, "C:\\Program Files\\AutoCAD 2002\\plotters\\DWF ePlot (optimized for plotting).pc3");
4367
dw.dxfString( 4, "");
4368
dw.dxfString( 6, "");
4369
dw.dxfReal( 40, 0.0);
4370
dw.dxfReal( 41, 0.0);
4371
dw.dxfReal( 42, 0.0);
4372
dw.dxfReal( 43, 0.0);
4373
dw.dxfReal( 44, 0.0);
4374
dw.dxfReal( 45, 0.0);
4375
dw.dxfReal( 46, 0.0);
4376
dw.dxfReal( 47, 0.0);
4377
dw.dxfReal( 48, 0.0);
4378
dw.dxfReal( 49, 0.0);
4379
dw.dxfReal(140, 0.0);
4380
dw.dxfReal(141, 0.0);
4381
dw.dxfReal(142, 1.0);
4382
dw.dxfReal(143, 1.0);
4383
dw.dxfInt( 70, 1712);
4387
dw.dxfString( 7, "");
4389
dw.dxfReal(147, 1.0);
4390
dw.dxfReal(148, 0.0);
4391
dw.dxfReal(149, 0.0);
4392
dw.dxfString(100, "AcDbLayout");
4393
dw.dxfString( 1, "Model");
4396
dw.dxfReal( 10, 0.0);
4397
dw.dxfReal( 20, 0.0);
4398
dw.dxfReal( 11, 12.0);
4399
dw.dxfReal( 21, 9.0);
4400
dw.dxfReal( 12, 0.0);
4401
dw.dxfReal( 22, 0.0);
4402
dw.dxfReal( 32, 0.0);
4403
dw.dxfReal( 14, 0.0);
4404
dw.dxfReal( 24, 0.0);
4405
dw.dxfReal( 34, 0.0);
4406
dw.dxfReal( 15, 0.0);
4407
dw.dxfReal( 25, 0.0);
4408
dw.dxfReal( 35, 0.0);
4409
dw.dxfReal(146, 0.0);
4410
dw.dxfReal( 13, 0.0);
4411
dw.dxfReal( 23, 0.0);
4412
dw.dxfReal( 33, 0.0);
4413
dw.dxfReal( 16, 1.0);
4414
dw.dxfReal( 26, 0.0);
4415
dw.dxfReal( 36, 0.0);
4416
dw.dxfReal( 17, 0.0);
4417
dw.dxfReal( 27, 1.0);
4418
dw.dxfReal( 37, 0.0);
4420
//dw.dxfHex(330, dw.getModelSpaceHandle()); // 1F
4421
dw.dxfHex(330, 0x1F);
4422
dw.dxfString( 0, "LAYOUT");
4423
//dw.handle(); // 26
4425
//dw.dxfHex(330, dicId2); // 1A
4426
dw.dxfString(100, "AcDbPlotSettings");
4427
dw.dxfString( 1, "");
4428
dw.dxfString( 2, "C:\\Program Files\\AutoCAD 2002\\plotters\\DWF ePlot (optimized for plotting).pc3");
4429
dw.dxfString( 4, "");
4430
dw.dxfString( 6, "");
4431
dw.dxfReal( 40, 0.0);
4432
dw.dxfReal( 41, 0.0);
4433
dw.dxfReal( 42, 0.0);
4434
dw.dxfReal( 43, 0.0);
4435
dw.dxfReal( 44, 0.0);
4436
dw.dxfReal( 45, 0.0);
4437
dw.dxfReal( 46, 0.0);
4438
dw.dxfReal( 47, 0.0);
4439
dw.dxfReal( 48, 0.0);
4440
dw.dxfReal( 49, 0.0);
4441
dw.dxfReal(140, 0.0);
4442
dw.dxfReal(141, 0.0);
4443
dw.dxfReal(142, 1.0);
4444
dw.dxfReal(143, 1.0);
4445
dw.dxfInt( 70, 688);
4449
dw.dxfString( 7, "");
4451
dw.dxfReal(147, 1.0);
4452
dw.dxfReal(148, 0.0);
4453
dw.dxfReal(149, 0.0);
4454
dw.dxfString(100, "AcDbLayout");
4455
dw.dxfString( 1, "Layout2");
4458
dw.dxfReal( 10, 0.0);
4459
dw.dxfReal( 20, 0.0);
4460
dw.dxfReal( 11, 12.0);
4461
dw.dxfReal( 21, 9.0);
4462
dw.dxfReal( 12, 0.0);
4463
dw.dxfReal( 22, 0.0);
4464
dw.dxfReal( 32, 0.0);
4465
dw.dxfReal( 14, 0.0);
4466
dw.dxfReal( 24, 0.0);
4467
dw.dxfReal( 34, 0.0);
4468
dw.dxfReal( 15, 0.0);
4469
dw.dxfReal( 25, 0.0);
4470
dw.dxfReal( 35, 0.0);
4471
dw.dxfReal(146, 0.0);
4472
dw.dxfReal( 13, 0.0);
4473
dw.dxfReal( 23, 0.0);
4474
dw.dxfReal( 33, 0.0);
4475
dw.dxfReal( 16, 1.0);
4476
dw.dxfReal( 26, 0.0);
4477
dw.dxfReal( 36, 0.0);
4478
dw.dxfReal( 17, 0.0);
4479
dw.dxfReal( 27, 1.0);
4480
dw.dxfReal( 37, 0.0);
4482
//dw.dxfHex(330, dw.getPaperSpace0Handle()); // 23
4483
dw.dxfHex(330, 0x23);
4484
dw.dxfString( 0, "DICTIONARY");
4485
//dw.dxfHex(5, 0x2C);
4488
//dw.dxfHex(330, 0xC); // C
4489
dw.dxfString(100, "AcDbDictionary");
4491
dw.dxfString( 3, "DIMASSOC");
4492
//dw.dxfHex(350, 0x2F);
4493
dw.dxfHex(350, dw.getNextHandle()+1); // 2E
4494
dw.dxfString( 3, "HIDETEXT");
4495
//dw.dxfHex(350, 0x2E);
4496
dw.dxfHex(350, dw.getNextHandle()); // 2D
4497
dw.dxfString( 0, "DICTIONARYVAR");
4498
//dw.dxfHex(5, 0x2E);
4500
//dw.dxfHex(330, dicId5); // 2C
4501
dw.dxfString(100, "DictionaryVariables");
4504
dw.dxfString( 0, "DICTIONARYVAR");
4505
//dw.dxfHex(5, 0x2D);
4507
//dw.dxfHex(330, dicId5); // 2C
4508
dw.dxfString(100, "DictionaryVariables");
4515
* Writes the end of the objects section. This section is needed in VER_R13.
4516
* Note that this method currently only writes a faked OBJECTS section
4517
* to make the file readable by Aut*cad.
4519
void DL_Dxf::writeObjectsEnd(DL_WriterA& dw) {
4520
dw.dxfString( 0, "ENDSEC");
4526
* Writes a comment to the DXF file.
4528
void DL_Dxf::writeComment(DL_WriterA& dw, const string& comment) {
4529
dw.dxfString(999, comment);
4534
* Checks if the given variable is known by the given DXF version.
4536
bool DL_Dxf::checkVariable(const char* var, DL_Codes::version version) {
4537
if (version>=VER_2000) {
4539
} else if (version==VER_R12) {
4540
// these are all the variables recognized by dxf r12:
4541
if (!strcmp(var, "$ACADVER")) {
4544
if (!strcmp(var, "$ACADVER")) {
4547
if (!strcmp(var, "$ANGBASE")) {
4550
if (!strcmp(var, "$ANGDIR")) {
4553
if (!strcmp(var, "$ATTDIA")) {
4556
if (!strcmp(var, "$ATTMODE")) {
4559
if (!strcmp(var, "$ATTREQ")) {
4562
if (!strcmp(var, "$AUNITS")) {
4565
if (!strcmp(var, "$AUPREC")) {
4568
if (!strcmp(var, "$AXISMODE")) {
4571
if (!strcmp(var, "$AXISUNIT")) {
4574
if (!strcmp(var, "$BLIPMODE")) {
4577
if (!strcmp(var, "$CECOLOR")) {
4580
if (!strcmp(var, "$CELTYPE")) {
4583
if (!strcmp(var, "$CHAMFERA")) {
4586
if (!strcmp(var, "$CHAMFERB")) {
4589
if (!strcmp(var, "$CLAYER")) {
4592
if (!strcmp(var, "$COORDS")) {
4595
if (!strcmp(var, "$DIMALT")) {
4598
if (!strcmp(var, "$DIMALTD")) {
4601
if (!strcmp(var, "$DIMALTF")) {
4604
if (!strcmp(var, "$DIMAPOST")) {
4607
if (!strcmp(var, "$DIMASO")) {
4610
if (!strcmp(var, "$DIMASZ")) {
4613
if (!strcmp(var, "$DIMBLK")) {
4616
if (!strcmp(var, "$DIMBLK1")) {
4619
if (!strcmp(var, "$DIMBLK2")) {
4622
if (!strcmp(var, "$DIMCEN")) {
4625
if (!strcmp(var, "$DIMCLRD")) {
4628
if (!strcmp(var, "$DIMCLRE")) {
4631
if (!strcmp(var, "$DIMCLRT")) {
4634
if (!strcmp(var, "$DIMDLE")) {
4637
if (!strcmp(var, "$DIMDLI")) {
4640
if (!strcmp(var, "$DIMEXE")) {
4643
if (!strcmp(var, "$DIMEXO")) {
4646
if (!strcmp(var, "$DIMGAP")) {
4649
if (!strcmp(var, "$DIMLFAC")) {
4652
if (!strcmp(var, "$DIMLIM")) {
4655
if (!strcmp(var, "$DIMPOST")) {
4658
if (!strcmp(var, "$DIMRND")) {
4661
if (!strcmp(var, "$DIMSAH")) {
4664
if (!strcmp(var, "$DIMSCALE")) {
4667
if (!strcmp(var, "$DIMSE1")) {
4670
if (!strcmp(var, "$DIMSE2")) {
4673
if (!strcmp(var, "$DIMSHO")) {
4676
if (!strcmp(var, "$DIMSOXD")) {
4679
if (!strcmp(var, "$DIMSTYLE")) {
4682
if (!strcmp(var, "$DIMTAD")) {
4685
if (!strcmp(var, "$DIMTFAC")) {
4688
if (!strcmp(var, "$DIMTIH")) {
4691
if (!strcmp(var, "$DIMTIX")) {
4694
if (!strcmp(var, "$DIMTM")) {
4697
if (!strcmp(var, "$DIMTOFL")) {
4700
if (!strcmp(var, "$DIMTOH")) {
4703
if (!strcmp(var, "$DIMTOL")) {
4706
if (!strcmp(var, "$DIMTP")) {
4709
if (!strcmp(var, "$DIMTSZ")) {
4712
if (!strcmp(var, "$DIMTVP")) {
4715
if (!strcmp(var, "$DIMTXT")) {
4718
if (!strcmp(var, "$DIMZIN")) {
4721
if (!strcmp(var, "$DWGCODEPAGE")) {
4724
if (!strcmp(var, "$DRAGMODE")) {
4727
if (!strcmp(var, "$ELEVATION")) {
4730
if (!strcmp(var, "$EXTMAX")) {
4733
if (!strcmp(var, "$EXTMIN")) {
4736
if (!strcmp(var, "$FILLETRAD")) {
4739
if (!strcmp(var, "$FILLMODE")) {
4742
if (!strcmp(var, "$HANDLING")) {
4745
if (!strcmp(var, "$HANDSEED")) {
4748
if (!strcmp(var, "$INSBASE")) {
4751
if (!strcmp(var, "$LIMCHECK")) {
4754
if (!strcmp(var, "$LIMMAX")) {
4757
if (!strcmp(var, "$LIMMIN")) {
4760
if (!strcmp(var, "$LTSCALE")) {
4763
if (!strcmp(var, "$LUNITS")) {
4766
if (!strcmp(var, "$LUPREC")) {
4769
if (!strcmp(var, "$MAXACTVP")) {
4772
if (!strcmp(var, "$MENU")) {
4775
if (!strcmp(var, "$MIRRTEXT")) {
4778
if (!strcmp(var, "$ORTHOMODE")) {
4781
if (!strcmp(var, "$OSMODE")) {
4784
if (!strcmp(var, "$PDMODE")) {
4787
if (!strcmp(var, "$PDSIZE")) {
4790
if (!strcmp(var, "$PELEVATION")) {
4793
if (!strcmp(var, "$PEXTMAX")) {
4796
if (!strcmp(var, "$PEXTMIN")) {
4799
if (!strcmp(var, "$PLIMCHECK")) {
4802
if (!strcmp(var, "$PLIMMAX")) {
4805
if (!strcmp(var, "$PLIMMIN")) {
4808
if (!strcmp(var, "$PLINEGEN")) {
4811
if (!strcmp(var, "$PLINEWID")) {
4814
if (!strcmp(var, "$PSLTSCALE")) {
4817
if (!strcmp(var, "$PUCSNAME")) {
4820
if (!strcmp(var, "$PUCSORG")) {
4823
if (!strcmp(var, "$PUCSXDIR")) {
4826
if (!strcmp(var, "$PUCSYDIR")) {
4829
if (!strcmp(var, "$QTEXTMODE")) {
4832
if (!strcmp(var, "$REGENMODE")) {
4835
if (!strcmp(var, "$SHADEDGE")) {
4838
if (!strcmp(var, "$SHADEDIF")) {
4841
if (!strcmp(var, "$SKETCHINC")) {
4844
if (!strcmp(var, "$SKPOLY")) {
4847
if (!strcmp(var, "$SPLFRAME")) {
4850
if (!strcmp(var, "$SPLINESEGS")) {
4853
if (!strcmp(var, "$SPLINETYPE")) {
4856
if (!strcmp(var, "$SURFTAB1")) {
4859
if (!strcmp(var, "$SURFTAB2")) {
4862
if (!strcmp(var, "$SURFTYPE")) {
4865
if (!strcmp(var, "$SURFU")) {
4868
if (!strcmp(var, "$SURFV")) {
4871
if (!strcmp(var, "$TDCREATE")) {
4874
if (!strcmp(var, "$TDINDWG")) {
4877
if (!strcmp(var, "$TDUPDATE")) {
4880
if (!strcmp(var, "$TDUSRTIMER")) {
4883
if (!strcmp(var, "$TEXTSIZE")) {
4886
if (!strcmp(var, "$TEXTSTYLE")) {
4889
if (!strcmp(var, "$THICKNESS")) {
4892
if (!strcmp(var, "$TILEMODE")) {
4895
if (!strcmp(var, "$TRACEWID")) {
4898
if (!strcmp(var, "$UCSNAME")) {
4901
if (!strcmp(var, "$UCSORG")) {
4904
if (!strcmp(var, "$UCSXDIR")) {
4907
if (!strcmp(var, "$UCSYDIR")) {
4910
if (!strcmp(var, "$UNITMODE")) {
4913
if (!strcmp(var, "$USERI1")) {
4916
if (!strcmp(var, "$USERR1")) {
4919
if (!strcmp(var, "$USRTIMER")) {
4922
if (!strcmp(var, "$VISRETAIN")) {
4925
if (!strcmp(var, "$WORLDVIEW")) {
4928
if (!strcmp(var, "$FASTZOOM")) {
4931
if (!strcmp(var, "$GRIDMODE")) {
4934
if (!strcmp(var, "$GRIDUNIT")) {
4937
if (!strcmp(var, "$SNAPANG")) {
4940
if (!strcmp(var, "$SNAPBASE")) {
4943
if (!strcmp(var, "$SNAPISOPAIR")) {
4946
if (!strcmp(var, "$SNAPMODE")) {
4949
if (!strcmp(var, "$SNAPSTYLE")) {
4952
if (!strcmp(var, "$SNAPUNIT")) {
4955
if (!strcmp(var, "$VIEWCTR")) {
4958
if (!strcmp(var, "$VIEWDIR")) {
4961
if (!strcmp(var, "$VIEWSIZE")) {
4973
* @returns the library version as int (4 bytes, each byte one version number).
4974
* e.g. if str = "2.0.2.0" getLibVersion returns 0x02000200
4976
int DL_Dxf::getLibVersion(const char* str) {
4982
for (unsigned int i=0; i<strlen(str) && idx<3; ++i) {
4992
strncpy(v[0], str, d[0]);
4995
strncpy(v[1], &str[d[0]+1], d[1]-d[0]-1);
4996
v[1][d[1]-d[0]-1] = '\0';
4998
strncpy(v[2], &str[d[1]+1], d[2]-d[1]-1);
4999
v[2][d[2]-d[1]-1] = '\0';
5001
strncpy(v[3], &str[d[2]+1], d[3]-d[2]-1);
5002
v[3][d[3]-d[2]-1] = '\0';
5004
ret = (atoi(v[0])<<(3*8)) +
5005
(atoi(v[1])<<(2*8)) +
5006
(atoi(v[2])<<(1*8)) +
5007
(atoi(v[3])<<(0*8));
5011
std::cerr << "DL_Dxf::getLibVersion: invalid version number: " << str << "\n";
5019
* Some test routines.
5021
void DL_Dxf::test() {
5029
buf1 = new char[10];
5030
buf2 = new char[10];
5031
buf3 = new char[10];
5032
buf4 = new char[10];
5033
buf5 = new char[10];
5034
buf6 = new char[10];
5036
strcpy(buf1, " 10\n");
5038
strcpy(buf3, "10\n");
5039
strcpy(buf4, " 10 \n");
5040
strcpy(buf5, " 10 \r");
5041
strcpy(buf6, "\t10 \n");
5043
std::cout << "1 buf1: '" << buf1 << "'\n";
5044
stripWhiteSpace(&buf1);
5045
std::cout << "2 buf1: '" << buf1 << "'\n";
5046
//assert(!strcmp(buf1, "10"));
5048
std::cout << "1 buf2: '" << buf2 << "'\n";
5049
stripWhiteSpace(&buf2);
5050
std::cout << "2 buf2: '" << buf2 << "'\n";
5052
std::cout << "1 buf3: '" << buf3 << "'\n";
5053
stripWhiteSpace(&buf3);
5054
std::cout << "2 buf3: '" << buf3 << "'\n";
5056
std::cout << "1 buf4: '" << buf4 << "'\n";
5057
stripWhiteSpace(&buf4);
5058
std::cout << "2 buf4: '" << buf4 << "'\n";
5060
std::cout << "1 buf5: '" << buf5 << "'\n";
5061
stripWhiteSpace(&buf5);
5062
std::cout << "2 buf5: '" << buf5 << "'\n";
5064
std::cout << "1 buf6: '" << buf6 << "'\n";
5065
stripWhiteSpace(&buf6);
5066
std::cout << "2 buf6: '" << buf6 << "'\n";