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{
40}
41
42
44{
45 VECTOR2D coord = aCoordinate;
46 coord *= GetScale();
47 coord += GetImportOffsetMM();
48 coord *= GetMillimeterToIuFactor();
49
50 return VECTOR2I( KiROUND( coord.x ), KiROUND( coord.y ) );
51}
52
53
55{
57 double scale = ( factor.x + factor.y ) * 0.5;
58
59 if( aLineWidth <= 0.0 )
60 return int( GetLineWidthMM() * scale );
61
62 // aLineWidth is in mm:
63 return int( aLineWidth * scale );
64}
65
66
67void GRAPHICS_IMPORTER_PCBNEW::AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd,
68 double aWidth, const COLOR4D& aColor )
69{
70 std::unique_ptr<PCB_SHAPE> line( createDrawing() );
71 line->SetShape( SHAPE_T::SEGMENT );
72 line->SetLayer( GetLayer() );
73 line->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
74 line->SetStart( MapCoordinate( aOrigin ) );
75 line->SetEnd( MapCoordinate( aEnd ) );
76
77 // Skip 0 len lines:
78 if( line->GetStart() == line->GetEnd() )
79 return;
80
81 addItem( std::move( line ) );
82}
83
84
85void GRAPHICS_IMPORTER_PCBNEW::AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth,
86 bool aFilled, const COLOR4D& aColor )
87{
88 std::unique_ptr<PCB_SHAPE> circle( createDrawing() );
89 circle->SetShape( SHAPE_T::CIRCLE );
90 circle->SetFilled( aFilled );
91 circle->SetLayer( GetLayer() );
92 circle->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
93 circle->SetStart( MapCoordinate( aCenter ));
94 circle->SetEnd( MapCoordinate( VECTOR2D( aCenter.x + aRadius, aCenter.y ) ) );
95
96 addItem( std::move( circle ) );
97}
98
99
100void GRAPHICS_IMPORTER_PCBNEW::AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart,
101 const EDA_ANGLE& aAngle, double aWidth,
102 const COLOR4D& aColor )
103{
104 std::unique_ptr<PCB_SHAPE> arc( createDrawing() );
105 arc->SetShape( SHAPE_T::ARC );
106 arc->SetLayer( GetLayer() );
107
112 VECTOR2D end = aStart;
113 VECTOR2D mid = aStart;
114
115 RotatePoint( end, aCenter, -aAngle );
116 RotatePoint( mid, aCenter, -aAngle / 2.0 );
117
118 arc->SetArcGeometry( MapCoordinate( aStart ), MapCoordinate( mid ), MapCoordinate( end ) );
119
120 // Ensure the arc can be handled by Pcbnew. Arcs with a too big radius cannot.
121 // The criteria used here is radius < MAX_INT / 2.
122 // this is not perfect, but we do not know the exact final position of the arc, so
123 // we cannot test the coordinate values, because the arc can be moved before being placed.
124 VECTOR2D center = CalcArcCenter( arc->GetStart(), arc->GetEnd(), aAngle );
125 double radius = ( center - arc->GetStart() ).EuclideanNorm();
126 double rd_max_value = std::numeric_limits<VECTOR2I::coord_type>::max() / 2.0;
127
128 if( radius >= rd_max_value )
129 {
130 // Arc cannot be handled: convert it to a segment
131 AddLine( aStart, end, aWidth, aColor );
132 return;
133 }
134
135 arc->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
136
137 addItem( std::move( arc ) );
138}
139
140
141void GRAPHICS_IMPORTER_PCBNEW::AddPolygon( const std::vector<VECTOR2D>& aVertices, double aWidth,
142 const COLOR4D& aColor )
143{
144 std::vector<VECTOR2I> convertedPoints;
145 convertedPoints.reserve( aVertices.size() );
146
147 for( const VECTOR2D& precisePoint : aVertices )
148 convertedPoints.emplace_back( MapCoordinate( precisePoint ) );
149
150 std::unique_ptr<PCB_SHAPE> polygon( createDrawing() );
151 polygon->SetShape( SHAPE_T::POLY );
152 polygon->SetFilled( GetLayer() != Edge_Cuts );
153 polygon->SetLayer( GetLayer() );
154 polygon->SetPolyPoints( convertedPoints );
155
156 if( FOOTPRINT* parentFP = polygon->GetParentFootprint() )
157 {
158 polygon->Rotate( { 0, 0 }, parentFP->GetOrientation() );
159 polygon->Move( parentFP->GetPosition() );
160 }
161
162 polygon->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
163 addItem( std::move( polygon ) );
164}
165
166
167void GRAPHICS_IMPORTER_PCBNEW::AddText( const VECTOR2D& aOrigin, const wxString& aText,
168 double aHeight, double aWidth, double aThickness,
169 double aOrientation, GR_TEXT_H_ALIGN_T aHJustify,
170 GR_TEXT_V_ALIGN_T aVJustify, const COLOR4D& aColor )
171{
172 std::unique_ptr<PCB_TEXT> textItem = createText();
173 textItem->SetLayer( GetLayer() );
174 textItem->SetTextThickness( MapLineWidth( aThickness ) );
175 textItem->SetTextPos( MapCoordinate( aOrigin ) );
176 textItem->SetTextAngle( EDA_ANGLE( aOrientation, DEGREES_T ) );
177 textItem->SetTextWidth( aWidth * ImportScalingFactor().x );
178 textItem->SetTextHeight( aHeight * ImportScalingFactor().y );
179 textItem->SetVertJustify( aVJustify );
180 textItem->SetHorizJustify( aHJustify );
181 textItem->SetText( aText );
182
183 addItem( std::move( textItem ) );
184}
185
186
187void GRAPHICS_IMPORTER_PCBNEW::AddSpline( const VECTOR2D& aStart, const VECTOR2D& BezierControl1,
188 const VECTOR2D& BezierControl2, const VECTOR2D& aEnd,
189 double aWidth, const COLOR4D& aColor )
190{
191 std::unique_ptr<PCB_SHAPE> spline( createDrawing() );
192 spline->SetShape( SHAPE_T::BEZIER );
193 spline->SetLayer( GetLayer() );
194 spline->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
195 spline->SetStart( MapCoordinate( aStart ) );
196 spline->SetBezierC1( MapCoordinate( BezierControl1 ));
197 spline->SetBezierC2( MapCoordinate( BezierControl2 ));
198 spline->SetEnd( MapCoordinate( aEnd ) );
199 spline->RebuildBezierToSegmentsPointsList( aWidth );
200
201 // If the spline is degenerated (i.e. a segment) add it as segment or discard it if
202 // null (i.e. very small) length
203 if( spline->GetBezierPoints().size() <= 2 )
204 {
205 spline->SetShape( SHAPE_T::SEGMENT );
206 int dist = VECTOR2I(spline->GetStart()- spline->GetEnd()).EuclideanNorm();
207
208 // segment smaller than MIN_SEG_LEN_ACCEPTABLE_NM nanometers are skipped.
209 #define MIN_SEG_LEN_ACCEPTABLE_NM 20
210 if( dist < MIN_SEG_LEN_ACCEPTABLE_NM )
211 return;
212 }
213
214 addItem( std::move( spline ) );
215}
216
217
218std::unique_ptr<PCB_SHAPE> GRAPHICS_IMPORTER_BOARD::createDrawing()
219{
220 return std::make_unique<PCB_SHAPE>( m_board );
221}
222
223
224std::unique_ptr<PCB_TEXT> GRAPHICS_IMPORTER_BOARD::createText()
225{
226 return std::make_unique<PCB_TEXT>( m_board );
227}
228
229
231{
232 return std::make_unique<PCB_SHAPE>( m_footprint );
233}
234
235
237{
238 return std::make_unique<PCB_TEXT>( m_footprint );
239}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:247
std::unique_ptr< PCB_TEXT > createText() override
Target layer for the imported shapes.
std::unique_ptr< PCB_SHAPE > createDrawing() override
< Create an object representing a graphical shape.
std::unique_ptr< PCB_SHAPE > createDrawing() override
< Create an object representing a graphical shape.
std::unique_ptr< PCB_TEXT > createText() override
Target layer for the imported shapes.
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) override
Create an object representing a text.
void AddLine(const VECTOR2D &aOrigin, const VECTOR2D &aEnd, double aWidth, const COLOR4D &aColor) override
Create an object representing a line segment.
void AddSpline(const VECTOR2D &aStart, const VECTOR2D &aBezierControl1, const VECTOR2D &aBezierControl2, const VECTOR2D &aEnd, double aWidth, const COLOR4D &aColor) override
Create an object representing an arc.
void AddCircle(const VECTOR2D &aOrigin, double aRadius, double aWidth, bool aFilled, const COLOR4D &aColor) override
Create an object representing a circle.
virtual std::unique_ptr< PCB_SHAPE > createDrawing()=0
< Create an object representing a graphical shape.
virtual std::unique_ptr< PCB_TEXT > createText()=0
Target layer for the imported shapes.
int MapLineWidth(double aLineWidth)
If aLineWidth < 0, the default line thickness value is returned.
PCB_LAYER_ID GetLayer() const
Return the target layer for the imported shapes.
void AddArc(const VECTOR2D &aCenter, const VECTOR2D &aStart, const EDA_ANGLE &aAngle, double aWidth, const COLOR4D &aColor) override
Create an object representing an arc.
void AddPolygon(const std::vector< VECTOR2D > &aVertices, double aWidth, const COLOR4D &aColor) override
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 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:114
@ Dwgs_User
Definition: layer_ids.h:110
const int scale
constexpr int mmToIU(double mm) const
Definition: base_units.h:89
GR_TEXT_H_ALIGN_T
GR_TEXT_V_ALIGN_T
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Definition: trigo.cpp:183
const VECTOR2I CalcArcCenter(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Determine the center of an arc or circle given three points on its circumference.
Definition: trigo.cpp:458
double EuclideanNorm(const VECTOR2I &vector)
Definition: trigo.h:129
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