diff --git a/external/libdxfrw/drw_entities.cpp b/external/libdxfrw/drw_entities.cpp index 45ee0bc518c8..a8778980519a 100644 --- a/external/libdxfrw/drw_entities.cpp +++ b/external/libdxfrw/drw_entities.cpp @@ -626,7 +626,7 @@ bool DRW_Point::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs ) basePoint.y = buf->getBitDouble(); basePoint.z = buf->getBitDouble(); thickness = buf->getThickness( version > DRW::AC1014 );//BD - extPoint = buf->getExtrusion( version > DRW::AC1014 ); + extPoint = buf->getExtrusion( version > DRW::AC1014, haveExtrusion ); double x_axis = buf->getBitDouble();//BD QgsDebugMsgLevel( QStringLiteral( "point:%1 thickness:%2, extrusion:%3, x_axis:%4" ) @@ -697,7 +697,7 @@ bool DRW_Line::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs ) } thickness = buf->getThickness( version > DRW::AC1014 );//BD - extPoint = buf->getExtrusion( version > DRW::AC1014 ); + extPoint = buf->getExtrusion( version > DRW::AC1014, haveExtrusion ); QgsDebugMsgLevel( QStringLiteral( "startpoint:%1 endpoint:%2 thickness:%3 extrusion:%4" ) .arg( QStringLiteral( "%1,%2,%3" ).arg( basePoint.x ).arg( basePoint.y ).arg( basePoint.z ), @@ -781,7 +781,7 @@ bool DRW_Circle::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs ) basePoint.z = buf->getBitDouble(); mRadius = buf->getBitDouble(); thickness = buf->getThickness( version > DRW::AC1014 ); - extPoint = buf->getExtrusion( version > DRW::AC1014 ); + extPoint = buf->getExtrusion( version > DRW::AC1014, haveExtrusion ); QgsDebugMsgLevel( QStringLiteral( "center:%1 radius:%2 thickness:%3 extrusion:%4" ) .arg( QStringLiteral( "%1,%2,%3" ).arg( basePoint.x ).arg( basePoint.y ).arg( basePoint.z ) ) @@ -850,7 +850,7 @@ bool DRW_Arc::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs ) basePoint.z = buf->getBitDouble(); mRadius = buf->getBitDouble(); thickness = buf->getThickness( version > DRW::AC1014 ); - extPoint = buf->getExtrusion( version > DRW::AC1014 ); + extPoint = buf->getExtrusion( version > DRW::AC1014, haveExtrusion ); staangle = buf->getBitDouble(); endangle = buf->getBitDouble(); @@ -1062,7 +1062,7 @@ bool DRW_Trace::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs ) fourthPoint.x = buf->getRawDouble(); fourthPoint.y = buf->getRawDouble(); fourthPoint.z = basePoint.z; - extPoint = buf->getExtrusion( version > DRW::AC1014 ); + extPoint = buf->getExtrusion( version > DRW::AC1014, haveExtrusion ); QgsDebugMsgLevel( QStringLiteral( "base:%1 sec:%2 third:%3 fourth:%4 extrusion:%5 thickness:%6" ) .arg( QStringLiteral( "%1,%2,%3" ).arg( basePoint.x ).arg( basePoint.y ).arg( basePoint.z ), @@ -1305,7 +1305,7 @@ bool DRW_Insert::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs ) } angle = buf->getBitDouble(); - extPoint = buf->getExtrusion( false ); //3BD R14 style + extPoint = buf->getExtrusion( false, haveExtrusion ); //3BD R14 style QgsDebugMsgLevel( QStringLiteral( "scale:%1 angle:%2 extrusion:%3" ) .arg( QStringLiteral( "%1,%2,%3" ).arg( xscale ).arg( yscale ).arg( zscale ) ) @@ -1479,7 +1479,7 @@ bool DRW_LWPolyline::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs if ( flags & 2 ) thickness = buf->getBitDouble(); if ( flags & 1 ) - extPoint = buf->getExtrusion( false ); + extPoint = buf->getExtrusion( false, haveExtrusion ); vertexnum = buf->getBitLong(); RESERVE( vertlist, vertexnum ); @@ -1685,7 +1685,7 @@ bool DRW_Text::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs ) secPoint.y = buf->getRawDouble(); } secPoint.z = basePoint.z; - extPoint = buf->getExtrusion( version > DRW::AC1014 ); + extPoint = buf->getExtrusion( version > DRW::AC1014, haveExtrusion ); thickness = buf->getThickness( version > DRW::AC1014 ); /* Thickness BD 39 */ QgsDebugMsgLevel( QStringLiteral( "alignment:%1 extrusion:%2" ) @@ -1934,7 +1934,7 @@ bool DRW_Polyline::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs ) defendwidth = buf->getBitDouble(); thickness = buf->getThickness( version > DRW::AC1014 ); basePoint = DRW_Coord( 0, 0, buf->getBitDouble() ); - extPoint = buf->getExtrusion( version > DRW::AC1014 ); + extPoint = buf->getExtrusion( version > DRW::AC1014, haveExtrusion ); } else if ( oType == 0x10 ) //pline 3D { @@ -2987,7 +2987,7 @@ bool DRW_Dimension::parseDwg( DRW::Version version, dwgBuffer *buf, dwgBuffer *s QgsDebugMsgLevel( QStringLiteral( "dimVersion:%1" ).arg( dimVersion ), 4 ); Q_UNUSED( dimVersion ); } - extPoint = buf->getExtrusion( version > DRW::AC1014 ); + extPoint = buf->getExtrusion( version > DRW::AC1014, haveExtrusion ); QgsDebugMsgLevel( QStringLiteral( "extrusion:%1,%2,%3" ).arg( extPoint.x ).arg( extPoint.y ).arg( extPoint.z ), 4 ); @@ -3562,7 +3562,7 @@ bool DRW_Leader::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs ) QgsDebugMsgLevel( QStringLiteral( " endptproj: %1,%2,%3" ).arg( Endptproj.x ).arg( Endptproj.y ).arg( Endptproj.z ), 4 ); Q_UNUSED( Endptproj ); - extrusionPoint = buf->getExtrusion( version > DRW::AC1014 ); + extrusionPoint = buf->getExtrusion( version > DRW::AC1014, haveExtrusion ); QgsDebugMsgLevel( QStringLiteral( " extrusion: %1,%2,%3" ).arg( extrusionPoint.x ).arg( extrusionPoint.y ).arg( extrusionPoint.z ), 4 ); if ( version > DRW::AC1014 ) //2000+ diff --git a/external/libdxfrw/intern/dwgbuffer.cpp b/external/libdxfrw/intern/dwgbuffer.cpp index 92796cb38c02..d7fd5aab67e6 100644 --- a/external/libdxfrw/intern/dwgbuffer.cpp +++ b/external/libdxfrw/intern/dwgbuffer.cpp @@ -764,17 +764,20 @@ duint16 dwgBuffer::getObjType( DRW::Version v ) //OT * be followed by 3BD. * For R13-R14 this is 3BD. */ -DRW_Coord dwgBuffer::getExtrusion( bool b_R2000_style ) +DRW_Coord dwgBuffer::getExtrusion( bool b_R2000_style, bool &haveExtrusion ) { DRW_Coord ext( 0.0, 0.0, 1.0 ); + haveExtrusion = false; if ( b_R2000_style ) /* If the bit is one, the extrusion value is assumed to be 0,0,1*/ if ( getBit() == 1 ) return ext; + /*R13-R14 or bit == 0*/ ext.x = getBitDouble(); ext.y = getBitDouble(); ext.z = getBitDouble(); + haveExtrusion = ext.x != 0.0 || ext.y != 0.0 || ext.z != 1.0; return ext; } diff --git a/external/libdxfrw/intern/dwgbuffer.h b/external/libdxfrw/intern/dwgbuffer.h index 57e7d17d2985..37dd386c4648 100644 --- a/external/libdxfrw/intern/dwgbuffer.h +++ b/external/libdxfrw/intern/dwgbuffer.h @@ -126,7 +126,7 @@ class dwgBuffer //X, U, SN, - DRW_Coord getExtrusion( bool b_R2000_style ); //BE + DRW_Coord getExtrusion( bool b_R2000_style, bool &haveExtrusion ); //BE double getDefaultDouble( double d ); //DD double getThickness( bool b_R2000_style );//BT //3DD diff --git a/external/libdxfrw/intern/dwgreader.cpp b/external/libdxfrw/intern/dwgreader.cpp index 29f52eee6129..a388773d2282 100644 --- a/external/libdxfrw/intern/dwgreader.cpp +++ b/external/libdxfrw/intern/dwgreader.cpp @@ -1187,6 +1187,7 @@ bool dwgReader::readDwgEntity( dwgBuffer *dbuf, objHandle &obj, DRW_Interface &i #define ENTRY_PARSE(e) \ ret = e.parseDwg(version, &buff, bs); \ parseAttribs(&e); \ + e.applyExtrusion(); \ nextEntLink = e.nextEntLink; \ prevEntLink = e.prevEntLink; @@ -1426,11 +1427,15 @@ bool dwgReader::readDwgEntity( dwgBuffer *dbuf, objHandle &obj, DRW_Interface &i intfa.addPolyline( e ); break; } -// case 30: { -// DRW_Polyline e;// MESH (not pline) -// ENTRY_PARSE(e) -// intfa.addRay(e); -// break; } +#if 0 + case 30: + { + DRW_Polyline e;// MESH (not pline) + ENTRY_PARSE( e ) + intfa.addRay( e ); + break; + } +#endif case 41: { DRW_Xline e; diff --git a/src/app/dwg/qgsdwgimporter.cpp b/src/app/dwg/qgsdwgimporter.cpp index ce01efae3f9f..c9896143efa0 100644 --- a/src/app/dwg/qgsdwgimporter.cpp +++ b/src/app/dwg/qgsdwgimporter.cpp @@ -609,7 +609,7 @@ bool QgsDwgImporter::import( const QString &drawing, QString &error, bool doExpa { //loads dxf std::unique_ptr dxf( new dxfRW( drawing.toLocal8Bit() ) ); - if ( !dxf->read( this, false ) ) + if ( !dxf->read( this, true ) ) { result = DRW::BAD_UNKNOWN; } @@ -618,7 +618,7 @@ bool QgsDwgImporter::import( const QString &drawing, QString &error, bool doExpa { //loads dwg std::unique_ptr dwg( new dwgR( drawing.toLocal8Bit() ) ); - if ( !dwg->read( this, false ) ) + if ( !dwg->read( this, true ) ) { result = dwg->getError(); } @@ -2327,8 +2327,13 @@ void QgsDwgImporter::addText( const DRW_Text &data ) addEntity( dfn, f, data ); SETDOUBLE( height ); - SETSTRING( text ); + + QString text( decode( data.text ) ); + cleanText( text ); + setString( dfn, f, QStringLiteral( "text" ), text ); + SETDOUBLE( angle ); + setDouble( dfn, f, "angle", data.angle * 180.0 / M_PI ); SETDOUBLE( widthscale ); SETDOUBLE( oblique ); SETSTRING( style ); @@ -2616,7 +2621,8 @@ bool QgsDwgImporter::expandInserts( QString &error ) OGR_L_ResetReading( blocks ); - mBlocks.clear(); + mBlockNames.clear(); + mBlockBases.clear(); gdal::ogr_feature_unique_ptr f; for ( ;; ) @@ -2627,7 +2633,17 @@ bool QgsDwgImporter::expandInserts( QString &error ) QString name = QString::fromUtf8( OGR_F_GetFieldAsString( f.get(), nameIdx ) ); int handle = OGR_F_GetFieldAsInteger( f.get(), handleIdx ); - mBlocks.insert( name, handle ); + OGRGeometryH ogrG = OGR_F_GetGeometryRef( f.get() ); + + QgsGeometry g( QgsOgrUtils::ogrGeometryToQgsGeometry( ogrG ) ); + if ( g.isNull() ) + { + QgsDebugMsg( QStringLiteral( "%1: could not copy geometry" ).arg( OGR_F_GetFID( f.get() ) ) ); + continue; + } + + mBlockNames.insert( name, handle ); + mBlockBases.insert( name, g.asPoint() ); } return expandInserts( error, -1, QTransform() ); @@ -2724,20 +2740,24 @@ bool QgsDwgImporter::expandInserts( QString &error, int block, QTransform base ) } double blockLinewidth = OGR_F_GetFieldAsDouble( insert.get(), linewidthIdx ); - int handle = mBlocks.value( name, -1 ); + int handle = mBlockNames.value( name, -1 ); if ( handle < 0 ) { QgsDebugMsg( QStringLiteral( "Block '%1' not found" ).arg( name ) ); continue; } - QgsDebugMsgLevel( QStringLiteral( "Resolving %1/%2: p=%3,%4 scale=%5,%6 angle=%7" ) + QgsPointXY b = mBlockBases.value( name ); + + QgsDebugMsgLevel( QStringLiteral( "Resolving %1/%2: p=%3,%4 b=%5,%6 scale=%7,%8 angle=%9" ) .arg( name ).arg( handle, 0, 16 ) .arg( p.x() ).arg( p.y() ) + .arg( b.x() ).arg( b.y() ) .arg( xscale ).arg( yscale ).arg( angle ), 5 ); + QTransform t; - t.translate( p.x(), p.y() ).scale( xscale, yscale ).rotateRadians( angle ); + t.translate( p.x(), p.y() ).scale( xscale, yscale ).rotateRadians( angle ).translate( -b.x(), -b.y() ); t *= base; OGRLayerH src = nullptr; diff --git a/src/app/dwg/qgsdwgimporter.h b/src/app/dwg/qgsdwgimporter.h index 866eef494529..46a3bddbb553 100644 --- a/src/app/dwg/qgsdwgimporter.h +++ b/src/app/dwg/qgsdwgimporter.h @@ -218,7 +218,8 @@ class QgsDwgImporter : public DRW_Interface QHash mLayerLinewidth; QHash mLayerLinetype; QHash mLinetype; - QHash mBlocks; + QHash mBlockNames; + QHash mBlockBases; QLabel *mLabel = nullptr; int mEntities = 0;