From 21adc0aac5d0b1f39019312b41f4de45778236c0 Mon Sep 17 00:00:00 2001 From: Alex Shvartzkop Date: Mon, 9 Oct 2023 06:56:13 +0300 Subject: [PATCH] ADDED: Import vector graphics into Schematic editor (SVG, DXF). --- common/import_gfx/graphics_importer.h | 38 ++- .../import_gfx/graphics_importer_buffer.cpp | 23 +- common/import_gfx/graphics_importer_buffer.h | 93 ++++--- common/import_gfx/svg_import_plugin.cpp | 22 +- common/import_gfx/svg_import_plugin.h | 6 +- eeschema/CMakeLists.txt | 1 + eeschema/import_gfx/dialog_import_gfx_sch.cpp | 16 +- .../graphics_importer_lib_symbol.cpp | 14 +- .../import_gfx/graphics_importer_lib_symbol.h | 12 +- eeschema/import_gfx/graphics_importer_sch.cpp | 226 ++++++++++++++++++ eeschema/import_gfx/graphics_importer_sch.h | 82 +++++++ eeschema/menubar.cpp | 2 + eeschema/tools/ee_actions.cpp | 10 + eeschema/tools/ee_actions.h | 1 + eeschema/tools/sch_drawing_tools.cpp | 156 ++++++++++++ eeschema/tools/sch_drawing_tools.h | 2 + .../import_gfx/graphics_importer_pcbnew.cpp | 14 +- pcbnew/import_gfx/graphics_importer_pcbnew.h | 12 +- 18 files changed, 615 insertions(+), 115 deletions(-) create mode 100644 eeschema/import_gfx/graphics_importer_sch.cpp create mode 100644 eeschema/import_gfx/graphics_importer_sch.h diff --git a/common/import_gfx/graphics_importer.h b/common/import_gfx/graphics_importer.h index 65afab2152..8c8eb2a0c6 100644 --- a/common/import_gfx/graphics_importer.h +++ b/common/import_gfx/graphics_importer.h @@ -41,6 +41,34 @@ class EDA_ITEM; +/** + * A clone of IMPORTED_STROKE, but with floating-point width. + */ +class IMPORTED_STROKE +{ +public: + IMPORTED_STROKE( double aWidth = 0, PLOT_DASH_TYPE aPlotStyle = PLOT_DASH_TYPE::DEFAULT, + const KIGFX::COLOR4D& aColor = KIGFX::COLOR4D::UNSPECIFIED ) : + m_width( aWidth ), + m_plotstyle( aPlotStyle ), m_color( aColor ) + { + } + + double GetWidth() const { return m_width; } + void SetWidth( double aWidth ) { m_width = aWidth; } + + PLOT_DASH_TYPE GetPlotStyle() const { return m_plotstyle; } + void SetPlotStyle( PLOT_DASH_TYPE aPlotStyle ) { m_plotstyle = aPlotStyle; } + + KIGFX::COLOR4D GetColor() const { return m_color; } + void SetColor( const KIGFX::COLOR4D& aColor ) { m_color = aColor; } + +private: + double m_width; + PLOT_DASH_TYPE m_plotstyle; + KIGFX::COLOR4D m_color; +}; + /** * Interface that creates objects representing shapes for a given data model. */ @@ -212,7 +240,7 @@ public: * @param aStroke is the shape stroke parameters. */ virtual void AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd, - const STROKE_PARAMS& aStroke ) = 0; + const IMPORTED_STROKE& aStroke ) = 0; /** * Create an object representing a circle. @@ -221,7 +249,7 @@ public: * @param aRadius is the circle radius expressed in mm. * @param aStroke is the shape stroke parameters. */ - virtual void AddCircle( const VECTOR2D& aCenter, double aRadius, const STROKE_PARAMS& aStroke, + virtual void AddCircle( const VECTOR2D& aCenter, double aRadius, const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor ) = 0; /** @@ -234,7 +262,7 @@ public: * @param aStroke is the shape stroke parameters. */ virtual void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, const EDA_ANGLE& aAngle, - const STROKE_PARAMS& aStroke ) = 0; + const IMPORTED_STROKE& aStroke ) = 0; /** * Create an object representing a polygon. @@ -244,7 +272,7 @@ public: * @param aStroke is the shape stroke parameters. * @param aFillColor is the fill color. */ - virtual void AddPolygon( const std::vector& aVertices, const STROKE_PARAMS& aStroke, + virtual void AddPolygon( const std::vector& aVertices, const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor ) = 0; /** @@ -276,7 +304,7 @@ public: */ virtual void AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1, const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, - const STROKE_PARAMS& aStroke ) = 0; + const IMPORTED_STROKE& aStroke ) = 0; protected: ///< Add an item to the imported shapes list. diff --git a/common/import_gfx/graphics_importer_buffer.cpp b/common/import_gfx/graphics_importer_buffer.cpp index f37e833c7c..7a6ac21134 100644 --- a/common/import_gfx/graphics_importer_buffer.cpp +++ b/common/import_gfx/graphics_importer_buffer.cpp @@ -39,14 +39,14 @@ static std::unique_ptr make_shape( const Args&... aArguments ) } void GRAPHICS_IMPORTER_BUFFER::AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, - const STROKE_PARAMS& aStroke ) + const IMPORTED_STROKE& aStroke ) { m_shapes.push_back( make_shape( aStart, aEnd, aStroke ) ); } void GRAPHICS_IMPORTER_BUFFER::AddCircle( const VECTOR2D& aCenter, double aRadius, - const STROKE_PARAMS& aStroke, bool aFilled, + const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor ) { m_shapes.push_back( @@ -55,14 +55,14 @@ void GRAPHICS_IMPORTER_BUFFER::AddCircle( const VECTOR2D& aCenter, double aRadiu void GRAPHICS_IMPORTER_BUFFER::AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, - const EDA_ANGLE& aAngle, const STROKE_PARAMS& aStroke ) + const EDA_ANGLE& aAngle, const IMPORTED_STROKE& aStroke ) { m_shapes.push_back( make_shape( aCenter, aStart, aAngle, aStroke ) ); } void GRAPHICS_IMPORTER_BUFFER::AddPolygon( const std::vector& aVertices, - const STROKE_PARAMS& aStroke, bool aFilled, + const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor ) { m_shapes.push_back( make_shape( aVertices, aStroke, aFilled, aFillColor ) ); @@ -83,7 +83,7 @@ void GRAPHICS_IMPORTER_BUFFER::AddText( const VECTOR2D& aOrigin, const wxString& void GRAPHICS_IMPORTER_BUFFER::AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1, const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, - const STROKE_PARAMS& aStroke ) + const IMPORTED_STROKE& aStroke ) { m_shapes.push_back( make_shape( aStart, aBezierControl1, aBezierControl2, aEnd, aStroke ) ); @@ -106,7 +106,8 @@ void GRAPHICS_IMPORTER_BUFFER::ImportTo( GRAPHICS_IMPORTER& aImporter ) static void convertPolygon( std::list>& aShapes, std::vector& aPaths, GRAPHICS_IMPORTER::POLY_FILL_RULE aFillRule, - const STROKE_PARAMS& aStroke, bool aFilled, const COLOR4D& aFillColor ) + const IMPORTED_STROKE& aStroke, bool aFilled, + const COLOR4D& aFillColor ) { double minX = std::numeric_limits::max(); double minY = minX; @@ -182,10 +183,10 @@ static void convertPolygon( std::list>& aShapes, void GRAPHICS_IMPORTER_BUFFER::PostprocessNestedPolygons() { - int curShapeIdx = -1; - STROKE_PARAMS lastStroke; - bool lastFilled = false; - COLOR4D lastFillColor = COLOR4D::UNSPECIFIED; + int curShapeIdx = -1; + IMPORTED_STROKE lastStroke; + bool lastFilled = false; + COLOR4D lastFillColor = COLOR4D::UNSPECIFIED; std::list> newShapes; std::vector polypaths; @@ -212,7 +213,7 @@ void GRAPHICS_IMPORTER_BUFFER::PostprocessNestedPolygons() curShapeIdx = index; lastStroke = poly->GetStroke(); - lastFilled = poly->isFilled(); + lastFilled = poly->IsFilled(); lastFillColor = poly->GetFillColor(); polypaths.push_back( poly ); } diff --git a/common/import_gfx/graphics_importer_buffer.h b/common/import_gfx/graphics_importer_buffer.h index 09cf7920f8..9e5c244b35 100644 --- a/common/import_gfx/graphics_importer_buffer.h +++ b/common/import_gfx/graphics_importer_buffer.h @@ -32,6 +32,7 @@ #include #include + class IMPORTED_SHAPE { public: @@ -43,7 +44,7 @@ public: virtual void Transform( const MATRIX3x3D& aTransform, const VECTOR2D& aTranslation ) = 0; void SetParentShapeIndex( int aIndex ) { m_parentShapeIndex = aIndex; } - int GetParentShapeIndex() const { return m_parentShapeIndex; } + int GetParentShapeIndex() const { return m_parentShapeIndex; } protected: int m_parentShapeIndex = -1; @@ -53,7 +54,7 @@ protected: class IMPORTED_LINE : public IMPORTED_SHAPE { public: - IMPORTED_LINE( const VECTOR2D& aStart, const VECTOR2D& aEnd, const STROKE_PARAMS& aStroke ) : + IMPORTED_LINE( const VECTOR2D& aStart, const VECTOR2D& aEnd, const IMPORTED_STROKE& aStroke ) : m_start( aStart ), m_end( aEnd ), m_stroke( aStroke ) { } @@ -75,16 +76,16 @@ public: } private: - VECTOR2D m_start; - VECTOR2D m_end; - STROKE_PARAMS m_stroke; + VECTOR2D m_start; + VECTOR2D m_end; + IMPORTED_STROKE m_stroke; }; class IMPORTED_CIRCLE : public IMPORTED_SHAPE { public: - IMPORTED_CIRCLE( const VECTOR2D& aCenter, double aRadius, const STROKE_PARAMS& aStroke, + IMPORTED_CIRCLE( const VECTOR2D& aCenter, double aRadius, const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor ) : m_center( aCenter ), m_radius( aRadius ), m_stroke( aStroke ), m_filled( aFilled ), m_fillColor( aFillColor ) @@ -113,11 +114,11 @@ public: } private: - VECTOR2D m_center; - double m_radius; - STROKE_PARAMS m_stroke; - bool m_filled; - COLOR4D m_fillColor; + VECTOR2D m_center; + double m_radius; + IMPORTED_STROKE m_stroke; + bool m_filled; + COLOR4D m_fillColor; }; @@ -125,7 +126,7 @@ class IMPORTED_ARC : public IMPORTED_SHAPE { public: IMPORTED_ARC( const VECTOR2D& aCenter, const VECTOR2D& aStart, const EDA_ANGLE& aAngle, - const STROKE_PARAMS& aStroke ) : + const IMPORTED_STROKE& aStroke ) : m_center( aCenter ), m_start( aStart ), m_angle( aAngle ), m_stroke( aStroke ) { @@ -148,17 +149,17 @@ public: } private: - VECTOR2D m_center; - VECTOR2D m_start; - EDA_ANGLE m_angle; - STROKE_PARAMS m_stroke; + VECTOR2D m_center; + VECTOR2D m_start; + EDA_ANGLE m_angle; + IMPORTED_STROKE m_stroke; }; class IMPORTED_POLYGON : public IMPORTED_SHAPE { public: - IMPORTED_POLYGON( const std::vector& aVertices, const STROKE_PARAMS& aStroke, + IMPORTED_POLYGON( const std::vector& aVertices, const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor ) : m_vertices( aVertices ), m_stroke( aStroke ), m_filled( aFilled ), m_fillColor( aFillColor ) @@ -185,15 +186,15 @@ public: std::vector& Vertices() { return m_vertices; } - bool isFilled() const { return m_filled; } + bool IsFilled() const { return m_filled; } const COLOR4D& GetFillColor() const { return m_fillColor; } - const STROKE_PARAMS& GetStroke() const { return m_stroke; } + const IMPORTED_STROKE& GetStroke() const { return m_stroke; } private: std::vector m_vertices; - STROKE_PARAMS m_stroke; + IMPORTED_STROKE m_stroke; bool m_filled; COLOR4D m_fillColor; }; @@ -229,15 +230,15 @@ public: } private: - VECTOR2D m_origin; - const wxString m_text; - double m_height; - double m_width; - double m_thickness; - double m_orientation; - GR_TEXT_H_ALIGN_T m_hJustify; - GR_TEXT_V_ALIGN_T m_vJustify; - COLOR4D m_color; + VECTOR2D m_origin; + const wxString m_text; + double m_height; + double m_width; + double m_thickness; + double m_orientation; + GR_TEXT_H_ALIGN_T m_hJustify; + GR_TEXT_V_ALIGN_T m_vJustify; + COLOR4D m_color; }; @@ -246,7 +247,7 @@ class IMPORTED_SPLINE : public IMPORTED_SHAPE public: IMPORTED_SPLINE( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1, const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, - const STROKE_PARAMS& aStroke ) : + const IMPORTED_STROKE& aStroke ) : m_start( aStart ), m_bezierControl1( aBezierControl1 ), m_bezierControl2( aBezierControl2 ), m_end( aEnd ), m_stroke( aStroke ) @@ -272,11 +273,11 @@ public: } private: - VECTOR2D m_start; - VECTOR2D m_bezierControl1; - VECTOR2D m_bezierControl2; - VECTOR2D m_end; - STROKE_PARAMS m_stroke; + VECTOR2D m_start; + VECTOR2D m_bezierControl1; + VECTOR2D m_bezierControl2; + VECTOR2D m_end; + IMPORTED_STROKE m_stroke; }; @@ -284,15 +285,15 @@ class GRAPHICS_IMPORTER_BUFFER : public GRAPHICS_IMPORTER { public: void AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, - const STROKE_PARAMS& aStroke ) override; + const IMPORTED_STROKE& aStroke ) override; - void AddCircle( const VECTOR2D& aCenter, double aRadius, const STROKE_PARAMS& aStroke, + void AddCircle( const VECTOR2D& aCenter, double aRadius, const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor = COLOR4D::UNSPECIFIED ) override; void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, const EDA_ANGLE& aAngle, - const STROKE_PARAMS& aStroke ) override; + const IMPORTED_STROKE& aStroke ) override; - void AddPolygon( const std::vector& aVertices, const STROKE_PARAMS& aStroke, + void AddPolygon( const std::vector& aVertices, const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor = COLOR4D::UNSPECIFIED ) override; void AddText( const VECTOR2D& aOrigin, const wxString& aText, double aHeight, double aWidth, @@ -302,26 +303,20 @@ public: void AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1, const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, - const STROKE_PARAMS& aStroke ) override; + const IMPORTED_STROKE& aStroke ) override; void ImportTo( GRAPHICS_IMPORTER& aImporter ); void AddShape( std::unique_ptr& aShape ); - std::list>& GetShapes() - { - return m_shapes; - } + std::list>& GetShapes() { return m_shapes; } - void ClearShapes() - { - m_shapes.clear(); - } + void ClearShapes() { m_shapes.clear(); } void PostprocessNestedPolygons(); protected: ///< List of imported shapes - std::list< std::unique_ptr< IMPORTED_SHAPE > > m_shapes; + std::list> m_shapes; }; #endif /* GRAPHICS_IMPORTER_BUFFER */ diff --git a/common/import_gfx/svg_import_plugin.cpp b/common/import_gfx/svg_import_plugin.cpp index d83020bf9f..d412fa773b 100644 --- a/common/import_gfx/svg_import_plugin.cpp +++ b/common/import_gfx/svg_import_plugin.cpp @@ -174,7 +174,7 @@ bool SVG_IMPORT_PLUGIN::Import() dashType = PLOT_DASH_TYPE::DASHDOTDOT; } - STROKE_PARAMS stroke( lineWidth, dashType, strokeColor ); + IMPORTED_STROKE stroke( lineWidth, dashType, strokeColor ); GRAPHICS_IMPORTER::POLY_FILL_RULE rule = GRAPHICS_IMPORTER::PF_NONZERO; @@ -253,7 +253,7 @@ BOX2D SVG_IMPORT_PLUGIN::GetImageBBox() const void SVG_IMPORT_PLUGIN::DrawPath( const float* aPoints, int aNumPoints, bool aClosedPath, - const STROKE_PARAMS& aStroke, bool aFilled, + const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor ) { std::vector collectedPathPoints; @@ -269,13 +269,13 @@ void SVG_IMPORT_PLUGIN::DrawPath( const float* aPoints, int aNumPoints, bool aCl void SVG_IMPORT_PLUGIN::DrawCubicBezierPath( const float* aPoints, int aNumPoints, - std::vector< VECTOR2D >& aGeneratedPoints ) + std::vector& aGeneratedPoints ) { - const int pointsPerSegment = 4; - const int curveSpecificPointsPerSegment = 3; - const int curveSpecificCoordinatesPerSegment = 2 * curveSpecificPointsPerSegment; + const int pointsPerSegment = 4; + const int curveSpecificPointsPerSegment = 3; + const int curveSpecificCoordinatesPerSegment = 2 * curveSpecificPointsPerSegment; const float* currentPoints = aPoints; - int remainingPoints = aNumPoints; + int remainingPoints = aNumPoints; while( remainingPoints >= pointsPerSegment ) { @@ -286,8 +286,8 @@ void SVG_IMPORT_PLUGIN::DrawCubicBezierPath( const float* aPoints, int aNumPoint } -void SVG_IMPORT_PLUGIN::DrawCubicBezierCurve( const float* aPoints, - std::vector< VECTOR2D >& aGeneratedPoints ) +void SVG_IMPORT_PLUGIN::DrawCubicBezierCurve( const float* aPoints, + std::vector& aGeneratedPoints ) { auto start = getBezierPoint( aPoints, 0.0f ); auto end = getBezierPoint( aPoints, 1.0f ); @@ -300,7 +300,7 @@ void SVG_IMPORT_PLUGIN::DrawCubicBezierCurve( const float* aPoints, void SVG_IMPORT_PLUGIN::DrawPolygon( const std::vector& aPoints, - const STROKE_PARAMS& aStroke, bool aFilled, + const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor ) { m_internalImporter.AddPolygon( aPoints, aStroke, aFilled, aFillColor ); @@ -308,7 +308,7 @@ void SVG_IMPORT_PLUGIN::DrawPolygon( const std::vector& aPoints, void SVG_IMPORT_PLUGIN::DrawLineSegments( const std::vector& aPoints, - const STROKE_PARAMS& aStroke ) + const IMPORTED_STROKE& aStroke ) { unsigned int numLineStartPoints = aPoints.size() - 1; diff --git a/common/import_gfx/svg_import_plugin.h b/common/import_gfx/svg_import_plugin.h index b711a2e568..745688c927 100644 --- a/common/import_gfx/svg_import_plugin.h +++ b/common/import_gfx/svg_import_plugin.h @@ -72,17 +72,17 @@ public: private: void DrawPath( const float* aPoints, int aNumPoints, bool aClosedPath, - const STROKE_PARAMS& aStroke, bool aFilled, const COLOR4D& aFillColor ); + const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor ); void DrawCubicBezierPath( const float* aPoints, int aNumPoints, std::vector& aGeneratedPoints ); void DrawCubicBezierCurve( const float* aPoints, std::vector& aGeneratedPoints ); - void DrawPolygon( const std::vector& aPoints, const STROKE_PARAMS& aStroke, + void DrawPolygon( const std::vector& aPoints, const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor ); - void DrawLineSegments( const std::vector& aPoints, const STROKE_PARAMS& aStroke ); + void DrawLineSegments( const std::vector& aPoints, const IMPORTED_STROKE& aStroke ); struct NSVGimage* m_parsedImage; diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 788f5212a3..40204eebfd 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -285,6 +285,7 @@ set( EESCHEMA_IMPORT_GFX import_gfx/dialog_import_gfx_sch_base.cpp import_gfx/dialog_import_gfx_sch.cpp import_gfx/graphics_importer_lib_symbol.cpp + import_gfx/graphics_importer_sch.cpp ) set( EESCHEMA_SRCS diff --git a/eeschema/import_gfx/dialog_import_gfx_sch.cpp b/eeschema/import_gfx/dialog_import_gfx_sch.cpp index b1358473cc..7c971a24cb 100644 --- a/eeschema/import_gfx/dialog_import_gfx_sch.cpp +++ b/eeschema/import_gfx/dialog_import_gfx_sch.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -69,6 +70,8 @@ DIALOG_IMPORT_GFX_SCH::DIALOG_IMPORT_GFX_SCH( SCH_BASE_FRAME* aParent ) : m_yOrigin( aParent, m_yLabel, m_yCtrl, m_yUnits ), m_defaultLineWidth( aParent, m_lineWidthLabel, m_lineWidthCtrl, m_lineWidthUnits ) { + m_browseButton->SetBitmap( KiBitmap( BITMAPS::small_folder ) ); + auto initWidgetsFromSettings = [&]( const auto& aCfg ) { m_placementInteractive = aCfg->m_ImportGraphics.interactive_placement; @@ -87,8 +90,6 @@ DIALOG_IMPORT_GFX_SCH::DIALOG_IMPORT_GFX_SCH( SCH_BASE_FRAME* aParent ) : m_choiceDxfUnits->Append( unitEntry.second ); m_choiceDxfUnits->SetSelection( aCfg->m_ImportGraphics.dxf_units ); - - m_browseButton->SetBitmap( KiBitmap( BITMAPS::small_folder ) ); }; if( SYMBOL_EDIT_FRAME* symFrame = dynamic_cast( aParent ) ) @@ -101,10 +102,10 @@ DIALOG_IMPORT_GFX_SCH::DIALOG_IMPORT_GFX_SCH( SCH_BASE_FRAME* aParent ) : } else if( SCH_EDIT_FRAME* schFrame = dynamic_cast( aParent ) ) { - /*m_importer = std::make_unique( symFrame ); + m_importer = std::make_unique( schFrame->GetScreen() ); EESCHEMA_SETTINGS* cfg = m_parent->eeconfig(); - initWidgetsFromSettings( cfg );*/ + initWidgetsFromSettings( cfg ); } // construct an import manager with options from config @@ -155,18 +156,13 @@ DIALOG_IMPORT_GFX_SCH::~DIALOG_IMPORT_GFX_SCH() if( SYMBOL_EDIT_FRAME* symFrame = dynamic_cast( m_parent ) ) { - m_importer = std::make_unique( symFrame->GetCurSymbol(), - symFrame->GetUnit() ); - SYMBOL_EDITOR_SETTINGS* cfg = m_parent->libeditconfig(); saveToSettings( cfg ); } else if( SCH_EDIT_FRAME* schFrame = dynamic_cast( m_parent ) ) { - /*m_importer = std::make_unique( symFrame ); - EESCHEMA_SETTINGS* cfg = m_parent->eeconfig(); - saveToSettings( cfg );*/ + saveToSettings( cfg ); } m_textCtrlFileName->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, diff --git a/eeschema/import_gfx/graphics_importer_lib_symbol.cpp b/eeschema/import_gfx/graphics_importer_lib_symbol.cpp index 3dfc07532e..992a0dccff 100644 --- a/eeschema/import_gfx/graphics_importer_lib_symbol.cpp +++ b/eeschema/import_gfx/graphics_importer_lib_symbol.cpp @@ -63,9 +63,9 @@ int GRAPHICS_IMPORTER_LIB_SYMBOL::MapLineWidth( double aLineWidth ) } -STROKE_PARAMS GRAPHICS_IMPORTER_LIB_SYMBOL::MapStrokeParams( const STROKE_PARAMS& aStroke ) +STROKE_PARAMS GRAPHICS_IMPORTER_LIB_SYMBOL::MapStrokeParams( const IMPORTED_STROKE& aStroke ) { - int width = aStroke.GetWidth(); + double width = aStroke.GetWidth(); return STROKE_PARAMS( width != -1 ? MapLineWidth( width ) : -1, aStroke.GetPlotStyle(), aStroke.GetColor() ); @@ -73,7 +73,7 @@ STROKE_PARAMS GRAPHICS_IMPORTER_LIB_SYMBOL::MapStrokeParams( const STROKE_PARAMS void GRAPHICS_IMPORTER_LIB_SYMBOL::AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, - const STROKE_PARAMS& aStroke ) + const IMPORTED_STROKE& aStroke ) { VECTOR2I pt0 = MapCoordinate( aStart ); VECTOR2I pt1 = MapCoordinate( aEnd ); @@ -94,7 +94,7 @@ void GRAPHICS_IMPORTER_LIB_SYMBOL::AddLine( const VECTOR2D& aStart, const VECTOR void GRAPHICS_IMPORTER_LIB_SYMBOL::AddCircle( const VECTOR2D& aCenter, double aRadius, - const STROKE_PARAMS& aStroke, bool aFilled, + const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor ) { std::unique_ptr circle = std::make_unique( m_symbol, SHAPE_T::CIRCLE ); @@ -110,7 +110,7 @@ void GRAPHICS_IMPORTER_LIB_SYMBOL::AddCircle( const VECTOR2D& aCenter, double aR void GRAPHICS_IMPORTER_LIB_SYMBOL::AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, - const EDA_ANGLE& aAngle, const STROKE_PARAMS& aStroke ) + const EDA_ANGLE& aAngle, const IMPORTED_STROKE& aStroke ) { std::unique_ptr arc = std::make_unique( m_symbol, SHAPE_T::ARC ); arc->SetUnit( m_unit ); @@ -149,7 +149,7 @@ void GRAPHICS_IMPORTER_LIB_SYMBOL::AddArc( const VECTOR2D& aCenter, const VECTOR void GRAPHICS_IMPORTER_LIB_SYMBOL::AddPolygon( const std::vector& aVertices, - const STROKE_PARAMS& aStroke, bool aFilled, + const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor ) { std::vector convertedPoints; @@ -204,7 +204,7 @@ void GRAPHICS_IMPORTER_LIB_SYMBOL::AddText( const VECTOR2D& aOrigin, const wxStr void GRAPHICS_IMPORTER_LIB_SYMBOL::AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1, const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, - const STROKE_PARAMS& aStroke ) + const IMPORTED_STROKE& aStroke ) { std::unique_ptr spline = std::make_unique( m_symbol, SHAPE_T::BEZIER ); spline->SetUnit( m_unit ); diff --git a/eeschema/import_gfx/graphics_importer_lib_symbol.h b/eeschema/import_gfx/graphics_importer_lib_symbol.h index 5e1cd70a73..12c8b588d2 100644 --- a/eeschema/import_gfx/graphics_importer_lib_symbol.h +++ b/eeschema/import_gfx/graphics_importer_lib_symbol.h @@ -41,15 +41,15 @@ public: GRAPHICS_IMPORTER_LIB_SYMBOL( LIB_SYMBOL* aSymbol, int aUnit ); void AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, - const STROKE_PARAMS& aStroke ) override; + const IMPORTED_STROKE& aStroke ) override; - void AddCircle( const VECTOR2D& aCenter, double aRadius, const STROKE_PARAMS& aStroke, + void AddCircle( const VECTOR2D& aCenter, double aRadius, const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor = COLOR4D::UNSPECIFIED ) override; void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, const EDA_ANGLE& aAngle, - const STROKE_PARAMS& aStroke ) override; + const IMPORTED_STROKE& aStroke ) override; - void AddPolygon( const std::vector& aVertices, const STROKE_PARAMS& aStroke, + void AddPolygon( const std::vector& aVertices, const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor = COLOR4D::UNSPECIFIED ) override; void AddText( const VECTOR2D& aOrigin, const wxString& aText, double aHeight, double aWidth, @@ -59,7 +59,7 @@ public: void AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1, const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, - const STROKE_PARAMS& aStroke ) override; + const IMPORTED_STROKE& aStroke ) override; /** * Convert an imported coordinate to a board coordinate, according to the internal units, @@ -77,7 +77,7 @@ public: */ int MapLineWidth( double aLineWidth ); - STROKE_PARAMS MapStrokeParams( const STROKE_PARAMS& aStroke ); + STROKE_PARAMS MapStrokeParams( const IMPORTED_STROKE& aStroke ); LIB_SYMBOL* m_symbol; int m_unit; diff --git a/eeschema/import_gfx/graphics_importer_sch.cpp b/eeschema/import_gfx/graphics_importer_sch.cpp new file mode 100644 index 0000000000..021a5b52a5 --- /dev/null +++ b/eeschema/import_gfx/graphics_importer_sch.cpp @@ -0,0 +1,226 @@ +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2016 CERN + * @author Maciej Suminski + * Copyright (C) 2018-2023 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "graphics_importer_sch.h" + +#include +#include + +#include +#include +#include + + +GRAPHICS_IMPORTER_SCH::GRAPHICS_IMPORTER_SCH( SCH_SCREEN* aScreen ) : m_screen( aScreen ) +{ + m_millimeterToIu = schIUScale.mmToIU( 1.0 ); +} + + +VECTOR2I GRAPHICS_IMPORTER_SCH::MapCoordinate( const VECTOR2D& aCoordinate ) +{ + VECTOR2D coord = aCoordinate; + coord *= GetScale(); + coord += GetImportOffsetMM(); + coord *= GetMillimeterToIuFactor(); + + return VECTOR2I( KiROUND( coord.x ), KiROUND( coord.y ) ); +} + + +int GRAPHICS_IMPORTER_SCH::MapLineWidth( double aLineWidth ) +{ + VECTOR2D factor = ImportScalingFactor(); + double scale = ( std::abs( factor.x ) + std::abs( factor.y ) ) * 0.5; + + if( aLineWidth <= 0.0 ) + return int( GetLineWidthMM() * scale ); + + // aLineWidth is in mm: + return int( aLineWidth * scale ); +} + + +STROKE_PARAMS GRAPHICS_IMPORTER_SCH::MapStrokeParams( const IMPORTED_STROKE& aStroke ) +{ + double width = aStroke.GetWidth(); + + return STROKE_PARAMS( width != -1 ? MapLineWidth( width ) : -1, aStroke.GetPlotStyle(), + aStroke.GetColor() ); +} + + +void GRAPHICS_IMPORTER_SCH::AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, + const IMPORTED_STROKE& aStroke ) +{ + VECTOR2I pt0 = MapCoordinate( aStart ); + VECTOR2I pt1 = MapCoordinate( aEnd ); + + // Skip 0 len lines: + if( pt0 == pt1 ) + return; + + std::unique_ptr line = std::make_unique(); + line->SetStroke( MapStrokeParams( aStroke ) ); + + line->SetStartPoint( pt0 ); + line->SetEndPoint( pt1 ); + + addItem( std::move( line ) ); +} + + +void GRAPHICS_IMPORTER_SCH::AddCircle( const VECTOR2D& aCenter, double aRadius, + const IMPORTED_STROKE& aStroke, bool aFilled, + const COLOR4D& aFillColor ) +{ + std::unique_ptr circle = std::make_unique( SHAPE_T::CIRCLE ); + circle->SetFillColor( aFillColor ); + circle->SetFilled( aFilled ); + circle->SetStroke( MapStrokeParams( aStroke ) ); + circle->SetStart( MapCoordinate( aCenter ) ); + circle->SetEnd( MapCoordinate( VECTOR2D( aCenter.x + aRadius, aCenter.y ) ) ); + + addItem( std::move( circle ) ); +} + + +void GRAPHICS_IMPORTER_SCH::AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, + const EDA_ANGLE& aAngle, const IMPORTED_STROKE& aStroke ) +{ + std::unique_ptr arc = std::make_unique( SHAPE_T::ARC ); + + /** + * We need to perform the rotation/conversion here while still using floating point values + * to avoid rounding errors when operating in integer space in KiCad + */ + VECTOR2D end = aStart; + VECTOR2D mid = aStart; + + RotatePoint( end, aCenter, -aAngle ); + RotatePoint( mid, aCenter, -aAngle / 2.0 ); + + arc->SetArcGeometry( MapCoordinate( aStart ), MapCoordinate( mid ), MapCoordinate( end ) ); + + // Ensure the arc can be handled by KiCad. Arcs with a too big radius cannot. + // The criteria used here is radius < MAX_INT / 2. + // this is not perfect, but we do not know the exact final position of the arc, so + // we cannot test the coordinate values, because the arc can be moved before being placed. + VECTOR2D center = CalcArcCenter( arc->GetStart(), arc->GetEnd(), aAngle ); + double radius = ( center - arc->GetStart() ).EuclideanNorm(); + constexpr double rd_max_value = std::numeric_limits::max() / 2.0; + + if( radius >= rd_max_value ) + { + // Arc cannot be handled: convert it to a segment + AddLine( aStart, end, aStroke ); + return; + } + + arc->SetStroke( MapStrokeParams( aStroke ) ); + + addItem( std::move( arc ) ); +} + + +void GRAPHICS_IMPORTER_SCH::AddPolygon( const std::vector& aVertices, + const IMPORTED_STROKE& aStroke, bool aFilled, + const COLOR4D& aFillColor ) +{ + std::vector convertedPoints; + convertedPoints.reserve( aVertices.size() ); + + for( const VECTOR2D& precisePoint : aVertices ) + convertedPoints.emplace_back( MapCoordinate( precisePoint ) ); + + if( convertedPoints.empty() ) + return; + + std::unique_ptr polygon = std::make_unique( SHAPE_T::POLY ); + + if( aFilled ) + { + polygon->SetFillMode( aFillColor != COLOR4D::UNSPECIFIED ? FILL_T::FILLED_WITH_COLOR + : FILL_T::FILLED_SHAPE ); + } + + polygon->SetFillColor( aFillColor ); + polygon->SetPolyPoints( convertedPoints ); + polygon->AddPoint( convertedPoints[0] ); // Need to close last point for libedit + + polygon->SetStroke( MapStrokeParams( aStroke ) ); + + addItem( std::move( polygon ) ); +} + + +void GRAPHICS_IMPORTER_SCH::AddText( const VECTOR2D& aOrigin, const wxString& aText, + double aHeight, double aWidth, double aThickness, + double aOrientation, GR_TEXT_H_ALIGN_T aHJustify, + GR_TEXT_V_ALIGN_T aVJustify, const COLOR4D& aColor ) +{ + std::unique_ptr textItem = std::make_unique(); + textItem->SetTextColor( aColor ); + textItem->SetTextThickness( MapLineWidth( aThickness ) ); + textItem->SetTextPos( MapCoordinate( aOrigin ) ); + textItem->SetTextAngle( EDA_ANGLE( aOrientation, DEGREES_T ) ); + textItem->SetTextWidth( aWidth * ImportScalingFactor().x ); + textItem->SetTextHeight( aHeight * ImportScalingFactor().y ); + textItem->SetVertJustify( aVJustify ); + textItem->SetHorizJustify( aHJustify ); + textItem->SetText( aText ); + + addItem( std::move( textItem ) ); +} + + +void GRAPHICS_IMPORTER_SCH::AddSpline( const VECTOR2D& aStart, + const VECTOR2D& aBezierControl1, + const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, + const IMPORTED_STROKE& aStroke ) +{ + std::unique_ptr spline = std::make_unique( SHAPE_T::BEZIER ); + spline->SetStroke( MapStrokeParams( aStroke ) ); + spline->SetStart( MapCoordinate( aStart ) ); + spline->SetBezierC1( MapCoordinate( aBezierControl1 ) ); + spline->SetBezierC2( MapCoordinate( aBezierControl2 ) ); + spline->SetEnd( MapCoordinate( aEnd ) ); + spline->RebuildBezierToSegmentsPointsList( aStroke.GetWidth() ); + + // If the spline is degenerated (i.e. a segment) add it as segment or discard it if + // null (i.e. very small) length + if( spline->GetBezierPoints().size() <= 2 ) + { + spline->SetShape( SHAPE_T::SEGMENT ); + int dist = VECTOR2I( spline->GetStart() - spline->GetEnd() ).EuclideanNorm(); + +// segment smaller than MIN_SEG_LEN_ACCEPTABLE_NM nanometers are skipped. +#define MIN_SEG_LEN_ACCEPTABLE_NM 20 + if( dist < MIN_SEG_LEN_ACCEPTABLE_NM ) + return; + } + + addItem( std::move( spline ) ); +} diff --git a/eeschema/import_gfx/graphics_importer_sch.h b/eeschema/import_gfx/graphics_importer_sch.h new file mode 100644 index 0000000000..d8406d18ff --- /dev/null +++ b/eeschema/import_gfx/graphics_importer_sch.h @@ -0,0 +1,82 @@ +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2016 CERN + * Copyright (C) 2018-2023 KiCad Developers, see AUTHORS.txt for contributors. + * + * @author Maciej Suminski + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GRAPHICS_IMPORTER_SCH_H_ +#define GRAPHICS_IMPORTER_SCH_H_ + +#include + +class SCH_SCREEN; + + +class GRAPHICS_IMPORTER_SCH : public GRAPHICS_IMPORTER +{ +public: + GRAPHICS_IMPORTER_SCH( SCH_SCREEN* aScreen ); + + void AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, + const IMPORTED_STROKE& aStroke ) override; + + void AddCircle( const VECTOR2D& aCenter, double aRadius, const IMPORTED_STROKE& aStroke, + bool aFilled, const COLOR4D& aFillColor = COLOR4D::UNSPECIFIED ) override; + + void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, const EDA_ANGLE& aAngle, + const IMPORTED_STROKE& aStroke ) override; + + void AddPolygon( const std::vector& aVertices, const IMPORTED_STROKE& aStroke, + bool aFilled, const COLOR4D& aFillColor = COLOR4D::UNSPECIFIED ) override; + + void AddText( const VECTOR2D& aOrigin, const wxString& aText, double aHeight, double aWidth, + double aThickness, double aOrientation, GR_TEXT_H_ALIGN_T aHJustify, + GR_TEXT_V_ALIGN_T aVJustify, + const COLOR4D& aColor = COLOR4D::UNSPECIFIED ) override; + + void AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1, + const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, + const IMPORTED_STROKE& aStroke ) override; + + /** + * Convert an imported coordinate to a board coordinate, according to the internal units, + * user scale and offset + * + * @param aCoordinate is the imported coordinate in mm. + */ + VECTOR2I MapCoordinate( const VECTOR2D& aCoordinate ); + + /** + * If aLineWidth < 0, the default line thickness value is returned. + * + * @param aLineWidth is the line thickness in mm to convert. + * @return a line thickness in a board Iu value, according to the internal units. + */ + int MapLineWidth( double aLineWidth ); + + STROKE_PARAMS MapStrokeParams( const IMPORTED_STROKE& aStroke ); + + SCH_SCREEN* m_screen; +}; + +#endif /* GRAPHICS_IMPORTER_SCH_H_ */ diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp index 58ccf8225a..ef1432c993 100644 --- a/eeschema/menubar.cpp +++ b/eeschema/menubar.cpp @@ -118,6 +118,8 @@ void SCH_EDIT_FRAME::doReCreateMenuBar() submenuImport->Add( EE_ACTIONS::importFPAssignments, ACTION_MENU::NORMAL, _( "Footprint Assignments..." ) ); + submenuImport->Add( EE_ACTIONS::schImportGraphics, ACTION_MENU::NORMAL, _( "Graphics..." ) ); + fileMenu->Add( submenuImport ); diff --git a/eeschema/tools/ee_actions.cpp b/eeschema/tools/ee_actions.cpp index a3ffe45fb8..838df37f75 100644 --- a/eeschema/tools/ee_actions.cpp +++ b/eeschema/tools/ee_actions.cpp @@ -579,6 +579,16 @@ TOOL_ACTION EE_ACTIONS::placeImage( TOOL_ACTION_ARGS() .Flags( AF_ACTIVATE ) .Parameter( nullptr ) ); +TOOL_ACTION EE_ACTIONS::schImportGraphics( TOOL_ACTION_ARGS() + .Name( "eeschema.InteractiveDrawing.schImportGraphics" ) + .Scope( AS_GLOBAL ) + .DefaultHotkey( MD_SHIFT + MD_CTRL + 'F' ) + .LegacyHotkeyName( "Place DXF" ) + .MenuText( _( "Import Graphics..." ) ) + .Tooltip( _( "Import 2D drawing file" ) ) + .Icon( BITMAPS::import_vector ) + .Flags( AF_ACTIVATE ) ); + TOOL_ACTION EE_ACTIONS::finishSheet( TOOL_ACTION_ARGS() .Name( "eeschema.InteractiveDrawing.finishSheet" ) .Scope( AS_GLOBAL ) diff --git a/eeschema/tools/ee_actions.h b/eeschema/tools/ee_actions.h index e22d6be5c4..89c0d8bc56 100644 --- a/eeschema/tools/ee_actions.h +++ b/eeschema/tools/ee_actions.h @@ -97,6 +97,7 @@ public: static TOOL_ACTION drawArc; static TOOL_ACTION drawLines; static TOOL_ACTION placeImage; + static TOOL_ACTION schImportGraphics; static TOOL_ACTION undoLastSegment; static TOOL_ACTION switchSegmentPosture; static TOOL_ACTION finishLineWireOrBus; diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp index e37de97193..70dbb5640c 100644 --- a/eeschema/tools/sch_drawing_tools.cpp +++ b/eeschema/tools/sch_drawing_tools.cpp @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -81,6 +82,7 @@ SCH_DRAWING_TOOLS::SCH_DRAWING_TOOLS() : m_inPlaceSymbol( false ), m_inDrawShape( false ), m_inPlaceImage( false ), + m_inImportGraphics( false ), m_inSingleClickPlace( false ), m_inTwoClickPlace( false ), m_inDrawSheet( false ) @@ -757,6 +759,159 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent ) } +int SCH_DRAWING_TOOLS::SchImportGraphics( const TOOL_EVENT& aEvent ) +{ + if( m_inImportGraphics ) + return 0; + + REENTRANCY_GUARD guard( &m_inImportGraphics ); + + // Note: PlaceImportedGraphics() will convert PCB_SHAPE_T and PCB_TEXT_T to footprint + // items if needed + DIALOG_IMPORT_GFX_SCH dlg( m_frame ); + int dlgResult = dlg.ShowModal(); + + std::list>& list = dlg.GetImportedItems(); + + if( dlgResult != wxID_OK ) + return 0; + + // Ensure the list is not empty: + if( list.empty() ) + { + wxMessageBox( _( "No graphic items found in file." ) ); + return 0; + } + + m_toolMgr->RunAction( ACTIONS::cancelInteractive ); + + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + std::vector newItems; // all new items, including group + std::vector selectedItems; // the group, or newItems if no group + EE_SELECTION preview; + SCH_COMMIT commit( m_toolMgr ); + + for( std::unique_ptr& ptr : list ) + { + SCH_ITEM* item = dynamic_cast( ptr.get() ); + wxCHECK2( item, continue ); + + newItems.push_back( item ); + selectedItems.push_back( item ); + preview.Add( item ); + + ptr.release(); + } + + if( !dlg.IsPlacementInteractive() ) + { + // Place the imported drawings + for( SCH_ITEM* item : newItems ) + commit.Add(item, m_frame->GetScreen()); + + commit.Push( _( "Import Graphic" ) ); + return 0; + } + + m_view->Add( &preview ); + + // Clear the current selection then select the drawings so that edit tools work on them + m_toolMgr->RunAction( EE_ACTIONS::clearSelection ); + + EDA_ITEMS selItems( selectedItems.begin(), selectedItems.end() ); + m_toolMgr->RunAction( EE_ACTIONS::addItemsToSel, &selItems ); + + m_frame->PushTool( aEvent ); + + auto setCursor = [&]() + { + m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::MOVING ); + }; + + Activate(); + // Must be done after Activate() so that it gets set into the correct context + controls->ShowCursor( true ); + controls->ForceCursorPosition( false ); + // Set initial cursor + setCursor(); + + //SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::DXF ); + EE_GRID_HELPER grid( m_toolMgr ); + + // Now move the new items to the current cursor position: + VECTOR2I cursorPos = controls->GetCursorPosition( !aEvent.DisableGridSnapping() ); + VECTOR2I delta = cursorPos; + VECTOR2I currentOffset; + + for( SCH_ITEM* item : selectedItems ) + item->Move( delta ); + + currentOffset += delta; + + m_view->Update( &preview ); + + // Main loop: keep receiving events + while( TOOL_EVENT* evt = Wait() ) + { + setCursor(); + + grid.SetSnap( !evt->Modifier( MD_SHIFT ) ); + grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() ); + + cursorPos = grid.Align( controls->GetMousePosition(), GRID_GRAPHICS ); + controls->ForceCursorPosition( true, cursorPos ); + + if( evt->IsCancelInteractive() || evt->IsActivate() ) + { + m_toolMgr->RunAction( EE_ACTIONS::clearSelection ); + + for( SCH_ITEM* item : newItems ) + delete item; + + break; + } + else if( evt->IsMotion() ) + { + delta = cursorPos - currentOffset; + + for( SCH_ITEM* item : selectedItems ) + item->Move( delta ); + + currentOffset += delta; + + m_view->Update( &preview ); + } + else if( evt->IsClick( BUT_RIGHT ) ) + { + m_menu.ShowContextMenu( m_selectionTool->GetSelection() ); + } + else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) ) + { + // Place the imported drawings + for( SCH_ITEM* item : newItems ) + commit.Add( item, m_frame->GetScreen() ); + + commit.Push( _( "Import Graphic" ) ); + break; // This is a one-shot command, not a tool + } + else + { + evt->SetPassEvent(); + } + } + + preview.Clear(); + m_view->Remove( &preview ); + + m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); + controls->ForceCursorPosition( false ); + + m_frame->PopTool( aEvent ); + + return 0; +} + + int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent ) { VECTOR2I cursorPos; @@ -2021,4 +2176,5 @@ void SCH_DRAWING_TOOLS::setTransitions() Go( &SCH_DRAWING_TOOLS::DrawShape, EE_ACTIONS::drawArc.MakeEvent() ); Go( &SCH_DRAWING_TOOLS::DrawShape, EE_ACTIONS::drawTextBox.MakeEvent() ); Go( &SCH_DRAWING_TOOLS::PlaceImage, EE_ACTIONS::placeImage.MakeEvent() ); + Go( &SCH_DRAWING_TOOLS::SchImportGraphics, EE_ACTIONS::schImportGraphics.MakeEvent() ); } diff --git a/eeschema/tools/sch_drawing_tools.h b/eeschema/tools/sch_drawing_tools.h index 7dc964529a..81987e68f1 100644 --- a/eeschema/tools/sch_drawing_tools.h +++ b/eeschema/tools/sch_drawing_tools.h @@ -55,6 +55,7 @@ public: int DrawShape( const TOOL_EVENT& aEvent ); int DrawSheet( const TOOL_EVENT& aEvent ); int PlaceImage( const TOOL_EVENT& aEvent ); + int SchImportGraphics( const TOOL_EVENT& aEvent ); private: SCH_LINE* findWire( const VECTOR2I& aPosition ); @@ -95,6 +96,7 @@ private: bool m_inPlaceSymbol; bool m_inDrawShape; bool m_inPlaceImage; + bool m_inImportGraphics; bool m_inSingleClickPlace; bool m_inTwoClickPlace; bool m_inDrawSheet; diff --git a/pcbnew/import_gfx/graphics_importer_pcbnew.cpp b/pcbnew/import_gfx/graphics_importer_pcbnew.cpp index 781c99a111..d6c50f3ae9 100644 --- a/pcbnew/import_gfx/graphics_importer_pcbnew.cpp +++ b/pcbnew/import_gfx/graphics_importer_pcbnew.cpp @@ -64,9 +64,9 @@ int GRAPHICS_IMPORTER_PCBNEW::MapLineWidth( double aLineWidth ) } -STROKE_PARAMS GRAPHICS_IMPORTER_PCBNEW::MapStrokeParams( const STROKE_PARAMS& aStroke ) +STROKE_PARAMS GRAPHICS_IMPORTER_PCBNEW::MapStrokeParams( const IMPORTED_STROKE& aStroke ) { - int width = aStroke.GetWidth(); + double width = aStroke.GetWidth(); return STROKE_PARAMS( width != -1 ? MapLineWidth( width ) : -1, aStroke.GetPlotStyle(), aStroke.GetColor() ); @@ -74,7 +74,7 @@ STROKE_PARAMS GRAPHICS_IMPORTER_PCBNEW::MapStrokeParams( const STROKE_PARAMS& aS void GRAPHICS_IMPORTER_PCBNEW::AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, - const STROKE_PARAMS& aStroke ) + const IMPORTED_STROKE& aStroke ) { std::unique_ptr line( createDrawing() ); line->SetShape( SHAPE_T::SEGMENT ); @@ -92,7 +92,7 @@ void GRAPHICS_IMPORTER_PCBNEW::AddLine( const VECTOR2D& aStart, const VECTOR2D& void GRAPHICS_IMPORTER_PCBNEW::AddCircle( const VECTOR2D& aCenter, double aRadius, - const STROKE_PARAMS& aStroke, bool aFilled, + const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor ) { std::unique_ptr circle( createDrawing() ); @@ -108,7 +108,7 @@ void GRAPHICS_IMPORTER_PCBNEW::AddCircle( const VECTOR2D& aCenter, double aRadiu void GRAPHICS_IMPORTER_PCBNEW::AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, - const EDA_ANGLE& aAngle, const STROKE_PARAMS& aStroke ) + const EDA_ANGLE& aAngle, const IMPORTED_STROKE& aStroke ) { std::unique_ptr arc( createDrawing() ); arc->SetShape( SHAPE_T::ARC ); @@ -148,7 +148,7 @@ void GRAPHICS_IMPORTER_PCBNEW::AddArc( const VECTOR2D& aCenter, const VECTOR2D& void GRAPHICS_IMPORTER_PCBNEW::AddPolygon( const std::vector& aVertices, - const STROKE_PARAMS& aStroke, bool aFilled, + const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor ) { std::vector convertedPoints; @@ -196,7 +196,7 @@ void GRAPHICS_IMPORTER_PCBNEW::AddText( const VECTOR2D& aOrigin, const wxString& void GRAPHICS_IMPORTER_PCBNEW::AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1, const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, - const STROKE_PARAMS& aStroke ) + const IMPORTED_STROKE& aStroke ) { std::unique_ptr spline( createDrawing() ); spline->SetShape( SHAPE_T::BEZIER ); diff --git a/pcbnew/import_gfx/graphics_importer_pcbnew.h b/pcbnew/import_gfx/graphics_importer_pcbnew.h index 7ee1b3ddf2..de7005740b 100644 --- a/pcbnew/import_gfx/graphics_importer_pcbnew.h +++ b/pcbnew/import_gfx/graphics_importer_pcbnew.h @@ -60,15 +60,15 @@ public: } void AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, - const STROKE_PARAMS& aStroke ) override; + const IMPORTED_STROKE& aStroke ) override; - void AddCircle( const VECTOR2D& aCenter, double aRadius, const STROKE_PARAMS& aStroke, + void AddCircle( const VECTOR2D& aCenter, double aRadius, const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor = COLOR4D::UNSPECIFIED ) override; void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, const EDA_ANGLE& aAngle, - const STROKE_PARAMS& aStroke ) override; + const IMPORTED_STROKE& aStroke ) override; - void AddPolygon( const std::vector& aVertices, const STROKE_PARAMS& aStroke, + void AddPolygon( const std::vector& aVertices, const IMPORTED_STROKE& aStroke, bool aFilled, const COLOR4D& aFillColor = COLOR4D::UNSPECIFIED ) override; void AddText( const VECTOR2D& aOrigin, const wxString& aText, double aHeight, double aWidth, @@ -78,7 +78,7 @@ public: void AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1, const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, - const STROKE_PARAMS& aStroke ) override; + const IMPORTED_STROKE& aStroke ) override; /** * Convert an imported coordinate to a board coordinate, according to the internal units, @@ -96,7 +96,7 @@ public: */ int MapLineWidth( double aLineWidth ); - STROKE_PARAMS MapStrokeParams( const STROKE_PARAMS& aStroke ); + STROKE_PARAMS MapStrokeParams( const IMPORTED_STROKE& aStroke ); protected: ///< Create an object representing a graphical shape.