KiCad PCB EDA Suite
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-2022 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 <fp_shape.h>
30#include <pcb_text.h>
31#include <fp_text.h>
32#include <memory>
33#include <tuple>
34
35
37{
40}
41
42
44{
45 VECTOR2D coord = ( aCoordinate + GetImportOffsetMM() ) * ImportScalingFactor();
46 return VECTOR2I( KiROUND( coord.x ), KiROUND( coord.y ) );
47}
48
49
51{
52 if( aLineWidth <= 0.0 )
53 return int( GetLineWidthMM() * ImportScalingFactor() );
54
55 // aLineWidth is in mm:
56 return int( aLineWidth * ImportScalingFactor() );
57}
58
59
60void GRAPHICS_IMPORTER_PCBNEW::AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd,
61 double aWidth )
62{
63 std::unique_ptr<PCB_SHAPE> line( createDrawing() );
64 line->SetShape( SHAPE_T::SEGMENT );
65 line->SetLayer( GetLayer() );
66 line->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
67 line->SetStart( MapCoordinate( aOrigin ) );
68 line->SetEnd( MapCoordinate( aEnd ) );
69
70 // Skip 0 len lines:
71 if( line->GetStart() == line->GetEnd() )
72 return;
73
74
75 if( line->Type() == PCB_FP_SHAPE_T )
76 static_cast<FP_SHAPE*>( line.get() )->SetLocalCoord();
77
78 addItem( std::move( line ) );
79}
80
81
82void GRAPHICS_IMPORTER_PCBNEW::AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth,
83 bool aFilled )
84{
85 std::unique_ptr<PCB_SHAPE> circle( createDrawing() );
86 circle->SetShape( SHAPE_T::CIRCLE );
87 circle->SetFilled( aFilled );
88 circle->SetLayer( GetLayer() );
89 circle->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
90 circle->SetStart( MapCoordinate( aCenter ));
91 circle->SetEnd( MapCoordinate( VECTOR2D( aCenter.x + aRadius, aCenter.y ) ) );
92
93 if( circle->Type() == PCB_FP_SHAPE_T )
94 static_cast<FP_SHAPE*>( circle.get() )->SetLocalCoord();
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{
103 std::unique_ptr<PCB_SHAPE> arc( createDrawing() );
104 arc->SetShape( SHAPE_T::ARC );
105 arc->SetLayer( GetLayer() );
106
111 VECTOR2D end = aStart;
112 VECTOR2D mid = aStart;
113
114 RotatePoint( end, aCenter, -aAngle );
115 RotatePoint( mid, aCenter, -aAngle / 2.0 );
116
117 arc->SetArcGeometry( MapCoordinate( aStart ), MapCoordinate( mid ), MapCoordinate( end ) );
118
119 arc->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
120
121 if( arc->Type() == PCB_FP_SHAPE_T )
122 static_cast<FP_SHAPE*>( arc.get() )->SetLocalCoord();
123
124 addItem( std::move( arc ) );
125}
126
127
128void GRAPHICS_IMPORTER_PCBNEW::AddPolygon( const std::vector< VECTOR2D >& aVertices, double aWidth )
129{
130 std::vector<VECTOR2I> convertedPoints;
131 convertedPoints.reserve( aVertices.size() );
132
133 for( const VECTOR2D& precisePoint : aVertices )
134 convertedPoints.emplace_back( MapCoordinate( precisePoint ) );
135
136 std::unique_ptr<PCB_SHAPE> polygon( createDrawing() );
137 polygon->SetShape( SHAPE_T::POLY );
138 polygon->SetFilled( GetLayer() != Edge_Cuts );
139 polygon->SetLayer( GetLayer() );
140 polygon->SetPolyPoints( convertedPoints );
141
142 if( polygon->Type() == PCB_FP_SHAPE_T )
143 static_cast<FP_SHAPE*>( polygon.get() )->SetLocalCoord();
144
146 addItem( std::move( polygon ) );
147}
148
149
150void GRAPHICS_IMPORTER_PCBNEW::AddText( const VECTOR2D& aOrigin, const wxString& aText,
151 double aHeight, double aWidth, double aThickness,
152 double aOrientation, GR_TEXT_H_ALIGN_T aHJustify,
153 GR_TEXT_V_ALIGN_T aVJustify )
154{
155 std::unique_ptr<BOARD_ITEM> boardItem;
156 EDA_TEXT* textItem;
157 tie( boardItem, textItem ) = createText();
158 boardItem->SetLayer( GetLayer() );
159 textItem->SetTextThickness( MapLineWidth( aThickness ) );
160 textItem->SetTextPos( MapCoordinate( aOrigin ) );
161 textItem->SetTextAngle( EDA_ANGLE( aOrientation, DEGREES_T ) ); // Pcbnew uses the decidegree
162 textItem->SetTextWidth( aWidth * ImportScalingFactor() );
163 textItem->SetTextHeight( aHeight * ImportScalingFactor() );
164 textItem->SetVertJustify( aVJustify );
165 textItem->SetHorizJustify( aHJustify );
166 textItem->SetText( aText );
167
168 if( boardItem->Type() == PCB_FP_TEXT_T )
169 static_cast<FP_TEXT*>( boardItem.get() )->SetLocalCoord();
170
171 addItem( std::move( boardItem ) );
172}
173
174
175void GRAPHICS_IMPORTER_PCBNEW::AddSpline( const VECTOR2D& aStart, const VECTOR2D& BezierControl1,
176 const VECTOR2D& BezierControl2, const VECTOR2D& aEnd,
177 double aWidth )
178{
179 std::unique_ptr<PCB_SHAPE> spline( createDrawing() );
180 spline->SetShape( SHAPE_T::BEZIER );
181 spline->SetLayer( GetLayer() );
182 spline->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
183 spline->SetStart( MapCoordinate( aStart ) );
184 spline->SetBezierC1( MapCoordinate( BezierControl1 ));
185 spline->SetBezierC2( MapCoordinate( BezierControl2 ));
186 spline->SetEnd( MapCoordinate( aEnd ) );
187 spline->RebuildBezierToSegmentsPointsList( aWidth );
188
189 // If the spline is degenerated (i.e. a segment) add it as segment or discard it if
190 // null (i.e. very small) length
191 if( spline->GetBezierPoints().size() <= 2 )
192 {
193 spline->SetShape( SHAPE_T::SEGMENT );
194 int dist = VECTOR2I(spline->GetStart()- spline->GetEnd()).EuclideanNorm();
195
196 // segment smaller than MIN_SEG_LEN_ACCEPTABLE_NM nanometers are skipped.
197 #define MIN_SEG_LEN_ACCEPTABLE_NM 20
198 if( dist < MIN_SEG_LEN_ACCEPTABLE_NM )
199 return;
200 }
201
202
203 if( spline->Type() == PCB_FP_SHAPE_T )
204 static_cast<FP_SHAPE*>( spline.get() )->SetLocalCoord();
205
206 addItem( std::move( spline ) );
207}
208
209
210std::unique_ptr<PCB_SHAPE> GRAPHICS_IMPORTER_BOARD::createDrawing()
211{
212 return std::make_unique<PCB_SHAPE>( m_board );
213}
214
215
216std::pair<std::unique_ptr<BOARD_ITEM>, EDA_TEXT*> GRAPHICS_IMPORTER_BOARD::createText()
217{
218 PCB_TEXT* text = new PCB_TEXT( m_board );
219 return make_pair( std::unique_ptr<BOARD_ITEM>( text ), static_cast<EDA_TEXT*>( text ) );
220}
221
222
224{
225 return std::make_unique<FP_SHAPE>( m_footprint );
226}
227
228
229std::pair<std::unique_ptr<BOARD_ITEM>, EDA_TEXT*> GRAPHICS_IMPORTER_FOOTPRINT::createText()
230{
232 return make_pair( std::unique_ptr<BOARD_ITEM>( text ), static_cast<EDA_TEXT*>( text ) );
233}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:72
void SetTextPos(const VECTOR2I &aPoint)
Definition: eda_text.cpp:373
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:250
void SetTextWidth(int aWidth)
Definition: eda_text.cpp:357
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:187
void SetTextHeight(int aHeight)
Definition: eda_text.cpp:365
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:165
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:195
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:242
std::pair< std::unique_ptr< BOARD_ITEM >, EDA_TEXT * > createText() override
Target layer for the imported shapes.
std::unique_ptr< PCB_SHAPE > createDrawing() override
< Create an object representing a graphical shape.
std::pair< std::unique_ptr< BOARD_ITEM >, EDA_TEXT * > createText() override
Target layer for the imported shapes.
std::unique_ptr< PCB_SHAPE > createDrawing() override
< Create an object representing a graphical shape.
void AddArc(const VECTOR2D &aCenter, const VECTOR2D &aStart, const EDA_ANGLE &aAngle, double aWidth) override
Create an object representing an arc.
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) override
Create an object representing a text.
void AddSpline(const VECTOR2D &aStart, const VECTOR2D &aBezierControl1, const VECTOR2D &aBezierControl2, const VECTOR2D &aEnd, double aWidth) override
Create an object representing an arc.
void AddLine(const VECTOR2D &aOrigin, const VECTOR2D &aEnd, double aWidth) override
Create an object representing a line segment.
void AddPolygon(const std::vector< VECTOR2D > &aVertices, double aWidth) override
void AddCircle(const VECTOR2D &aOrigin, double aRadius, double aWidth, bool aFilled) override
Create an object representing a circle.
virtual std::unique_ptr< PCB_SHAPE > createDrawing()=0
< Create an object representing a graphical shape.
virtual std::pair< std::unique_ptr< BOARD_ITEM >, EDA_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.
VECTOR2I MapCoordinate(const VECTOR2D &aCoordinate)
Convert an imported coordinate to a board coordinate, according to the internal units,...
double ImportScalingFactor() const
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
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: pcb_shape.h:72
Simple container to manage line stroke parameters.
Definition: stroke_params.h:88
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
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
@ PCB_FP_SHAPE_T
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:94
@ PCB_FP_TEXT_T
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
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:589
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590