Skip to content

Commit

Permalink
backport dwg import fixes
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
jef-n committed Feb 26, 2019
1 parent 36a1046 commit fb81ce6
Show file tree
Hide file tree
Showing 13 changed files with 743 additions and 340 deletions.
46 changes: 35 additions & 11 deletions external/libdxfrw/drw_entities.cpp
Expand Up @@ -10,17 +10,29 @@
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
******************************************************************************/

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

#include <cstdlib>

#include "drw_entities.h"
#include "intern/dxfreader.h"
#include "intern/dwgbuffer.h"
#include "intern/drw_dbg.h"

#undef QGISDEBUG
#include "qgslogger.h"
#include <QStringList>

#include "qgslogger.h"

#ifndef DWGDEBUG
#undef QgsDebugCall
#undef QgsDebugMsg
#undef QgsDebugMsgLevel
#define QgsDebugCall
#define QgsDebugMsg(str)
#define QgsDebugMsgLevel(str, level)
#endif

#define RESERVE( vector, size ) try { \
vector.reserve(size); \
} catch(const std::exception &e) { \
Expand Down Expand Up @@ -436,7 +448,7 @@ bool DRW_Entity::parseDwg( DRW::Version version, dwgBuffer *buf, dwgBuffer *strB
duint8 unk = buf->getBit();
QgsDebugMsg( QString( "unknown bit: %1" ).arg( unk ) );
}
#endif
#endif // 0
return buf->isGood();
}

Expand Down Expand Up @@ -1537,7 +1549,7 @@ bool DRW_LWPolyline::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs
#if 0
if ( vertlist.size() < i )
vertlist.at( i )->vertexId = vertexId;
#endif
#endif // 0
}
}
//add widths
Expand Down Expand Up @@ -1592,7 +1604,7 @@ void DRW_Text::parseCode( int code, dxfReader *reader )
angle = reader->getDouble() / ARAD;
break;
case 51:
oblique = reader->getDouble();
oblique = reader->getDouble() / ARAD;
break;
case 71:
textgen = reader->getInt32();
Expand Down Expand Up @@ -1789,6 +1801,7 @@ bool DRW_MText::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs )

extPoint = buf->get3BitDouble(); /* Extrusion 3BD 210 Undocumented; */
secPoint = buf->get3BitDouble(); /* X-axis dir 3BD 11 */
haveXAxis = true;
updateAngle();
widthscale = buf->getBitDouble(); /* Rect width BD 41 */
if ( version > DRW::AC1018 ) //2007+
Expand Down Expand Up @@ -2178,7 +2191,7 @@ void DRW_Hatch::parseCode( int code, dxfReader *reader )
else if ( ellipse ) ellipse->endparam = reader->getDouble() / ARAD;
break;
case 52:
angle = reader->getDouble();
angle = reader->getDouble() / ARAD;
break;
case 73:
if ( arc ) arc->isccw = reader->getInt32();
Expand Down Expand Up @@ -2320,7 +2333,7 @@ bool DRW_Hatch::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs )

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

for ( dint32 j = 0; j < numPathSeg; ++j )
for ( dint32 j = 0; j < numPathSeg && buf->isGood(); ++j )
{
duint8 typePath = buf->getRawChar8();
QgsDebugMsg( QString( " typepath: %1" ).arg( typePath ) );
Expand Down Expand Up @@ -2364,15 +2377,26 @@ bool DRW_Hatch::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs )
.arg( spline->nknots ).arg( spline->ncontrol )
);
RESERVE( spline->knotslist, spline->nknots );
for ( dint32 j = 0; j < spline->nknots; ++j )
dint32 j;
for ( j = 0; j < spline->nknots && buf->isGood(); ++j )
{
spline->knotslist.push_back( buf->getBitDouble() );
QgsDebugMsg( QString( " knot %1: %2" ).arg( j )
.arg( spline->knotslist.back() )
);
}

if ( !buf->isGood() )
{
QgsDebugMsg( QStringLiteral( "NOT GOOD at %1! degree:%2 flags:0x%3 nknots:%4 ncontrol:%5" )
.arg( j )
.arg( spline->degree ).arg( spline->flags, 0, 16 )
.arg( spline->nknots ).arg( spline->ncontrol )
);
}

