KiCad PCB EDA Suite
zone.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) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
6  * Copyright (C) 1992-2021 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 <bitmaps.h>
28 #include <geometry/shape_null.h>
29 #include <core/mirror.h>
30 #include <advanced_config.h>
31 #include <pcb_edit_frame.h>
32 #include <pcb_screen.h>
33 #include <board.h>
34 #include <board_design_settings.h>
35 #include <pad.h>
36 #include <zone.h>
37 #include <string_utils.h>
38 #include <math_for_graphics.h>
41 #include <trigo.h>
42 #include <i18n_utility.h>
43 
44 ZONE::ZONE( BOARD_ITEM_CONTAINER* aParent, bool aInFP ) :
45  BOARD_CONNECTED_ITEM( aParent, aInFP ? PCB_FP_ZONE_T : PCB_ZONE_T ),
46  m_area( 0.0 )
47 {
48  m_CornerSelection = nullptr; // no corner is selected
49  m_isFilled = false; // fill status : true when the zone is filled
53  m_hv45 = false;
54  m_hatchThickness = 0;
55  m_hatchGap = 0;
56  m_hatchOrientation = 0.0;
57  m_hatchSmoothingLevel = 0; // Grid pattern smoothing type. 0 = no smoothing
58  m_hatchSmoothingValue = 0.1; // Grid pattern chamfer value relative to the gap value
59  // used only if m_hatchSmoothingLevel > 0
60  m_hatchHoleMinArea = 0.3; // Min size before holes are dropped (ratio of hole size)
61  m_hatchBorderAlgorithm = 1; // 0 = use zone min thickness; 1 = use hatch width
62  m_priority = 0;
64  SetIsRuleArea( aInFP ); // Zones living in footprints have the rule area option
65  SetDoNotAllowCopperPour( false ); // has meaning only if m_isRuleArea == true
66  SetDoNotAllowVias( true ); // has meaning only if m_isRuleArea == true
67  SetDoNotAllowTracks( true ); // has meaning only if m_isRuleArea == true
68  SetDoNotAllowPads( true ); // has meaning only if m_isRuleArea == true
69  SetDoNotAllowFootprints( false ); // has meaning only if m_isRuleArea == true
70  m_cornerRadius = 0;
71  SetLocalFlags( 0 ); // flags temporary used in zone calculations
72  m_Poly = new SHAPE_POLY_SET(); // Outlines
73  m_fillVersion = 5; // set the "old" way to build filled polygon areas (< 6.0.x)
75  aParent->GetZoneSettings().ExportSetting( *this );
76 
80 
81  m_needRefill = false; // True only after edits.
82 }
83 
84 
85 ZONE::ZONE( const ZONE& aZone )
86  : BOARD_CONNECTED_ITEM( aZone ),
87  m_Poly( nullptr ),
88  m_CornerSelection( nullptr )
89 {
91 }
92 
93 
94 ZONE& ZONE::operator=( const ZONE& aOther )
95 {
97 
98  InitDataFromSrcInCopyCtor( aOther );
99 
100  return *this;
101 }
102 
103 
105 {
106  delete m_Poly;
107  delete m_CornerSelection;
108 }
109 
110 
112 {
113  // members are expected non initialize in this.
114  // InitDataFromSrcInCopyCtor() is expected to be called
115  // only from a copy constructor.
116 
117  // Copy only useful EDA_ITEM flags:
118  m_flags = aZone.m_flags;
120 
121  // Replace the outlines for aZone outlines.
122  delete m_Poly;
123  m_Poly = new SHAPE_POLY_SET( *aZone.m_Poly );
124 
127  m_zoneName = aZone.m_zoneName;
128  m_priority = aZone.m_priority;
129  m_isRuleArea = aZone.m_isRuleArea;
130  SetLayerSet( aZone.GetLayerSet() );
131 
137 
139  m_ZoneClearance = aZone.m_ZoneClearance; // clearance value
144 
145  m_isFilled = aZone.m_isFilled;
146  m_needRefill = aZone.m_needRefill;
147 
150 
151  m_fillMode = aZone.m_fillMode; // solid vs. hatched
153  m_hatchGap = aZone.m_hatchGap;
159 
160  // For corner moving, corner index to drag, or nullptr if no selection
161  delete m_CornerSelection;
162  m_CornerSelection = nullptr;
163 
164  for( PCB_LAYER_ID layer : aZone.GetLayerSet().Seq() )
165  {
166  m_FilledPolysList[layer] = aZone.m_FilledPolysList.at( layer );
167  m_RawPolysList[layer] = aZone.m_RawPolysList.at( layer );
168  m_filledPolysHash[layer] = aZone.m_filledPolysHash.at( layer );
169  m_FillSegmList[layer] = aZone.m_FillSegmList.at( layer ); // vector <> copy
170  m_insulatedIslands[layer] = aZone.m_insulatedIslands.at( layer );
171  }
172 
176 
177  SetLocalFlags( aZone.GetLocalFlags() );
178 
179  m_netinfo = aZone.m_netinfo;
180 
181  m_hv45 = aZone.m_hv45;
182  m_area = aZone.m_area;
183 }
184 
185 
187 {
188  return new ZONE( *this );
189 }
190 
191 
193 {
194  bool change = false;
195 
196  for( std::pair<const PCB_LAYER_ID, SHAPE_POLY_SET>& pair : m_FilledPolysList )
197  {
198  change |= !pair.second.IsEmpty();
199  m_insulatedIslands[pair.first].clear();
200  pair.second.RemoveAllContours();
201  }
202 
203  for( std::pair<const PCB_LAYER_ID, std::vector<SEG> >& pair : m_FillSegmList )
204  {
205  change |= !pair.second.empty();
206  pair.second.clear();
207  }
208 
209  m_isFilled = false;
210  m_fillFlags.clear();
211 
212  return change;
213 }
214 
215 
216 wxPoint ZONE::GetPosition() const
217 {
218  return (wxPoint) GetCornerPosition( 0 );
219 }
220 
221 
223 {
224  return BOARD_ITEM::GetLayer();
225 }
226 
227 
229 {
230  return ( m_layerSet & LSET::AllCuMask() ).count() > 0;
231 }
232 
233 
234 bool ZONE::CommonLayerExists( const LSET aLayerSet ) const
235 {
236  LSET common = GetLayerSet() & aLayerSet;
237 
238  return common.count() > 0;
239 }
240 
241 
243 {
244  SetLayerSet( LSET( aLayer ) );
245 
246  m_layer = aLayer;
247 }
248 
249 
250 void ZONE::SetLayerSet( LSET aLayerSet )
251 {
252  if( GetIsRuleArea() )
253  {
254  // Rule areas can only exist on copper layers
255  aLayerSet &= LSET::AllCuMask();
256  }
257 
258  if( aLayerSet.count() == 0 )
259  return;
260 
261  if( m_layerSet != aLayerSet )
262  {
263  SetNeedRefill( true );
264 
265  UnFill();
266 
267  m_FillSegmList.clear();
268  m_FilledPolysList.clear();
269  m_RawPolysList.clear();
270  m_filledPolysHash.clear();
271  m_insulatedIslands.clear();
272 
273  for( PCB_LAYER_ID layer : aLayerSet.Seq() )
274  {
275  m_FillSegmList[layer] = {};
276  m_FilledPolysList[layer] = {};
277  m_RawPolysList[layer] = {};
278  m_filledPolysHash[layer] = {};
279  m_insulatedIslands[layer] = {};
280  }
281  }
282 
283  m_layerSet = aLayerSet;
284 
285  // Set the single layer parameter. For zones that can be on many layers, this parameter
286  // is arbitrary at best, but some code still uses it.
287  // Priority is F_Cu then B_Cu then to the first selected layer
288  m_layer = aLayerSet.Seq()[0];
289 
290  if( m_layer != F_Cu && aLayerSet[B_Cu] )
291  m_layer = B_Cu;
292 }
293 
294 
296 {
297  return m_layerSet;
298 }
299 
300 
301 void ZONE::ViewGetLayers( int aLayers[], int& aCount ) const
302 {
303  LSEQ layers = m_layerSet.Seq();
304 
305  for( unsigned int idx = 0; idx < layers.size(); idx++ )
306  aLayers[idx] = LAYER_ZONE_START + layers[idx];
307 
308  aCount = layers.size();
309 }
310 
311 
312 double ZONE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
313 {
314  constexpr double HIDE = std::numeric_limits<double>::max();
315 
316  return aView->IsLayerVisible( LAYER_ZONES ) ? 0.0 : HIDE;
317 }
318 
319 
320 bool ZONE::IsOnLayer( PCB_LAYER_ID aLayer ) const
321 {
322  return m_layerSet.test( aLayer );
323 }
324 
325 
327 {
328  auto bb = m_Poly->BBox();
329 
330  EDA_RECT ret( (wxPoint) bb.GetOrigin(), wxSize( bb.GetWidth(), bb.GetHeight() ) );
331 
332  return ret;
333 }
334 
335 
336 int ZONE::GetThermalReliefGap( PAD* aPad, wxString* aSource ) const
337 {
338  if( aPad->GetEffectiveThermalGap() == 0 )
339  {
340  if( aSource )
341  *aSource = _( "zone" );
342 
343  return m_thermalReliefGap;
344  }
345 
346  return aPad->GetEffectiveThermalGap( aSource );
347 
348 }
349 
350 
351 int ZONE::GetThermalReliefSpokeWidth( PAD* aPad, wxString* aSource ) const
352 {
353  if( aPad->GetEffectiveThermalSpokeWidth() == 0 )
354  {
355  if( aSource )
356  *aSource = _( "zone" );
357 
359  }
360 
361  return aPad->GetEffectiveThermalSpokeWidth( aSource );
362 }
363 
364 
365 void ZONE::SetCornerRadius( unsigned int aRadius )
366 {
367  if( m_cornerRadius != aRadius )
368  SetNeedRefill( true );
369 
370  m_cornerRadius = aRadius;
371 }
372 
373 
375 {
376  if( ADVANCED_CFG::GetCfg().m_DebugZoneFiller && LSET::InternalCuMask().Contains( aLayer ) )
377  return false;
378 
380 }
381 
382 
384 
385 
387 {
388  if( !m_filledPolysHash.count( aLayer ) )
389  return g_nullPoly.GetHash();
390  else
391  return m_filledPolysHash.at( aLayer );
392 }
393 
394 
396 {
397  if( !m_FilledPolysList.count( aLayer ) )
399  else
400  m_filledPolysHash[aLayer] = m_FilledPolysList.at( aLayer ).GetHash();
401 }
402 
403 
404 bool ZONE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
405 {
406  // When looking for an "exact" hit aAccuracy will be 0 which works poorly for very thin
407  // lines. Give it a floor.
408  int accuracy = std::max( aAccuracy, Millimeter2iu( 0.1 ) );
409 
410  return HitTestForCorner( aPosition, accuracy * 2 ) || HitTestForEdge( aPosition, accuracy );
411 }
412 
413 
414 void ZONE::SetSelectedCorner( const wxPoint& aPosition, int aAccuracy )
415 {
417 
418  // If there is some corner to be selected, assign it to m_CornerSelection
419  if( HitTestForCorner( aPosition, aAccuracy * 2, corner )
420  || HitTestForEdge( aPosition, aAccuracy, corner ) )
421  {
422  if( m_CornerSelection == nullptr )
424 
425  *m_CornerSelection = corner;
426  }
427 }
428 
429 bool ZONE::HitTestForCorner( const wxPoint& refPos, int aAccuracy,
430  SHAPE_POLY_SET::VERTEX_INDEX& aCornerHit ) const
431 {
432  return m_Poly->CollideVertex( VECTOR2I( refPos ), aCornerHit, aAccuracy );
433 }
434 
435 
436 bool ZONE::HitTestForCorner( const wxPoint& refPos, int aAccuracy ) const
437 {
439  return HitTestForCorner( refPos, aAccuracy, dummy );
440 }
441 
442 
443 bool ZONE::HitTestForEdge( const wxPoint& refPos, int aAccuracy,
444  SHAPE_POLY_SET::VERTEX_INDEX& aCornerHit ) const
445 {
446  return m_Poly->CollideEdge( VECTOR2I( refPos ), aCornerHit, aAccuracy );
447 }
448 
449 
450 bool ZONE::HitTestForEdge( const wxPoint& refPos, int aAccuracy ) const
451 {
453  return HitTestForEdge( refPos, aAccuracy, dummy );
454 }
455 
456 
457 bool ZONE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
458 {
459  // Calculate bounding box for zone
460  EDA_RECT bbox = GetBoundingBox();
461  bbox.Normalize();
462 
463  EDA_RECT arect = aRect;
464  arect.Normalize();
465  arect.Inflate( aAccuracy );
466 
467  if( aContained )
468  {
469  return arect.Contains( bbox );
470  }
471  else
472  {
473  // Fast test: if aBox is outside the polygon bounding box, rectangles cannot intersect
474  if( !arect.Intersects( bbox ) )
475  return false;
476 
477  int count = m_Poly->TotalVertices();
478 
479  for( int ii = 0; ii < count; ii++ )
480  {
481  auto vertex = m_Poly->CVertex( ii );
482  auto vertexNext = m_Poly->CVertex( ( ii + 1 ) % count );
483 
484  // Test if the point is within the rect
485  if( arect.Contains( ( wxPoint ) vertex ) )
486  return true;
487 
488  // Test if this edge intersects the rect
489  if( arect.Intersects( ( wxPoint ) vertex, ( wxPoint ) vertexNext ) )
490  return true;
491  }
492 
493  return false;
494  }
495 }
496 
497 
498 int ZONE::GetLocalClearance( wxString* aSource ) const
499 {
500  if( m_isRuleArea )
501  return 0;
502 
503  if( aSource )
504  *aSource = _( "zone" );
505 
506  return m_ZoneClearance;
507 }
508 
509 
510 bool ZONE::HitTestFilledArea( PCB_LAYER_ID aLayer, const wxPoint &aRefPos, int aAccuracy ) const
511 {
512  // Rule areas have no filled area, but it's generally nice to treat their interior as if it were
513  // filled so that people don't have to select them by their outline (which is min-width)
514  if( GetIsRuleArea() )
515  return m_Poly->Contains( VECTOR2I( aRefPos.x, aRefPos.y ), -1, aAccuracy );
516 
517  if( !m_FilledPolysList.count( aLayer ) )
518  return false;
519 
520  return m_FilledPolysList.at( aLayer ).Contains( VECTOR2I( aRefPos.x, aRefPos.y ), -1,
521  aAccuracy );
522 }
523 
524 
525 bool ZONE::HitTestCutout( const VECTOR2I& aRefPos, int* aOutlineIdx, int* aHoleIdx ) const
526 {
527  // Iterate over each outline polygon in the zone and then iterate over
528  // each hole it has to see if the point is in it.
529  for( int i = 0; i < m_Poly->OutlineCount(); i++ )
530  {
531  for( int j = 0; j < m_Poly->HoleCount( i ); j++ )
532  {
533  if( m_Poly->Hole( i, j ).PointInside( aRefPos ) )
534  {
535  if( aOutlineIdx )
536  *aOutlineIdx = i;
537 
538  if( aHoleIdx )
539  *aHoleIdx = j;
540 
541  return true;
542  }
543  }
544  }
545 
546  return false;
547 }
548 
549 
550 void ZONE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
551 {
552  EDA_UNITS units = aFrame->GetUserUnits();
553  wxString msg;
554 
555  if( GetIsRuleArea() )
556  msg = _( "Rule Area" );
557  else if( IsOnCopperLayer() )
558  msg = _( "Copper Zone" );
559  else
560  msg = _( "Non-copper Zone" );
561 
562  // Display Cutout instead of Outline for holes inside a zone (i.e. when num contour !=0).
563  // Check whether the selected corner is in a hole; i.e., in any contour but the first one.
564  if( m_CornerSelection != nullptr && m_CornerSelection->m_contour > 0 )
565  msg << wxT( " " ) << _( "Cutout" );
566 
567  aList.emplace_back( _( "Type" ), msg );
568 
569  if( GetIsRuleArea() )
570  {
571  msg.Empty();
572 
573  if( GetDoNotAllowVias() )
574  AccumulateDescription( msg, _( "No vias" ) );
575 
576  if( GetDoNotAllowTracks() )
577  AccumulateDescription( msg, _( "No tracks" ) );
578 
579  if( GetDoNotAllowPads() )
580  AccumulateDescription( msg, _( "No pads" ) );
581 
583  AccumulateDescription( msg, _( "No copper zones" ) );
584 
586  AccumulateDescription( msg, _( "No footprints" ) );
587 
588  if( !msg.IsEmpty() )
589  aList.emplace_back( MSG_PANEL_ITEM( _( "Restrictions" ), msg ) );
590  }
591  else if( IsOnCopperLayer() )
592  {
593  aList.emplace_back( _( "Net" ), UnescapeString( GetNetname() ) );
594 
595  aList.emplace_back( _( "NetClass" ), UnescapeString( GetNetClass()->GetName() ) );
596 
597  // Display priority level
598  aList.emplace_back( _( "Priority" ), wxString::Format( "%d", GetPriority() ) );
599  }
600 
601  if( IsLocked() )
602  aList.emplace_back( _( "Status" ), _( "Locked" ) );
603 
604  wxString layerDesc;
605  int count = 0;
606 
607  for( PCB_LAYER_ID layer : m_layerSet.Seq() )
608  {
609  if( count == 0 )
610  layerDesc = GetBoard()->GetLayerName( layer );
611 
612  count++;
613  }
614 
615  if( count > 1 )
616  layerDesc.Printf( _( "%s and %d more" ), layerDesc, count - 1 );
617 
618  aList.emplace_back( _( "Layer" ), layerDesc );
619 
620  if( !m_zoneName.empty() )
621  aList.emplace_back( _( "Name" ), m_zoneName );
622 
623  switch( m_fillMode )
624  {
625  case ZONE_FILL_MODE::POLYGONS: msg = _( "Solid" ); break;
626  case ZONE_FILL_MODE::HATCH_PATTERN: msg = _( "Hatched" ); break;
627  default: msg = _( "Unknown" ); break;
628  }
629 
630  aList.emplace_back( _( "Fill Mode" ), msg );
631 
632  msg = MessageTextFromValue( units, m_area, true, EDA_DATA_TYPE::AREA );
633  aList.emplace_back( _( "Filled Area" ), msg );
634 
635  wxString source;
636  int clearance = GetOwnClearance( GetLayer(), &source );
637 
638  aList.emplace_back( wxString::Format( _( "Min Clearance: %s" ),
639  MessageTextFromValue( units, clearance ) ),
640  wxString::Format( _( "(from %s)" ), source ) );
641 
642  // Useful for statistics, especially when zones are complex the number of hatches
643  // and filled polygons can explain the display and DRC calculation time:
644  msg.Printf( wxT( "%d" ), (int) m_borderHatchLines.size() );
645  aList.emplace_back( MSG_PANEL_ITEM( _( "HatchBorder Lines" ), msg ) );
646 
647  PCB_LAYER_ID layer = m_layer;
648 
649  // NOTE: This brings in dependence on PCB_EDIT_FRAME to the qa tests, which isn't ideal.
650  // TODO: Figure out a way for items to know the active layer without the whole edit frame?
651 #if 0
652  if( PCB_EDIT_FRAME* pcbframe = dynamic_cast<PCB_EDIT_FRAME*>( aFrame ) )
653  {
654  if( m_FilledPolysList.count( pcbframe->GetActiveLayer() ) )
655  layer = pcbframe->GetActiveLayer();
656  }
657 #endif
658 
659  if( !GetIsRuleArea() )
660  {
661  auto layer_it = m_FilledPolysList.find( layer );
662 
663  if( layer_it == m_FilledPolysList.end() )
664  layer_it = m_FilledPolysList.begin();
665 
666  if( layer_it != m_FilledPolysList.end() )
667  {
668  msg.Printf( wxT( "%d" ), layer_it->second.TotalVertices() );
669  aList.emplace_back( MSG_PANEL_ITEM( _( "Corner Count" ), msg ) );
670  }
671  }
672 }
673 
674 
675 void ZONE::Move( const wxPoint& offset )
676 {
677  /* move outlines */
678  m_Poly->Move( offset );
679 
680  HatchBorder();
681 
682  for( std::pair<const PCB_LAYER_ID, SHAPE_POLY_SET>& pair : m_FilledPolysList )
683  pair.second.Move( offset );
684 
685  for( std::pair<const PCB_LAYER_ID, std::vector<SEG> >& pair : m_FillSegmList )
686  {
687  for( SEG& seg : pair.second )
688  {
689  seg.A += VECTOR2I( offset );
690  seg.B += VECTOR2I( offset );
691  }
692  }
693 }
694 
695 
696 void ZONE::MoveEdge( const wxPoint& offset, int aEdge )
697 {
698  int next_corner;
699 
700  if( m_Poly->GetNeighbourIndexes( aEdge, nullptr, &next_corner ) )
701  {
702  m_Poly->SetVertex( aEdge, m_Poly->CVertex( aEdge ) + VECTOR2I( offset ) );
703  m_Poly->SetVertex( next_corner, m_Poly->CVertex( next_corner ) + VECTOR2I( offset ) );
704  HatchBorder();
705 
706  SetNeedRefill( true );
707  }
708 }
709 
710 
711 void ZONE::Rotate( const wxPoint& aCentre, double aAngle )
712 {
713  aAngle = -DECIDEG2RAD( aAngle );
714 
715  m_Poly->Rotate( aAngle, VECTOR2I( aCentre ) );
716  HatchBorder();
717 
718  /* rotate filled areas: */
719  for( std::pair<const PCB_LAYER_ID, SHAPE_POLY_SET>& pair : m_FilledPolysList )
720  pair.second.Rotate( aAngle, VECTOR2I( aCentre ) );
721 
722  for( std::pair<const PCB_LAYER_ID, std::vector<SEG> >& pair : m_FillSegmList )
723  {
724  for( SEG& seg : pair.second )
725  {
726  wxPoint a( seg.A );
727  RotatePoint( &a, aCentre, aAngle );
728  seg.A = a;
729  wxPoint b( seg.B );
730  RotatePoint( &b, aCentre, aAngle );
731  seg.B = a;
732  }
733  }
734 }
735 
736 
737 void ZONE::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
738 {
739  Mirror( aCentre, aFlipLeftRight );
740  int copperLayerCount = GetBoard()->GetCopperLayerCount();
741 
742  if( GetIsRuleArea() )
743  SetLayerSet( FlipLayerMask( GetLayerSet(), copperLayerCount ) );
744  else
745  SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
746 }
747 
748 
749 void ZONE::Mirror( const wxPoint& aMirrorRef, bool aMirrorLeftRight )
750 {
751  // ZONEs mirror about the x-axis (why?!?)
752  m_Poly->Mirror( aMirrorLeftRight, !aMirrorLeftRight, VECTOR2I( aMirrorRef ) );
753 
754  HatchBorder();
755 
756  for( std::pair<const PCB_LAYER_ID, SHAPE_POLY_SET>& pair : m_FilledPolysList )
757  pair.second.Mirror( aMirrorLeftRight, !aMirrorLeftRight, VECTOR2I( aMirrorRef ) );
758 
759  for( std::pair<const PCB_LAYER_ID, std::vector<SEG> >& pair : m_FillSegmList )
760  {
761  for( SEG& seg : pair.second )
762  {
763  if( aMirrorLeftRight )
764  {
765  MIRROR( seg.A.x, aMirrorRef.x );
766  MIRROR( seg.B.x, aMirrorRef.x );
767  }
768  else
769  {
770  MIRROR( seg.A.y, aMirrorRef.y );
771  MIRROR( seg.B.y, aMirrorRef.y );
772  }
773  }
774  }
775 }
776 
777 
778 ZONE_CONNECTION ZONE::GetPadConnection( PAD* aPad, wxString* aSource ) const
779 {
780  if( aPad == nullptr || aPad->GetEffectiveZoneConnection() == ZONE_CONNECTION::INHERITED )
781  {
782  if( aSource )
783  *aSource = _( "zone" );
784 
785  return m_PadConnection;
786  }
787  else
788  {
789  return aPad->GetEffectiveZoneConnection( aSource );
790  }
791 }
792 
793 
794 void ZONE::RemoveCutout( int aOutlineIdx, int aHoleIdx )
795 {
796  // Ensure the requested cutout is valid
797  if( m_Poly->OutlineCount() < aOutlineIdx || m_Poly->HoleCount( aOutlineIdx ) < aHoleIdx )
798  return;
799 
800  SHAPE_POLY_SET cutPoly( m_Poly->Hole( aOutlineIdx, aHoleIdx ) );
801 
802  // Add the cutout back to the zone
804 
805  SetNeedRefill( true );
806 }
807 
808 
809 void ZONE::AddPolygon( const SHAPE_LINE_CHAIN& aPolygon )
810 {
811  wxASSERT( aPolygon.IsClosed() );
812 
813  // Add the outline as a new polygon in the polygon set
814  if( m_Poly->OutlineCount() == 0 )
815  m_Poly->AddOutline( aPolygon );
816  else
817  m_Poly->AddHole( aPolygon );
818 
819  SetNeedRefill( true );
820 }
821 
822 
823 void ZONE::AddPolygon( std::vector< wxPoint >& aPolygon )
824 {
825  if( aPolygon.empty() )
826  return;
827 
828  SHAPE_LINE_CHAIN outline;
829 
830  // Create an outline and populate it with the points of aPolygon
831  for( const wxPoint& pt : aPolygon)
832  outline.Append( pt );
833 
834  outline.SetClosed( true );
835 
836  AddPolygon( outline );
837 }
838 
839 
840 bool ZONE::AppendCorner( wxPoint aPosition, int aHoleIdx, bool aAllowDuplication )
841 {
842  // Ensure the main outline exists:
843  if( m_Poly->OutlineCount() == 0 )
844  m_Poly->NewOutline();
845 
846  // If aHoleIdx >= 0, the corner musty be added to the hole, index aHoleIdx.
847  // (remember: the index of the first hole is 0)
848  // Return error if if does dot exist.
849  if( aHoleIdx >= m_Poly->HoleCount( 0 ) )
850  return false;
851 
852  m_Poly->Append( aPosition.x, aPosition.y, -1, aHoleIdx, aAllowDuplication );
853 
854  SetNeedRefill( true );
855 
856  return true;
857 }
858 
859 
860 wxString ZONE::GetSelectMenuText( EDA_UNITS aUnits ) const
861 {
862  wxString layerDesc;
863  int count = 0;
864 
865  for( PCB_LAYER_ID layer : m_layerSet.Seq() )
866  {
867  if( count == 0 )
868  layerDesc = GetBoard()->GetLayerName( layer );
869 
870  count++;
871  }
872 
873  if( count > 1 )
874  layerDesc.Printf( _( "%s and %d more" ), layerDesc, count - 1 );
875 
876  // Check whether the selected contour is a hole (contour index > 0)
877  if( m_CornerSelection != nullptr && m_CornerSelection->m_contour > 0 )
878  {
879  if( GetIsRuleArea() )
880  return wxString::Format( _( "Rule Area Cutout on %s" ), layerDesc );
881  else
882  return wxString::Format( _( "Zone Cutout on %s" ), layerDesc );
883  }
884  else
885  {
886  if( GetIsRuleArea() )
887  return wxString::Format( _( "Rule Area on %s" ), layerDesc );
888  else
889  return wxString::Format( _( "Zone %s on %s" ), GetNetnameMsg(), layerDesc );
890  }
891 }
892 
893 
895 {
896  return m_borderHatchPitch;
897 }
898 
899 
900 void ZONE::SetBorderDisplayStyle( ZONE_BORDER_DISPLAY_STYLE aHatchStyle, int aHatchPitch,
901  bool aRebuildHatch )
902 {
903  SetHatchPitch( aHatchPitch );
904  m_borderStyle = aHatchStyle;
905 
906  if( aRebuildHatch )
907  HatchBorder();
908 }
909 
910 
911 void ZONE::SetHatchPitch( int aPitch )
912 {
913  m_borderHatchPitch = aPitch;
914 }
915 
916 
918 {
919  m_borderHatchLines.clear();
920 }
921 
922 
923 // Creates hatch lines inside the outline of the complex polygon
924 // sort function used in ::HatchBorder to sort points by descending wxPoint.x values
925 bool sortEndsByDescendingX( const VECTOR2I& ref, const VECTOR2I& tst )
926 {
927  return tst.x < ref.x;
928 }
929 
930 
932 {
933  UnHatchBorder();
934 
936  || m_borderHatchPitch == 0
937  || m_Poly->IsEmpty() )
938  {
939  return;
940  }
941 
942  // define range for hatch lines
943  int min_x = m_Poly->CVertex( 0 ).x;
944  int max_x = m_Poly->CVertex( 0 ).x;
945  int min_y = m_Poly->CVertex( 0 ).y;
946  int max_y = m_Poly->CVertex( 0 ).y;
947 
948  for( auto iterator = m_Poly->IterateWithHoles(); iterator; iterator++ )
949  {
950  if( iterator->x < min_x )
951  min_x = iterator->x;
952 
953  if( iterator->x > max_x )
954  max_x = iterator->x;
955 
956  if( iterator->y < min_y )
957  min_y = iterator->y;
958 
959  if( iterator->y > max_y )
960  max_y = iterator->y;
961  }
962 
963  // Calculate spacing between 2 hatch lines
964  int spacing;
965 
967  spacing = m_borderHatchPitch;
968  else
969  spacing = m_borderHatchPitch * 2;
970 
971  // set the "length" of hatch lines (the length on horizontal axis)
972  int hatch_line_len = m_borderHatchPitch;
973 
974  // To have a better look, give a slope depending on the layer
975  LAYER_NUM layer = GetLayer();
976  int slope_flag = (layer & 1) ? 1 : -1; // 1 or -1
977  double slope = 0.707106 * slope_flag; // 45 degrees slope
978  int max_a, min_a;
979 
980  if( slope_flag == 1 )
981  {
982  max_a = KiROUND( max_y - slope * min_x );
983  min_a = KiROUND( min_y - slope * max_x );
984  }
985  else
986  {
987  max_a = KiROUND( max_y - slope * max_x );
988  min_a = KiROUND( min_y - slope * min_x );
989  }
990 
991  min_a = (min_a / spacing) * spacing;
992 
993  // calculate an offset depending on layer number,
994  // for a better look of hatches on a multilayer board
995  int offset = (layer * 7) / 8;
996  min_a += offset;
997 
998  // loop through hatch lines
999  #define MAXPTS 200 // Usually we store only few values per one hatch line
1000  // depending on the complexity of the zone outline
1001 
1002  static std::vector<VECTOR2I> pointbuffer;
1003  pointbuffer.clear();
1004  pointbuffer.reserve( MAXPTS + 2 );
1005 
1006  for( int a = min_a; a < max_a; a += spacing )
1007  {
1008  // get intersection points for this hatch line
1009 
1010  // Note: because we should have an even number of intersections with the
1011  // current hatch line and the zone outline (a closed polygon,
1012  // or a set of closed polygons), if an odd count is found
1013  // we skip this line (should not occur)
1014  pointbuffer.clear();
1015 
1016  // Iterate through all vertices
1017  for( auto iterator = m_Poly->IterateSegmentsWithHoles(); iterator; iterator++ )
1018  {
1019  double x, y;
1020  bool ok;
1021 
1022  SEG segment = *iterator;
1023 
1024  ok = FindLineSegmentIntersection( a, slope, segment.A.x, segment.A.y, segment.B.x,
1025  segment.B.y, x, y );
1026 
1027  if( ok )
1028  {
1029  VECTOR2I point( KiROUND( x ), KiROUND( y ) );
1030  pointbuffer.push_back( point );
1031  }
1032 
1033  if( pointbuffer.size() >= MAXPTS ) // overflow
1034  {
1035  wxASSERT( 0 );
1036  break;
1037  }
1038  }
1039 
1040  // ensure we have found an even intersection points count
1041  // because intersections are the ends of segments
1042  // inside the polygon(s) and a segment has 2 ends.
1043  // if not, this is a strange case (a bug ?) so skip this hatch
1044  if( pointbuffer.size() % 2 != 0 )
1045  continue;
1046 
1047  // sort points in order of descending x (if more than 2) to
1048  // ensure the starting point and the ending point of the same segment
1049  // are stored one just after the other.
1050  if( pointbuffer.size() > 2 )
1051  sort( pointbuffer.begin(), pointbuffer.end(), sortEndsByDescendingX );
1052 
1053  // creates lines or short segments inside the complex polygon
1054  for( unsigned ip = 0; ip < pointbuffer.size(); ip += 2 )
1055  {
1056  int dx = pointbuffer[ip + 1].x - pointbuffer[ip].x;
1057 
1058  // Push only one line for diagonal hatch,
1059  // or for small lines < twice the line length
1060  // else push 2 small lines
1062  || std::abs( dx ) < 2 * hatch_line_len )
1063  {
1064  m_borderHatchLines.emplace_back( SEG( pointbuffer[ip], pointbuffer[ ip + 1] ) );
1065  }
1066  else
1067  {
1068  double dy = pointbuffer[ip + 1].y - pointbuffer[ip].y;
1069  slope = dy / dx;
1070 
1071  if( dx > 0 )
1072  dx = hatch_line_len;
1073  else
1074  dx = -hatch_line_len;
1075 
1076  int x1 = KiROUND( pointbuffer[ip].x + dx );
1077  int x2 = KiROUND( pointbuffer[ip + 1].x - dx );
1078  int y1 = KiROUND( pointbuffer[ip].y + dx * slope );
1079  int y2 = KiROUND( pointbuffer[ip + 1].y - dx * slope );
1080 
1081  m_borderHatchLines.emplace_back( SEG( pointbuffer[ip].x, pointbuffer[ip].y,
1082  x1, y1 ) );
1083 
1084  m_borderHatchLines.emplace_back( SEG( pointbuffer[ip+1].x, pointbuffer[ip+1].y,
1085  x2, y2 ) );
1086  }
1087  }
1088  }
1089 }
1090 
1091 
1093 {
1094  return Mils2iu( 20 );
1095 }
1096 
1097 
1099 {
1100  return BITMAPS::add_zone;
1101 }
1102 
1103 
1105 {
1106  assert( aImage->Type() == PCB_ZONE_T || aImage->Type() == PCB_FP_ZONE_T );
1107 
1108  std::swap( *((ZONE*) this), *((ZONE*) aImage) );
1109 }
1110 
1111 
1113 {
1114  if( aLayer == UNDEFINED_LAYER )
1115  {
1116  for( std::pair<const PCB_LAYER_ID, SHAPE_POLY_SET>& pair : m_FilledPolysList )
1117  pair.second.CacheTriangulation();
1118  }
1119  else
1120  {
1121  if( m_FilledPolysList.count( aLayer ) )
1123  }
1124 }
1125 
1126 
1127 bool ZONE::IsIsland( PCB_LAYER_ID aLayer, int aPolyIdx ) const
1128 {
1129  if( GetNetCode() < 1 )
1130  return true;
1131 
1132  if( !m_insulatedIslands.count( aLayer ) )
1133  return false;
1134 
1135  return m_insulatedIslands.at( aLayer ).count( aPolyIdx );
1136 }
1137 
1138 
1139 void ZONE::GetInteractingZones( PCB_LAYER_ID aLayer, std::vector<ZONE*>* aZones ) const
1140 {
1141  int epsilon = Millimeter2iu( 0.001 );
1142 
1143  for( ZONE* candidate : GetBoard()->Zones() )
1144  {
1145  if( candidate == this )
1146  continue;
1147 
1148  if( !candidate->GetLayerSet().test( aLayer ) )
1149  continue;
1150 
1151  if( candidate->GetIsRuleArea() )
1152  continue;
1153 
1154  if( candidate->GetNetCode() != GetNetCode() )
1155  continue;
1156 
1157  for( auto iter = m_Poly->CIterate(); iter; iter++ )
1158  {
1159  if( candidate->m_Poly->Collide( iter.Get(), epsilon ) )
1160  {
1161  aZones->push_back( candidate );
1162  break;
1163  }
1164  }
1165  }
1166 }
1167 
1168 
1170  SHAPE_POLY_SET* aBoardOutline,
1171  SHAPE_POLY_SET* aSmoothedPolyWithApron ) const
1172 {
1173  if( GetNumCorners() <= 2 ) // malformed zone. polygon calculations will not like it ...
1174  return false;
1175 
1176  // Processing of arc shapes in zones is not yet supported because Clipper can't do boolean
1177  // operations on them. The poly outline must be flattened first.
1178  SHAPE_POLY_SET flattened = *m_Poly;
1179  flattened.ClearArcs();
1180 
1181  if( GetIsRuleArea() )
1182  {
1183  // We like keepouts just the way they are....
1184  aSmoothedPoly = flattened;
1185  return true;
1186  }
1187 
1188  const BOARD* board = GetBoard();
1189  int maxError = ARC_HIGH_DEF;
1190  bool keepExternalFillets = false;
1191 
1192  if( board )
1193  {
1194  BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
1195 
1196  maxError = bds.m_MaxError;
1197  keepExternalFillets = bds.m_ZoneKeepExternalFillets;
1198  }
1199 
1200  auto smooth = [&]( SHAPE_POLY_SET& aPoly )
1201  {
1202  switch( m_cornerSmoothingType )
1203  {
1205  aPoly = aPoly.Chamfer( (int) m_cornerRadius );
1206  break;
1207 
1209  {
1210  aPoly = aPoly.Fillet( (int) m_cornerRadius, maxError );
1211  break;
1212  }
1213 
1214  default:
1215  break;
1216  }
1217  };
1218 
1219  std::vector<ZONE*> interactingZones;
1220  GetInteractingZones( aLayer, &interactingZones );
1221 
1222  SHAPE_POLY_SET* maxExtents = &flattened;
1223  SHAPE_POLY_SET withFillets;
1224 
1225  aSmoothedPoly = flattened;
1226 
1227  // Should external fillets (that is, those applied to concave corners) be kept? While it
1228  // seems safer to never have copper extend outside the zone outline, 5.1.x and prior did
1229  // indeed fill them so we leave the mode available.
1230  if( keepExternalFillets )
1231  {
1232  withFillets = flattened;
1233  smooth( withFillets );
1234  withFillets.BooleanAdd( flattened, SHAPE_POLY_SET::PM_FAST );
1235  maxExtents = &withFillets;
1236  }
1237 
1238  for( ZONE* zone : interactingZones )
1239  {
1240  SHAPE_POLY_SET flattened_outline = *zone->Outline();
1241  flattened_outline.ClearArcs();
1242  aSmoothedPoly.BooleanAdd( flattened_outline, SHAPE_POLY_SET::PM_FAST );
1243  }
1244 
1245  if( aBoardOutline )
1246  {
1247  SHAPE_POLY_SET poly = *aBoardOutline;
1249  }
1250 
1251  smooth( aSmoothedPoly );
1252 
1253  if( aSmoothedPolyWithApron )
1254  {
1255  SHAPE_POLY_SET poly = *maxExtents;
1256  poly.Inflate( m_ZoneMinThickness, 64 );
1257  *aSmoothedPolyWithApron = aSmoothedPoly;
1258  aSmoothedPolyWithApron->BooleanIntersection( poly, SHAPE_POLY_SET::PM_FAST );
1259  }
1260 
1261  aSmoothedPoly.BooleanIntersection( *maxExtents, SHAPE_POLY_SET::PM_FAST );
1262 
1263  return true;
1264 }
1265 
1266 
1268 {
1269  m_area = 0.0;
1270 
1271  // Iterate over each outline polygon in the zone and then iterate over
1272  // each hole it has to compute the total area.
1273  for( std::pair<const PCB_LAYER_ID, SHAPE_POLY_SET>& pair : m_FilledPolysList )
1274  {
1275  SHAPE_POLY_SET& poly = pair.second;
1276 
1277  for( int i = 0; i < poly.OutlineCount(); i++ )
1278  {
1279  m_area += poly.Outline( i ).Area();
1280 
1281  for( int j = 0; j < poly.HoleCount( i ); j++ )
1282  m_area -= poly.Hole( i, j ).Area();
1283  }
1284  }
1285 
1286  return m_area;
1287 }
1288 
1289 
1290 void ZONE::TransformSmoothedOutlineToPolygon( SHAPE_POLY_SET& aCornerBuffer, int aClearance,
1291  SHAPE_POLY_SET* aBoardOutline ) const
1292 {
1293  // Creates the zone outline polygon (with holes if any)
1294  SHAPE_POLY_SET polybuffer;
1295  BuildSmoothedPoly( polybuffer, GetLayer(), aBoardOutline );
1296 
1297  // Calculate the polygon with clearance
1298  // holes are linked to the main outline, so only one polygon is created.
1299  if( aClearance )
1300  {
1301  const BOARD* board = GetBoard();
1302  int maxError = ARC_HIGH_DEF;
1303 
1304  if( board )
1305  maxError = board->GetDesignSettings().m_MaxError;
1306 
1307  int segCount = GetArcToSegmentCount( aClearance, maxError, 360.0 );
1308  polybuffer.Inflate( aClearance, segCount );
1309  }
1310 
1311  polybuffer.Fracture( SHAPE_POLY_SET::PM_FAST );
1312  aCornerBuffer.Append( polybuffer );
1313 }
1314 
1315 
1316 bool ZONE::IsKeepout() const
1317 {
1320 }
1321 
1322 
1323 bool ZONE::KeepoutAll() const
1324 {
1327 }
1328 
1329 
1331  ZONE( aParent, true )
1332 {
1333  // in a footprint, net classes are not managed.
1334  // so set the net to NETINFO_LIST::ORPHANED_ITEM
1335  SetNetCode( -1, true );
1336 }
1337 
1338 
1339 FP_ZONE::FP_ZONE( const FP_ZONE& aZone ) :
1340  ZONE( aZone.GetParent(), true )
1341 {
1342  InitDataFromSrcInCopyCtor( aZone );
1343 }
1344 
1345 
1347 {
1348  ZONE::operator=( aOther );
1349  return *this;
1350 }
1351 
1352 
1354 {
1355  return new FP_ZONE( *this );
1356 }
1357 
1358 
1359 double FP_ZONE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
1360 {
1361  constexpr double HIDE = (double)std::numeric_limits<double>::max();
1362 
1363  if( !aView )
1364  return 0;
1365 
1366  if( !aView->IsLayerVisible( LAYER_ZONES ) )
1367  return HIDE;
1368 
1369  bool flipped = GetParent() && GetParent()->GetLayer() == B_Cu;
1370 
1371  // Handle Render tab switches
1372  if( !flipped && !aView->IsLayerVisible( LAYER_MOD_FR ) )
1373  return HIDE;
1374 
1375  if( flipped && !aView->IsLayerVisible( LAYER_MOD_BK ) )
1376  return HIDE;
1377 
1378  // Other layers are shown without any conditions
1379  return 0.0;
1380 }
1381 
1382 
1383 std::shared_ptr<SHAPE> ZONE::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
1384 {
1385  std::shared_ptr<SHAPE> shape;
1386 
1387  if( m_FilledPolysList.find( aLayer ) == m_FilledPolysList.end() )
1388  {
1389  shape = std::make_shared<SHAPE_NULL>();
1390  }
1391  else
1392  {
1393  shape.reset( m_FilledPolysList.at( aLayer ).Clone() );
1394  }
1395 
1396  return shape;
1397 }
1398 
1399 
1401  PCB_LAYER_ID aLayer, int aClearance, int aError,
1402  ERROR_LOC aErrorLoc, bool aIgnoreLineWidth ) const
1403 {
1404  wxASSERT_MSG( !aIgnoreLineWidth, "IgnoreLineWidth has no meaning for zones." );
1405 
1406  if( !m_FilledPolysList.count( aLayer ) )
1407  return;
1408 
1409  aCornerBuffer = m_FilledPolysList.at( aLayer );
1410 
1411  int numSegs = GetArcToSegmentCount( aClearance, aError, 360.0 );
1412  aCornerBuffer.Inflate( aClearance, numSegs );
1414 }
1415 
1416 
1418  int aError ) const
1419 {
1420  if( !m_FilledPolysList.count( aLayer ) || m_FilledPolysList.at( aLayer ).IsEmpty() )
1421  return;
1422 
1423  // Just add filled areas if filled polygons outlines have no thickness
1424  if( !GetFilledPolysUseThickness() || GetMinThickness() == 0 )
1425  {
1426  const SHAPE_POLY_SET& polys = m_FilledPolysList.at( aLayer );
1427  aCornerBuffer.Append( polys );
1428  return;
1429  }
1430 
1431  // Filled areas have polygons with outline thickness.
1432  // we must create the polygons and add inflated polys
1433  SHAPE_POLY_SET polys = m_FilledPolysList.at( aLayer );
1434 
1435  auto board = GetBoard();
1436  int maxError = ARC_HIGH_DEF;
1437 
1438  if( board )
1439  maxError = board->GetDesignSettings().m_MaxError;
1440 
1441  int numSegs = GetArcToSegmentCount( GetMinThickness(), maxError, 360.0 );
1442 
1444 
1445  aCornerBuffer.Append( polys );
1446 }
1447 
1448 
1449 static struct ZONE_DESC
1450 {
1452  {
1454  .Map( ZONE_CONNECTION::INHERITED, _HKI( "Inherited" ) )
1455  .Map( ZONE_CONNECTION::NONE, _HKI( "None" ) )
1456  .Map( ZONE_CONNECTION::THERMAL, _HKI( "Thermal reliefs" ) )
1457  .Map( ZONE_CONNECTION::FULL, _HKI( "Solid" ) )
1458  .Map( ZONE_CONNECTION::THT_THERMAL, _HKI( "Reliefs for PTH" ) );
1459 
1461  REGISTER_TYPE( ZONE );
1463  propMgr.AddProperty( new PROPERTY<ZONE, unsigned>( _HKI( "Priority" ),
1465  //propMgr.AddProperty( new PROPERTY<ZONE, bool>( "Filled",
1466  //&ZONE::SetIsFilled, &ZONE::IsFilled ) );
1467  propMgr.AddProperty( new PROPERTY<ZONE, wxString>( _HKI( "Name" ),
1469  propMgr.AddProperty( new PROPERTY<ZONE, int>( _HKI( "Clearance Override" ),
1472  propMgr.AddProperty( new PROPERTY<ZONE, int>( _HKI( "Min Width" ),
1475  propMgr.AddProperty( new PROPERTY_ENUM<ZONE, ZONE_CONNECTION>( _HKI( "Pad Connections" ),
1477  propMgr.AddProperty( new PROPERTY<ZONE, int>( _HKI( "Thermal Relief Gap" ),
1480  propMgr.AddProperty( new PROPERTY<ZONE, int>( _HKI( "Thermal Relief Width" ),
1483  }
1484 } _ZONE_DESC;
1485 
ZONE_BORDER_DISPLAY_STYLE m_borderStyle
Definition: zone.h:927
int TotalVertices() const
Delete aIdx-th polygon from the set.
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:750
int GetNumCorners(void) const
Access to m_Poly parameters.
Definition: zone.h:523
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: zone.cpp:1098
ZONE_CONNECTION
How pads are covered by copper in zone.
Definition: zones.h:41
ZONE_CONNECTION GetPadConnection() const
Definition: zone.h:241
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aAddUnitLabel, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
Definition: base_units.cpp:104
bool m_doNotAllowFootprints
Definition: zone.h:850
void SetCornerRadius(unsigned int aRadius)
Definition: zone.cpp:365
void CacheTriangulation(PCB_LAYER_ID aLayer=UNDEFINED_LAYER)
Create a list of triangles that "fill" the solid areas used for instance to draw these solid areas on...
Definition: zone.cpp:1112
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:65
unsigned int m_cornerRadius
Definition: zone.h:825
void TransformSmoothedOutlineToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aClearance, SHAPE_POLY_SET *aBoardOutline) const
Convert the outlines shape to a polygon with no holes inflated (optional) by max( aClearanceValue,...
Definition: zone.cpp:1290
#define TYPE_HASH(x)
Definition: property.h:59
LSET FlipLayerMask(LSET aMask, int aCopperLayersCount)
Calculate the mask layer when flipping a footprint.
Definition: lset.cpp:567
ENUM_TO_WXANY(ZONE_CONNECTION)
int OutlineCount() const
Return the number of vertices in a given outline/hole.
void RemoveCutout(int aOutlineIdx, int aHoleIdx)
Remove a cutout from the zone.
Definition: zone.cpp:794
void SetZoneName(const wxString &aName)
Definition: zone.h:130
bool GetDoNotAllowFootprints() const
Definition: zone.h:738
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:362
void SetDoNotAllowTracks(bool aEnable)
Definition: zone.h:745
void UnHatchBorder()
Clear the zone's hatch.
Definition: zone.cpp:917
ZONE_FILL_MODE m_fillMode
How to fill areas:
Definition: zone.h:885
SEGMENT_ITERATOR IterateSegmentsWithHoles()
Return an iterator object, for the aOutline-th outline in the set (with holes).
int m_ZoneClearance
Definition: zone.h:853
unsigned GetPriority() const
Definition: zone.h:122
void BooleanAdd(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset difference For aFastMode meaning, see function booleanOp.
NETCLASS * GetNetClass() const override
Return the NETCLASS for this item.
Definition: zone.h:87
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition: zone.h:733
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:49
int m_cornerSmoothingType
Definition: zone.h:824
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aHatchStyle, int aHatchPitch, bool aRebuildHatch)
Set all hatch parameters for the zone.
Definition: zone.cpp:900
SHAPE_POLY_SET * m_Poly
Outline of the zone.
Definition: zone.h:823
int GetBorderHatchPitch() const
HatchBorder related methods.
Definition: zone.cpp:894
wxString m_zoneName
An optional unique name for this zone, used for identifying it in DRC checking.
Definition: zone.h:828
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the aGlobalIndex-th vertex in the poly set.
int m_hatchSmoothingLevel
Definition: zone.h:889
void SetLayerSet(LSET aLayerSet) override
Definition: zone.cpp:250
ZONE_CONNECTION m_PadConnection
Definition: zone.h:852
bool GetDoNotAllowVias() const
Definition: zone.h:735
double m_area
Definition: zone.h:936
bool m_doNotAllowTracks
Definition: zone.h:848
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition: lset.cpp:521
bool IsEmpty() const
~ZONE()
Definition: zone.cpp:104
long long int m_minIslandArea
When island removal mode is set to AREA, islands below this area will be removed.
Definition: zone.h:863
double m_hatchOrientation
Definition: zone.h:888
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: zone.cpp:295
static ENUM_MAP< T > & Instance()
Definition: property.h:510
bool CommonLayerExists(const LSET aLayerSet) const
Test if this zone shares a common layer with the given layer set.
Definition: zone.cpp:234
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
Structure to hold the necessary information in order to index a vertex on a SHAPE_POLY_SET object: th...
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the aIndex-th subpolygon in the set.
int LAYER_NUM
This can be replaced with int and removed.
Definition: layer_ids.h:41
std::map< PCB_LAYER_ID, std::set< int > > m_insulatedIslands
For each layer, a set of insulated islands that were not removed.
Definition: zone.h:932
bool BuildSmoothedPoly(SHAPE_POLY_SET &aSmoothedPoly, PCB_LAYER_ID aLayer, SHAPE_POLY_SET *aBoardOutline, SHAPE_POLY_SET *aSmoothedPolyWithApron=nullptr) const
Definition: zone.cpp:1169
virtual bool IsOnLayer(PCB_LAYER_ID) const override
Test to see if this object is on the given layer.
Definition: zone.cpp:320
show footprints on back
Definition: layer_ids.h:205
#define ZONE_THERMAL_RELIEF_COPPER_WIDTH_MIL
Definition: zones.h:30
void Rotate(double aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
bool Contains(const VECTOR2I &aP, int aSubpolyIndex=-1, int aAccuracy=0, bool aUseBBoxCaches=false) const
Return true if a given subpolygon contains the point aP.
int GetEffectiveThermalGap(wxString *aSource=nullptr) const
Return the effective thermal gap having resolved any inheritance.
Definition: pad.cpp:844
double Area(bool aAbsolute=true) const
Return the area of this chain.
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:481
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
The base class for create windows for drawing purpose.
MD5_HASH GetHashValue(PCB_LAYER_ID aLayer)
Definition: zone.cpp:386
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
Definition: zone.cpp:550
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
virtual bool IsLocked() const
Definition: board_item.cpp:64
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:411
void SetPriority(unsigned aPriority)
Definition: zone.h:117
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:590
ZONE(BOARD_ITEM_CONTAINER *parent, bool aInFP=false)
The ctor to build ZONE, but compatible with FP_ZONE requirement.
Definition: zone.cpp:44
int m_hatchThickness
Definition: zone.h:886
#define REGISTER_TYPE(x)
Definition: property_mgr.h:248
bool HitTestFilledArea(PCB_LAYER_ID aLayer, const wxPoint &aRefPos, int aAccuracy=0) const
Test if the given wxPoint is within the bounds of a filled area of this zone.
Definition: zone.cpp:510
bool Contains(const wxPoint &aPoint) const
Definition: eda_rect.cpp:57
LSET m_layerSet
Definition: zone.h:830
virtual void SwapData(BOARD_ITEM *aImage) override
Swap data between aItem and aImage.
Definition: zone.cpp:1104
bool HitTestForCorner(const wxPoint &refPos, int aAccuracy, SHAPE_POLY_SET::VERTEX_INDEX &aCornerHit) const
Test if the given wxPoint is near a corner.
Definition: zone.cpp:429
virtual void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
Definition: zone.cpp:737
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirror the line points about y or x (or both)
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
Control for copper zone opacity/visibility (color ignored)
Definition: layer_ids.h:227
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
bool m_doNotAllowVias
Definition: zone.h:847
void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:40
void SetIsRuleArea(bool aEnable)
Definition: zone.h:742
int GetThermalReliefGap() const
Definition: zone.h:191
bool GetNeighbourIndexes(int aGlobalIndex, int *aPrevious, int *aNext)
Return the global indexes of the previous and the next corner of the aGlobalIndex-th corner of a cont...
static LIB_SYMBOL * dummy()
Used to draw a dummy shape when a LIB_SYMBOL is not found in library.
Definition: sch_symbol.cpp:72
int GetEffectiveThermalSpokeWidth(wxString *aSource=nullptr) const
Return the effective thermal spoke width having resolved any inheritance.
Definition: pad.cpp:825
void Rotate(const wxPoint &aCentre, double aAngle) override
Move the outlines.
Definition: zone.cpp:711
void SetVertex(const VERTEX_INDEX &aIndex, const VECTOR2I &aPos)
Accessor function to set the position of a specific point.
void GetInteractingZones(PCB_LAYER_ID aLayer, std::vector< ZONE * > *aZones) const
Some intersecting zones, despite being on the same layer with the same net, cannot be merged due to o...
Definition: zone.cpp:1139
bool HitTestCutout(const VECTOR2I &aRefPos, int *aOutlineIdx=nullptr, int *aHoleIdx=nullptr) const
Test if the given point is contained within a cutout of the zone.
Definition: zone.cpp:525
std::map< PCB_LAYER_ID, bool > m_fillFlags
Definition: zone.h:922
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
bool GetDoNotAllowPads() const
Definition: zone.h:737
void MoveEdge(const wxPoint &offset, int aEdge)
Move the outline Edge.
Definition: zone.cpp:696
Display value expressed in distance units (mm/inch)
Definition: property.h:53
bool GetDoNotAllowCopperPour() const
Definition: zone.h:734
virtual void ViewGetLayers(int aLayers[], int &aCount) const override
Return the all the layers within the VIEW the object is painted on.
Definition: zone.cpp:301
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:504
pads are covered by copper
int GetLocalClearance() const
Definition: zone.h:157
int GetMinThickness() const
Definition: zone.h:244
const EDA_RECT GetBoundingBox() const override
Definition: zone.cpp:326
MD5_HASH GetHash() const
void Move(const VECTOR2I &aVector) override
bool IsClosed() const override
static int GetDefaultHatchPitch()
Definition: zone.cpp:1092
void ExportSetting(ZONE &aTarget, bool aFullExport=true) const
Function ExportSetting copy settings to a given zone.
void SetDoNotAllowPads(bool aEnable)
Definition: zone.h:746
void HatchBorder()
Compute the hatch lines depending on the hatch parameters and stores it in the zone's attribute m_bor...
Definition: zone.cpp:931
ITERATOR IterateWithHoles(int aOutline)
Represent a set of closed polygons.
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: zone.cpp:1383
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Test if a point is near an outline edge or a corner of this zone.
Definition: zone.cpp:404
SHAPE_LINE_CHAIN & Outline(int aIndex)
virtual PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: zone.cpp:222
void SetSelectedCorner(int aCorner)
Definition: zone.h:285
ZONE_CONNECTION GetEffectiveZoneConnection(wxString *aSource=nullptr) const
Return the zone connection in effect (either locally overridden or overridden in the parent footprint...
Definition: pad.cpp:804
int GetLocalFlags() const
Definition: zone.h:305
bool PointInside(const VECTOR2I &aPt, int aAccuracy=0, bool aUseBBoxCache=false) const
Check if point aP lies inside a polygon (any type) defined by the line chain.
bool GetDoNotAllowTracks() const
Definition: zone.h:736
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
int m_thermalReliefGap
Definition: zone.h:875
show footprints on front
Definition: layer_ids.h:204
bool m_hv45
Definition: zone.h:934
static LSET InternalCuMask()
Return a complete set of internal copper layers which is all Cu layers except F_Cu and B_Cu.
Definition: lset.cpp:710
Virtual layers for stacking zones and tracks on a given copper layer.
Definition: layer_ids.h:242
void InitDataFromSrcInCopyCtor(const ZONE &aZone)
Copy aZone data to me.
Definition: zone.cpp:111
SHAPE_POLY_SET::VERTEX_INDEX * m_CornerSelection
The index of the corner being moved or nullptr if no corner is selected.
Definition: zone.h:899
#define _(s)
ISLAND_REMOVAL_MODE m_islandRemovalMode
Definition: zone.h:857
void SetDoNotAllowVias(bool aEnable)
Definition: zone.h:744
a few functions useful in geometry calculations.
#define MAXPTS
void Simplify(POLYGON_MODE aFastMode)
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
class ZONE, a copper pour area
Definition: typeinfo.h:105
bool sortEndsByDescendingX(const VECTOR2I &ref, const VECTOR2I &tst)
Definition: zone.cpp:925
static SHAPE_POLY_SET g_nullPoly
Definition: zone.cpp:383
void SetMinThickness(int aMinThickness)
Definition: zone.h:245
void TransformSolidAreasShapesToPolygon(PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aCornerBuffer, int aError=ARC_HIGH_DEF) const
Convert solid areas full shapes to polygon set (the full shape is the polygon area with a thick outli...
Definition: zone.cpp:1417
std::map< PCB_LAYER_ID, MD5_HASH > m_filledPolysHash
A hash value used in zone filling calculations to see if the filled areas are up to date.
Definition: zone.h:925
virtual const ZONE_SETTINGS & GetZoneSettings() const
Fetch the zone settings for this container.
void BooleanIntersection(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset union between a and b, store the result in it self For aFastMode meaning,...
int NewOutline()
Creates a new hole in a given outline.
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.
#define ZONE_THICKNESS_MIL
Definition: zones.h:31
int m_ZoneMinThickness
Definition: zone.h:854
CONST_ITERATOR CIterate(int aFirst, int aLast, bool aIterateHoles=false) const
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Assign the members of aItem to another object.
Definition: eda_item.cpp:180
void Fracture(POLYGON_MODE aFastMode)
Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Return the area of this poly set.
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
Definition: layer_ids.h:465
wxString UnescapeString(const wxString &aSource)
Thermal relief only for THT pads.
std::map< PCB_LAYER_ID, SHAPE_POLY_SET > m_RawPolysList
Definition: zone.h:918
wxString GetNetnameMsg() const
void BuildHashValue(PCB_LAYER_ID aLayer)
Build the hash value of m_FilledPolysList, and store it internally in m_filledPolysHash.
Definition: zone.cpp:395
bool m_isRuleArea
Definition: zone.h:841
void Inflate(int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
Perform outline inflation/deflation.
Some functions to handle hotkeys in KiCad.
void Move(const wxPoint &offset) override
Move the outlines.
Definition: zone.cpp:675
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
std::map< PCB_LAYER_ID, std::vector< SEG > > m_FillSegmList
Segments used to fill the zone (#m_FillMode ==1 ), when fill zone by segment is used.
Definition: zone.h:907
int m_borderHatchPitch
Definition: zone.h:928
Definition: seg.h:40
EDA_UNITS
Definition: eda_units.h:38
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
void Normalize()
Ensures that the height ant width are positive.
Definition: eda_rect.cpp:35
bool IsKeepout() const
Definition: zone.cpp:1316
Use thermal relief for pads.
std::vector< SEG > m_borderHatchLines
Definition: zone.h:929
void SetLocalFlags(int aFlags)
Definition: zone.h:306
bool CollideEdge(const VECTOR2I &aPoint, VERTEX_INDEX &aClosestVertex, int aClearance=0) const
Check whether aPoint collides with any edge of any of the contours of the polygon.
void SetPadConnection(ZONE_CONNECTION aPadConnection)
Definition: zone.h:242
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:840
int m_hatchBorderAlgorithm
Definition: zone.h:895
bool HitTestForEdge(const wxPoint &refPos, int aAccuracy, SHAPE_POLY_SET::VERTEX_INDEX &aCornerHit) const
Test if the given wxPoint is near a segment defined by 2 corners.
Definition: zone.cpp:443
ZONE_DESC()
Definition: zone.cpp:1451
wxPoint GetPosition() const override
Definition: zone.cpp:216
bool m_isFilled
True when a zone was filled, false after deleting the filled areas.
Definition: zone.h:866
FP_ZONE & operator=(const FP_ZONE &aOther)
Definition: zone.cpp:1346
void AccumulateDescription(wxString &aDesc, const wxString &aItem)
Utility to build comma separated lists in messages.
Definition: string_utils.h:319
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:32
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
void SetDoNotAllowCopperPour(bool aEnable)
Definition: zone.h:743
bool IsIsland(PCB_LAYER_ID aLayer, int aPolyIdx) const
Check if a given filled polygon is an insulated island.
Definition: zone.cpp:1127
Represent a polyline (an zero-thickness chain of connected line segments).
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
NETINFO_ITEM * m_netinfo
Store all information about the net that item belongs to.
void SetHatchPitch(int aPitch)
Set the hatch pitch parameter for the zone.
Definition: zone.cpp:911
Definition: layer_ids.h:71
int m_hatchGap
Definition: zone.h:887
void AddProperty(PROPERTY_BASE *aProperty)
Register a property.
int GetCopperLayerCount() const
Definition: board.cpp:455
class ZONE, managed by a footprint
Definition: typeinfo.h:94
VECTOR2I A
Definition: seg.h:48
const VECTOR2I & GetCornerPosition(int aCornerIndex) const
Definition: zone.h:563
Handle the component boundary box.
Definition: eda_rect.h:42
double DECIDEG2RAD(double deg)
Definition: trigo.h:233
FP_ZONE(BOARD_ITEM_CONTAINER *aParent)
Definition: zone.cpp:1330
The main frame for Pcbnew.
void ClearArcs()
Appends a vertex at the end of the given outline/hole (default: the last outline)
void Mirror(const wxPoint &aMirrorRef, bool aMirrorLeftRight)
Mirror the outlines relative to a given horizontal axis the layer is not changed.
Definition: zone.cpp:749
bool IsOnCopperLayer() const override
Definition: zone.cpp:228
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
bool m_doNotAllowCopperPour
Definition: zone.h:846
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:100
void InflateWithLinkedHoles(int aFactor, int aCircleSegmentsCount, POLYGON_MODE aFastMode)
Perform outline inflation/deflation, using round corners.
Pads are not covered.
virtual int GetOwnClearance(PCB_LAYER_ID aLayer, wxString *aSource=nullptr) const
Return an item's "own" clearance in internal units.
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: zone.cpp:186
bool Intersects(const EDA_RECT &aRect) const
Test for a common area between rectangles.
Definition: eda_rect.cpp:150
PCB_LAYER_ID m_layer
Definition: board_item.h:316
int m_fillVersion
Definition: zone.h:855
void SetThermalReliefGap(int aThermalReliefGap)
Definition: zone.h:183
ZONE_BORDER_DISPLAY_STYLE
Zone border styles.
Definition: zone_settings.h:46
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:36
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:62
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition: zone.cpp:242
void SetNeedRefill(bool aNeedRefill)
Definition: zone.h:238
double m_hatchHoleMinArea
Definition: zone.h:894
double CalculateFilledArea()
Compute the area currently occupied by the zone fill.
Definition: zone.cpp:1267
#define ZONE_THERMAL_RELIEF_GAP_MIL
Definition: zones.h:29
void SetLocalClearance(int aClearance)
Definition: zone.h:158
bool m_needRefill
False when a zone was refilled, true after changes in zone params.
Definition: zone.h:873
void AddPolygon(std::vector< wxPoint > &aPolygon)
Add a polygon to the zone outline.
Definition: zone.cpp:823
int GetThermalReliefSpokeWidth() const
Definition: zone.h:202
Abstract interface for BOARD_ITEMs capable of storing other items inside.
EDA_MSG_PANEL items for displaying messages.
Definition: msgpanel.h:53
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:68
ZONE & operator=(const ZONE &aOther)
Definition: zone.cpp:94
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Return the text to display to be used in the selection clarification context menu when multiple items...
Definition: zone.cpp:860
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the zone shape to a closed polygon Used in filling zones calculations Circles and arcs are ap...
Definition: zone.cpp:1400
Definition: pad.h:57
bool UnFill()
Removes the zone filling.
Definition: zone.cpp:192
wxString GetZoneName() const
Definition: zone.h:129
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: zone.cpp:1359
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:135
bool m_forceVisible
Definition: eda_item.h:480
static constexpr int Millimeter2iu(double mm)
#define _HKI(x)
std::map< PCB_LAYER_ID, SHAPE_POLY_SET > m_FilledPolysList
Definition: zone.h:917
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:140
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: zone.cpp:312
unsigned m_priority
Definition: zone.h:836
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)
double m_hatchSmoothingValue
Definition: zone.h:893
A specialization of ZONE for use in footprints.
Definition: zone.h:946
bool CollideVertex(const VECTOR2I &aPoint, VERTEX_INDEX &aClosestVertex, int aClearance=0) const
Check whether aPoint collides with any vertex of any of the contours of the polygon.
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
int m_thermalReliefSpokeWidth
Definition: zone.h:876
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Inflate the rectangle horizontally by dx and vertically by dy.
Definition: eda_rect.cpp:364
static struct ZONE_DESC _ZONE_DESC
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113
void SetDoNotAllowFootprints(bool aEnable)
Definition: zone.h:747
bool GetFilledPolysUseThickness() const
Definition: zone.h:689
bool KeepoutAll() const
Definition: zone.cpp:1323
Container for design settings for a BOARD object.
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:405
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...
void SetThermalReliefSpokeWidth(int aThermalReliefSpokeWidth)
Definition: zone.h:194
bool m_doNotAllowPads
Definition: zone.h:849
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: zone.cpp:1353
VECTOR2I B
Definition: seg.h:49