KiCad PCB EDA Suite
pcb_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 <developer@lura.sk>
5  * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
6  * Copyright (C) 2017-2020 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 
26 #include <pcad/pcb_polygon.h>
27 
28 #include <board.h>
29 #include <footprint.h>
30 #include <fp_shape.h>
31 #include <math/util.h> // for KiROUND
32 #include <xnode.h>
33 #include <zone.h>
34 
35 #include <wx/gdicmn.h>
36 #include <wx/string.h>
37 
38 namespace PCAD2KICAD {
39 
40 PCB_POLYGON::PCB_POLYGON( PCB_CALLBACKS* aCallbacks, BOARD* aBoard, int aPCadLayer ) :
41  PCB_COMPONENT( aCallbacks, aBoard )
42 {
43  m_width = 0;
44 
45  // P-CAD polygons are similar to zones (and we're going to convert them as such), except
46  // that they don't avoid other copper pours. So effectively they're very-high-priority
47  // zones.
48  m_priority = 100000;
49 
50  m_objType = wxT( 'Z' );
51  m_PCadLayer = aPCadLayer;
53  m_filled = true;
54 }
55 
56 
58 {
59  int i, island;
60 
61  for( i = 0; i < (int) m_outline.GetCount(); i++ )
62  {
63  delete m_outline[i];
64  }
65 
66  for( island = 0; island < (int) m_cutouts.GetCount(); island++ )
67  {
68  for( i = 0; i < (int) m_cutouts[island]->GetCount(); i++ )
69  {
70  delete (*m_cutouts[island])[i];
71  }
72 
73  delete m_cutouts[island];
74  }
75 
76  for( island = 0; island < (int) m_islands.GetCount(); island++ )
77  {
78  for( i = 0; i < (int) m_islands[island]->GetCount(); i++ )
79  {
80  delete (*m_islands[island])[i];
81  }
82 
83  delete m_islands[island];
84  }
85 }
86 
87 void PCB_POLYGON::AssignNet( const wxString& aNetName )
88 {
89  m_net = aNetName;
91 }
92 
93 void PCB_POLYGON::SetOutline( VERTICES_ARRAY* aOutline )
94 {
95  int i;
96 
97  m_outline.Empty();
98 
99  for( i = 0; i < (int) aOutline->GetCount(); i++ )
100  m_outline.Add( new wxRealPoint( (*aOutline)[i]->x, (*aOutline)[i]->y ) );
101 
102  if( m_outline.Count() > 0 )
103  {
104  m_positionX = m_outline[0]->x;
105  m_positionY = m_outline[0]->y;
106  }
107 }
108 
109 void PCB_POLYGON::FormPolygon( XNODE* aNode, VERTICES_ARRAY* aPolygon,
110  const wxString& aDefaultUnits, const wxString& aActualConversion )
111 {
112  XNODE* lNode;
113  double x, y;
114 
115  lNode = FindNode( aNode, wxT( "pt" ) );
116 
117  while( lNode )
118  {
119  if( lNode->GetName() == wxT( "pt" ) )
120  {
121  SetDoublePrecisionPosition( lNode->GetNodeContent(), aDefaultUnits, &x, &y,
122  aActualConversion );
123  aPolygon->Add( new wxRealPoint( x, y ) );
124  }
125 
126  lNode = lNode->GetNext();
127  }
128 }
129 
130 
131 bool PCB_POLYGON::Parse( XNODE* aNode, const wxString& aDefaultUnits,
132  const wxString& aActualConversion )
133 {
134  XNODE* lNode;
135  wxString propValue;
136 
137  lNode = FindNode( aNode, wxT( "netNameRef" ) );
138 
139  if( lNode )
140  {
141  lNode->GetAttribute( wxT( "Name" ), &propValue );
142  propValue.Trim( false );
143  propValue.Trim( true );
144  m_net = propValue;
146  }
147 
148  // retrieve polygon outline
149  FormPolygon( aNode, &m_outline, aDefaultUnits, aActualConversion );
150 
151  m_positionX = m_outline[0]->x;
152  m_positionY = m_outline[0]->y;
153 
154  // fill the polygon with the same contour as its outline is
155  m_islands.Add( new VERTICES_ARRAY );
156  FormPolygon( aNode, m_islands[0], aDefaultUnits, aActualConversion );
157 
158  return true;
159 }
160 
161 
163 {
165  {
166  FP_SHAPE* dwg = new FP_SHAPE( aFootprint, SHAPE_T::POLY );
167  aFootprint->Add( dwg );
168 
169  dwg->SetWidth( 0 );
170  dwg->SetLayer( m_KiCadLayer );
171 
172  auto outline = new std::vector<wxPoint>;
173  for( auto point : m_outline )
174  outline->push_back( wxPoint( point->x, point->y ) );
175 
176  dwg->SetPolyPoints( *outline );
177  dwg->SetStart0( *outline->begin() );
178  dwg->SetEnd0( outline->back() );
179  dwg->SetDrawCoord();
180 
181  delete( outline );
182  }
183 }
184 
185 
187 {
188  int i = 0;
189 
190  if( m_outline.GetCount() > 0 )
191  {
192  ZONE* zone = new ZONE( m_board );
193  m_board->Add( zone, ADD_MODE::APPEND );
194 
195  zone->SetLayer( m_KiCadLayer );
196  zone->SetNetCode( m_netCode );
197 
198  // add outline
199  for( i = 0; i < (int) m_outline.GetCount(); i++ )
200  {
201  zone->AppendCorner( wxPoint( KiROUND( m_outline[i]->x ),
202  KiROUND( m_outline[i]->y ) ), -1 );
203  }
204 
205  zone->SetLocalClearance( m_width );
206 
207  zone->SetPriority( m_priority );
208 
210  zone->GetDefaultHatchPitch(), true );
211 
212  if ( m_objType == wxT( 'K' ) )
213  {
214  zone->SetIsRuleArea( true );
215  zone->SetDoNotAllowTracks( true );
216  zone->SetDoNotAllowVias( true );
217  zone->SetDoNotAllowPads( true );
218  zone->SetDoNotAllowCopperPour( true );
219  zone->SetDoNotAllowFootprints( false );
220  }
221  else if( m_objType == wxT( 'C' ) )
222  {
223  // convert cutouts to keepouts because standalone cutouts are not supported in KiCad
224  zone->SetIsRuleArea( true );
225  zone->SetDoNotAllowCopperPour( true );
226  zone->SetDoNotAllowTracks( false );
227  zone->SetDoNotAllowVias( false );
228  zone->SetDoNotAllowPads( false );
229  zone->SetDoNotAllowFootprints( false );
230  }
231 
232  //if( m_filled )
233  // zone->BuildFilledPolysListData( m_board );
234  }
235 }
236 
237 
239 {
241 
243 }
244 
245 
246 void PCB_POLYGON::SetPosOffset( int aX_offs, int aY_offs )
247 {
248  int i, island;
249 
250  PCB_COMPONENT::SetPosOffset( aX_offs, aY_offs );
251 
252  for( i = 0; i < (int) m_outline.GetCount(); i++ )
253  {
254  m_outline[i]->x += aX_offs;
255  m_outline[i]->y += aY_offs;
256  }
257 
258  for( island = 0; island < (int) m_islands.GetCount(); island++ )
259  {
260  for( i = 0; i < (int) m_islands[island]->GetCount(); i++ )
261  {
262  (*m_islands[island])[i]->x += aX_offs;
263  (*m_islands[island])[i]->y += aY_offs;
264  }
265  }
266 
267  for( island = 0; island < (int) m_cutouts.GetCount(); island++ )
268  {
269  for( i = 0; i < (int) m_cutouts[island]->GetCount(); i++ )
270  {
271  (*m_cutouts[island])[i]->x += aX_offs;
272  (*m_cutouts[island])[i]->y += aY_offs;
273  }
274  }
275 }
276 
277 } // namespace PCAD2KICAD
void SetEnd0(const wxPoint &aPoint)
Definition: fp_shape.h:114
void SetDoNotAllowTracks(bool aEnable)
Definition: zone.h:745
polygon (not yet used for tracks, but could be in microwave apps)
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:192
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aHatchStyle, int aHatchPitch, bool aRebuildHatch)
Set all hatch parameters for the zone.
Definition: zone.cpp:896
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition: lset.cpp:521
void SetOutline(VERTICES_ARRAY *aOutline)
Definition: pcb_polygon.cpp:93
void AddToFootprint(FOOTPRINT *aFootprint) override
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
virtual bool Parse(XNODE *aNode, const wxString &aDefaultUnits, const wxString &aActualConversion)
void AddToBoard() override
ISLANDS_ARRAY m_cutouts
Definition: pcb_polygon.h:68
void SetPriority(unsigned aPriority)
Definition: zone.h:117
virtual void Flip() override
int GetNetCode(const wxString &aNetName) const
Definition: pcb_component.h:58
void SetIsRuleArea(bool aEnable)
Definition: zone.h:742
virtual void SetPosOffset(int aX_offs, int aY_offs)
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: board.cpp:607
VERTICES_ARRAY m_outline
Definition: pcb_polygon.h:66
static int GetDefaultHatchPitch()
Definition: zone.cpp:1088
void SetDoNotAllowPads(bool aEnable)
Definition: zone.h:746
virtual void SetPosOffset(int aX_offs, int aY_offs) override
bool IsNonCopperLayer(LAYER_NUM aLayerId)
Test whether a layer is a non copper layer.
Definition: layer_ids.h:798
void SetDoNotAllowVias(bool aEnable)
Definition: zone.h:744
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
Definition: fp_shape.cpp:82
void SetStart0(const wxPoint &aPoint)
Definition: fp_shape.h:111
void FormPolygon(XNODE *aNode, VERTICES_ARRAY *aPolygon, const wxString &aDefaultUnits, const wxString &actualConversion)
PCB_LAYER_ID GetKiCadLayer() const
Definition: pcb_component.h:56
Hold an XML or S-expression element.
Definition: xnode.h:43
XNODE * GetNext() const
Definition: xnode.h:67
bool AppendCorner(wxPoint aPosition, int aHoleIdx, bool aAllowDuplication=false)
Add a new corner to the zone outline (to the main outline or a hole)
Definition: zone.cpp:836
ISLANDS_ARRAY m_islands
Definition: pcb_polygon.h:67
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
void SetDoNotAllowCopperPour(bool aEnable)
Definition: zone.h:743
void SetWidth(int aWidth)
Definition: pcb_shape.h:96
XNODE * FindNode(XNODE *aChild, const wxString &aTag)
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:73
void SetDoublePrecisionPosition(const wxString &aStr, const wxString &aDefaultMeasurementUnit, double *aX, double *aY, const wxString &aActualConversion)
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition: zone.cpp:238
void SetLocalClearance(int aClearance)
Definition: zone.h:158
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Removes an item from the container.
Definition: footprint.cpp:513
void AssignNet(const wxString &aNetName)
Definition: pcb_polygon.cpp:87
void SetPolyPoints(const std::vector< wxPoint > &aPoints)
Definition: pcb_shape.cpp:1153
PCB_POLYGON(PCB_CALLBACKS *aCallbacks, BOARD *aBoard, int aPCadLayer)
Definition: pcb_polygon.cpp:40
void SetDoNotAllowFootprints(bool aEnable)
Definition: zone.h:747