diff --git a/pcbnew/import_gfx/dxf_import_plugin.cpp b/pcbnew/import_gfx/dxf_import_plugin.cpp index cc6d892bcd..304bded42a 100644 --- a/pcbnew/import_gfx/dxf_import_plugin.cpp +++ b/pcbnew/import_gfx/dxf_import_plugin.cpp @@ -263,7 +263,10 @@ DXF_IMPORT_LAYER* DXF_IMPORT_PLUGIN::getImportLayer( const std::string& aLayerNa if( !layerName.IsEmpty() ) { auto resultIt = std::find_if( m_layers.begin(), m_layers.end(), - [layerName]( const auto& it ) { return it->m_layerName == layerName; } ); + [layerName]( const auto& it ) + { + return it->m_layerName == layerName; + } ); if( resultIt != m_layers.end() ) layer = resultIt->get(); @@ -273,18 +276,38 @@ DXF_IMPORT_LAYER* DXF_IMPORT_PLUGIN::getImportLayer( const std::string& aLayerNa } +DXF_IMPORT_BLOCK* DXF_IMPORT_PLUGIN::getImportBlock( const std::string& aBlockName ) +{ + DXF_IMPORT_BLOCK* block = nullptr; + wxString blockName = wxString::FromUTF8( aBlockName.c_str() ); + + if( !blockName.IsEmpty() ) + { + auto resultIt = std::find_if( m_blocks.begin(), m_blocks.end(), + [blockName]( const auto& it ) + { + return it->m_name == blockName; + } ); + + if( resultIt != m_blocks.end() ) + block = resultIt->get(); + } + + return block; +} + + void DXF_IMPORT_PLUGIN::addLine( const DL_LineData& aData ) { - if( m_currentBlock != nullptr ) - return; - DXF_IMPORT_LAYER* layer = getImportLayer( attributes.getLayer() ); double lineWidth = lineWeightToWidth( attributes.getWidth(), layer ); VECTOR2D start( mapX( aData.x1 ), mapY( aData.y1 ) ); VECTOR2D end( mapX( aData.x2 ), mapY( aData.y2 ) ); - m_internalImporter.AddLine( start, end, lineWidth ); + GRAPHICS_IMPORTER_BUFFER* bufferToUse = + ( m_currentBlock != nullptr ) ? &m_currentBlock->buffer : &m_internalImporter; + bufferToUse->AddLine( start, end, lineWidth ); updateImageLimits( start ); updateImageLimits( end ); @@ -311,9 +334,6 @@ void DXF_IMPORT_PLUGIN::addPolyline(const DL_PolylineData& aData ) void DXF_IMPORT_PLUGIN::addVertex( const DL_VertexData& aData ) { - if( m_currentBlock != nullptr ) - return; - if( m_curr_entity.m_EntityParseStatus == 0 ) return; // Error @@ -379,7 +399,8 @@ void DXF_IMPORT_PLUGIN::addBlock( const DL_BlockData& aData ) { wxString name = wxString::FromUTF8( aData.name.c_str() ); - std::unique_ptr block = std::make_unique( name, aData.bpx, aData.bpy ); + std::unique_ptr block = + std::make_unique( name, aData.bpx, aData.bpy ); m_blocks.push_back( std::move( block ) ); @@ -394,21 +415,33 @@ void DXF_IMPORT_PLUGIN::endBlock() void DXF_IMPORT_PLUGIN::addInsert( const DL_InsertData& aData ) { - wxString blockName = wxString::FromUTF8( aData.name.c_str() ); + DXF_IMPORT_BLOCK* block = getImportBlock( aData.name ); + if( block == nullptr ) + return; + VECTOR2D translation( mapX( aData.ipx ), mapY( aData.ipy ) ); + VECTOR2D scale( mapX( aData.sx ), mapY( aData.sy ) ); + + for( auto& shape : block->buffer.GetShapes() ) + { + std::unique_ptr newShape = shape->clone(); + + newShape->Translate( translation ); + + m_internalImporter.AddShape( newShape ); + } } void DXF_IMPORT_PLUGIN::addCircle( const DL_CircleData& aData ) { - if( m_currentBlock != nullptr ) - return; - VECTOR2D center( mapX( aData.cx ), mapY( aData.cy ) ); DXF_IMPORT_LAYER* layer = getImportLayer( attributes.getLayer() ); double lineWidth = lineWeightToWidth( attributes.getWidth(), layer ); - m_internalImporter.AddCircle( center, mapDim( aData.radius ), lineWidth, false ); + GRAPHICS_IMPORTER_BUFFER* bufferToUse = + ( m_currentBlock != nullptr ) ? &m_currentBlock->buffer : &m_internalImporter; + bufferToUse->AddCircle( center, mapDim( aData.radius ), lineWidth, false ); VECTOR2D radiusDelta( mapDim( aData.radius ), mapDim( aData.radius ) ); @@ -442,7 +475,10 @@ void DXF_IMPORT_PLUGIN::addArc( const DL_ArcData& aData ) DXF_IMPORT_LAYER* layer = getImportLayer( attributes.getLayer() ); double lineWidth = lineWeightToWidth( attributes.getWidth(), layer ); - m_internalImporter.AddArc( center, arcStart, angle, lineWidth ); + + GRAPHICS_IMPORTER_BUFFER* bufferToUse = + ( m_currentBlock != nullptr ) ? &m_currentBlock->buffer : &m_internalImporter; + bufferToUse->AddArc( center, arcStart, angle, lineWidth ); VECTOR2D radiusDelta( mapDim( aData.radius ), mapDim( aData.radius ) ); @@ -453,9 +489,6 @@ void DXF_IMPORT_PLUGIN::addArc( const DL_ArcData& aData ) void DXF_IMPORT_PLUGIN::addText( const DL_TextData& aData ) { - if( m_currentBlock != nullptr ) - return; - VECTOR2D refPoint( mapX( aData.ipx ), mapY( aData.ipy ) ); VECTOR2D secPoint( mapX( aData.apx ), mapY( aData.apy ) ); @@ -565,8 +598,10 @@ void DXF_IMPORT_PLUGIN::addText( const DL_TextData& aData ) double cosine = cos(angleInRads); double sine = sin(angleInRads); - m_internalImporter.AddText( refPoint, text, textHeight, charWidth, textThickness, - angle_degree, hJustify, vJustify ); + GRAPHICS_IMPORTER_BUFFER* bufferToUse = + ( m_currentBlock != nullptr ) ? &m_currentBlock->buffer : &m_internalImporter; + bufferToUse->AddText( refPoint, text, textHeight, charWidth, textThickness, angle_degree, + hJustify, vJustify ); // Calculate the boundary box and update the image limits: bottomLeft.x = bottomLeft.x * cosine - bottomLeft.y * sine; @@ -596,9 +631,6 @@ void DXF_IMPORT_PLUGIN::addText( const DL_TextData& aData ) void DXF_IMPORT_PLUGIN::addMText( const DL_MTextData& aData ) { - if( m_currentBlock != nullptr ) - return; - wxString text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) ); wxString attrib, tmp; @@ -725,8 +757,11 @@ void DXF_IMPORT_PLUGIN::addMText( const DL_MTextData& aData ) double cosine = cos(angleInRads); double sine = sin(angleInRads); - m_internalImporter.AddText( textpos, text, textHeight, charWidth, - textThickness, angle_degree, hJustify, vJustify ); + + GRAPHICS_IMPORTER_BUFFER* bufferToUse = + ( m_currentBlock != nullptr ) ? &m_currentBlock->buffer : &m_internalImporter; + bufferToUse->AddText( textpos, text, textHeight, charWidth, + textThickness, angle_degree, hJustify, vJustify ); bottomLeft.x = bottomLeft.x * cosine - bottomLeft.y * sine; bottomLeft.y = bottomLeft.x * sine + bottomLeft.y * cosine; @@ -1057,7 +1092,10 @@ void DXF_IMPORT_PLUGIN::insertLine( const VECTOR2D& aSegStart, { VECTOR2D origin( SCALE_FACTOR( aSegStart.x ), SCALE_FACTOR( aSegStart.y ) ); VECTOR2D end( SCALE_FACTOR( aSegEnd.x ), SCALE_FACTOR( aSegEnd.y ) ); - m_internalImporter.AddLine( origin, end, aWidth ); + + GRAPHICS_IMPORTER_BUFFER* bufferToUse = + ( m_currentBlock != nullptr ) ? &m_currentBlock->buffer : &m_internalImporter; + bufferToUse->AddLine( origin, end, aWidth ); updateImageLimits( origin ); updateImageLimits( end ); @@ -1132,7 +1170,9 @@ void DXF_IMPORT_PLUGIN::insertArc( const VECTOR2D& aSegStart, const VECTOR2D& aS angle = -angle; } - m_internalImporter.AddArc( center, arc_start, angle, aWidth ); + GRAPHICS_IMPORTER_BUFFER* bufferToUse = + ( m_currentBlock != nullptr ) ? &m_currentBlock->buffer : &m_internalImporter; + bufferToUse->AddArc( center, arc_start, angle, aWidth ); VECTOR2D radiusDelta( SCALE_FACTOR( radius ), SCALE_FACTOR( radius ) ); @@ -1211,7 +1251,9 @@ void DXF_IMPORT_PLUGIN::insertSpline( int aWidth ) else end = bezierControl2; - m_internalImporter.AddSpline( start, bezierControl1, bezierControl2, end , aWidth ); + GRAPHICS_IMPORTER_BUFFER* bufferToUse = + ( m_currentBlock != nullptr ) ? &m_currentBlock->buffer : &m_internalImporter; + bufferToUse->AddSpline( start, bezierControl1, bezierControl2, end, aWidth ); } #endif } diff --git a/pcbnew/import_gfx/dxf_import_plugin.h b/pcbnew/import_gfx/dxf_import_plugin.h index a6c1bc8428..e5cae34909 100644 --- a/pcbnew/import_gfx/dxf_import_plugin.h +++ b/pcbnew/import_gfx/dxf_import_plugin.h @@ -140,6 +140,8 @@ public: wxString m_name; double m_x, m_y; + GRAPHICS_IMPORTER_BUFFER buffer; + DXF_IMPORT_BLOCK( wxString aName, double aX, double aY ) { m_name = aName; @@ -323,6 +325,14 @@ private: */ DXF_IMPORT_LAYER* getImportLayer( const std::string& aLayerName ); + /** + * Returns the import layer block + * + * @param aBlockName is the raw string from dxflib + * @returns The given block by name or nullptf if not found + */ + DXF_IMPORT_BLOCK* getImportBlock( const std::string& aBlockName ); + // Functions to aid in the creation of a Polyline void insertLine( const VECTOR2D& aSegStart, const VECTOR2D& aSegEnd, int aWidth ); void insertArc( const VECTOR2D& aSegStart, const VECTOR2D& aSegEnd, diff --git a/pcbnew/import_gfx/graphics_importer_buffer.cpp b/pcbnew/import_gfx/graphics_importer_buffer.cpp index 503e7f6f76..6be5c61b2f 100644 --- a/pcbnew/import_gfx/graphics_importer_buffer.cpp +++ b/pcbnew/import_gfx/graphics_importer_buffer.cpp @@ -74,6 +74,12 @@ void GRAPHICS_IMPORTER_BUFFER::AddSpline( const VECTOR2D& aStart, const VECTOR2D } +void GRAPHICS_IMPORTER_BUFFER::AddShape( std::unique_ptr& aShape ) +{ + m_shapes.push_back( std::move( aShape ) ); +} + + void GRAPHICS_IMPORTER_BUFFER::ImportTo( GRAPHICS_IMPORTER& aImporter ) { for( auto& shape : m_shapes ) diff --git a/pcbnew/import_gfx/graphics_importer_buffer.h b/pcbnew/import_gfx/graphics_importer_buffer.h index 13e353c3c5..2c61920ba5 100644 --- a/pcbnew/import_gfx/graphics_importer_buffer.h +++ b/pcbnew/import_gfx/graphics_importer_buffer.h @@ -35,6 +35,10 @@ class IMPORTED_SHAPE public: virtual ~IMPORTED_SHAPE() {} virtual void ImportTo( GRAPHICS_IMPORTER& aImporter ) const = 0; + + virtual std::unique_ptr clone() const = 0; + + virtual void Translate( const VECTOR2D& aVec ) = 0; }; @@ -53,10 +57,21 @@ public: aImporter.AddLine( m_start, m_end, m_width ); } + virtual std::unique_ptr clone() const override + { + return std::make_unique( *this ); + } + + void Translate( const VECTOR2D& aVec ) override + { + m_start += aVec; + m_end += aVec; + } + private: - const VECTOR2D m_start; - const VECTOR2D m_end; - double m_width; + VECTOR2D m_start; + VECTOR2D m_end; + double m_width; }; @@ -76,11 +91,21 @@ public: aImporter.AddCircle( m_center, m_radius, m_width, m_filled ); } + virtual std::unique_ptr clone() const override + { + return std::make_unique( *this ); + } + + void Translate( const VECTOR2D& aVec ) override + { + m_center += aVec; + } + private: - const VECTOR2D m_center; - double m_radius; - double m_width; - bool m_filled; + VECTOR2D m_center; + double m_radius; + double m_width; + bool m_filled; }; @@ -100,11 +125,22 @@ public: aImporter.AddArc( m_center, m_start, m_angle, m_width ); } + virtual std::unique_ptr clone() const override + { + return std::make_unique( *this ); + } + + void Translate( const VECTOR2D& aVec ) override + { + m_center += aVec; + m_start += aVec; + } + private: - const VECTOR2D m_center; - const VECTOR2D m_start; - double m_angle; - double m_width; + VECTOR2D m_center; + VECTOR2D m_start; + double m_angle; + double m_width; }; @@ -122,8 +158,21 @@ public: aImporter.AddPolygon( m_vertices, m_width ); } + virtual std::unique_ptr clone() const override + { + return std::make_unique( *this ); + } + + void Translate( const VECTOR2D& aVec ) override + { + for( auto& vertex : m_vertices ) + { + vertex += aVec; + } + } + private: - const std::vector m_vertices; + std::vector m_vertices; double m_width; }; @@ -151,8 +200,18 @@ public: m_thickness, m_orientation, m_hJustify, m_vJustify ); } + virtual std::unique_ptr clone() const override + { + return std::make_unique( *this ); + } + + void Translate( const VECTOR2D& aVec ) override + { + m_origin += aVec; + } + private: - const VECTOR2D m_origin; + VECTOR2D m_origin; const wxString m_text; double m_height; double m_width; @@ -181,12 +240,25 @@ public: aImporter.AddSpline( m_start, m_bezierControl1, m_bezierControl2, m_end, m_width ); } + virtual std::unique_ptr clone() const override + { + return std::make_unique( *this ); + } + + void Translate( const VECTOR2D& aVec ) override + { + m_start += aVec; + m_bezierControl1 += aVec; + m_bezierControl2 += aVec; + m_end += aVec; + } + private: - const VECTOR2D m_start; - const VECTOR2D m_bezierControl1; - const VECTOR2D m_bezierControl2; - const VECTOR2D m_end; - double m_width; + VECTOR2D m_start; + VECTOR2D m_bezierControl1; + VECTOR2D m_bezierControl2; + VECTOR2D m_end; + double m_width; }; @@ -209,6 +281,12 @@ public: const VECTOR2D& BezierControl2, const VECTOR2D& aEnd , double aWidth ) override; void ImportTo( GRAPHICS_IMPORTER& aImporter ); + void AddShape( std::unique_ptr& aShape ); + + std::list>& GetShapes() + { + return m_shapes; + } protected: ///> List of imported shapes