Skip to content

Commit

Permalink
dwg/dxf import:
Browse files Browse the repository at this point in the history
* fix orientation of TEXT entities
* also clean TEXT strings
* support non-origin-based blocks
* support extrusion

(cherry picked from commit 94fa3c4)
  • Loading branch information
jef-n authored and nyalldawson committed Oct 25, 2019
1 parent 64ad560 commit beace18
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 34 deletions.
37 changes: 19 additions & 18 deletions external/libdxfrw/drw_entities.cpp
Expand Up @@ -627,7 +627,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

QgsDebugMsg( QString( "point:%1 thickness:%2, extrusion:%3, x_axis:%4" )
Expand Down Expand Up @@ -698,13 +698,14 @@ bool DRW_Line::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs )
}

thickness = buf->getThickness( version > DRW::AC1014 );//BD
extPoint = buf->getExtrusion( version > DRW::AC1014 );
QgsDebugMsg( QString( "startpoint:%1 endpoint:%2 thickness:%3 extrusion:%4" )
.arg( QString( "%1,%2,%3" ).arg( basePoint.x ).arg( basePoint.y ).arg( basePoint.z ) )
.arg( QString( "%1,%2,%3" ).arg( secPoint.x ).arg( secPoint.y ).arg( secPoint.z ) )
.arg( thickness )
.arg( QString( "%1,%2,%3" ).arg( extPoint.x ).arg( extPoint.y ).arg( extPoint.z ) )
);
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 ),
QStringLiteral( "%1,%2,%3" ).arg( secPoint.x ).arg( secPoint.y ).arg( secPoint.z ) )
.arg( thickness )
.arg( QStringLiteral( "%1,%2,%3" ).arg( extPoint.x ).arg( extPoint.y ).arg( extPoint.z ) ), 4
);

ret = DRW_Entity::parseDwgEntHandle( version, buf );
if ( !ret )
Expand Down Expand Up @@ -781,7 +782,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 );

QgsDebugMsg( QString( "center:%1 radius:%2 thickness:%3 extrusion:%4" )
.arg( QString( "%1,%2,%3" ).arg( basePoint.x ).arg( basePoint.y ).arg( basePoint.z ) )
Expand Down Expand Up @@ -850,7 +851,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();

Expand Down Expand Up @@ -1062,7 +1063,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 );

QgsDebugMsg( QString( "base:%1 sec:%2 third:%3 fourth:%4 extrusion:%5 thickness:%6" )
.arg( QString( "%1,%2,%3" ).arg( basePoint.x ).arg( basePoint.y ).arg( basePoint.z ) )
Expand Down Expand Up @@ -1305,7 +1306,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

QgsDebugMsg( QString( "scale:%1, angle:%2 extrusion:%3" )
.arg( QString( "%1,%2,%3" ).arg( xscale ).arg( yscale ).arg( zscale ) )
Expand Down Expand Up @@ -1478,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 );
Expand Down Expand Up @@ -1683,7 +1684,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 */

QgsDebugMsg( QString( "alignment:%1 extrusion:%2" )
Expand Down Expand Up @@ -1932,7 +1933,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
{
Expand Down Expand Up @@ -2984,7 +2985,7 @@ bool DRW_Dimension::parseDwg( DRW::Version version, dwgBuffer *buf, dwgBuffer *s
QgsDebugMsg( QString( "dimVersion:%1" ).arg( dimVersion ) );
Q_UNUSED( dimVersion );
}
extPoint = buf->getExtrusion( version > DRW::AC1014 );
extPoint = buf->getExtrusion( version > DRW::AC1014, haveExtrusion );

QgsDebugMsg( QString( "extrusion:%1,%2,%3" ).arg( extPoint.x ).arg( extPoint.y ).arg( extPoint.z ) );

Expand Down Expand Up @@ -3559,8 +3560,8 @@ bool DRW_Leader::parseDwg( DRW::Version version, dwgBuffer *buf, duint32 bs )
QgsDebugMsg( QString( " endptproj: %1,%2,%3" ).arg( Endptproj.x ).arg( Endptproj.y ).arg( Endptproj.z ) );
Q_UNUSED( Endptproj );

extrusionPoint = buf->getExtrusion( version > DRW::AC1014 );
QgsDebugMsg( QString( " extrusion: %1,%2,%3" ).arg( extrusionPoint.x ).arg( extrusionPoint.y ).arg( extrusionPoint.z ) );
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+
{
Expand Down
5 changes: 4 additions & 1 deletion external/libdxfrw/intern/dwgbuffer.cpp
Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion external/libdxfrw/intern/dwgbuffer.h
Expand Up @@ -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
Expand Down
15 changes: 10 additions & 5 deletions external/libdxfrw/intern/dwgreader.cpp
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down
36 changes: 28 additions & 8 deletions src/app/dwg/qgsdwgimporter.cpp
Expand Up @@ -610,7 +610,7 @@ bool QgsDwgImporter::import( const QString &drawing, QString &error, bool doExpa
{
//loads dxf
std::unique_ptr<dxfRW> dxf( new dxfRW( drawing.toLocal8Bit() ) );
if ( !dxf->read( this, false ) )
if ( !dxf->read( this, true ) )
{
result = DRW::BAD_UNKNOWN;
}
Expand All @@ -619,7 +619,7 @@ bool QgsDwgImporter::import( const QString &drawing, QString &error, bool doExpa
{
//loads dwg
std::unique_ptr<dwgR> dwg( new dwgR( drawing.toLocal8Bit() ) );
if ( !dwg->read( this, false ) )
if ( !dwg->read( this, true ) )
{
result = dwg->getError();
}
Expand Down Expand Up @@ -2328,8 +2328,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 );
Expand Down Expand Up @@ -2617,7 +2622,8 @@ bool QgsDwgImporter::expandInserts( QString &error )

OGR_L_ResetReading( blocks );

mBlocks.clear();
mBlockNames.clear();
mBlockBases.clear();

gdal::ogr_feature_unique_ptr f;
for ( ;; )
Expand All @@ -2628,7 +2634,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() );
Expand Down Expand Up @@ -2725,20 +2741,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;
Expand Down
3 changes: 2 additions & 1 deletion src/app/dwg/qgsdwgimporter.h
Expand Up @@ -218,7 +218,8 @@ class QgsDwgImporter : public DRW_Interface
QHash<QString, double> mLayerLinewidth;
QHash<QString, QString> mLayerLinetype;
QHash<QString, QString> mLinetype;
QHash<QString, int> mBlocks;
QHash<QString, int> mBlockNames;
QHash<QString, QgsPointXY> mBlockBases;

QLabel *mLabel = nullptr;
int mEntities = 0;
Expand Down

0 comments on commit beace18

Please sign in to comment.