KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcad_polygon.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) 2007, 2008 Lubo Racko <[email protected]>
5 * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <[email protected]>
6 * Copyright The 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, see <https://www.gnu.org/licenses/>.
20 */
21
22#include <pcad/pcad_polygon.h>
23
24#include <board.h>
25#include <footprint.h>
26#include <pcb_shape.h>
27#include <math/util.h> // for KiROUND
28#include <xnode.h>
29#include <zone.h>
30
31#include <wx/string.h>
32
33namespace PCAD2KICAD {
34
35PCAD_POLYGON::PCAD_POLYGON( PCAD_CALLBACKS* aCallbacks, BOARD* aBoard, int aPCadLayer ) :
36 PCAD_PCB_COMPONENT( aCallbacks, aBoard )
37{
38 m_Width = 0;
39
40 // P-CAD polygons are similar to zones (and we're going to convert them as such), except
41 // that they don't avoid other copper pours. So effectively they're very-high-priority
42 // zones.
43 m_Priority = 100000;
44
45 m_ObjType = wxT( 'Z' );
46 m_PCadLayer = aPCadLayer;
48 m_filled = true;
49}
50
51
53{
54 int i, island;
55
56 for( i = 0; i < (int) m_Outline.GetCount(); i++ )
57 delete m_Outline[i];
58
59 for( island = 0; island < (int) m_Cutouts.GetCount(); island++ )
60 {
61 for( i = 0; i < (int) m_Cutouts[island]->GetCount(); i++ )
62 delete (*m_Cutouts[island])[i];
63
64 delete m_Cutouts[island];
65 }
66
67 for( island = 0; island < (int) m_Islands.GetCount(); island++ )
68 {
69 for( i = 0; i < (int) m_Islands[island]->GetCount(); i++ )
70 delete (*m_Islands[island])[i];
71
72 delete m_Islands[island];
73 }
74}
75
76void PCAD_POLYGON::AssignNet( const wxString& aNetName )
77{
78 m_Net = aNetName;
80}
81
82void PCAD_POLYGON::SetOutline( VERTICES_ARRAY* aOutline )
83{
84 int i;
85
86 m_Outline.Empty();
87
88 for( i = 0; i < (int) aOutline->GetCount(); i++ )
89 m_Outline.Add( new wxRealPoint( (*aOutline)[i]->x, (*aOutline)[i]->y ) );
90
91 if( m_Outline.Count() > 0 )
92 {
93 m_PositionX = m_Outline[0]->x;
94 m_PositionY = m_Outline[0]->y;
95 }
96}
97
98void PCAD_POLYGON::FormPolygon( XNODE* aNode, VERTICES_ARRAY* aPolygon,
99 const wxString& aDefaultUnits, const wxString& aActualConversion )
100{
101 XNODE* lNode;
102 double x, y;
103
104 lNode = FindNode( aNode, wxT( "pt" ) );
105
106 while( lNode )
107 {
108 if( lNode->GetName() == wxT( "pt" ) )
109 {
110 SetDoublePrecisionPosition( lNode->GetNodeContent(), aDefaultUnits, &x, &y,
111 aActualConversion );
112 aPolygon->Add( new wxRealPoint( x, y ) );
113 }
114
115 lNode = lNode->GetNext();
116 }
117}
118
119
120bool PCAD_POLYGON::Parse( XNODE* aNode, const wxString& aDefaultUnits,
121 const wxString& aActualConversion )
122{
123 XNODE* lNode;
124 wxString propValue;
125
126 lNode = FindNode( aNode, wxT( "netNameRef" ) );
127
128 if( lNode )
129 {
130 lNode->GetAttribute( wxT( "Name" ), &propValue );
131 propValue.Trim( false );
132 propValue.Trim( true );
133 m_Net = propValue;
135 }
136
137 // retrieve polygon outline
138 FormPolygon( aNode, &m_Outline, aDefaultUnits, aActualConversion );
139
140 m_PositionX = m_Outline[0]->x;
141 m_PositionY = m_Outline[0]->y;
142
143 // fill the polygon with the same contour as its outline is
144 m_Islands.Add( new VERTICES_ARRAY );
145 FormPolygon( aNode, m_Islands[0], aDefaultUnits, aActualConversion );
146
147 return true;
148}
149
150
152{
153 if( m_Outline.GetCount() > 0 )
154 {
155 if( aFootprint )
156 {
157 PCB_SHAPE* dwg = new PCB_SHAPE( aFootprint, SHAPE_T::POLY );
158 aFootprint->Add( dwg );
159
160 dwg->SetStroke( STROKE_PARAMS( 0 ) );
161 dwg->SetLayer( m_KiCadLayer );
162
163 auto outline = new std::vector<VECTOR2I>;
164
165 for( auto point : m_Outline )
166 outline->push_back( VECTOR2I( point->x, point->y ) );
167
168 dwg->SetPolyPoints( *outline );
169 dwg->SetStart( *outline->begin() );
170 dwg->SetEnd( outline->back() );
171 dwg->Rotate( { 0, 0 }, aFootprint->GetOrientation() );
172 dwg->Move( aFootprint->GetPosition() );
173
174 delete( outline );
175 }
176 else
177 {
178 ZONE* zone = new ZONE( m_board );
179 m_board->Add( zone, ADD_MODE::APPEND );
180
181 zone->SetLayer( m_KiCadLayer );
182 zone->SetNetCode( m_NetCode );
183
184 // add outline
185 for( int i = 0; i < (int) m_Outline.GetCount(); i++ )
186 {
187 zone->AppendCorner( KiROUND( m_Outline[i]->x, m_Outline[i]->y ), -1 );
188 }
189
190 zone->SetLocalClearance( m_Width );
191
193
195 zone->GetDefaultHatchPitch(), true );
196
197 if ( m_ObjType == wxT( 'K' ) )
198 {
199 zone->SetIsRuleArea( true );
200 zone->SetDoNotAllowTracks( true );
201 zone->SetDoNotAllowVias( true );
202 zone->SetDoNotAllowPads( true );
203 zone->SetDoNotAllowZoneFills( true );
204 zone->SetDoNotAllowFootprints( false );
205 }
206 else if( m_ObjType == wxT( 'C' ) )
207 {
208 // convert cutouts to keepouts because standalone cutouts are not supported in KiCad
209 zone->SetIsRuleArea( true );
210 zone->SetDoNotAllowZoneFills( true );
211 zone->SetDoNotAllowTracks( false );
212 zone->SetDoNotAllowVias( false );
213 zone->SetDoNotAllowPads( false );
214 zone->SetDoNotAllowFootprints( false );
215 }
216
217 //if( m_filled )
218 // zone->BuildFilledPolysListData( m_board );
219 }
220 }
221}
222
223
225{
227
228 m_KiCadLayer = m_board->FlipLayer( m_KiCadLayer );
229}
230
231
232void PCAD_POLYGON::SetPosOffset( int aX_offs, int aY_offs )
233{
234 int i, island;
235
236 PCAD_PCB_COMPONENT::SetPosOffset( aX_offs, aY_offs );
237
238 for( i = 0; i < (int) m_Outline.GetCount(); i++ )
239 {
240 m_Outline[i]->x += aX_offs;
241 m_Outline[i]->y += aY_offs;
242 }
243
244 for( island = 0; island < (int) m_Islands.GetCount(); island++ )
245 {
246 for( i = 0; i < (int) m_Islands[island]->GetCount(); i++ )
247 {
248 (*m_Islands[island])[i]->x += aX_offs;
249 (*m_Islands[island])[i]->y += aY_offs;
250 }
251 }
252
253 for( island = 0; island < (int) m_Cutouts.GetCount(); island++ )
254 {
255 for( i = 0; i < (int) m_Cutouts[island]->GetCount(); i++ )
256 {
257 (*m_Cutouts[island])[i]->x += aX_offs;
258 (*m_Cutouts[island])[i]->y += aY_offs;
259 }
260 }
261}
262
263} // namespace PCAD2KICAD
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:986
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:372
void SetPolyPoints(const std::vector< VECTOR2I > &aPoints)
EDA_ANGLE GetOrientation() const
Definition footprint.h:406
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
VECTOR2I GetPosition() const override
Definition footprint.h:403
virtual void SetPosOffset(int aX_offs, int aY_offs)
int GetNetCode(const wxString &aNetName) const
PCAD_PCB_COMPONENT(PCAD_CALLBACKS *aCallbacks, BOARD *aBoard)
virtual void Flip() override
void SetOutline(VERTICES_ARRAY *aOutline)
virtual bool Parse(XNODE *aNode, const wxString &aDefaultUnits, const wxString &aActualConversion)
VERTICES_ARRAY m_Outline
void FormPolygon(XNODE *aNode, VERTICES_ARRAY *aPolygon, const wxString &aDefaultUnits, const wxString &actualConversion)
PCAD_POLYGON(PCAD_CALLBACKS *aCallbacks, BOARD *aBoard, int aPCadLayer)
void AssignNet(const wxString &aNetName)
void AddToBoard(FOOTPRINT *aFootprint=nullptr) override
virtual void SetPosOffset(int aX_offs, int aY_offs) override
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
void SetEnd(const VECTOR2I &aEnd) override
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void Move(const VECTOR2I &aMoveVector) override
Move this object.
void SetStart(const VECTOR2I &aStart) override
void SetStroke(const STROKE_PARAMS &aStroke) override
Simple container to manage line stroke parameters.
An extension of wxXmlNode that can format its contents as KiCad-style s-expressions.
Definition xnode.h:67
XNODE * GetNext() const
Definition xnode.h:102
Handle a list of polygons defining a copper zone.
Definition zone.h:70
void SetDoNotAllowPads(bool aEnable)
Definition zone.h:830
void SetLocalClearance(std::optional< int > aClearance)
Definition zone.h:183
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aBorderHatchStyle, int aBorderHatchPitch, bool aRebuilBorderdHatch)
Set all hatch parameters for the zone.
Definition zone.cpp:1458
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition zone.cpp:599
bool SetNetCode(int aNetCode, bool aNoAssert) override
Override that clamps the netcode to 0 when this zone is in copper-thieving fill mode.
Definition zone.cpp:581
void SetIsRuleArea(bool aEnable)
Definition zone.h:812
void SetDoNotAllowTracks(bool aEnable)
Definition zone.h:829
void SetDoNotAllowVias(bool aEnable)
Definition zone.h:828
void SetDoNotAllowFootprints(bool aEnable)
Definition zone.h:831
bool AppendCorner(VECTOR2I aPosition, int aHoleIdx, bool aAllowDuplication=false)
Add a new corner to the zone outline (to the main outline or a hole)
Definition zone.cpp:1367
void SetDoNotAllowZoneFills(bool aEnable)
Definition zone.h:827
void SetAssignedPriority(unsigned aPriority)
Definition zone.h:117
static int GetDefaultHatchPitch()
Definition zone.cpp:1535
XNODE * FindNode(XNODE *aChild, const wxString &aTag)
void SetDoublePrecisionPosition(const wxString &aStr, const wxString &aDefaultMeasurementUnit, double *aX, double *aY, const wxString &aActualConversion)
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683