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
This commit is contained in:
Seth Hillbrand 2019-10-23 03:25:21 -07:00
parent 3b1817ee32
commit df3fabfa21
2 changed files with 80 additions and 35 deletions

View File

@ -62,6 +62,7 @@ DXF_IMPORT_PLUGIN::DXF_IMPORT_PLUGIN() : DL_CreationAdapter()
m_yOffset = 0.0; // Y coord offset for conversion (in mm) 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_DXF2mm = 1.0; // The scale factor to convert DXF units to mm
m_version = 0; // the dxf version, not yet used m_version = 0; // the dxf version, not yet used
m_inBlock = false; // Discard blocks
m_defaultThickness = 0.2; // default thickness (in mm) m_defaultThickness = 0.2; // default thickness (in mm)
m_brdLayer = Dwgs_User; // The default import layer m_brdLayer = Dwgs_User; // The default import layer
m_importAsfootprintGraphicItems = true; m_importAsfootprintGraphicItems = true;
@ -169,6 +170,9 @@ void DXF_IMPORT_PLUGIN::reportMsg( const char* aMessage )
void DXF_IMPORT_PLUGIN::addSpline( const DL_SplineData& aData ) void DXF_IMPORT_PLUGIN::addSpline( const DL_SplineData& aData )
{ {
if( m_inBlock )
return;
// Called when starting reading a spline // Called when starting reading a spline
m_curr_entity.Clear(); m_curr_entity.Clear();
m_curr_entity.m_EntityParseStatus = 1; 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 ) void DXF_IMPORT_PLUGIN::addControlPoint( const DL_ControlPointData& aData )
{ {
if( m_inBlock )
return;
// Called for every spline control point, when reading a spline entity // 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, m_curr_entity.m_SplineControlPointList.push_back( SPLINE_CTRL_POINT( aData.x , aData.y,
aData.w ) ); aData.w ) );
@ -195,6 +202,9 @@ void DXF_IMPORT_PLUGIN::addControlPoint( const DL_ControlPointData& aData )
void DXF_IMPORT_PLUGIN::addFitPoint( const DL_FitPointData& 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 // Called for every spline fit point, when reading a spline entity
// we store only the X,Y coord values in a VECTOR2D // we store only the X,Y coord values in a VECTOR2D
m_curr_entity.m_SplineFitPointList.push_back( VECTOR2D( aData.x, aData.y ) ); 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) void DXF_IMPORT_PLUGIN::addKnot( const DL_KnotData& aData)
{ {
if( m_inBlock )
return;
// Called for every spline knot value, when reading a spline entity // Called for every spline knot value, when reading a spline entity
m_curr_entity.m_SplineKnotsList.push_back( aData.k ); 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 ) void DXF_IMPORT_PLUGIN::addLine( const DL_LineData& aData )
{ {
if( m_inBlock )
return;
VECTOR2D start( mapX( aData.x1 ), mapY( aData.y1 ) ); VECTOR2D start( mapX( aData.x1 ), mapY( aData.y1 ) );
VECTOR2D end( mapX( aData.x2 ), mapY( aData.y2 ) ); VECTOR2D end( mapX( aData.x2 ), mapY( aData.y2 ) );
double lineWidth = mapWidth( attributes.getWidth() ); 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 ) void DXF_IMPORT_PLUGIN::addPolyline(const DL_PolylineData& aData )
{ {
if( m_inBlock )
return;
// Convert DXF Polylines into a series of KiCad Lines and Arcs. // Convert DXF Polylines into a series of KiCad Lines and Arcs.
// A Polyline (as opposed to a LWPolyline) may be a 3D line or // 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 // 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 ) void DXF_IMPORT_PLUGIN::addVertex( const DL_VertexData& aData )
{ {
if( m_inBlock )
return;
if( m_curr_entity.m_EntityParseStatus == 0 ) if( m_curr_entity.m_EntityParseStatus == 0 )
return; // Error 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 ) void DXF_IMPORT_PLUGIN::addCircle( const DL_CircleData& aData )
{ {
if( m_inBlock )
return;
VECTOR2D center( mapX( aData.cx ), mapY( aData.cy ) ); VECTOR2D center( mapX( aData.cx ), mapY( aData.cy ) );
double lineWidth = mapWidth( attributes.getWidth() ); double lineWidth = mapWidth( attributes.getWidth() );
m_internalImporter.AddCircle( center, mapDim( aData.radius ), lineWidth ); 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 ) void DXF_IMPORT_PLUGIN::addArc( const DL_ArcData& aData )
{ {
if( m_inBlock )
return;
// Init arc centre: // Init arc centre:
VECTOR2D center( mapX( aData.cx ), mapY( aData.cy ) ); 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 ) void DXF_IMPORT_PLUGIN::addText( const DL_TextData& aData )
{ {
if( m_inBlock )
return;
VECTOR2D refPoint( mapX( aData.ipx ), mapY( aData.ipy ) ); VECTOR2D refPoint( mapX( aData.ipx ), mapY( aData.ipy ) );
VECTOR2D secPoint( mapX( aData.apx ), mapY( aData.apy ) ); 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 ) void DXF_IMPORT_PLUGIN::addMText( const DL_MTextData& aData )
{ {
if( m_inBlock )
return;
wxString text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) ); wxString text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) );
wxString attrib, tmp; 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 ) 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"). // Called for every int variable in the DXF file (e.g. "$INSUNITS").
if( key == "$DWGCODEPAGE" ) if( key == "$DWGCODEPAGE" )

View File

@ -124,6 +124,7 @@ private:
double m_DXF2mm; // The scale factor to convert DXF units to mm 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_brdLayer; // The board layer to place imported DXF items
int m_version; // the dxf version, not used here 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 std::string m_codePage; // The code page, not used here
bool m_importAsfootprintGraphicItems; // Use module items instead of board items when true. bool m_importAsfootprintGraphicItems; // Use module items instead of board items when true.
// true when the items are imported in the footprint editor // 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 addLayer( const DL_LayerData& aData ) override;
virtual void addLine( const DL_LineData& 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 addCircle( const DL_CircleData& aData ) override;
virtual void addArc( const DL_ArcData& aData ) override; virtual void addArc( const DL_ArcData& aData ) override;
//virtual void addLWPolyline( const DRW_LWPolyline& aData ) override; //virtual void addLWPolyline( const DRW_LWPolyline& aData ) override;
@ -289,54 +300,36 @@ private:
// Not yet handled DXF entities: // Not yet handled DXF entities:
virtual void addDimAlign( const DL_DimensionData&, 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&, 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&, 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&, 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&, 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&, 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&, virtual void addDimOrdinate( const DL_DimensionData&,
const DL_DimOrdinateData& ) override { reportMsg( "DL_Dimension not managed" ); } const DL_DimOrdinateData& ) override {}
virtual void addLeader( const DL_LeaderData& ) override virtual void addLeader( const DL_LeaderData& ) override {}
{
reportMsg( "DL_Leader not managed" );
}
virtual void addLeaderVertex( const DL_LeaderVertexData& ) override virtual void addLeaderVertex( const DL_LeaderVertexData& ) override {}
{
reportMsg( "DL_LeaderVertex not managed" );
}
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 addTrace( const DL_TraceData& ) override {}
virtual void add3dFace( const DL_3dFaceData& ) override virtual void add3dFace( const DL_3dFaceData& ) override {}
{
reportMsg( "DL_3dFace not managed" );
}
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 addImage( const DL_ImageData& ) override {}
virtual void linkImage( const DL_ImageDefData& ) override virtual void linkImage( const DL_ImageDefData& ) override {}
{
reportMsg( "DL_ImageDef not managed" );
}
virtual void addHatchLoop( const DL_HatchLoopData& ) override virtual void addHatchLoop( const DL_HatchLoopData& ) override {}
{
reportMsg( "DL_HatchLoop not managed" );
}
virtual void addHatchEdge( const DL_HatchEdgeData& ) override virtual void addHatchEdge( const DL_HatchEdgeData& ) override {}
{
reportMsg( "DL_HatchEdge not managed" );
}
/** /**
* Convert a native unicode string into a DXF encoded string. * Convert a native unicode string into a DXF encoded string.