KiCad PCB EDA Suite
Loading...
Searching...
No Matches
graphics_importer_pcbnew.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KICAD, a free EDA CAD application.
3 *
4 * Copyright (C) 2016 CERN
5 * @author Maciej Suminski <[email protected]>
6 * Copyright (C) 2018-2023 KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
27
28#include <board.h>
29#include <footprint.h>
30#include <pcb_shape.h>
31#include <pcb_text.h>
32#include <memory>
33#include <tuple>
34
35
37 m_parent( aParent )
38{
41}
42
43
45{
46 VECTOR2D coord = aCoordinate;
47 coord *= GetScale();
48 coord += GetImportOffsetMM();
49 coord *= GetMillimeterToIuFactor();
50
51 return VECTOR2I( KiROUND( coord.x ), KiROUND( coord.y ) );
52}
53
54
56{
58 double scale = ( factor.x + factor.y ) * 0.5;
59
60 if( aLineWidth <= 0.0 )
61 return int( GetLineWidthMM() * scale );
62
63 // aLineWidth is in mm:
64 return int( aLineWidth * scale );
65}
66
67
69{
70 double width = aStroke.GetWidth();
71
72 return STROKE_PARAMS( width != -1 ? MapLineWidth( width ) : -1, aStroke.GetPlotStyle(),
73 aStroke.GetColor() );
74}
75
76
77void GRAPHICS_IMPORTER_PCBNEW::AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd,
78 const IMPORTED_STROKE& aStroke )
79{
80 std::unique_ptr<PCB_SHAPE> line = std::make_unique<PCB_SHAPE>( m_parent );
81 line->SetShape( SHAPE_T::SEGMENT );
82 line->SetLayer( GetLayer() );
83 line->SetStroke( MapStrokeParams( aStroke ) );
84 line->SetStart( MapCoordinate( aStart ) );
85 line->SetEnd( MapCoordinate( aEnd ) );
86
87 // Skip 0 len lines:
88 if( line->GetStart() == line->GetEnd() )
89 return;
90
91 addItem( std::move( line ) );
92}
93
94
95void GRAPHICS_IMPORTER_PCBNEW::AddCircle( const VECTOR2D& aCenter, double aRadius,
96 const IMPORTED_STROKE& aStroke, bool aFilled,
97 const COLOR4D& aFillColor )
98{
99 std::unique_ptr<PCB_SHAPE> circle = std::make_unique<PCB_SHAPE>( m_parent );
100 circle->SetShape( SHAPE_T::CIRCLE );
101 circle->SetFilled( aFilled );
102 circle->SetLayer( GetLayer() );
103 circle->SetStroke( MapStrokeParams( aStroke ) );
104 circle->SetStart( MapCoordinate( aCenter ) );
105 circle->SetEnd( MapCoordinate( VECTOR2D( aCenter.x + aRadius, aCenter.y ) ) );
106
107 addItem( std::move( circle ) );
108}
109
110
111void GRAPHICS_IMPORTER_PCBNEW::AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart,
112 const EDA_ANGLE& aAngle, const IMPORTED_STROKE& aStroke )
113{
114 std::unique_ptr<PCB_SHAPE> arc = std::make_unique<PCB_SHAPE>( m_parent );
115 arc->SetShape( SHAPE_T::ARC );
116 arc->SetLayer( GetLayer() );
117
122 VECTOR2D end = aStart;
123 VECTOR2D mid = aStart;
124
125 RotatePoint( end, aCenter, -aAngle );
126 RotatePoint( mid, aCenter, -aAngle / 2.0 );
127
128 arc->SetArcGeometry( MapCoordinate( aStart ), MapCoordinate( mid ), MapCoordinate( end ) );
129
130 // Ensure the arc can be handled by Pcbnew. Arcs with a too big radius cannot.
131 // The criteria used here is radius < MAX_INT / 2.
132 // this is not perfect, but we do not know the exact final position of the arc, so
133 // we cannot test the coordinate values, because the arc can be moved before being placed.
134 VECTOR2D center = MapCoordinate( aCenter );
135 double radius = ( center - MapCoordinate( aStart ) ).EuclideanNorm();
136 double rd_max_value = std::numeric_limits<VECTOR2I::coord_type>::max() / 2.0;
137
138 if( radius >= rd_max_value )
139 {
140 // Arc cannot be handled: convert it to a segment
141 AddLine( aStart, end, aStroke );
142 return;
143 }
144
145 arc->SetStroke( MapStrokeParams( aStroke ) );
146
147 addItem( std::move( arc ) );
148}
149
150
151void GRAPHICS_IMPORTER_PCBNEW::AddPolygon( const std::vector<VECTOR2D>& aVertices,
152 const IMPORTED_STROKE& aStroke, bool aFilled,
153 const COLOR4D& aFillColor )
154{
155 std::vector<VECTOR2I> convertedPoints;
156 convertedPoints.reserve( aVertices.size() );
157
158 for( const VECTOR2D& precisePoint : aVertices )
159 convertedPoints.emplace_back( MapCoordinate( precisePoint ) );
160
161 std::unique_ptr<PCB_SHAPE> polygon = std::make_unique<PCB_SHAPE>( m_parent );
162 polygon->SetShape( SHAPE_T::POLY );
163 polygon->SetFilled( GetLayer() != Edge_Cuts );
164 polygon->SetLayer( GetLayer() );
165 polygon->SetPolyPoints( convertedPoints );
166
167 if( FOOTPRINT* parentFP = polygon->GetParentFootprint() )
168 {
169 polygon->Rotate( { 0, 0 }, parentFP->GetOrientation() );
170 polygon->Move( parentFP->GetPosition() );
171 }
172
173 polygon->SetStroke( MapStrokeParams( aStroke ) );
174
175 if( polygon->IsPolyShapeValid() )
176 addItem( std::move( polygon ) );
177}
178
179
180void GRAPHICS_IMPORTER_PCBNEW::AddText( const VECTOR2D& aOrigin, const wxString& aText,
181 double aHeight, double aWidth, double aThickness,
182 double aOrientation, GR_TEXT_H_ALIGN_T aHJustify,
183 GR_TEXT_V_ALIGN_T aVJustify, const COLOR4D& aColor )
184{
185 std::unique_ptr<PCB_TEXT> textItem = std::make_unique<PCB_TEXT>( m_parent );
186 textItem->SetLayer( GetLayer() );
187 textItem->SetTextThickness( MapLineWidth( aThickness ) );
188 textItem->SetTextPos( MapCoordinate( aOrigin ) );
189 textItem->SetTextAngle( EDA_ANGLE( aOrientation, DEGREES_T ) );
190 textItem->SetTextWidth( aWidth * ImportScalingFactor().x );
191 textItem->SetTextHeight( aHeight * ImportScalingFactor().y );
192 textItem->SetVertJustify( aVJustify );
193 textItem->SetHorizJustify( aHJustify );
194 textItem->SetText( aText );
195
196 addItem( std::move( textItem ) );
197}
198
199
200void GRAPHICS_IMPORTER_PCBNEW::AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1,
201 const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd,
202 const IMPORTED_STROKE& aStroke )
203{
204 std::unique_ptr<PCB_SHAPE> spline = std::make_unique<PCB_SHAPE>( m_parent );
205 spline->SetShape( SHAPE_T::BEZIER );
206 spline->SetLayer( GetLayer() );
207 spline->SetStroke( MapStrokeParams( aStroke ) );
208 spline->SetStart( MapCoordinate( aStart ) );
209 spline->SetBezierC1( MapCoordinate( aBezierControl1 ));
210 spline->SetBezierC2( MapCoordinate( aBezierControl2 ));
211 spline->SetEnd( MapCoordinate( aEnd ) );
212 spline->RebuildBezierToSegmentsPointsList( aStroke.GetWidth() );
213
214 // If the spline is degenerated (i.e. a segment) add it as segment or discard it if
215 // null (i.e. very small) length
216 if( spline->GetBezierPoints().size() <= 2 )
217 {
218 spline->SetShape( SHAPE_T::SEGMENT );
219 int dist = VECTOR2I(spline->GetStart()- spline->GetEnd()).EuclideanNorm();
220
221 // segment smaller than MIN_SEG_LEN_ACCEPTABLE_NM nanometers are skipped.
222 #define MIN_SEG_LEN_ACCEPTABLE_NM 20
223 if( dist < MIN_SEG_LEN_ACCEPTABLE_NM )
224 return;
225 }
226
227 addItem( std::move( spline ) );
228}
229
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
Abstract interface for BOARD_ITEMs capable of storing other items inside.
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:248
GRAPHICS_IMPORTER_PCBNEW(BOARD_ITEM_CONTAINER *aParent)
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
Create an object representing a text.
BOARD_ITEM_CONTAINER * m_parent
void AddArc(const VECTOR2D &aCenter, const VECTOR2D &aStart, const EDA_ANGLE &aAngle, const IMPORTED_STROKE &aStroke) override
Create an object representing an arc.
void AddCircle(const VECTOR2D &aCenter, double aRadius, const IMPORTED_STROKE &aStroke, bool aFilled, const COLOR4D &aFillColor=COLOR4D::UNSPECIFIED) override
Create an object representing a circle.
void AddLine(const VECTOR2D &aStart, const VECTOR2D &aEnd, const IMPORTED_STROKE &aStroke) override
Create an object representing a line segment.
void AddSpline(const VECTOR2D &aStart, const VECTOR2D &aBezierControl1, const VECTOR2D &aBezierControl2, const VECTOR2D &aEnd, const IMPORTED_STROKE &aStroke) override
Create an object representing an arc.
int MapLineWidth(double aLineWidth)
If aLineWidth < 0, the default line thickness value is returned.
PCB_LAYER_ID m_layer
< Target layer for the imported shapes.
void AddPolygon(const std::vector< VECTOR2D > &aVertices, const IMPORTED_STROKE &aStroke, bool aFilled, const COLOR4D &aFillColor=COLOR4D::UNSPECIFIED) override
Create an object representing a polygon.
STROKE_PARAMS MapStrokeParams(const IMPORTED_STROKE &aStroke)
VECTOR2I MapCoordinate(const VECTOR2D &aCoordinate)
Convert an imported coordinate to a board coordinate, according to the internal units,...
VECTOR2D GetScale() const
double GetMillimeterToIuFactor()
double GetLineWidthMM() const
Return the line width used for importing the outlines (in mm).
void addItem(std::unique_ptr< EDA_ITEM > aItem)
< Add an item to the imported shapes list.
double m_millimeterToIu
Offset (in mm) for imported coordinates.
const VECTOR2D & GetImportOffsetMM() const
VECTOR2D ImportScalingFactor() const
A clone of IMPORTED_STROKE, but with floating-point width.
LINE_STYLE GetPlotStyle() const
double GetWidth() const
KIGFX::COLOR4D GetColor() const
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
Simple container to manage line stroke parameters.
Definition: stroke_params.h:81
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:265
@ DEGREES_T
Definition: eda_angle.h:31
#define MIN_SEG_LEN_ACCEPTABLE_NM
@ Edge_Cuts
Definition: layer_ids.h:113
@ Dwgs_User
Definition: layer_ids.h:109
const int scale
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
GR_TEXT_H_ALIGN_T
GR_TEXT_V_ALIGN_T
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition: trigo.cpp:228
double EuclideanNorm(const VECTOR2I &vector)
Definition: trigo.h:128
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:85
VECTOR2< double > VECTOR2D
Definition: vector2d.h:587
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588