1
/****************************************************************************
3
** This file is part of the LibreCAD project, a 2D CAD program
5
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
6
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
9
** This file may be distributed and/or modified under the terms of the
10
** GNU General Public License version 2 as published by the Free Software
11
** Foundation and appearing in the file gpl-2.0.txt included in the
12
** packaging of this file.
14
** This program is distributed in the hope that it will be useful,
15
** but WITHOUT ANY WARRANTY; without even the implied warranty of
16
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
** GNU General Public License for more details.
19
** You should have received a copy of the GNU General Public License
20
** along with this program; if not, write to the Free Software
21
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
** This copyright notice MUST APPEAR in all copies of the script!
25
**********************************************************************/
28
#include "rs_filterdxfrw.h"
29
#include "rs_filterdxf1.h"
34
#include "rs_information.h"
35
#include "rs_utility.h"
36
#include "rs_system.h"
37
#include "rs_dimlinear.h"
38
#include "rs_dimaligned.h"
39
#include "rs_dimangular.h"
40
#include "rs_dimdiametric.h"
41
#include "rs_dimradial.h"
43
#include "rs_leader.h"
47
* Default constructor.
49
RS_FilterDXF1::RS_FilterDXF1()
50
:RS_FilterInterface() {
52
RS_DEBUG->print("Setting up DXF 1 filter...");
58
* Implementation of the method used for RS_Import to communicate
61
* @param graphic The graphic in which the entities from the file
62
* will be created or the graphics from which the entities are
63
* taken to be stored in a file.
65
bool RS_FilterDXF1::fileImport(RS_Graphic& g, const QString& file, RS2::FormatType /*type*/) {
66
RS_DEBUG->print("DXF1 Filter: importing file '%s'...", file.toLatin1().data());
77
if(readFileInBuffer()) {
79
return readFromBuffer();
88
* Reads a dxf1 file from buffer.
90
bool RS_FilterDXF1::readFromBuffer() {
91
RS_DEBUG->print( "\nDXF: Read from buffer" );
93
bool ret; // returned value
94
QString dxfLine; // A line in the dxf file
95
QString dxfCode; // A Code in the dxf file as string
96
int code=-1; // Dxf-code as number
97
double vx1=0.0, vy1=0.0; // Start point
98
double vx2=0.0, vy2=0.0; // End point
99
double vcx=0.0, vcy=0.0; // Centre
100
double vcr=0.0; // Radius
101
double va1=0.0, va2=0.0; // Start / End Angle
102
//double vab=0.0, // Bulge
103
// vpx=0.0, vpy=0.0; // First Polyline point
104
//double ax=0.0, ay=0.0; // Current coordinate
105
//bool plClose=false; // Polyline closed-flag
106
QString lastLayer; // Last used layer name (test adding only
107
// if the new layer!=lastLayer)
108
//int currentLayerNum=0; // Current layer number
109
RS_Layer* currentLayer=0; // Pointer to current layer
110
//QList<RGraphic> blockList; // List of blocks
111
//blockList.setAutoDelete( true );
112
//bool oldColorNumbers=false; // use old color numbers (qcad<1.5.3)
115
///if(!add) graphic->clearLayers();
117
//graphic->addLayer(DEF_DEFAULTLAYER);
119
//RS_DEBUG->print( "\nDefault layer added" );
121
// Loaded graphics without unit information: load as unit less:
122
//graphic->setUnit( None );
124
RS_DEBUG->print( "\nUnit set" );
130
RS_DEBUG->print( "\nBuffer OK" );
131
RS_DEBUG->print( "\nBuffer: " );
132
RS_DEBUG->print( fBuf );
135
dxfLine=getBufLine();
136
pen = RS_Pen(RS_Color(RS2::FlagByLayer), RS2::WidthByLayer, RS2::LineByLayer);
138
RS_DEBUG->print( "\ndxfLine: " );
139
RS_DEBUG->print( dxfLine.toLatin1().data() );
141
// $-Setting in the header of DXF found
142
// RVT_PORT changed all occurenses of if (dxfline && ....) to if (dxfline.size() ......)
143
if( dxfLine.size() &&
149
if( dxfLine=="$INSUNITS" ) {
150
dxfCode=getBufLine();
152
if( dxfCode.toInt()==70 ) {
153
dxfLine=getBufLine() ;
154
if( dxfLine.size() ) {
155
graphic->addVariable("$INSUNITS", dxfLine, 70);
157
switch( dxfLine.toInt() ) {
158
case 0: graphic->setUnit( RS2::None ); break;
159
case 1: graphic->setUnit( RS2::Inch ); break;
160
case 2: graphic->setUnit( RS2::Foot ); break;
161
case 3: graphic->setUnit( RS2::Mile ); break;
162
case 4: graphic->setUnit( RS2::Millimeter ); break;
163
case 5: graphic->setUnit( RS2::Centimeter ); break;
164
case 6: graphic->setUnit( RS2::Meter ); break;
165
case 7: graphic->setUnit( RS2::Kilometer ); break;
166
case 8: graphic->setUnit( RS2::Microinch ); break;
167
case 9: graphic->setUnit( RS2::Mil ); break;
168
case 10: graphic->setUnit( RS2::Yard ); break;
169
case 11: graphic->setUnit( RS2::Angstrom ); break;
170
case 12: graphic->setUnit( RS2::Nanometer ); break;
171
case 13: graphic->setUnit( RS2::Micron ); break;
172
case 14: graphic->setUnit( RS2::Decimeter ); break;
173
case 15: graphic->setUnit( RS2::Decameter ); break;
174
case 16: graphic->setUnit( RS2::Hectometer ); break;
175
case 17: graphic->setUnit( RS2::Gigameter ); break;
176
case 18: graphic->setUnit( RS2::Astro ); break;
177
case 19: graphic->setUnit( RS2::Lightyear ); break;
178
case 20: graphic->setUnit( RS2::Parsec ); break;
181
graphic->setDimensionUnit( graphic->getUnit() );
182
//graphic->setGridUnit( graphic->getUnit() );
191
else if( dxfLine=="$DIMALT" ) {
192
dxfCode=getBufLine();
194
if( dxfCode.toInt()==70 ) {
195
dxfLine=getBufLine();
196
if( dxfLine.size() ) {
197
graphic->addVariable("$DIMALT", dxfLine, 70);
199
switch( dxfLine.toInt() ) {
200
case 0: graphic->setDimensionUnit( RS2::None ); break;
201
case 1: graphic->setDimensionUnit( RS2::Inch ); break;
202
case 2: graphic->setDimensionUnit( RS2::Foot ); break;
203
case 3: graphic->setDimensionUnit( RS2::Mile ); break;
204
case 4: graphic->setDimensionUnit( RS2::Millimeter ); break;
205
case 5: graphic->setDimensionUnit( RS2::Centimeter ); break;
206
case 6: graphic->setDimensionUnit( RS2::Meter ); break;
207
case 7: graphic->setDimensionUnit( RS2::Kilometer ); break;
208
case 8: graphic->setDimensionUnit( RS2::Microinch ); break;
209
case 9: graphic->setDimensionUnit( RS2::Mil ); break;
210
case 10: graphic->setDimensionUnit( RS2::Yard ); break;
211
case 11: graphic->setDimensionUnit( RS2::Angstrom ); break;
212
case 12: graphic->setDimensionUnit( RS2::Nanometer ); break;
213
case 13: graphic->setDimensionUnit( RS2::Micron ); break;
214
case 14: graphic->setDimensionUnit( RS2::Decimeter ); break;
215
case 15: graphic->setDimensionUnit( RS2::Decameter ); break;
216
case 16: graphic->setDimensionUnit( RS2::Hectometer ); break;
217
case 17: graphic->setDimensionUnit( RS2::Gigameter ); break;
218
case 18: graphic->setDimensionUnit( RS2::Astro ); break;
219
case 19: graphic->setDimensionUnit( RS2::Lightyear ); break;
220
case 20: graphic->setDimensionUnit( RS2::Parsec ); break;
230
/*else if( dxfLine=="$DIMLUNIT" ) {
231
if(dxfCode=getBufLine()) {
232
if( dxfCode.toInt()==70 ) {
233
if( dxfLine=getBufLine() ) {
234
switch( dxfLine.toInt() ) {
235
case 1: graphic->setDimensionFormat( Scientific ); break;
237
case 3: graphic->setDimensionFormat( Decimal ); break;
239
case 5: graphic->setDimensionFormat( Fractional ); break;
247
// Dimension Arrow Size:
249
else if( dxfLine=="$DIMASZ" ) {
250
dxfCode=getBufLine();
252
if( dxfCode.toInt()==40 ) {
253
dxfLine=getBufLine() ;
254
if( dxfLine.size()) {
255
graphic->addVariable("$DIMASZ", dxfLine, 40);
256
//graphic->setDimensionArrowSize( dxfLine.toDouble() );
265
else if( dxfLine=="$DIMSCALE" ) {
266
if(dxfCode=getBufLine()) {
267
if( dxfCode.toInt()==40 ) {
268
if( dxfLine=getBufLine() ) {
269
graphic->setDimensionScale( dxfLine.toDouble() );
276
// Dimension Text Height:
285
else if( dxfLine=="$DIMTXT" ) {
286
dxfLine=getBufLine();
288
if( dxfCode.toInt()==40 ) {
289
dxfLine=getBufLine();
290
if( dxfLine.size() ) {
291
graphic->addVariable("$DIMTXT", dxfLine, 40);
292
//graphic->setDimensionTextHeight( dxfLine.toDouble() );
298
// Dimension exactness:
307
else if( dxfLine=="$DIMRND" ) {
308
dxfLine=getBufLine();
310
if( dxfCode.toInt()==40 ) {
311
dxfLine=getBufLine();
312
if( dxfLine.size() ) {
313
graphic->addVariable("$DIMRND", dxfLine, 40);
314
//if( dxfLine.toDouble()>0.000001 ) {
315
//graphic->setDimensionExactness( dxfLine.toDouble() );
322
// Dimension over length:
331
else if( dxfLine=="$DIMEXE" ) {
332
dxfLine=getBufLine();
334
if( dxfCode.toInt()==40 ) {
335
dxfLine=getBufLine();
336
if( dxfLine.size() ) {
337
graphic->addVariable("$DIMEXE", dxfLine, 40);
338
//graphic->setDimensionOverLength( dxfLine.toDouble() );
344
// Dimension under length:
353
else if( dxfLine=="$DIMEXO" ) {
354
dxfLine=getBufLine();
356
if( dxfCode.toInt()==40 ) {
357
dxfLine=getBufLine();
358
if( dxfLine.size() ) {
359
graphic->addVariable("$DIMEXO", dxfLine, 40);
360
//graphic->setDimensionUnderLength( dxfLine.toDouble() );
367
// Angle dimension format:
376
else if( dxfLine=="$DIMAUNIT" ) {
377
dxfLine=getBufLine();
379
if( dxfCode.toInt()==70 ) {
380
dxfLine=getBufLine();
381
if( dxfLine.size() ) {
382
graphic->addVariable("$DIMAUNIT", dxfLine, 70);
384
switch( dxfLine.toInt() ) {
385
case 0: graphic->setAngleDimensionFormat( DecimalDegrees ); break;
386
case 1: graphic->setAngleDimensionFormat( DegreesMinutesSeconds ); break;
387
case 2: graphic->setAngleDimensionFormat( Gradians ); break;
388
case 3: graphic->setAngleDimensionFormat( Radians ); break;
389
case 4: graphic->setAngleDimensionFormat( Surveyor ); break;
398
// Angle dimension exactness:
400
else if( dxfLine=="$DIMADEC" ) {
401
dxfLine=getBufLine();
403
if( dxfCode.toInt()==70 ) {
404
dxfLine=getBufLine();
405
if( dxfLine.size() ) {
406
graphic->addVariable("$DIMADEC", dxfLine, 70);
407
//graphic->setAngleDimensionExactness( RS_Math::pow(0.1, dxfLine.toInt()) );
415
else if( dxfLine=="$GRIDUNIT" ) {
416
dxfLine=getBufLine();
418
if( dxfCode.toInt()==10 ) {
419
dxfLine=getBufLine();
420
if (dxfLine.size()) {
421
double x = atof(dxfLine.toLatin1().data());
422
dxfLine=getBufLine();
423
if (dxfLine.size()) {
424
double y = atof(dxfLine.toLatin1().data());
426
graphic->addVariable("$GRIDUNIT", RS_Vector(x,y), 10);
433
double gx=dxfLine.toDouble();
434
if (gx<0.0001) gx=0.0001;
435
graphic->setMinGridX(gx);
436
graphic->setGridFormat( Fractional );
438
for( double q=0.00000001; q<=100000.0; q*=10.0 ) {
439
if( mtCompFloat(gx, q, q/1000.0) ) {
440
graphic->setGridFormat( Decimal );
448
if(dxfCode=getBufLine()) {
449
if( dxfCode.toInt()==20 ) {
450
if( dxfLine=getBufLine() ) {
451
double gy=dxfLine.toDouble();
452
if (gy<0.0001) gy=0.0001;
453
graphic->setMinGridY(gy);
459
// Page limits min x/y:
461
/*else if( dxfLine=="$PLIMMIN" ) {
462
if(dxfCode=getBufLine()) {
463
if( dxfCode.toInt()==10 ) {
464
if( dxfLine=getBufLine() ) {
465
graphic->setPageOriginX( dxfLine.toDouble() );
469
if(dxfCode=getBufLine()) {
470
if( dxfCode.toInt()==20 ) {
471
if( dxfLine=getBufLine() ) {
472
graphic->setPageOriginY( dxfLine.toDouble() );
479
// Page limits min x/y:
482
else if( dxfLine=="$PLIMMAX" ) {
483
if(dxfCode=getBufLine()) {
484
if( dxfCode.toInt()==10 ) {
485
if( dxfLine=getBufLine() ) {
486
graphic->setPageSizeX( dxfLine.toDouble() - graphic->getPageOriginX() );
490
if(dxfCode=getBufLine()) {
491
if( dxfCode.toInt()==20 ) {
492
if( dxfLine=getBufLine() ) {
493
graphic->setPageSizeY( dxfLine.toDouble() - graphic->getPageOriginY() );
500
// Paper space scale:
503
else if( dxfLine=="$PSVPSCALE" ) {
504
if(dxfCode=getBufLine()) {
505
if( dxfCode.toInt()==40 ) {
506
if( dxfLine=getBufLine() ) {
507
graphic->setPaperSpace( dxfLine.toDouble() );
518
else if(dxfLine.size() &&
519
dxfLine[0]>='A' && dxfLine[0]<='Z') {
522
// End of file reached
529
else if(dxfLine=="LAYER") {
532
dxfCode=getBufLine();
534
code=dxfCode.toInt();
535
if(dxfCode.size() && code!=0) {
536
dxfLine=getBufLine();
539
case 2: // Layer name
540
if (dxfLine=="(null)" || dxfLine=="default") {
543
graphic->addLayer(new RS_Layer(dxfLine));
544
graphic->activateLayer(dxfLine);
545
currentLayer = graphic->getActiveLayer();
548
case 70: // Visibility
550
if(dxfLine.toInt()&5) {
551
if(currentLayerNum>=0 && currentLayerNum<DEF_MAXLAYERS) {
552
graphic->layer[currentLayerNum].DelFlag(Y_VISIBLE);
559
//currentLayer->setStyle( graphic->nameToStyle(dxfLine) );
560
pen.setLineType(RS_FilterDXFRW::nameToLineType(dxfLine));
562
case 39: // Thickness
563
//if(currentLayer) currentLayer->setWidth(dxfLine.toInt());
564
pen.setWidth(numberToWidth(dxfLine.toInt()));
567
pen.setColor(RS_FilterDXFRW::numberToColor(dxfLine.toInt()));
569
// currentLayer->setColor( graphic->numberToColor(dxfLine.toInt(), !oldColorNumbers));
577
} while(dxfCode.size() && code!=0);
579
currentLayer->setPen(pen);
581
//graphic->setStyle("CONTINOUS");
582
//graphic->setWidth(0);
583
//graphic->setColor(0, false);
589
else if(dxfLine=="POINT") {
591
dxfCode=getBufLine();
593
code=dxfCode.toInt();
594
if(dxfCode.size() && code!=0) {
595
dxfLine=getBufLine();
599
pen.setLineType(RS_FilterDXFRW::nameToLineType(dxfLine));
602
//if(dxfLine!=lastLayer) {
603
if (dxfLine=="(null)" || dxfLine=="default") {
606
graphic->activateLayer(dxfLine);
611
dxfLine.replace( QRegExp(","), "." );
612
vx1 = dxfLine.toDouble();
615
dxfLine.replace( QRegExp(","), "." );
616
vy1 = dxfLine.toDouble();
618
case 39: // Thickness
619
pen.setWidth(numberToWidth(dxfLine.toInt()));
622
pen.setColor(RS_FilterDXFRW::numberToColor(dxfLine.toInt()));
629
} while(dxfCode.size() && code!=0);
630
graphic->setActivePen(pen);
631
graphic->addEntity(new RS_Point(graphic,
632
RS_PointData(RS_Vector(vx1, vy1))));
638
else if(dxfLine=="LINE") {
640
dxfCode=getBufLine();
643
code=dxfCode.toInt();
644
if(dxfCode.size() && code!=0) {
646
dxfLine=getBufLine();
651
pen.setLineType(RS_FilterDXFRW::nameToLineType(dxfLine));
654
//if(dxfLine!=lastLayer) {
655
if (dxfLine=="(null)" || dxfLine=="default") {
658
graphic->activateLayer(dxfLine);
663
dxfLine.replace( QRegExp(","), "." );
664
vx1 = dxfLine.toDouble();
667
dxfLine.replace( QRegExp(","), "." );
668
vy1 = dxfLine.toDouble();
671
dxfLine.replace( QRegExp(","), "." );
672
vx2 = dxfLine.toDouble();
675
dxfLine.replace( QRegExp(","), "." );
676
vy2 = dxfLine.toDouble();
678
case 39: // Thickness
679
pen.setWidth(numberToWidth(dxfLine.toInt()));
682
pen.setColor(RS_FilterDXFRW::numberToColor(dxfLine.toInt()));
689
} while(dxfCode.size() && code!=0);
691
//if(!mtCompFloat(vx1, vx2) || !mtCompFloat(vy1, vy2)) {
692
//graphic->addLine(vx1, vy1, vx2, vy2, currentLayerNum, add);
693
graphic->setActivePen(pen);
694
graphic->addEntity(new RS_Line(graphic,
695
RS_LineData(RS_Vector(vx1, vy1), RS_Vector(vx2, vy2))));
703
else if(dxfLine=="ARC") {
705
dxfCode=getBufLine();
707
code=dxfCode.toInt();
708
if(dxfCode.size() && code!=0) {
709
dxfLine=getBufLine();
713
pen.setLineType(RS_FilterDXFRW::nameToLineType(dxfLine));
716
//if(dxfLine!=lastLayer) {
717
if (dxfLine=="(null)" || dxfLine=="default") {
720
graphic->activateLayer(dxfLine);
725
dxfLine.replace( QRegExp(","), "." );
726
vcx = dxfLine.toDouble();
729
dxfLine.replace( QRegExp(","), "." );
730
vcy = dxfLine.toDouble();
733
dxfLine.replace( QRegExp(","), "." );
734
vcr = dxfLine.toDouble();
736
case 50: // Start Angle
737
dxfLine.replace( QRegExp(","), "." );
738
va1 = RS_Math::correctAngle(dxfLine.toDouble()/ARAD);
740
case 51: // End Angle
741
dxfLine.replace( QRegExp(","), "." );
742
va2 = RS_Math::correctAngle(dxfLine.toDouble()/ARAD);
744
case 39: // Thickness
745
pen.setWidth(numberToWidth(dxfLine.toInt()));
748
pen.setColor(RS_FilterDXFRW::numberToColor(dxfLine.toInt()));
755
} while(dxfCode.size() && code!=0);
756
//if(vcr>0.0 && !mtCompFloat(va1, va2)) {
757
// graphic->addArc(vcx, vcy, vcr, va1, va2, false, currentLayerNum, add);
759
graphic->setActivePen(pen);
760
graphic->addEntity(new RS_Arc(graphic,
761
RS_ArcData(RS_Vector(vcx, vcy),
762
vcr, va1, va2, false)));
768
else if(dxfLine=="CIRCLE") {
770
dxfCode=getBufLine();
772
code=dxfCode.toInt();
773
if(dxfCode.size() && code!=0) {
774
dxfLine=getBufLine();
778
pen.setLineType(RS_FilterDXFRW::nameToLineType(dxfLine));
781
//if(dxfLine!=lastLayer) {
782
if (dxfLine=="(null)" || dxfLine=="default") {
785
graphic->activateLayer(dxfLine);
790
dxfLine.replace( QRegExp(","), "." );
791
vcx = dxfLine.toDouble();
794
dxfLine.replace( QRegExp(","), "." );
795
vcy = dxfLine.toDouble();
798
dxfLine.replace( QRegExp(","), "." );
799
vcr = dxfLine.toDouble();
801
case 39: // Thickness
802
pen.setWidth(numberToWidth(dxfLine.toInt()));
805
pen.setColor(RS_FilterDXFRW::numberToColor(dxfLine.toInt()));
812
} while(dxfCode.size() && code!=0);
814
graphic->addCircle(vcx, vcy, vcr, 0.0, 360.0, false, currentLayerNum, add);
816
graphic->setActivePen(pen);
817
graphic->addEntity(new RS_Circle(graphic,
818
RS_CircleData(RS_Vector(vcx, vcy),
827
if(dxfLine=="HATCH") {
829
dxfCode=getBufLine();
830
if(dxfCode) code=dxfCode.toInt();
831
if(dxfCode && code!=0) {
832
dxfLine=getBufLine();
836
// if(dxfLine!=lastLayer) {
837
if (dxfLine=="(null)" || dxfLine=="default") {
840
graphic->activateLayer(dxfLine);
845
vx1 = dxfLine.toDouble();
848
vy1 = dxfLine.toDouble();
849
//graphic->Vec[vc].CreatePoint(vy1, vx1, currentLayerNum);
850
//if(vc<vElements-1) ++vc;
853
vx2 = dxfLine.toDouble();
856
vy2 = dxfLine.toDouble();
857
//graphic->Vec[vc].CreatePoint(vy2, vx2, currentLayerNum);
858
//if(vc<vElements-1) ++vc;
865
}while(dxfCode && code!=0);
867
if(!mt.CompFloat(vx1, vx2) || !mt.CompFloat(vy1, vy2)) {
868
graphic->Vec[vc].CreateLine(vx1, vy1, vx2, vy2, currentLayerNum);
869
if(vc<vElements-1) ++vc;
871
if(++updProgress==1000) {
872
np->getStateWin()->UpdateProgressBar((int)(pcFact*vc)+25);
883
else if(dxfLine=="TEXT") {
885
QString vtext; // the text
886
char vtextStyle[256]; // text style (normal_ro, cursive_ri, normal_st, ...)
887
double vheight=10.0; // text height
888
double vtextAng=0.0; // text angle
889
//double vradius=0.0; // text radius
890
//double vletterspace=2.0; // Text letter space
891
//double vwordspace=6.0; // Text wordspace
892
QString vfont; // font "normal", "cursive", ...
893
RS_MTextData::HAlign vhalign=RS_MTextData::HALeft;
894
// alignment (0=left, 1=center, 2=right)
895
//int vattachement=7; // 1=top left, 2, 3, 4, 5, 6, 7, 8, 9=bottom right
896
//unsigned vfl=0; // special flags
897
//RLZ: unused bool codeSeven=false; // Have we found a code seven?
899
vtextStyle[0] = '\0';
903
dxfCode=getBufLine();
905
code=dxfCode.toInt();
906
if(dxfCode.size() && code!=0) {
907
if(code!=1 && code!=3 && code!=7)
908
dxfLine=getBufLine();
909
if(dxfLine.size() || code==1 || code==3 || code==7) {
913
case 1: // Text itself
915
strDecodeDxfString(vtext);
918
case 3: // Text parts (always 250 chars)
923
pen.setLineType(RS_FilterDXFRW::nameToLineType(dxfLine));
927
// Text style (normal_ro#50.0,
928
// cursive_ri#20.0, normal_st)
929
qstrncpy(vtextStyle, getBufLine().toLatin1().data(), 249);
935
sscanf(vtextStyle, "%[^_#\n]", dummy);
942
if(strstr(vtextStyle, "_ro"))
944
else if(strstr(vtextStyle, "_ri"))
951
/*if(strstr(vtextStyle, "_fix")) {
952
vfl=vfl|E_FIXEDWIDTH;
955
// get radius, letterspace, wordspace:
958
char *ptr; // pointer to value
959
ptr = strchr(vtextStyle, '#');
962
/*if(vfl&E_ROUNDOUT || vfl&E_ROUNDIN) {
965
sscanf(ptr, "%lf", &vradius);
967
ptr = strchr(ptr, '#');
970
// Parse letter space:
973
sscanf(ptr, "%lf", &vletterspace);
976
ptr = strchr(ptr, '#');
980
sscanf(ptr, "%lf", &vwordspace);
986
//RLZ: unused codeSeven=true;
990
//if(dxfLine!=lastLayer) {
991
if (dxfLine=="(null)" || dxfLine=="default") {
994
graphic->activateLayer(dxfLine);
1000
dxfLine.replace( QRegExp(","), "." );
1001
vx1 = dxfLine.toDouble();
1004
dxfLine.replace( QRegExp(","), "." );
1005
vy1 = dxfLine.toDouble();
1008
dxfLine.replace( QRegExp(","), "." );
1009
vheight = dxfLine.toDouble();
1011
vletterspace = vheight*0.2;
1012
vwordspace = vheight*0.6;
1016
dxfLine.replace( QRegExp(","), "." );
1017
vtextAng = dxfLine.toDouble() / ARAD;
1019
case 72: {// alignment
1021
int v = dxfLine.toInt();
1023
vhalign = RS_MTextData::HACenter;
1025
vhalign = RS_MTextData::HARight;
1027
vhalign = RS_MTextData::HALeft;
1031
case 39: // Thickness
1032
pen.setWidth(numberToWidth(dxfLine.toInt()));
1035
pen.setColor(RS_FilterDXFRW::numberToColor(dxfLine.toInt()));
1042
} while(dxfCode.size() && code!=0);
1043
char* i=strchr(vtextStyle, '#');
1048
new RS_MText(graphic,
1050
RS_Vector(vx1, vy1),
1053
RS_MTextData::VABottom,
1055
RS_MTextData::LeftToRight,
1056
RS_MTextData::Exact,
1069
else if(dxfLine=="DIMENSION") {
1071
double v10=0.0, v20=0.0;
1072
double v13=0.0, v23=0.0;
1073
double v14=0.0, v24=0.0;
1074
double v15=0.0, v25=0.0;
1075
double v16=0.0, v26=0.0;
1076
double v40=0.0, v50=0.0;
1079
dxfCode=getBufLine();
1080
if(dxfCode.size()) {
1081
code=dxfCode.toInt();
1083
if(dxfCode.size() && code!=0) {
1084
dxfLine=getBufLine();
1085
if(dxfLine.size()) {
1087
case 1: // Text (if any)
1090
// Mend unproper savings of older versions:
1091
if(dimText==" " || dimText==";;")
1094
//else dimText.replace(QRegExp("%%c"), "¯");
1096
strDecodeDxfString(dimText);
1099
pen.setLineType(RS_FilterDXFRW::nameToLineType(dxfLine));
1102
//if(dxfLine!=lastLayer) {
1103
if (dxfLine=="(null)" || dxfLine=="default") {
1106
graphic->activateLayer(dxfLine);
1107
//lastLayer=dxfLine;
1110
case 10: // line position x
1111
dxfLine.replace( QRegExp(","), "." );
1112
v10 = dxfLine.toDouble();
1114
case 20: // line position y
1115
dxfLine.replace( QRegExp(","), "." );
1116
v20 = dxfLine.toDouble();
1119
dxfLine.replace( QRegExp(","), "." );
1120
v13 = dxfLine.toDouble();
1123
dxfLine.replace( QRegExp(","), "." );
1124
v23 = dxfLine.toDouble();
1127
dxfLine.replace( QRegExp(","), "." );
1128
v14 = dxfLine.toDouble();
1131
dxfLine.replace( QRegExp(","), "." );
1132
v24 = dxfLine.toDouble();
1135
dxfLine.replace( QRegExp(","), "." );
1136
v15 = dxfLine.toDouble();
1139
dxfLine.replace( QRegExp(","), "." );
1140
v25 = dxfLine.toDouble();
1143
dxfLine.replace( QRegExp(","), "." );
1144
v16 = dxfLine.toDouble();
1147
dxfLine.replace( QRegExp(","), "." );
1148
v26 = dxfLine.toDouble();
1151
dxfLine.replace( QRegExp(","), "." );
1152
v40 = dxfLine.toDouble();
1155
dxfLine.replace( QRegExp(","), "." );
1156
v50 = dxfLine.toDouble();
1159
typ = dxfLine.toInt();
1161
case 39: // Thickness
1162
pen.setWidth(numberToWidth(dxfLine.toInt()));
1165
pen.setColor(RS_FilterDXFRW::numberToColor(dxfLine.toInt()));
1173
} while(dxfCode.size() && code!=0);
1177
// Remove Bit values:
1179
typ-=128; // Location of Text
1182
typ-= 64; // Ordinate
1192
RS_Vector(v10, v20),
1193
RS_Vector(0.0, 0.0),
1194
RS_MTextData::VABottom,
1195
RS_MTextData::HACenter,
1196
RS_MTextData::Exact,
1203
RS_Vector(v13, v23),
1204
RS_Vector(v14, v24),
1210
graphic->addEntity(d);
1217
RS_Vector(v13, v23).angleTo(RS_Vector(v10,v20));
1219
RS_Vector(v13, v23).distanceTo(RS_Vector(v10,v20));
1222
defP.setPolar(dist, angle);
1223
defP+=RS_Vector(v14, v24);
1230
RS_Vector(0.0, 0.0),
1231
RS_MTextData::VABottom,
1232
RS_MTextData::HACenter,
1233
RS_MTextData::Exact,
1240
RS_Vector(v13, v23),
1245
graphic->addEntity(d);
1252
RS_LineData(RS_Vector(v13, v23),
1253
RS_Vector(v14, v24)));
1255
RS_LineData(RS_Vector(v10, v20),
1256
RS_Vector(v15, v25)));
1258
RS_VectorSolutions s;
1259
//bool inters=false;
1260
//tmpEl1.getIntersection(&tmpEl2,
1261
// &inters, &vcx, &vcy, 0,0,0,0, false);
1262
s = RS_Information::getIntersection(
1265
if (s.get(0).valid) {
1268
//vcr = RS_Vector(vcx, vcy).distanceTo(v16, v26);
1270
/*if(RS_Vector(vcx,vcy).distanceTo(v13,v23)<vcr) {
1271
va1 = tl1.getAngle1();
1273
va1 = tl2.getAngle2();
1276
if(RS_Vector(vcx,vcy).distanceTo(v10,v20)<vcr) {
1277
va2 = tl2.getAngle1();
1279
va2 = tl2.getAngle2();
1283
graphic->addDimension(vcx, vcy, va1, va2,
1284
mtGetDistance(vcx, vcy, v13, v23),
1285
mtGetDistance(vcx, vcy, v10, v20),
1297
RS_Vector(v10, v20),
1298
RS_Vector(0.0, 0.0),
1299
RS_MTextData::VABottom,
1300
RS_MTextData::HACenter,
1301
RS_MTextData::Exact,
1308
RS_Vector(v13, v23),
1309
RS_Vector(vcx, vcy),
1310
RS_Vector(vcx, vcy),
1315
graphic->addEntity(d);
1323
graphic->addDimension(v10, v20, v15, v25,
1326
E_STRAIGHT|E_RADIUS,
1333
.angleTo(RS_Vector(v15, v25));
1335
v2.setPolar(v40, ang);
1340
RS_Vector(v10, v20),
1341
RS_Vector(0.0, 0.0),
1342
RS_MTextData::VABottom,
1343
RS_MTextData::HACenter,
1344
RS_MTextData::Exact,
1351
RS_Vector(v10, v20) + v2,
1356
graphic->addEntity(d);
1363
graphic->addDimension(v13, v23, v14, v24,
1372
.angleTo(RS_Vector(v15, v25));
1374
v2.setPolar(v40, ang);
1375
RS_DimDiametric* d =
1376
new RS_DimDiametric(
1379
RS_Vector(v10, v20),
1380
RS_Vector(0.0, 0.0),
1389
RS_DimDiametricData(
1390
RS_Vector(v10, v20) + v2,
1395
graphic->addEntity(d);
1397
RS_LeaderData data(true);
1399
new RS_Leader(graphic, data);
1400
d->addVertex(RS_Vector(v14, v24));
1401
d->addVertex(RS_Vector(v10, v20));
1403
graphic->addEntity(d);
1407
//graphic->elementCurrent()->setText(dimText);
1416
else if(dxfLine=="HATCH") {
1417
QString patternName="45";
1418
double patternScale=1.0;
1421
int nextObjectTyp=T_LINE;
1422
double v10=0.0, v20=0.0,
1427
dxfCode=getBufLine();
1428
if(dxfCode) code=dxfCode.toInt();
1429
if(dxfCode && code!=0) {
1430
dxfLine=getBufLine();
1434
patternName = dxfLine;
1437
pen.setLineType(RS_FilterDXF::nameToLineType(dxfLine));
1440
// if(dxfLine!=lastLayer) {
1441
if (dxfLine=="(null)" || dxfLine=="default") {
1444
graphic->activateLayer(dxfLine);
1445
//lastLayer=dxfLine;
1448
case 10: // Start point/center of boundary line/arc
1449
dxfLine.replace( QRegExp(","), "." );
1450
v10=dxfLine.toDouble();
1452
case 20: // Start point/center of boundary line/arc
1453
dxfLine.replace( QRegExp(","), "." );
1454
v20=dxfLine.toDouble();
1456
case 11: // End point of boundary line
1457
dxfLine.replace( QRegExp(","), "." );
1458
v11=dxfLine.toDouble();
1460
case 21: // End point of boundary line
1461
dxfLine.replace( QRegExp(","), "." );
1462
v21=dxfLine.toDouble();
1463
if(nextObjectTyp==T_LINE) {
1464
int elnu=graphic->addLine(v10, v20, v11, v21, currentLayerNum, add);
1465
graphic->elementAt(elnu)->setFlag(E_TAGGED);
1468
case 40: // Radius of boundary entity
1469
dxfLine.replace( QRegExp(","), "." );
1470
v40=dxfLine.toDouble();
1472
case 50: // Start angle
1473
dxfLine.replace( QRegExp(","), "." );
1474
v50=dxfLine.toDouble();
1476
case 51: // End angle
1477
dxfLine.replace( QRegExp(","), "." );
1478
v51=dxfLine.toDouble();
1480
case 73: // Counterclockwise?
1481
if(nextObjectTyp==T_ARC) {
1483
if( mtCompFloat( v50, 0.0 ) && mtCompFloat( v51, 0.0 ) ) {
1484
elnu=graphic->addCircle(v10, v20, v40, 0.0, 360.0, (bool)dxfLine.toInt(), currentLayerNum, add);
1487
elnu=graphic->addArc(v10, v20, v40, v50, v51, (bool)dxfLine.toInt(), currentLayerNum, add);
1489
graphic->elementAt(elnu)->setFlag(E_TAGGED);
1490
//newEl = new RElement( graphic );
1491
//newEl->createArc(v10, v20, v40, v50, v51, (bool)dxfLine.toInt());
1492
//boundaryList.append(newEl);
1496
dxfLine.replace( QRegExp(","), "." );
1497
patternScale=dxfLine.toDouble();
1502
case 70: // Solid (=1) or pattern (=0)
1505
case 39: // Thickness
1506
pen.setWidth(RS_FilterDXF::numberToWidth(dxfLine.toInt()));
1509
pen.setColor(RS_FilterDXF::numberToColor(dxfLine.toInt()));
1511
case 91: // Number of boundary paths (loops)
1512
//numPaths=dxfLine.toInt();
1514
case 92: // Typ of boundary
1517
case 93: // Number of edges in this boundary
1518
//numEdges=dxfLine.toInt();
1520
case 72: // Edge typ
1521
switch(dxfLine.toInt()) {
1522
case 1: nextObjectTyp=T_LINE; break;
1523
case 2: nextObjectTyp=T_ARC; break;
1533
}while(dxfCode && code!=0);
1535
graphic->addHatching(patternScale,
1540
graphic->editDelete(false);
1547
while(dxfLine.size() && dxfLine!="EOF");
1549
//graphic->terminateAction();
1551
//graphic->debugElements();
1567
* Resets the whole object
1570
void RS_FilterDXF1::reset() {
1585
* Reset buffer pointer to the beginning of the buffer:
1587
void RS_FilterDXF1::resetBufP() {
1594
* Set buffer pointer to the given index:
1596
void RS_FilterDXF1::setBufP(int _fBufP) {
1597
if(_fBufP<(int)fSize) {
1606
void RS_FilterDXF1::delBuffer() {
1616
* Remove any 13-characters in the buffer:
1618
void RS_FilterDXF1::dos2unix() {
1619
char *src = fBuf, *dst = fBuf;
1624
while (*src != '\0') {
1637
// Get next line in the buffer:
1638
// and overread ALL seperators
1640
// return: -Null-string: end of buffer
1641
// -String which is the next line in buffer
1643
QString RS_FilterDXF1::getBufLine() {
1647
if (fBufP >= (int)fSize)
1648
return QString::null;
1653
/*if (*ret == '\0' && noEmptyLines) {
1654
while (++fBufP < (int)fSize && fBuf[fBufP] == '\0')
1656
if (fBufP >= (int)fSize)
1657
return QString::null;
1661
// Move fBufP pointer to the next line
1662
while (fBufP < (int)fSize && fBuf[fBufP++] != '\0')
1665
str = QString::fromLocal8Bit(ret).simplified();
1677
// Get next line in the buffer:
1678
// and overread ALL seperators
1680
// return: -Null-string: end of buffer
1681
// -String which is the next line in buffer
1683
char* RS_FilterDXF1::getBufLineCh() {
1686
if (fBufP >= (int)fSize)
1692
/*if (*ret == '\0' && noEmptyLines) {
1693
while (++fBufP < (int)fSize && fBuf[fBufP] == '\0')
1695
if (fBufP >= (int)fSize)
1700
// Move fBufP pointer to the next line
1701
while (fBufP < (int)fSize && fBuf[fBufP++] != '\0')
1709
// Copy buffer from a given string:
1711
void RS_FilterDXF1::copyBufFrom(const char* _buf) {
1713
fBuf = new char[strlen(_buf)+16];
1720
// Go to the next '_lstr'-line in buffer:
1722
// return: true: line found
1723
// false: end of buffer
1725
bool RS_FilterDXF1::gotoBufLine(char* _lstr) {
1729
} while(!l.isNull() && l!=_lstr);
1738
// Goto next line where the string _lstr appears:
1740
// return: true: string in line found
1741
// false: end of buffer
1744
bool RS_FilterDXF1::gotoBufLineString(char* _lstr) {
1748
} while(!l.isNull() && l.contains(_lstr));
1757
// Replace bynary Bytes (<32) by an other (given) byte:
1759
void RS_FilterDXF1::replaceBinaryBytesBy(char _c) {
1762
for(bc=0; bc<(int)fSize; ++bc) {
1763
if(fBuf[bc]<32 && fBuf[bc]>=0) {
1771
// Separate buffer (change chars sc1 and sc2 in '\0'
1773
void RS_FilterDXF1::separateBuf(char _c1,
1779
for(bc=0; bc<(int)fSize; ++bc) {
1780
if(fBuf[bc]==_c1 || fBuf[bc]==_c2 ||
1781
fBuf[bc]==_c3 || fBuf[bc]==_c4 ) {
1789
// remove comment between '_fc' and '_lc'
1790
// comments get replaced by '\0'
1792
void RS_FilterDXF1::removeComment(char _fc, char _lc) {
1793
bool rem=false; // Are we removing currrently?
1796
for(bc=0; bc<(int)fSize; ++bc) {
1810
// Read file '_name' in buffer (buf)
1812
// '_bNum' : Max number of Bytes
1814
// return: true: successful
1815
// false: file not found
1817
bool RS_FilterDXF1::readFileInBuffer(char* _name, int _bNum) {
1818
file.setFileName(_name);
1819
return readFileInBuffer(_bNum);
1824
// Read file in buffer (buf)
1826
// 'bNum' : Max number of Bytes
1828
// return: true: successful
1829
// false: file not found
1831
bool RS_FilterDXF1::readFileInBuffer(int _bNum) {
1832
fPointer = fopen(name.toLatin1().data(), "rb");//RLZ verify with locales
1833
if(fPointer!=NULL) {
1834
if(file.open(fPointer, QIODevice::ReadOnly)) {
1839
fBuf = new char[_bNum+16];
1841
file.read(fBuf, _bNum);
1847
// Convert 13/10 to 10
1858
// Decode a DXF string to the C-convention (special character \P is a \n)
1860
void RS_FilterDXF1::strDecodeDxfString(QString& str) {
1863
str.replace(QRegExp("%%c"), QChar(0xF8)); // Diameter
1864
str.replace(QRegExp("%%d"), QChar(0xB0)); // Degree
1865
str.replace(QRegExp("%%p"), QChar(0xB1)); // Plus/minus
1866
str.replace(QRegExp("\\\\[pP]"), QChar('\n'));
1872
// Compare two double values:
1874
// return: true: values are equal
1875
// false: values are not equal
1877
bool RS_FilterDXF1::mtCompFloat(double _v1, double _v2, double _tol) {
1878
double delta = _v2-_v1;
1880
if(delta>-_tol && delta<_tol)
1887
* Converts a line width number (e.g. 1) into a RS2::LineWidth.
1889
RS2::LineWidth RS_FilterDXF1::numberToWidth(int num) {
1892
return RS2::WidthByLayer;
1895
return RS2::WidthByBlock;
1898
return RS2::WidthDefault;
1902
return RS2::Width00;
1904
return RS2::Width01;
1905
} else if (num<11) {
1906
return RS2::Width02;
1907
} else if (num<14) {
1908
return RS2::Width03;
1909
} else if (num<16) {
1910
return RS2::Width04;
1911
} else if (num<19) {
1912
return RS2::Width05;
1913
} else if (num<22) {
1914
return RS2::Width06;
1915
} else if (num<27) {
1916
return RS2::Width07;
1917
} else if (num<32) {
1918
return RS2::Width08;
1919
} else if (num<37) {
1920
return RS2::Width09;
1921
} else if (num<45) {
1922
return RS2::Width10;
1923
} else if (num<52) {
1924
return RS2::Width11;
1925
} else if (num<57) {
1926
return RS2::Width12;
1927
} else if (num<65) {
1928
return RS2::Width13;
1929
} else if (num<75) {
1930
return RS2::Width14;
1931
} else if (num<85) {
1932
return RS2::Width15;
1933
} else if (num<95) {
1934
return RS2::Width16;
1935
} else if (num<103) {
1936
return RS2::Width17;
1937
} else if (num<112) {
1938
return RS2::Width18;
1939
} else if (num<130) {
1940
return RS2::Width19;
1941
} else if (num<149) {
1942
return RS2::Width20;
1943
} else if (num<180) {
1944
return RS2::Width21;
1945
} else if (num<205) {
1946
return RS2::Width22;
1948
return RS2::Width23;
1952
return (RS2::LineWidth)num;
1958
* Converts a RS2::LineWidth into an int width.
1960
int RS_FilterDXF1::widthToNumber(RS2::LineWidth width) {
1962
case RS2::WidthByLayer:
1965
case RS2::WidthByBlock:
1968
case RS2::WidthDefault: