From df3fabfa21c1488c2ce9c2505de9663489d677df Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Wed, 23 Oct 2019 03:25:21 -0700 Subject: [PATCH] pcbnew: Fix DXF Import with blocks BLOCK elements in DXF are re-usable bits that are useful when editing the file but should not be shown when importing the model. This skips all references except those that exist in the default "*Model_Space". This block is required in each DXF file and cannot be renamed. Fixes: lp:1790821 * https://bugs.launchpad.net/kicad/+bug/1790821 --- pcbnew/import_gfx/dxf_import_plugin.cpp | 52 ++++++++++++++++++++ pcbnew/import_gfx/dxf_import_plugin.h | 63 +++++++++++-------------- 2 files changed, 80 insertions(+), 35 deletions(-) diff --git a/pcbnew/import_gfx/dxf_import_plugin.cpp b/pcbnew/import_gfx/dxf_import_plugin.cpp index 0fb7a3bfb4..bfcc74ceea 100644 --- a/pcbnew/import_gfx/dxf_import_plugin.cpp +++ b/pcbnew/import_gfx/dxf_import_plugin.cpp @@ -62,6 +62,7 @@ DXF_IMPORT_PLUGIN::DXF_IMPORT_PLUGIN() : DL_CreationAdapter() m_yOffset = 0.0; // Y coord offset for conversion (in mm) m_DXF2mm = 1.0; // The scale factor to convert DXF units to mm m_version = 0; // the dxf version, not yet used + m_inBlock = false; // Discard blocks m_defaultThickness = 0.2; // default thickness (in mm) m_brdLayer = Dwgs_User; // The default import layer m_importAsfootprintGraphicItems = true; @@ -169,6 +170,9 @@ void DXF_IMPORT_PLUGIN::reportMsg( const char* aMessage ) void DXF_IMPORT_PLUGIN::addSpline( const DL_SplineData& aData ) { + if( m_inBlock ) + return; + // Called when starting reading a spline m_curr_entity.Clear(); m_curr_entity.m_EntityParseStatus = 1; @@ -187,6 +191,9 @@ void DXF_IMPORT_PLUGIN::addSpline( const DL_SplineData& aData ) void DXF_IMPORT_PLUGIN::addControlPoint( const DL_ControlPointData& aData ) { + if( m_inBlock ) + return; + // Called for every spline control point, when reading a spline entity m_curr_entity.m_SplineControlPointList.push_back( SPLINE_CTRL_POINT( aData.x , aData.y, aData.w ) ); @@ -195,6 +202,9 @@ void DXF_IMPORT_PLUGIN::addControlPoint( const DL_ControlPointData& aData ) void DXF_IMPORT_PLUGIN::addFitPoint( const DL_FitPointData& aData ) { + if( m_inBlock ) + return; + // Called for every spline fit point, when reading a spline entity // we store only the X,Y coord values in a VECTOR2D m_curr_entity.m_SplineFitPointList.push_back( VECTOR2D( aData.x, aData.y ) ); @@ -203,6 +213,9 @@ void DXF_IMPORT_PLUGIN::addFitPoint( const DL_FitPointData& aData ) void DXF_IMPORT_PLUGIN::addKnot( const DL_KnotData& aData) { + if( m_inBlock ) + return; + // Called for every spline knot value, when reading a spline entity m_curr_entity.m_SplineKnotsList.push_back( aData.k ); } @@ -220,6 +233,9 @@ void DXF_IMPORT_PLUGIN::addLayer( const DL_LayerData& aData ) void DXF_IMPORT_PLUGIN::addLine( const DL_LineData& aData ) { + if( m_inBlock ) + return; + VECTOR2D start( mapX( aData.x1 ), mapY( aData.y1 ) ); VECTOR2D end( mapX( aData.x2 ), mapY( aData.y2 ) ); double lineWidth = mapWidth( attributes.getWidth() ); @@ -233,6 +249,9 @@ void DXF_IMPORT_PLUGIN::addLine( const DL_LineData& aData ) void DXF_IMPORT_PLUGIN::addPolyline(const DL_PolylineData& aData ) { + if( m_inBlock ) + return; + // Convert DXF Polylines into a series of KiCad Lines and Arcs. // A Polyline (as opposed to a LWPolyline) may be a 3D line or // even a 3D Mesh. The only type of Polyline which is guaranteed @@ -248,6 +267,9 @@ void DXF_IMPORT_PLUGIN::addPolyline(const DL_PolylineData& aData ) void DXF_IMPORT_PLUGIN::addVertex( const DL_VertexData& aData ) { + if( m_inBlock ) + return; + if( m_curr_entity.m_EntityParseStatus == 0 ) return; // Error @@ -308,8 +330,26 @@ void DXF_IMPORT_PLUGIN::endEntity() } +void DXF_IMPORT_PLUGIN::addBlock( const DL_BlockData& aData ) +{ + // The DXF blocks are not useful in our import, so we skip them with the exception + // of the main block that is shown when editing the file + if( aData.name.compare( "*Model_Space") ) + m_inBlock = true; +} + + +void DXF_IMPORT_PLUGIN::endBlock() +{ + m_inBlock = false; +} + + void DXF_IMPORT_PLUGIN::addCircle( const DL_CircleData& aData ) { + if( m_inBlock ) + return; + VECTOR2D center( mapX( aData.cx ), mapY( aData.cy ) ); double lineWidth = mapWidth( attributes.getWidth() ); m_internalImporter.AddCircle( center, mapDim( aData.radius ), lineWidth ); @@ -323,6 +363,9 @@ void DXF_IMPORT_PLUGIN::addCircle( const DL_CircleData& aData ) void DXF_IMPORT_PLUGIN::addArc( const DL_ArcData& aData ) { + if( m_inBlock ) + return; + // Init arc centre: VECTOR2D center( mapX( aData.cx ), mapY( aData.cy ) ); @@ -353,6 +396,9 @@ void DXF_IMPORT_PLUGIN::addArc( const DL_ArcData& aData ) void DXF_IMPORT_PLUGIN::addText( const DL_TextData& aData ) { + if( m_inBlock ) + return; + VECTOR2D refPoint( mapX( aData.ipx ), mapY( aData.ipy ) ); VECTOR2D secPoint( mapX( aData.apx ), mapY( aData.apy ) ); @@ -493,6 +539,9 @@ void DXF_IMPORT_PLUGIN::addText( const DL_TextData& aData ) void DXF_IMPORT_PLUGIN::addMText( const DL_MTextData& aData ) { + if( m_inBlock ) + return; + wxString text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) ); wxString attrib, tmp; @@ -649,6 +698,9 @@ void DXF_IMPORT_PLUGIN::addMText( const DL_MTextData& aData ) void DXF_IMPORT_PLUGIN::setVariableInt( const std::string& key, int value, int code ) { + if( m_inBlock ) + return; + // Called for every int variable in the DXF file (e.g. "$INSUNITS"). if( key == "$DWGCODEPAGE" ) diff --git a/pcbnew/import_gfx/dxf_import_plugin.h b/pcbnew/import_gfx/dxf_import_plugin.h index d738f6e9a2..fce2d3bdef 100644 --- a/pcbnew/import_gfx/dxf_import_plugin.h +++ b/pcbnew/import_gfx/dxf_import_plugin.h @@ -124,6 +124,7 @@ private: double m_DXF2mm; // The scale factor to convert DXF units to mm int m_brdLayer; // The board layer to place imported DXF items int m_version; // the dxf version, not used here + bool m_inBlock; // Are we parsing a block std::string m_codePage; // The code page, not used here bool m_importAsfootprintGraphicItems; // Use module items instead of board items when true. // true when the items are imported in the footprint editor @@ -262,6 +263,16 @@ private: virtual void addLayer( const DL_LayerData& aData ) override; virtual void addLine( const DL_LineData& aData) override; + + /** + * Called for each BLOCK in the DXF file + * These are re-usable elements that may be placed into the model space. The elements + * are dereferenced to the model, so we just need to skip the re-parsing for the block + * elements. + */ + virtual void addBlock( const DL_BlockData& ) override; + virtual void endBlock() override; + virtual void addCircle( const DL_CircleData& aData ) override; virtual void addArc( const DL_ArcData& aData ) override; //virtual void addLWPolyline( const DRW_LWPolyline& aData ) override; @@ -289,54 +300,36 @@ private: // Not yet handled DXF entities: virtual void addDimAlign( const DL_DimensionData&, - const DL_DimAlignedData& ) override { reportMsg( "DL_Dimension not managed" ); } + const DL_DimAlignedData& ) override {} virtual void addDimLinear( const DL_DimensionData&, - const DL_DimLinearData& ) override { reportMsg( "DL_Dimension not managed" ); } + const DL_DimLinearData& ) override {} virtual void addDimRadial( const DL_DimensionData&, - const DL_DimRadialData& ) override { reportMsg( "DL_Dimension not managed" ); } + const DL_DimRadialData& ) override {} virtual void addDimDiametric( const DL_DimensionData&, - const DL_DimDiametricData& ) override { reportMsg( "DL_Dimension not managed" ); } + const DL_DimDiametricData& ) override {} virtual void addDimAngular( const DL_DimensionData&, - const DL_DimAngularData& ) override { reportMsg( "DL_Dimension not managed" ); } + const DL_DimAngularData& ) override {} virtual void addDimAngular3P( const DL_DimensionData&, - const DL_DimAngular3PData& ) override { reportMsg( "DL_Dimension not managed" ); } + const DL_DimAngular3PData& ) override {} virtual void addDimOrdinate( const DL_DimensionData&, - const DL_DimOrdinateData& ) override { reportMsg( "DL_Dimension not managed" ); } - virtual void addLeader( const DL_LeaderData& ) override - { - reportMsg( "DL_Leader not managed" ); - } + const DL_DimOrdinateData& ) override {} + virtual void addLeader( const DL_LeaderData& ) override {} - virtual void addLeaderVertex( const DL_LeaderVertexData& ) override - { - reportMsg( "DL_LeaderVertex not managed" ); - } + virtual void addLeaderVertex( const DL_LeaderVertexData& ) override {} - virtual void addHatch( const DL_HatchData& ) override { reportMsg( "DL_Hatch not managed" ); } + virtual void addHatch( const DL_HatchData& ) override {} - virtual void addTrace( const DL_TraceData& ) override { reportMsg( "DL_Trace not managed" ); } - virtual void add3dFace( const DL_3dFaceData& ) override - { - reportMsg( "DL_3dFace not managed" ); - } + virtual void addTrace( const DL_TraceData& ) override {} + virtual void add3dFace( const DL_3dFaceData& ) override {} - virtual void addSolid( const DL_SolidData& ) override { reportMsg( "DL_Solid not managed" ); } + virtual void addSolid( const DL_SolidData& ) override {} - virtual void addImage( const DL_ImageData& ) override { reportMsg( "DL_ImageDa not managed" ); } - virtual void linkImage( const DL_ImageDefData& ) override - { - reportMsg( "DL_ImageDef not managed" ); - } + virtual void addImage( const DL_ImageData& ) override {} + virtual void linkImage( const DL_ImageDefData& ) override {} - virtual void addHatchLoop( const DL_HatchLoopData& ) override - { - reportMsg( "DL_HatchLoop not managed" ); - } + virtual void addHatchLoop( const DL_HatchLoopData& ) override {} - virtual void addHatchEdge( const DL_HatchEdgeData& ) override - { - reportMsg( "DL_HatchEdge not managed" ); - } + virtual void addHatchEdge( const DL_HatchEdgeData& ) override {} /** * Convert a native unicode string into a DXF encoded string.