Skip to content

Commit fb81ce6

Browse files
committed
backport dwg import fixes
fec20ae dwg import: less noisy noise reduction 3aa2d9f dwg import: catch spline misinterpretation (fixes #20392) 1a96982 dwg import: fix handling of arc and splines in hatches 6090a93 dwg import: less noisy debugging 92e7faa dwg/dxf import: fix angle and alignment handing of (m)texts 0f6421d dwg import: use Q_DECLARE_TR_FUNCTIONS in QgsDwgImporter f12cac7 dwg import: progress display e1562a7 dwg import: support dxf encoding (fixes #15999) b8c727f dwg import: force polyline and hatch/ring continuity 355deb5 dwg import: fix exception (fixes #21177) d84c34e dwg import: support nested blocks (refs #20392) fd15c3e dwg import: handle wrong hatch interpretation (refs #20392)
1 parent 36a1046 commit fb81ce6

File tree

13 files changed

+743
-340
lines changed

13 files changed

+743
-340
lines changed

external/libdxfrw/drw_entities.cpp

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,29 @@
1010
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
1111
******************************************************************************/
1212

13+
// uncomment to get detailed debug output on DWG read. Caution: this option makes DWG import super-slow!
14+
// #define DWGDEBUG 1
15+
1316
#include <cstdlib>
1417

1518
#include "drw_entities.h"
1619
#include "intern/dxfreader.h"
1720
#include "intern/dwgbuffer.h"
1821
#include "intern/drw_dbg.h"
1922

20-
#undef QGISDEBUG
21-
#include "qgslogger.h"
2223
#include <QStringList>
2324

25+
#include "qgslogger.h"
26+
27+
#ifndef DWGDEBUG
28+
#undef QgsDebugCall
29+
#undef QgsDebugMsg
30+
#undef QgsDebugMsgLevel
31+
#define QgsDebugCall
32+
#define QgsDebugMsg(str)
33+
#define QgsDebugMsgLevel(str, level)
34+
#endif
35+
2436
#define RESERVE( vector, size ) try { \
2537
vector.reserve(size); \
2638
} catch(const std::exception &e) { \
@@ -436,7 +448,7 @@ bool DRW_Entity::parseDwg( DRW::Version version, dwgBuffer *buf, dwgBuffer *strB
436448
duint8 unk = buf->getBit();
437449
QgsDebugMsg( QString( "unknown bit: %1" ).arg( unk ) );
438450
}
439-
#endif
451+
#endif // 0
440452
return buf->isGood();
441453
}
442454

@@ -1537,7 +1549,7 @@ bool DRW_LWPolyline::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs
15371549
#if 0
15381550
if ( vertlist.size() < i )
15391551
vertlist.at( i )->vertexId = vertexId;
1540-
#endif
1552+
#endif // 0
15411553
}
15421554
}
15431555
//add widths
@@ -1592,7 +1604,7 @@ void DRW_Text::parseCode( int code, dxfReader *reader )
15921604
angle = reader->getDouble() / ARAD;
15931605
break;
15941606
case 51:
1595-
oblique = reader->getDouble();
1607+
oblique = reader->getDouble() / ARAD;
15961608
break;
15971609
case 71:
15981610
textgen = reader->getInt32();
@@ -1789,6 +1801,7 @@ bool DRW_MText::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs )
17891801

17901802
extPoint = buf->get3BitDouble(); /* Extrusion 3BD 210 Undocumented; */
17911803
secPoint = buf->get3BitDouble(); /* X-axis dir 3BD 11 */
1804+
haveXAxis = true;
17921805
updateAngle();
17931806
widthscale = buf->getBitDouble(); /* Rect width BD 41 */
17941807
if ( version > DRW::AC1018 ) //2007+
@@ -2178,7 +2191,7 @@ void DRW_Hatch::parseCode( int code, dxfReader *reader )
21782191
else if ( ellipse ) ellipse->endparam = reader->getDouble() / ARAD;
21792192
break;
21802193
case 52:
2181-
angle = reader->getDouble();
2194+
angle = reader->getDouble() / ARAD;
21822195
break;
21832196
case 73:
21842197
if ( arc ) arc->isccw = reader->getInt32();
@@ -2320,7 +2333,7 @@ bool DRW_Hatch::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs )
23202333

23212334
QgsDebugMsg( QString( "segs: %1" ).arg( numPathSeg ) );
23222335