RESERVE( spline->controllist, spline->ncontrol );
for ( dint32 j = 0; j < spline->ncontrol && buf->isGood(); ++j )
for ( j = 0; j < spline->ncontrol && buf->isGood(); ++j )
{
DRW_Coord *crd = new DRW_Coord( buf->get2RawDouble() );
spline->controllist.push_back( crd );
Expand Down Expand Up @@ -2933,10 +2957,10 @@ void DRW_Dimension::parseCode( int code, dxfReader *reader )
rot = reader->getDouble();
break;
case 50:
angle = reader->getDouble();
angle = reader->getDouble() / ARAD;
break;
case 52:
oblique = reader->getDouble();
oblique = reader->getDouble() / ARAD;
break;
case 40:
length = reader->getDouble();
Expand Down
15 changes: 14 additions & 1 deletion external/libdxfrw/drw_header.cpp
Expand Up @@ -10,17 +10,30 @@
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
******************************************************************************/

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

#include "drw_header.h"
#include "intern/dxfreader.h"
#include "intern/dxfwriter.h"
#include "intern/drw_dbg.h"
#include "intern/dwgbuffer.h"

#include "qgslogger.h"
#include <QStringList>

#include <cassert>

#include "qgslogger.h"

#ifndef DWGDEBUG
#undef QgsDebugCall
#undef QgsDebugMsg
#undef QgsDebugMsgLevel
#define QgsDebugCall
#define QgsDebugMsg(str)
#define QgsDebugMsgLevel(str, level)
#endif

DRW_Header::DRW_Header()
: curr( nullptr )
, version( DRW::AC1021 )
Expand Down
16 changes: 14 additions & 2 deletions external/libdxfrw/drw_objects.cpp
Expand Up @@ -10,6 +10,9 @@
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
******************************************************************************/

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

#include <iostream>
#include <cmath>

Expand All @@ -20,10 +23,19 @@
#include "intern/drw_dbg.h"
#include "intern/dwgutil.h"

#undef QGISDEBUG
#include "qgslogger.h"
#include <QStringList>

#include "qgslogger.h"

#ifndef DWGDEBUG
#undef QgsDebugCall
#undef QgsDebugMsg
#undef QgsDebugMsgLevel
#define QgsDebugCall
#define QgsDebugMsg(str)
#define QgsDebugMsgLevel(str, level)
#endif

#define RESERVE( vector, size ) try { \
vector.reserve(size); \
} catch(const std::exception &e) { \
Expand Down
3 changes: 2 additions & 1 deletion external/libdxfrw/intern/drw_textcodec.cpp
Expand Up @@ -296,7 +296,8 @@ std::string DRW_Converter::encodeNum( int c )
return std::string( ( char * )ret );
}

/** 's' is a string with at least 4 bytes length
/**
* 's' is a string with at least 4 bytes length
** returned 'b' is byte length of encoded char: 2,3 or 4
**/
int DRW_Converter::decodeNum( std::string s, int *b )
Expand Down
42 changes: 16 additions & 26 deletions external/libdxfrw/intern/dwgbuffer.cpp
Expand Up @@ -10,34 +10,23 @@
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
******************************************************************************/

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

#include "dwgbuffer.h"
#include "../libdwgr.h"
#include "drw_textcodec.h"
#include "drw_dbg.h"

#undef QGISDEBUG
#include "qgslogger.h"

#if 0
//#include <bitset>
#include <fstream>
#include <algorithm>
#include <sstream>
#include "dwgreader.h"
#include "dxfwriter.h"

#define FIRSTHANDLE 48

enum sections
{
secUnknown,
secHeader,
secTables,
secBlocks,
secEntities,
secObjects
};
#ifndef DWGDEBUG
#undef QgsDebugCall
#undef QgsDebugMsg
#undef QgsDebugMsgLevel
#define QgsDebugCall
#define QgsDebugMsg(str)
#define QgsDebugMsgLevel(str, level)
#endif

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

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

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

duint16 idx = getBitShort();
QgsDebugMsg( QString( "idx reads COLOR: 0x%1" ).arg( idx, 0, 16 ) );
QgsDebugMsgLevel( QString( "idx reads COLOR: 0x%1" ).arg( idx, 0, 16 ), 4 );

duint16 flags = idx >> 8;

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

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

if ( flags & 0x80 )
{
// complex color (rgb)
rgb = getBitLong() & 0xffffff;

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

if ( flags & 0x80 )
{
QgsDebugMsg( "acdbColor COLOR are present" );
QgsDebugMsgLevel( "acdbColor COLOR are present", 4 );
}
}

if ( flags & 0x20 )
{
transparency = getBitLong();
QgsDebugMsg( QString( "Transparency COLOR:0x%1" ).arg( transparency, 0, 16 ) );
QgsDebugMsgLevel( QString( "Transparency COLOR:0x%1" ).arg( transparency, 0, 16 ), 4 );
}

return idx; //default return ByLayer
Expand Down

0 comments on commit fb81ce6

Please sign in to comment.