2323-
for ( dint32 j = 0; j < numPathSeg; ++j )
2336+
for ( dint32 j = 0; j < numPathSeg && buf->isGood(); ++j )
23242337
{
23252338
duint8 typePath = buf->getRawChar8();
23262339
QgsDebugMsg( QString( " typepath: %1" ).arg( typePath ) );
@@ -2364,15 +2377,26 @@ bool DRW_Hatch::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs )
23642377
.arg( spline->nknots ).arg( spline->ncontrol )
23652378
);
23662379
RESERVE( spline->knotslist, spline->nknots );
2367-
for ( dint32 j = 0; j < spline->nknots; ++j )
2380+
dint32 j;
2381+
for ( j = 0; j < spline->nknots && buf->isGood(); ++j )
23682382
{
23692383
spline->knotslist.push_back( buf->getBitDouble() );
23702384
QgsDebugMsg( QString( " knot %1: %2" ).arg( j )
23712385
.arg( spline->knotslist.back() )
23722386
);
23732387
}
2388+
2389+
if ( !buf->isGood() )
2390+
{
2391+
QgsDebugMsg( QStringLiteral( "NOT GOOD at %1! degree:%2 flags:0x%3 nknots:%4 ncontrol:%5" )
2392+
.arg( j )
2393+
.arg( spline->degree ).arg( spline->flags, 0, 16 )
2394+
.arg( spline->nknots ).arg( spline->ncontrol )
2395+
);
2396+
}
2397+
23742398
RESERVE( spline->controllist, spline->ncontrol );
2375-
for ( dint32 j = 0; j < spline->ncontrol && buf->isGood(); ++j )
2399+
for ( j = 0; j < spline->ncontrol && buf->isGood(); ++j )
23762400
{
23772401
DRW_Coord *crd = new DRW_Coord( buf->get2RawDouble() );
23782402
spline->controllist.push_back( crd );
@@ -2933,10 +2957,10 @@ void DRW_Dimension::parseCode( int code, dxfReader *reader )
29332957
rot = reader->getDouble();
29342958
break;
29352959
case 50:
2936-
angle = reader->getDouble();
2960+
angle = reader->getDouble() / ARAD;
29372961
break;
29382962
case 52:
2939-
oblique = reader->getDouble();
2963+
oblique = reader->getDouble() / ARAD;
29402964
break;
29412965
case 40:
29422966
length = reader->getDouble();

external/libdxfrw/drw_header.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,30 @@
1010
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
1111
******************************************************************************/
1212

13+
// uncomment to get detailed debug output on DWG read. Caution: this option makes DWG import super-slow!
14+
// #define DWGDEBUG 1
15+
1316
#include "drw_header.h"
1417
#include "intern/dxfreader.h"
1518
#include "intern/dxfwriter.h"
1619
#include "intern/drw_dbg.h"
1720
#include "intern/dwgbuffer.h"
1821

19-
#include "qgslogger.h"
2022
#include <QStringList>
2123

2224
#include <cassert>
2325

26+
#include "qgslogger.h"
27+
28+
#ifndef DWGDEBUG
29+
#undef QgsDebugCall
30+
#undef QgsDebugMsg
31+
#undef QgsDebugMsgLevel
32+
#define QgsDebugCall
33+
#define QgsDebugMsg(str)
34+
#define QgsDebugMsgLevel(str, level)
35+
#endif
36+
2437
DRW_Header::DRW_Header()
2538
: curr( nullptr )
2639
, version( DRW::AC1021 )

external/libdxfrw/drw_objects.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
1111
******************************************************************************/
1212

13+
// uncomment to get detailed debug output on DWG read. Caution: this option makes DWG import super-slow!
14+
// #define DWGDEBUG 1
15+
1316
#include <iostream>
1417
#include <cmath>
1518

@@ -20,10 +23,19 @@
2023
#include "intern/drw_dbg.h"
2124
#include "intern/dwgutil.h"
2225

23-
#undef QGISDEBUG
24-
#include "qgslogger.h"
2526
#include <QStringList>
2627

28+
#include "qgslogger.h"
29+
30+
#ifndef DWGDEBUG
31+
#undef QgsDebugCall
32+
#undef QgsDebugMsg
33+
#undef QgsDebugMsgLevel
34+
#define QgsDebugCall
35+
#define QgsDebugMsg(str)
36+
#define QgsDebugMsgLevel(str, level)
37+
#endif
38+
2739
#define RESERVE( vector, size ) try { \
2840
vector.reserve(size); \
2941
} catch(const std::exception &e) { \

external/libdxfrw/intern/drw_textcodec.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,8 @@ std::string DRW_Converter::encodeNum( int c )
296296
return std::string( ( char * )ret );
297297
}
298298

299-
/** 's' is a string with at least 4 bytes length
299+
/**
300+
* 's' is a string with at least 4 bytes length
300301
** returned 'b' is byte length of encoded char: 2,3 or 4
301302
**/
302303
int DRW_Converter::decodeNum( std::string s, int *b )

external/libdxfrw/intern/dwgbuffer.cpp

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,23 @@
1010
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
1111
******************************************************************************/
1212

13+
// uncomment to get detailed debug output on DWG read. Caution: this option makes DWG import super-slow!
14+
// #define DWGDEBUG 1
1315

1416
#include "dwgbuffer.h"
1517
#include "../libdwgr.h"
1618
#include "drw_textcodec.h"
1719
#include "drw_dbg.h"
1820

19-
#undef QGISDEBUG
2021
#include "qgslogger.h"
2122

22-
#if 0
23-
//#include <bitset>
24-
#include <fstream>
25-
#include <algorithm>
26-
#include <sstream>
27-
#include "dwgreader.h"
28-
#include "dxfwriter.h"
29-
30-
#define FIRSTHANDLE 48
31-
32-
enum sections
33-
{
34-
secUnknown,
35-
secHeader,
36-
secTables,
37-
secBlocks,
38-
secEntities,
39-
secObjects
40-
};
23+
#ifndef DWGDEBUG
24+
#undef QgsDebugCall
25+
#undef QgsDebugMsg
26+
#undef QgsDebugMsgLevel
27+
#define QgsDebugCall
28+
#define QgsDebugMsg(str)
29+
#define QgsDebugMsgLevel(str, level)
4130
#endif
4231

4332
static unsigned int crctable[256] =
@@ -711,7 +700,8 @@ std::string dwgBuffer::getCP8Text()
711700

712701
//TU unicode 16 bit (UCS) text converted to utf8
713702

714-
/** Reads 2-bytes char (UCS2, nullptr terminated) and convert to std::string (only for Latin-1)
703+
/**
704+
* Reads 2-bytes char (UCS2, nullptr terminated) and convert to std::string (only for Latin-1)
715705
ts= total input size in bytes.
716706
**/
717707
std::string dwgBuffer::getUCSStr( duint16 ts )
@@ -919,31 +909,31 @@ duint32 dwgBuffer::getEnColor( DRW::Version v, int &rgb, int &transparency )
919909
transparency = 0;
920910

921911
duint16 idx = getBitShort();
922-
QgsDebugMsg( QString( "idx reads COLOR: 0x%1" ).arg( idx, 0, 16 ) );
912+
QgsDebugMsgLevel( QString( "idx reads COLOR: 0x%1" ).arg( idx, 0, 16 ), 4 );
923913

924914
duint16 flags = idx >> 8;
925915

926916
idx = idx & 0x1FF; //RLZ: warning this is correct?
927917

928-
QgsDebugMsg( QString( "flag COLOR:0x%1, index COLOR:0x%2" ).arg( flags, 0, 16 ).arg( idx, 0, 16 ) );
918+
QgsDebugMsgLevel( QString( "flag COLOR:0x%1, index COLOR:0x%2" ).arg( flags, 0, 16 ).arg( idx, 0, 16 ), 4 );
929919

930920
if ( flags & 0x80 )
931921
{
932922
// complex color (rgb)
933923
rgb = getBitLong() & 0xffffff;
934924

935-
QgsDebugMsg( QString( "RGB COLOR:0x%1" ).arg( rgb, 0, 16 ) );
925+
QgsDebugMsgLevel( QString( "RGB COLOR:0x%1" ).arg( rgb, 0, 16 ), 4 );
936926

937927
if ( flags & 0x80 )
938928
{
939-
QgsDebugMsg( "acdbColor COLOR are present" );
929+
QgsDebugMsgLevel( "acdbColor COLOR are present", 4 );
940930
}
941931
}
942932

943933
if ( flags & 0x20 )
944934
{
945935
transparency = getBitLong();
946-
QgsDebugMsg( QString( "Transparency COLOR:0x%1" ).arg( transparency, 0, 16 ) );
936+
QgsDebugMsgLevel( QString( "Transparency COLOR:0x%1" ).arg( transparency, 0, 16 ), 4 );
947937
}
948938

949939
return idx; //default return ByLayer

0 commit comments

Comments
 (0)