KiCad PCB EDA Suite
class_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 <dick@softplc.com>
6  * Copyright (C) 1992-2019 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>
27 #include <fctsys.h>
29 #include <kicad_string.h>
30 #include <macros.h>
31 #include <msgpanel.h>
32 #include <pcb_base_frame.h>
33 #include <pcb_screen.h>
34 #include <richio.h>
35 #include <trigo.h>
36 #include <convert_to_biu.h>
37 #include <class_board.h>
38 #include <class_zone.h>
39 #include <pcbnew.h>
40 #include <zones.h>
41 #include <math_for_graphics.h>
43 #include <math/util.h> // for KiROUND
44 #include <pgm_base.h>
47 
48 
51  m_area( 0.0 )
52 {
53  m_CornerSelection = nullptr; // no corner is selected
54  m_IsFilled = false; // fill status : true when the zone is filled
58  m_hv45 = false;
62  m_HatchFillTypeSmoothingLevel = 0; // Grid pattern smoothing type. 0 = no smoothing
63  m_HatchFillTypeSmoothingValue = 0.1; // Grid pattern chamfer value relative to the gap value
64  // used only if m_HatchFillTypeSmoothingLevel > 0
65  m_priority = 0;
67  SetIsKeepout( aInModule ? true : false ); // Zones living in modules have the keepout option.
68  SetDoNotAllowCopperPour( false ); // has meaning only if m_isKeepout == true
69  SetDoNotAllowVias( true ); // has meaning only if m_isKeepout == true
70  SetDoNotAllowTracks( true ); // has meaning only if m_isKeepout == true
71  SetDoNotAllowPads( true ); // has meaning only if m_isKeepout == true
72  SetDoNotAllowFootprints( false ); // has meaning only if m_isKeepout == true
73  m_cornerRadius = 0;
74  SetLocalFlags( 0 ); // flags tempoarry used in zone calculations
75  m_Poly = new SHAPE_POLY_SET(); // Outlines
76  m_FilledPolysUseThickness = true; // set the "old" way to build filled polygon areas (before 6.0.x)
77  aParent->GetZoneSettings().ExportSetting( *this );
78 
79  m_needRefill = false; // True only after some edition.
80 }
81 
82 
84  : BOARD_CONNECTED_ITEM( aZone.GetParent(), PCB_ZONE_AREA_T )
85 {
87 }
88 
89 
91 {
93 
94  // Replace the outlines for aOther outlines.
95  delete m_Poly;
96  m_Poly = new SHAPE_POLY_SET( *aOther.m_Poly );
97 
98  m_isKeepout = aOther.m_isKeepout;
99  m_CornerSelection = nullptr; // for corner moving, corner index to (null if no selection)
100  m_ZoneClearance = aOther.m_ZoneClearance; // clearance value
103  m_FillMode = aOther.m_FillMode; // filling mode (segments/polygons)
107  SetHatchStyle( aOther.GetHatchStyle() );
108  SetHatchPitch( aOther.GetHatchPitch() );
109  m_HatchLines = aOther.m_HatchLines; // copy vector <SEG>
112  m_FillSegmList.clear();
114 
120 
121  SetLayerSet( aOther.GetLayerSet() );
122 
123  return *this;
124 }
125 
126 
128 {
129  delete m_Poly;
130  delete m_CornerSelection;
131 }
132 
133 
135 {
136  // members are expected non initialize in this.
137  // initDataFromSrcInCopyCtor() is expected to be called
138  // only from a copy constructor.
139 
140  // Copy only useful EDA_ITEM flags:
141  m_Flags = aZone.m_Flags;
143 
144  m_isKeepout = aZone.m_isKeepout;
145  SetLayerSet( aZone.GetLayerSet() );
146 
147  m_Poly = new SHAPE_POLY_SET( *aZone.m_Poly );
148 
149  // For corner moving, corner index to drag, or nullptr if no selection
150  m_CornerSelection = nullptr;
151  m_IsFilled = aZone.m_IsFilled;
152  m_ZoneClearance = aZone.m_ZoneClearance; // clearance value
155  m_FillMode = aZone.m_FillMode; // Filling mode (segments/polygons)
156  m_hv45 = aZone.m_hv45;
157  m_priority = aZone.m_priority;
162  m_FillSegmList = aZone.m_FillSegmList; // vector <> copy
163 
169 
172 
173  m_hatchStyle = aZone.m_hatchStyle;
174  m_hatchPitch = aZone.m_hatchPitch;
175  m_HatchLines = aZone.m_HatchLines;
176 
182 
183  SetLocalFlags( aZone.GetLocalFlags() );
184 
185  // Now zone type and layer are set, transfer net info
186  // (has meaning only for copper zones)
187  m_netinfo = aZone.m_netinfo;
188 
189  m_area = aZone.m_area;
190 
191  SetNeedRefill( aZone.NeedRefill() );
192 }
193 
194 
196 {
197  return new ZONE_CONTAINER( *this );
198 }
199 
200 
202 {
203  bool change = ( !m_FilledPolysList.IsEmpty() || m_FillSegmList.size() > 0 );
204 
206  m_FillSegmList.clear();
207  m_IsFilled = false;
208 
209  return change;
210 }
211 
212 
214 {
215  return (wxPoint) GetCornerPosition( 0 );
216 }
217 
218 
220 {
221  return BOARD_ITEM::GetLayer();
222 }
223 
224 
226 {
227  if( GetIsKeepout() )
228  {
229  return ( m_layerSet & LSET::AllCuMask() ).count() > 0;
230  }
231  else
232  {
233  return IsCopperLayer( GetLayer() );
234  }
235 }
236 
237 
238 bool ZONE_CONTAINER::CommonLayerExists( const LSET aLayerSet ) const
239 {
240  LSET common = GetLayerSet() & aLayerSet;
241 
242  return common.count() > 0;
243 }
244 
245 
247 {
248  SetLayerSet( LSET( aLayer ) );
249 
250  m_Layer = aLayer;
251 }
252 
253 
255 {
256  if( GetIsKeepout() )
257  {
258  // Keepouts can only exist on copper layers
259  aLayerSet &= LSET::AllCuMask();
260  }
261 
262  if( aLayerSet.count() == 0 )
263  return;
264 
265  if( m_layerSet != aLayerSet )
266  SetNeedRefill( true );
267 
268  m_layerSet = aLayerSet;
269 
270  // Set the single layer parameter.
271  // For keepout zones that can be on many layers, this parameter does not have
272  // really meaning and is a bit arbitrary if more than one layer is set.
273  // But many functions are using it.
274  // So we need to initialize it to a reasonable value.
275  // Priority is F_Cu then B_Cu then to the first selected layer
276  m_Layer = aLayerSet.Seq()[0];
277 
278  if( m_Layer != F_Cu && aLayerSet[B_Cu] )
279  m_Layer = B_Cu;
280 }
281 
282 
284 {
285  // TODO - Enable multi-layer zones for all zone types
286  // not just keepout zones
287  if( GetIsKeepout() )
288  {
289  return m_layerSet;
290  }
291  else
292  {
293  return LSET( m_Layer );
294  }
295 }
296 
297 void ZONE_CONTAINER::ViewGetLayers( int aLayers[], int& aCount ) const
298 {
299  if( GetIsKeepout() )
300  {
301  LSEQ layers = m_layerSet.Seq();
302 
303  for( unsigned int idx = 0; idx < layers.size(); idx++ )
304  aLayers[idx] = layers[idx];
305 
306  aCount = layers.size();
307  }
308  else
309  {
310  aLayers[0] = m_Layer;
311  aCount = 1;
312  }
313 }
314 
315 
317 {
318  if( GetIsKeepout() )
319  return m_layerSet.test( aLayer );
320 
321  return BOARD_ITEM::IsOnLayer( aLayer );
322 }
323 
324 
326 {
327  auto bb = m_Poly->BBox();
328 
329  EDA_RECT ret( (wxPoint) bb.GetOrigin(), wxSize( bb.GetWidth(), bb.GetHeight() ) );
330 
331  return ret;
332 }
333 
334 
336 {
337  if( aPad == NULL || aPad->GetThermalGap() == 0 )
338  return m_ThermalReliefGap;
339  else
340  return aPad->GetThermalGap();
341 }
342 
343 
345 {
346  if( aPad == NULL || aPad->GetThermalWidth() == 0 )
348  else
349  return aPad->GetThermalWidth();
350 }
351 
352 
353 int ZONE_CONTAINER::GetKeepouts( std::map<int, wxString>* aSources ) const
354 {
355  wxString source;
356  int keepouts = 0;
357 
358  auto setFlag = [&]( int aFlag )
359  {
360  keepouts |= aFlag;
361 
362  if( aSources )
363  (*aSources)[ aFlag ] = source;
364  };
365 
366  if( m_isKeepout )
367  {
368  if( aSources )
369  source = _( "zone properties" );
370 
371  if( m_doNotAllowTracks )
372  setFlag( DISALLOW_TRACKS );
373 
374  if( m_doNotAllowVias )
375  setFlag( DISALLOW_VIAS );
376 
377  if( m_doNotAllowPads )
378  setFlag( DISALLOW_PADS );
379 
381  setFlag( DISALLOW_FOOTPRINTS );
382 
384  setFlag( DISALLOW_ZONES );
385  }
386 
387  DRC_RULE* rule = GetRule( this, nullptr, DISALLOW_CONSTRAINT );
388 
389  if( rule )
390  {
391  if( aSources )
392  source = wxString::Format( _( "'%s' rule" ), rule->m_Name );
393 
394  if( ( rule->m_DisallowFlags & DISALLOW_VIAS ) > 0 )
395  setFlag( DISALLOW_VIAS );
396 
397  if( ( rule->m_DisallowFlags & DISALLOW_MICRO_VIAS ) > 0 )
398  setFlag( DISALLOW_MICRO_VIAS );
399 
400  if( ( rule->m_DisallowFlags & DISALLOW_BB_VIAS ) > 0 )
401  setFlag( DISALLOW_BB_VIAS );
402 
403  if( ( rule->m_DisallowFlags & DISALLOW_TRACKS ) > 0 )
404  setFlag( DISALLOW_TRACKS );
405 
406  if( ( rule->m_DisallowFlags & DISALLOW_PADS ) > 0 )
407  setFlag( DISALLOW_PADS );
408 
409  if( ( rule->m_DisallowFlags & DISALLOW_ZONES ) > 0 )
410  setFlag( DISALLOW_ZONES );
411 
412  if( ( rule->m_DisallowFlags & DISALLOW_TEXTS ) > 0 )
413  setFlag( DISALLOW_TEXTS );
414 
415  if( ( rule->m_DisallowFlags & DISALLOW_GRAPHICS ) > 0 )
416  setFlag( DISALLOW_GRAPHICS );
417 
418  if( ( rule->m_DisallowFlags & DISALLOW_HOLES ) > 0 )
419  setFlag( DISALLOW_HOLES );
420 
421  if( ( rule->m_DisallowFlags & DISALLOW_FOOTPRINTS ) > 0 )
422  setFlag( DISALLOW_FOOTPRINTS );
423  }
424 
425  return keepouts;
426 }
427 
428 
429 void ZONE_CONTAINER::SetCornerRadius( unsigned int aRadius )
430 {
431  if( m_cornerRadius != aRadius )
432  SetNeedRefill( true );
433 
434  m_cornerRadius = aRadius;
435 }
436 
437 
438 bool ZONE_CONTAINER::HitTest( const wxPoint& aPosition, int aAccuracy ) const
439 {
440  // Normally accuracy is zoom-relative, but for the generic HitTest we just use
441  // a fixed (small) value.
442  int accuracy = std::max( aAccuracy, Millimeter2iu( 0.1 ) );
443 
444  return HitTestForCorner( aPosition, accuracy * 2 ) || HitTestForEdge( aPosition, accuracy );
445 }
446 
447 
448 void ZONE_CONTAINER::SetSelectedCorner( const wxPoint& aPosition, int aAccuracy )
449 {
451 
452  // If there is some corner to be selected, assign it to m_CornerSelection
453  if( HitTestForCorner( aPosition, aAccuracy * 2, corner )
454  || HitTestForEdge( aPosition, aAccuracy, corner ) )
455  {
456  if( m_CornerSelection == nullptr )
458 
459  *m_CornerSelection = corner;
460  }
461 }
462 
463 bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos, int aAccuracy,
464  SHAPE_POLY_SET::VERTEX_INDEX& aCornerHit ) const
465 {
466  return m_Poly->CollideVertex( VECTOR2I( refPos ), aCornerHit, aAccuracy );
467 }
468 
469 
470 bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos, int aAccuracy ) const
471 {
473  return HitTestForCorner( refPos, aAccuracy, dummy );
474 }
475 
476 
477 bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos, int aAccuracy,
478  SHAPE_POLY_SET::VERTEX_INDEX& aCornerHit ) const
479 {
480  return m_Poly->CollideEdge( VECTOR2I( refPos ), aCornerHit, aAccuracy );
481 }
482 
483 
484 bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos, int aAccuracy ) const
485 {
487  return HitTestForEdge( refPos, aAccuracy, dummy );
488 }
489 
490 
491 bool ZONE_CONTAINER::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
492 {
493  // Calculate bounding box for zone
494  EDA_RECT bbox = GetBoundingBox();
495  bbox.Normalize();
496 
497  EDA_RECT arect = aRect;
498  arect.Normalize();
499  arect.Inflate( aAccuracy );
500 
501  if( aContained )
502  {
503  return arect.Contains( bbox );
504  }
505  else // Test for intersection between aBox and the polygon
506  // For a polygon, using its bounding box has no sense here
507  {
508  // Fast test: if aBox is outside the polygon bounding box, rectangles cannot intersect
509  if( !arect.Intersects( bbox ) )
510  return false;
511 
512  int count = m_Poly->TotalVertices();
513 
514  for( int ii = 0; ii < count; ii++ )
515  {
516  auto vertex = m_Poly->CVertex( ii );
517  auto vertexNext = m_Poly->CVertex( ( ii + 1 ) % count );
518 
519  // Test if the point is within the rect
520  if( arect.Contains( ( wxPoint ) vertex ) )
521  {
522  return true;
523  }
524 
525  // Test if this edge intersects the rect
526  if( arect.Intersects( ( wxPoint ) vertex, ( wxPoint ) vertexNext ) )
527  {
528  return true;
529  }
530  }
531 
532  return false;
533  }
534 }
535 
536 
537 int ZONE_CONTAINER::GetLocalClearance( wxString* aSource ) const
538 {
539  if( m_isKeepout )
540  return 0;
541 
542  if( aSource )
543  *aSource = _( "zone" );
544 
545  return m_ZoneClearance;
546 }
547 
548 
549 bool ZONE_CONTAINER::HitTestFilledArea( const wxPoint& aRefPos ) const
550 {
551  return m_FilledPolysList.Contains( VECTOR2I( aRefPos.x, aRefPos.y ) );
552 }
553 
554 
555 bool ZONE_CONTAINER::HitTestCutout( const VECTOR2I& aRefPos, int* aOutlineIdx, int* aHoleIdx ) const
556 {
557  // Iterate over each outline polygon in the zone and then iterate over
558  // each hole it has to see if the point is in it.
559  for( int i = 0; i < m_Poly->OutlineCount(); i++ )
560  {
561  for( int j = 0; j < m_Poly->HoleCount( i ); j++ )
562  {
563  if( m_Poly->Hole( i, j ).PointInside( aRefPos ) )
564  {
565  if( aOutlineIdx )
566  *aOutlineIdx = i;
567 
568  if( aHoleIdx )
569  *aHoleIdx = j;
570 
571  return true;
572  }
573  }
574  }
575 
576  return false;
577 }
578 
579 
580 void ZONE_CONTAINER::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
581 {
582  EDA_UNITS units = aFrame->GetUserUnits();
583  wxString msg, msg2;
584 
585  if( GetIsKeepout() )
586  msg = _( "Keepout Area" );
587  else if( IsOnCopperLayer() )
588  msg = _( "Copper Zone" );
589  else
590  msg = _( "Non-copper Zone" );
591 
592  // Display Cutout instead of Outline for holes inside a zone
593  // i.e. when num contour !=0
594  // Check whether the selected corner is in a hole; i.e., in any contour but the first one.
595  if( m_CornerSelection != nullptr && m_CornerSelection->m_contour > 0 )
596  msg << wxT( " " ) << _( "Cutout" );
597 
598  aList.emplace_back( _( "Type" ), msg, DARKCYAN );
599 
600  if( GetIsKeepout() )
601  {
602  msg.Empty();
603 
604  if( GetDoNotAllowVias() )
605  AccumulateDescription( msg, _( "No vias" ) );
606 
607  if( GetDoNotAllowTracks() )
608  AccumulateDescription( msg, _( "No tracks" ) );
609 
610  if( GetDoNotAllowPads() )
611  AccumulateDescription( msg, _( "No pads" ) );
612 
614  AccumulateDescription( msg, _( "No copper zones" ) );
615 
617  AccumulateDescription( msg, _( "No footprints" ) );
618 
619  aList.emplace_back( MSG_PANEL_ITEM( _( "Keepout" ), msg, RED ) );
620  }
621  else if( IsOnCopperLayer() )
622  {
623  if( GetNetCode() >= 0 )
624  {
625  NETINFO_ITEM* net = GetNet();
626  NETCLASS* netclass = nullptr;
627 
628  if( net )
629  {
630  if( net->GetNet() )
631  netclass = GetNetClass();
632  else
633  netclass = GetBoard()->GetDesignSettings().GetDefault();
634 
635  msg = UnescapeString( net->GetNetname() );
636  }
637  else
638  {
639  msg = wxT( "<no name>" );
640  }
641 
642  aList.emplace_back( _( "Net" ), msg, RED );
643 
644  if( netclass )
645  aList.emplace_back( _( "NetClass" ), netclass->GetName(), DARKMAGENTA );
646  }
647 
648  // Display priority level
649  msg.Printf( wxT( "%d" ), GetPriority() );
650  aList.emplace_back( _( "Priority" ), msg, BLUE );
651  }
652 
653  aList.emplace_back( _( "Layer" ), LayerMaskDescribe( GetBoard(), m_layerSet ), DARKGREEN );
654 
655  switch( m_FillMode )
656  {
657  case ZONE_FILL_MODE::POLYGONS: msg = _( "Solid" ); break;
658  case ZONE_FILL_MODE::HATCH_PATTERN: msg = _( "Hatched" ); break;
659  default: msg = _( "Unknown" ); break;
660  }
661 
662  aList.emplace_back( _( "Fill Mode" ), msg, BROWN );
663 
664  msg = MessageTextFromValue( units, m_area, false, EDA_DATA_TYPE::AREA );
665  aList.emplace_back( _( "Filled Area" ), msg, BLUE );
666 
667  wxString source;
668  int clearance = GetClearance( nullptr, &source );
669 
670  msg.Printf( _( "Min Clearance: %s" ), MessageTextFromValue( units, clearance, true ) );
671  msg2.Printf( _( "(from %s)" ), source );
672  aList.emplace_back( msg, msg2, BLACK );
673 }
674 
675 
676 /* Geometric transforms: */
677 
678 void ZONE_CONTAINER::Move( const wxPoint& offset )
679 {
680  /* move outlines */
681  m_Poly->Move( offset );
682 
683  Hatch();
684 
685  m_FilledPolysList.Move( offset );
686 
687  for( SEG& seg : m_FillSegmList )
688  {
689  seg.A += VECTOR2I( offset );
690  seg.B += VECTOR2I( offset );
691  }
692 }
693 
694 
695 void ZONE_CONTAINER::MoveEdge( const wxPoint& offset, int aEdge )
696 {
697  int next_corner;
698 
699  if( m_Poly->GetNeighbourIndexes( aEdge, nullptr, &next_corner ) )
700  {
701  m_Poly->SetVertex( aEdge, m_Poly->CVertex( aEdge ) + VECTOR2I( offset ) );
702  m_Poly->SetVertex( next_corner, m_Poly->CVertex( next_corner ) + VECTOR2I( offset ) );
703  Hatch();
704 
705  SetNeedRefill( true );
706  }
707 }
708 
709 
710 void ZONE_CONTAINER::Rotate( const wxPoint& centre, double angle )
711 {
712  wxPoint pos;
713 
714  angle = -DECIDEG2RAD( angle );
715 
716  m_Poly->Rotate( angle, VECTOR2I( centre ) );
717  Hatch();
718 
719  /* rotate filled areas: */
720  m_FilledPolysList.Rotate( angle, VECTOR2I( centre ) );
721 
722  for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
723  {
724  wxPoint a( m_FillSegmList[ic].A );
725  RotatePoint( &a, centre, angle );
726  m_FillSegmList[ic].A = a;
727  wxPoint b( m_FillSegmList[ic].B );
728  RotatePoint( &b, centre, angle );
729  m_FillSegmList[ic].B = a;
730  }
731 }
732 
733 
734 void ZONE_CONTAINER::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
735 {
736  Mirror( aCentre, aFlipLeftRight );
737  int copperLayerCount = GetBoard()->GetCopperLayerCount();
738 
739  if( GetIsKeepout() )
740  SetLayerSet( FlipLayerMask( GetLayerSet(), copperLayerCount ) );
741  else
742  SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
743 }
744 
745 
746 void ZONE_CONTAINER::Mirror( const wxPoint& aMirrorRef, bool aMirrorLeftRight )
747 {
748  // ZONE_CONTAINERs mirror about the x-axis (why?!?)
749  m_Poly->Mirror( aMirrorLeftRight, !aMirrorLeftRight, VECTOR2I( aMirrorRef ) );
750 
751  Hatch();
752 
753  m_FilledPolysList.Mirror( aMirrorLeftRight, !aMirrorLeftRight, VECTOR2I( aMirrorRef ) );
754 
755  for( SEG& seg : m_FillSegmList )
756  {
757  if( aMirrorLeftRight )
758  {
759  MIRROR( seg.A.x, aMirrorRef.x );
760  MIRROR( seg.B.x, aMirrorRef.x );
761  }
762  else
763  {
764  MIRROR( seg.A.y, aMirrorRef.y );
765  MIRROR( seg.B.y, aMirrorRef.y );
766  }
767  }
768 }
769 
770 
772 {
773  if( aPad == NULL || aPad->GetZoneConnection() == ZONE_CONNECTION::INHERITED )
774  return m_PadConnection;
775  else
776  return aPad->GetZoneConnection();
777 }
778 
779 
780 void ZONE_CONTAINER::RemoveCutout( int aOutlineIdx, int aHoleIdx )
781 {
782  // Ensure the requested cutout is valid
783  if( m_Poly->OutlineCount() < aOutlineIdx || m_Poly->HoleCount( aOutlineIdx ) < aHoleIdx )
784  return;
785 
786  SHAPE_POLY_SET cutPoly( m_Poly->Hole( aOutlineIdx, aHoleIdx ) );
787 
788  // Add the cutout back to the zone
790 
791  SetNeedRefill( true );
792 }
793 
794 
796 {
797  wxASSERT( aPolygon.IsClosed() );
798 
799  // Add the outline as a new polygon in the polygon set
800  if( m_Poly->OutlineCount() == 0 )
801  m_Poly->AddOutline( aPolygon );
802  else
803  m_Poly->AddHole( aPolygon );
804 
805  SetNeedRefill( true );
806 }
807 
808 
809 void ZONE_CONTAINER::AddPolygon( std::vector< wxPoint >& aPolygon )
810 {
811  if( aPolygon.empty() )
812  return;
813 
814  SHAPE_LINE_CHAIN outline;
815 
816  // Create an outline and populate it with the points of aPolygon
817  for( const wxPoint& pt : aPolygon)
818  outline.Append( pt );
819 
820  outline.SetClosed( true );
821 
822  AddPolygon( outline );
823 }
824 
825 
826 bool ZONE_CONTAINER::AppendCorner( wxPoint aPosition, int aHoleIdx, bool aAllowDuplication )
827 {
828  // Ensure the main outline exists:
829  if( m_Poly->OutlineCount() == 0 )
830  m_Poly->NewOutline();
831 
832  // If aHoleIdx >= 0, the corner musty be added to the hole, index aHoleIdx.
833  // (remember: the index of the first hole is 0)
834  // Return error if if does dot exist.
835  if( aHoleIdx >= m_Poly->HoleCount( 0 ) )
836  return false;
837 
838  m_Poly->Append( aPosition.x, aPosition.y, -1, aHoleIdx, aAllowDuplication );
839 
840  SetNeedRefill( true );
841 
842  return true;
843 }
844 
845 
847 {
848  wxString text;
849 
850  // Check whether the selected contour is a hole (contour index > 0)
851  if( m_CornerSelection != nullptr && m_CornerSelection->m_contour > 0 )
852  text << wxT( " " ) << _( "(Cutout)" );
853 
854  if( GetIsKeepout() )
855  text << wxT( " " ) << _( "(Keepout)" );
856  else
857  text << GetNetnameMsg();
858 
859  return wxString::Format( _( "Zone Outline %s on %s" ), text, GetLayerName() );
860 }
861 
862 
864 {
865  return m_hatchPitch;
866 }
867 
868 
869 void ZONE_CONTAINER::SetHatch( ZONE_HATCH_STYLE aHatchStyle, int aHatchPitch, bool aRebuildHatch )
870 {
871  SetHatchPitch( aHatchPitch );
872  m_hatchStyle = aHatchStyle;
873 
874  if( aRebuildHatch )
875  Hatch();
876 }
877 
878 
880 {
881  m_hatchPitch = aPitch;
882 }
883 
884 
886 {
887  m_HatchLines.clear();
888 }
889 
890 
891 // Creates hatch lines inside the outline of the complex polygon
892 // sort function used in ::Hatch to sort points by descending wxPoint.x values
893 bool sortEndsByDescendingX( const VECTOR2I& ref, const VECTOR2I& tst )
894 {
895  return tst.x < ref.x;
896 }
897 
898 
900 {
901  UnHatch();
902 
904  return;
905 
906  // define range for hatch lines
907  int min_x = m_Poly->CVertex( 0 ).x;
908  int max_x = m_Poly->CVertex( 0 ).x;
909  int min_y = m_Poly->CVertex( 0 ).y;
910  int max_y = m_Poly->CVertex( 0 ).y;
911 
912  for( auto iterator = m_Poly->IterateWithHoles(); iterator; iterator++ )
913  {
914  if( iterator->x < min_x )
915  min_x = iterator->x;
916 
917  if( iterator->x > max_x )
918  max_x = iterator->x;
919 
920  if( iterator->y < min_y )
921  min_y = iterator->y;
922 
923  if( iterator->y > max_y )
924  max_y = iterator->y;
925  }
926 
927  // Calculate spacing between 2 hatch lines
928  int spacing;
929 
931  spacing = m_hatchPitch;
932  else
933  spacing = m_hatchPitch * 2;
934 
935  // set the "length" of hatch lines (the length on horizontal axis)
936  int hatch_line_len = m_hatchPitch;
937 
938  // To have a better look, give a slope depending on the layer
939  LAYER_NUM layer = GetLayer();
940  int slope_flag = (layer & 1) ? 1 : -1; // 1 or -1
941  double slope = 0.707106 * slope_flag; // 45 degrees slope
942  int max_a, min_a;
943 
944  if( slope_flag == 1 )
945  {
946  max_a = KiROUND( max_y - slope * min_x );
947  min_a = KiROUND( min_y - slope * max_x );
948  }
949  else
950  {
951  max_a = KiROUND( max_y - slope * max_x );
952  min_a = KiROUND( min_y - slope * min_x );
953  }
954 
955  min_a = (min_a / spacing) * spacing;
956 
957  // calculate an offset depending on layer number,
958  // for a better look of hatches on a multilayer board
959  int offset = (layer * 7) / 8;
960  min_a += offset;
961 
962  // loop through hatch lines
963  #define MAXPTS 200 // Usually we store only few values per one hatch line
964  // depending on the complexity of the zone outline
965 
966  static std::vector<VECTOR2I> pointbuffer;
967  pointbuffer.clear();
968  pointbuffer.reserve( MAXPTS + 2 );
969 
970  for( int a = min_a; a < max_a; a += spacing )
971  {
972  // get intersection points for this hatch line
973 
974  // Note: because we should have an even number of intersections with the
975  // current hatch line and the zone outline (a closed polygon,
976  // or a set of closed polygons), if an odd count is found
977  // we skip this line (should not occur)
978  pointbuffer.clear();
979 
980  // Iterate through all vertices
981  for( auto iterator = m_Poly->IterateSegmentsWithHoles(); iterator; iterator++ )
982  {
983  double x, y, x2, y2;
984  int ok;
985 
986  SEG segment = *iterator;
987 
988  ok = FindLineSegmentIntersection( a, slope,
989  segment.A.x, segment.A.y,
990  segment.B.x, segment.B.y,
991  &x, &y, &x2, &y2 );
992 
993  if( ok )
994  {
995  VECTOR2I point( KiROUND( x ), KiROUND( y ) );
996  pointbuffer.push_back( point );
997  }
998 
999  if( ok == 2 )
1000  {
1001  VECTOR2I point( KiROUND( x2 ), KiROUND( y2 ) );
1002  pointbuffer.push_back( point );
1003  }
1004 
1005  if( pointbuffer.size() >= MAXPTS ) // overflow
1006  {
1007  wxASSERT( 0 );
1008  break;
1009  }
1010  }
1011 
1012  // ensure we have found an even intersection points count
1013  // because intersections are the ends of segments
1014  // inside the polygon(s) and a segment has 2 ends.
1015  // if not, this is a strange case (a bug ?) so skip this hatch
1016  if( pointbuffer.size() % 2 != 0 )
1017  continue;
1018 
1019  // sort points in order of descending x (if more than 2) to
1020  // ensure the starting point and the ending point of the same segment
1021  // are stored one just after the other.
1022  if( pointbuffer.size() > 2 )
1023  sort( pointbuffer.begin(), pointbuffer.end(), sortEndsByDescendingX );
1024 
1025  // creates lines or short segments inside the complex polygon
1026  for( unsigned ip = 0; ip < pointbuffer.size(); ip += 2 )
1027  {
1028  int dx = pointbuffer[ip + 1].x - pointbuffer[ip].x;
1029 
1030  // Push only one line for diagonal hatch,
1031  // or for small lines < twice the line length
1032  // else push 2 small lines
1034  || std::abs( dx ) < 2 * hatch_line_len )
1035  {
1036  m_HatchLines.emplace_back( SEG( pointbuffer[ip], pointbuffer[ip + 1] ) );
1037  }
1038  else
1039  {
1040  double dy = pointbuffer[ip + 1].y - pointbuffer[ip].y;
1041  slope = dy / dx;
1042 
1043  if( dx > 0 )
1044  dx = hatch_line_len;
1045  else
1046  dx = -hatch_line_len;
1047 
1048  int x1 = KiROUND( pointbuffer[ip].x + dx );
1049  int x2 = KiROUND( pointbuffer[ip + 1].x - dx );
1050  int y1 = KiROUND( pointbuffer[ip].y + dx * slope );
1051  int y2 = KiROUND( pointbuffer[ip + 1].y - dx * slope );
1052 
1053  m_HatchLines.emplace_back( SEG( pointbuffer[ip].x, pointbuffer[ip].y, x1, y1 ) );
1054 
1055  m_HatchLines.emplace_back( SEG( pointbuffer[ip+1].x, pointbuffer[ip+1].y, x2, y2 ) );
1056  }
1057  }
1058  }
1059 }
1060 
1061 
1063 {
1064  return Mils2iu( 20 );
1065 }
1066 
1067 
1069 {
1070  return add_zone_xpm;
1071 }
1072 
1073 
1075 {
1076  assert( aImage->Type() == PCB_ZONE_AREA_T );
1077 
1078  std::swap( *((ZONE_CONTAINER*) this), *((ZONE_CONTAINER*) aImage) );
1079 }
1080 
1081 
1083 {
1085 }
1086 
1087 
1088 /*
1089  * Some intersecting zones, despite being on the same layer with the same net, cannot be
1090  * merged due to other parameters such as fillet radius. The copper pour will end up
1091  * effectively merged though, so we want to keep the corners of such intersections sharp.
1092  */
1093 void ZONE_CONTAINER::GetColinearCorners( BOARD* aBoard, std::set<VECTOR2I>& aCorners )
1094 {
1095  int epsilon = Millimeter2iu( 0.001 );
1096 
1097  // Things get messy when zone of different nets intersect. To do it right we'd need to
1098  // run our colinear test with the final filled regions rather than the outline regions.
1099  // However, since there's no order dependance the only way to do that is to iterate
1100  // through successive zone fills until the results are no longer changing -- and that's
1101  // not going to happen. So we punt and ignore any "messy" corners.
1102  std::set<VECTOR2I> colinearCorners;
1103  std::set<VECTOR2I> messyCorners;
1104 
1105  for( ZONE_CONTAINER* candidate : aBoard->Zones() )
1106  {
1107  if( candidate == this )
1108  continue;
1109 
1110  if( candidate->GetLayerSet() != GetLayerSet() )
1111  continue;
1112 
1113  if( candidate->GetIsKeepout() != GetIsKeepout() )
1114  continue;
1115 
1116  for( auto iter = m_Poly->CIterate(); iter; iter++ )
1117  {
1118  if( candidate->m_Poly->Collide( iter.Get(), epsilon ) )
1119  {
1120  if( candidate->GetNetCode() == GetNetCode() )
1121  colinearCorners.insert( VECTOR2I( iter.Get() ) );
1122  else
1123  messyCorners.insert( VECTOR2I( iter.Get() ) );
1124  }
1125  }
1126  }
1127 
1128  for( VECTOR2I corner : colinearCorners )
1129  {
1130  if( messyCorners.count( corner ) == 0 )
1131  aCorners.insert( corner );
1132  }
1133 }
1134 
1135 
1137  std::set<VECTOR2I>* aPreserveCorners ) const
1138 {
1139  if( GetNumCorners() <= 2 ) // malformed zone. polygon calculations do not like it ...
1140  return false;
1141 
1142  // Make a smoothed polygon out of the user-drawn polygon if required
1143  switch( m_cornerSmoothingType )
1144  {
1146  aSmoothedPoly = m_Poly->Chamfer( m_cornerRadius, aPreserveCorners );
1147  break;
1148 
1150  {
1151  auto board = GetBoard();
1152  int maxError = ARC_HIGH_DEF;
1153 
1154  if( board )
1155  maxError = board->GetDesignSettings().m_MaxError;
1156 
1157  aSmoothedPoly = m_Poly->Fillet( m_cornerRadius, maxError, aPreserveCorners );
1158  break;
1159  }
1160  default:
1161  // Acute angles between adjacent edges can create issues in calculations,
1162  // in inflate/deflate outlines transforms, especially when the angle is very small.
1163  // We can avoid issues by creating a very small chamfer which remove acute angles,
1164  // or left it without chamfer and use only CPOLYGONS_LIST::InflateOutline to create
1165  // clearance areas
1166  aSmoothedPoly = m_Poly->Chamfer( Millimeter2iu( 0.0 ), aPreserveCorners );
1167  break;
1168  }
1169 
1170  return true;
1171 };
1172 
1173 
1175 {
1176  m_area = 0.0;
1177 
1178  // Iterate over each outline polygon in the zone and then iterate over
1179  // each hole it has to compute the total area.
1180  for( int i = 0; i < m_FilledPolysList.OutlineCount(); i++ )
1181  {
1183 
1184  for( int j = 0; j < m_FilledPolysList.HoleCount( i ); j++ )
1185  {
1186  m_area -= m_FilledPolysList.Hole( i, j ).Area();
1187  }
1188  }
1189 
1190  return m_area;
1191 }
1192 
1193 
1194 /* Function TransformOutlinesShapeWithClearanceToPolygon
1195  * Convert the zone filled areas polygons to polygons
1196  * inflated (optional) by max( aClearanceValue, the zone clearance)
1197  * and copy them in aCornerBuffer
1198  * @param aClearance the clearance around outlines
1199  * @param aPreserveCorners an optional set of corners which should not be chamfered/filleted
1200  */
1202  int aClearance, std::set<VECTOR2I>* aPreserveCorners ) const
1203 {
1204  // Creates the zone outline polygon (with holes if any)
1205  SHAPE_POLY_SET polybuffer;
1206  BuildSmoothedPoly( polybuffer, aPreserveCorners );
1207 
1208  // Calculate the polygon with clearance
1209  // holes are linked to the main outline, so only one polygon is created.
1210  if( aClearance )
1211  {
1212  BOARD* board = GetBoard();
1213  int maxError = ARC_HIGH_DEF;
1214 
1215  if( board )
1216  maxError = board->GetDesignSettings().m_MaxError;
1217 
1218  int segCount = std::max( GetArcToSegmentCount( aClearance, maxError, 360.0 ), 3 );
1219  polybuffer.Inflate( aClearance, segCount );
1220  }
1221 
1222  polybuffer.Fracture( SHAPE_POLY_SET::PM_FAST );
1223  aCornerBuffer.Append( polybuffer );
1224 }
1225 
1226 //
1227 /********* MODULE_ZONE_CONTAINER **************/
1228 //
1230  ZONE_CONTAINER( aParent, true )
1231 {
1232  // in a footprint, net classes are not managed.
1233  // so set the net to NETINFO_LIST::ORPHANED_ITEM
1234  SetNetCode( -1, true );
1235 }
1236 
1237 
1239  : ZONE_CONTAINER( aZone.GetParent(), true )
1240 {
1241  initDataFromSrcInCopyCtor( aZone );
1242 }
1243 
1244 
1246 {
1247  ZONE_CONTAINER::operator=( aOther );
1248  return *this;
1249 }
1250 
1251 
1253 {
1254  return new MODULE_ZONE_CONTAINER( *this );
1255 }
1256 
1257 
1258 unsigned int MODULE_ZONE_CONTAINER::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
1259 {
1260  const int HIDE = std::numeric_limits<unsigned int>::max();
1261 
1262  if( !aView )
1263  return 0;
1264 
1265  bool flipped = GetParent() && GetParent()->GetLayer() == B_Cu;
1266 
1267  // Handle Render tab switches
1268  if( !flipped && !aView->IsLayerVisible( LAYER_MOD_FR ) )
1269  return HIDE;
1270 
1271  if( flipped && !aView->IsLayerVisible( LAYER_MOD_BK ) )
1272  return HIDE;
1273 
1274  // Other layers are shown without any conditions
1275  return 0;
1276 }
Definition: colors.h:57
void SetDoNotAllowTracks(bool aEnable)
Definition: class_zone.h:680
int TotalVertices() const
Returns total number of vertices stored in the set.
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:712
void MoveEdge(const wxPoint &offset, int aEdge)
Function MoveEdge Move the outline Edge.
Definition: class_zone.cpp:695
EDA_UNITS
Definition: common.h:196
void Rotate(double aAngle, const VECTOR2I &aCenter={ 0, 0 })
Function Rotate rotates all vertices by a given angle.
ZONE_CONNECTION
How pads are covered by copper in zone.
Definition: zones.h:41
void SetHatchPitch(int aPitch)
Function SetHatchPitch sets the hatch pitch parameter for the zone.
Definition: class_zone.cpp:879
bool GetDoNotAllowPads() const
Definition: class_zone.h:665
ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
void SetHatch(ZONE_HATCH_STYLE aHatchStyle, int aHatchPitch, bool aRebuildHatch)
Function SetHatch sets all hatch parameters for the zone.
Definition: class_zone.cpp:869
virtual void SwapData(BOARD_ITEM *aImage) override
Swap data between aItem and aImage.
int m_ZoneClearance
Clearance value in internal units.
Definition: class_zone.h:789
void Mirror(const wxPoint &aMirrorRef, bool aMirrorLeftRight)
Function Mirror Mirror the outlines , relative to a given horizontal axis the layer is not changed.
Definition: class_zone.cpp:746
#define DISALLOW_TRACKS
Definition: drc_rule.h:44
#define DISALLOW_TEXTS
Definition: drc_rule.h:47
LSET FlipLayerMask(LSET aMask, int aCopperLayersCount)
Calculate the mask layer when flipping a footprint BACK and FRONT copper layers, mask,...
Definition: lset.cpp:531
int GetNetCode() const
Function GetNetCode.
int OutlineCount() const
Returns the number of outlines in the set
PNG memory record (file in memory).
Definition: bitmap_def.h:29
bool m_doNotAllowPads
Definition: class_zone.h:785
bool CommonLayerExists(const LSET aLayerSet) const
Function CommonLayerExist Test if this zone shares a common layer with the given layer set.
Definition: class_zone.cpp:238
int GetThermalReliefCopperBridge(D_PAD *aPad=NULL) const
Definition: class_zone.cpp:344
SEGMENT_ITERATOR IterateSegmentsWithHoles()
Returns an iterator object, for all outlines in the set (with holes)
void BooleanAdd(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset union For aFastMode meaning, see function booleanOp
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
Definition: class_zone.cpp:195
bool CollideEdge(const VECTOR2I &aPoint, VERTEX_INDEX &aClosestVertex, int aClearance=0)
Function CollideEdge Checks whether aPoint collides with any edge of any of the contours of the polyg...
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
bool m_doNotAllowTracks
Definition: class_zone.h:784
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox (virtual)
Definition: class_zone.cpp:325
NETINFO_ITEM * GetNet() const
Function GetNet Returns NET_INFO object for a given item.
wxString m_Name
Definition: drc_rule.h:73
const wxString & GetName() const
Definition: netclass.h:96
void SetCornerRadius(unsigned int aRadius)
Definition: class_zone.cpp:429
SHAPE_POLY_SET::VERTEX_INDEX * m_CornerSelection
The index of the corner being moved or nullptr if no corner is selected.
Definition: class_zone.h:833
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Returns the index-th vertex in a given hole outline within a given outline
virtual bool IsOnLayer(PCB_LAYER_ID) const override
Function IsOnLayer tests to see if this object is on the given layer.
Definition: class_zone.cpp:316
NETCLASS * GetNetClass() const
Function GetNetClassPtr returns the NETCLASS for this item.
void SetDoNotAllowFootprints(bool aEnable)
Definition: class_zone.h:682
bool HitTestForCorner(const wxPoint &refPos, int aAccuracy, SHAPE_POLY_SET::VERTEX_INDEX &aCornerHit) const
Function HitTestForCorner tests if the given wxPoint is near a corner.
Definition: class_zone.cpp:463
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Function FlippedLayerNumber.
Definition: lset.cpp:485
bool IsEmpty() const
Returns true if the set is empty (no polygons at all)
class ZONE_CONTAINER, a zone area
Definition: typeinfo.h:102
ZONE_CONTAINER(BOARD_ITEM_CONTAINER *parent, bool aInModule=false)
The ctor to build ZONE_CONTAINER, but comaptible with MODULE_ZONE_CONTAINER requirement.
Definition: class_zone.cpp:49
virtual PCB_LAYER_ID GetLayer() const override
Function GetLayer returns the primary layer this item is on.
Definition: class_zone.cpp:219
Struct VERTEX_INDEX.
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Returns the reference to aHole-th hole in the aIndex-th outline
bool HitTestFilledArea(const wxPoint &aRefPos) const
Function HitTestFilledArea tests if the given wxPoint is within the bounds of a filled area of this z...
Definition: class_zone.cpp:549
void SetHatchStyle(ZONE_HATCH_STYLE aStyle)
Definition: class_zone.h:547
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:542
#define DISALLOW_MICRO_VIAS
Definition: drc_rule.h:42
MODULE_ZONE_CONTAINER(BOARD_ITEM_CONTAINER *aParent)
static wxString LayerMaskDescribe(const BOARD *aBoard, LSET aMask)
Helper function Return a string (to be shown to the user) describing a layer mask.
bool Contains(const VECTOR2I &aP, int aSubpolyIndex=-1, int aAccuracy=0, bool aUseBBoxCaches=false) const
Returns true if a given subpolygon contains the point aP.
ZONE_SEGMENT_FILL m_FillSegmList
Segments used to fill the zone (m_FillMode ==1 ), when fill zone by segment is used.
Definition: class_zone.h:841
void RemoveCutout(int aOutlineIdx, int aHoleIdx)
Remove a cutout from the zone.
Definition: class_zone.cpp:780
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
void Inflate(int aAmount, int aCircleSegmentsCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
Performs outline inflation/deflation.
int GetThermalReliefGap(D_PAD *aPad=NULL) const
Definition: class_zone.cpp:335
#define DISALLOW_HOLES
Definition: drc_rule.h:49
int m_DisallowFlags
Definition: drc_rule.h:75
The base class for create windows for drawing purpose.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
#define DISALLOW_PADS
Definition: drc_rule.h:45
int GetThermalGap() const
Definition: class_pad.cpp:760
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Function Seq returns an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:377
const wxPoint GetPosition() const override
Definition: class_zone.cpp:213
BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected and have...
bool Contains(const wxPoint &aPoint) const
Function Contains.
static int GetDefaultHatchPitch()
Function GetDefaultHatchPitchMils.
struct SHAPE_POLY_SET::VERTEX_INDEX VERTEX_INDEX
Struct VERTEX_INDEX.
bool m_doNotAllowFootprints
Definition: class_zone.h:786
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirrors the line points about y or x (or both)
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
void SetDoNotAllowVias(bool aEnable)
Definition: class_zone.h:679
This file contains miscellaneous commonly used macros and functions.
bool GetDoNotAllowVias() const
Definition: class_zone.h:663
Classes used in Pcbnew, CvPcb and GerbView.
ZONE_CONNECTION m_PadConnection
Definition: class_zone.h:788
show modules on front
bool GetNeighbourIndexes(int aGlobalIndex, int *aPrevious, int *aNext)
Returns the global indexes of the previous and the next corner of the aGlobalIndex-th corner of a con...
virtual LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
Definition: class_zone.cpp:283
void SetVertex(const VERTEX_INDEX &aIndex, const VECTOR2I &aPos)
Function SetVertex Accessor function to set the position of a specific point.
PCB_LAYER_ID m_Layer
void SetLayerSet(LSET aLayerSet)
Definition: class_zone.cpp:254
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:175
void GetColinearCorners(BOARD *aBoard, std::set< VECTOR2I > &colinearCorners)
Some intersecting zones, despite being on the same layer with the same net, cannot be merged due to o...
#define MAXPTS
void SetClosed(bool aClosed)
Function SetClosed()
#define DISALLOW_GRAPHICS
Definition: drc_rule.h:48
bool sortEndsByDescendingX(const VECTOR2I &ref, const VECTOR2I &tst)
Definition: class_zone.cpp:893
int m_HatchFillTypeSmoothingLevel
Grid pattern smoothing type, similar to corner smoothing type 0 = no smoothing, 1 = fillet,...
Definition: class_zone.h:826
PCB_LAYER_ID
A quick note on layer IDs:
DRC_RULE * GetRule(const BOARD_ITEM *aItem, const BOARD_ITEM *bItem, int aConstraint)
Definition: drc_rule.cpp:67
LSET is a set of PCB_LAYER_IDs.
int m_ThermalReliefCopperBridge
Definition: class_zone.h:806
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Function IsOnLayer tests to see if this object is on the given layer.
std::vector< SEG > m_HatchLines
Definition: class_zone.h:858
#define NULL
void Move(const VECTOR2I &aVector) override
ZONE_CONTAINER & operator=(const ZONE_CONTAINER &aOther)
Definition: class_zone.cpp:90
unsigned int ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Function ViewGetLOD() Returns the level of detail (LOD) of the item.
ITERATOR IterateWithHoles(int aOutline)
Function IterateWithHoles.
SHAPE_POLY_SET.
double m_HatchFillTypeOrientation
Grid style shape: orientation in degrees of the grid lines.
Definition: class_zone.h:822
SHAPE_LINE_CHAIN & Outline(int aIndex)
Returns the reference to aIndex-th outline in the set
#define DISALLOW_CONSTRAINT
Definition: drc_rule.h:39
bool BuildSmoothedPoly(SHAPE_POLY_SET &aSmoothedPoly, std::set< VECTOR2I > *aPreserveCorners) const
Function GetSmoothedPoly returns a pointer to the corner-smoothed version of m_Poly.
bool m_IsFilled
True when a zone was filled, false after deleting the filled areas.
Definition: class_zone.h:794
ZONE_CONNECTION GetZoneConnection() const
Definition: class_pad.cpp:738
int GetThermalWidth() const
Definition: class_pad.cpp:749
ZONE_HATCH_STYLE m_hatchStyle
Definition: class_zone.h:856
NETCLASS handles a collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:55
SHAPE_POLY_SET * m_Poly
Outline of the zone.
Definition: class_zone.h:762
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Function HitTest tests if a point is near an outline edge or a corner of this zone.
Definition: class_zone.cpp:438
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
bool GetDoNotAllowCopperPour() const
Definition: class_zone.h:662
unsigned m_priority
Definition: class_zone.h:772
#define DISALLOW_FOOTPRINTS
Definition: drc_rule.h:50
void Rotate(const wxPoint &centre, double angle) override
Function Rotate Move the outlines.
Definition: class_zone.cpp:710
bool m_doNotAllowVias
Definition: class_zone.h:783
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Function SetLayer sets the layer this item is on.
Definition: class_zone.cpp:246
bool CollideVertex(const VECTOR2I &aPoint, VERTEX_INDEX &aClosestVertex, int aClearance=0)
Function CollideVertex Checks whether aPoint collides with any vertex of any of the contours of the p...
bool UnFill()
Function UnFill Removes the zone filling.
Definition: class_zone.cpp:201
const wxString & GetNetname() const
Function GetNetname.
Definition: netinfo.h:231
int m_cornerSmoothingType
Definition: class_zone.h:763
int GetNumCorners(void) const
Access to m_Poly parameters.
Definition: class_zone.h:454
void CacheTriangulation()
(re)create a list of triangles that "fill" the solid areas.
void TransformOutlinesShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aMinClearanceValue, std::set< VECTOR2I > *aPreserveCorners=nullptr) const
Function TransformOutlinesShapeWithClearanceToPolygon Convert the outlines shape to a polygon with no...
bool SetNetCode(int aNetCode, bool aNoAssert=false)
Sets net using a net code.
double m_HatchFillTypeSmoothingValue
Grid pattern smoothing value for smoothing shape size calculations this is the ratio between the gap ...
Definition: class_zone.h:830
a few functions useful in geometry calculations.
Definition: colors.h:60
int GetLocalClearance(wxString *aSource=nullptr) const override
Function GetLocalClearance returns any local clearances set in the "classic" (ie: pre-rule) system.
Definition: class_zone.cpp:537
virtual void ViewGetLayers(int aLayers[], int &aCount) const override
Function ViewGetLayers() Returns the all the layers within the VIEW the object is painted on.
Definition: class_zone.cpp:297
ZONE_CONNECTION GetPadConnection(D_PAD *aPad=NULL) const
Definition: class_zone.cpp:771
void ExportSetting(ZONE_CONTAINER &aTarget, bool aFullExport=true) const
Function ExportSetting copy settings to a given zone.
void SetDoNotAllowPads(bool aEnable)
Definition: class_zone.h:681
int NewOutline()
Creates a new empty polygon in the set and returns its index
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
int HoleCount(int aOutline) const
Returns the number of holes in a given outline
CONST_ITERATOR CIterate(int aFirst, int aLast, bool aIterateHoles=false) const
ZONE_HATCH_STYLE GetHatchStyle() const
Definition: class_zone.h:542
void AddPolygon(std::vector< wxPoint > &aPolygon)
add a polygon to the zone outline if the zone outline is empty, this is the main outline else it is a...
Definition: class_zone.cpp:809
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Operator assignment is used to assign the members of aItem to another object.
SHAPE_POLY_SET m_FilledPolysList
Definition: class_zone.h:851
void Fracture(POLYGON_MODE aFastMode)
Converts a set of polygons with holes to a singe outline with "slits"/"fractures" connecting the oute...
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Adds a new hole to the given outline (default: last) and returns its index
void SetSelectedCorner(int aCorner)
Definition: class_zone.h:226
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
bool GetIsKeepout() const
Accessors to parameters used in Keepout zones:
Definition: class_zone.h:661
unsigned int m_cornerRadius
Definition: class_zone.h:764
#define DISALLOW_VIAS
Definition: drc_rule.h:41
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
bool NeedRefill() const
Definition: class_zone.h:178
wxString GetNetnameMsg() const
Function GetNetnameMsg.
double Area() const
void Move(const wxPoint &offset) override
Function Move Move the outlines.
Definition: class_zone.cpp:678
int GetKeepouts(std::map< int, wxString > *aSources=nullptr) const
Return a bitset of flags for keepouts.
Definition: class_zone.cpp:353
virtual int GetClearance(BOARD_ITEM *aItem=nullptr, wxString *aSource=nullptr) const
Function GetClearance returns the clearance in internal units.
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
Definition: class_zone.cpp:846
SHAPE_POLY_SET Fillet(int aRadius, int aErrorMax, std::set< VECTOR2I > *aPreserveCorners=nullptr)
Function Fillet returns a filleted version of the polygon set.
Definition: seg.h:39
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index
void Normalize()
Function Normalize ensures that the height ant width are positive.
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aUseMils, EDA_DATA_TYPE aType)
Definition: base_units.cpp:124
void AccumulateDescription(wxString &aDesc, const wxString &aItem)
Utility to build comma separated lists in messages.
Definition: macros.h:126
void SetDoNotAllowCopperPour(bool aEnable)
Definition: class_zone.h:678
const ZONE_SETTINGS & GetZoneSettings() const
Fetch the zone settings for this container.
NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:65
bool m_doNotAllowCopperPour
Definition: class_zone.h:782
double CalculateFilledArea()
Compute the area currently occupied by the zone fill.
int m_ThermalReliefGap
Width of the copper bridge in thermal reliefs.
Definition: class_zone.h:803
int m_ZoneMinThickness
Minimum thickness value in filled areas.
Definition: class_zone.h:790
ZONE_CONTAINERS & Zones()
Definition: class_board.h:270
ZONE_FILL_MODE m_FillMode
How to fill areas: ZONE_FILL_MODE::POLYGONS => use solid polygons ZONE_FILL_MODE::HATCH_PATTERN => us...
Definition: class_zone.h:813
unsigned GetPriority() const
Function GetPriority.
Definition: class_zone.h:100
see class PGM_BASE
MODULE_ZONE_CONTAINER & operator=(const MODULE_ZONE_CONTAINER &aOther)
void UnHatch()
Function UnHatch clears the zone's hatch.
Definition: class_zone.cpp:885
ZONE_HATCH_STYLE
Zone hatch styles.
Definition: zone_settings.h:45
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
int GetNet() const
Function GetNet.
Definition: netinfo.h:223
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:181
#define _(s)
Definition: 3d_actions.cpp:33
SHAPE_LINE_CHAIN.
int m_HatchFillTypeThickness
Grid style shape: thickness of lines (if 0 -> solid shape)
Definition: class_zone.h:816
NETINFO_ITEM * m_netinfo
Stores all informations about the net that item belongs to.
void initDataFromSrcInCopyCtor(const ZONE_CONTAINER &aZone)
Copy aZone data to me members are expected non initialize in this.
Definition: class_zone.cpp:134
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:131
bool HitTestCutout(const VECTOR2I &aRefPos, int *aOutlineIdx=nullptr, int *aHoleIdx=nullptr) const
Tests if the given point is contained within a cutout of the zone.
Definition: class_zone.cpp:555
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
STATUS_FLAGS m_Flags
Definition: base_struct.h:180
int GetCopperLayerCount() const
Function GetCopperLayerCount.
void RemoveAllContours()
Removes all outlines & holes (clears) the polygon set.
VECTOR2I A
Definition: seg.h:47
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
double DECIDEG2RAD(double deg)
Definition: trigo.h:218
SHAPE_POLY_SET Chamfer(int aDistance, std::set< VECTOR2I > *aPreserveCorners=nullptr)
Function Chamfer returns a chamfered version of the polygon set.
NETCLASS * GetDefault() const
Function GetDefault.
void Hatch()
Function Hatch computes the hatch lines depending on the hatch parameters and stores it in the zone's...
Definition: class_zone.cpp:899
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:61
int GetHatchPitch() const
Hatch related methods.
Definition: class_zone.cpp:863
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:163
void SetLocalFlags(int aFlags)
Definition: class_zone.h:247
MODULE_ZONE_CONTAINER is the same item as ZONE_CONTAINER, but with a specific type id ZONE_CONTAINER ...
Definition: class_zone.h:875
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
bool GetDoNotAllowTracks() const
Definition: class_zone.h:664
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
bool GetDoNotAllowFootprints() const
Definition: class_zone.h:666
const BITMAP_OPAQUE add_zone_xpm[1]
Definition: add_zone.cpp:74
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: class_zone.cpp:826
bool PointInside(const VECTOR2I &aPt, int aAccuracy=0, bool aUseBBoxCache=false) const
Function PointInside()
bool HitTestForEdge(const wxPoint &refPos, int aAccuracy, SHAPE_POLY_SET::VERTEX_INDEX &aCornerHit) const
Function HitTestForEdge tests if the given wxPoint is near a segment defined by 2 corners.
Definition: class_zone.cpp:477
bool m_needRefill
False when a zone was refilled, true after changes in zone params.
Definition: class_zone.h:800
Definition: colors.h:45
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
Definition: class_zone.cpp:580
bool IsClosed() const
Function IsClosed()
Abstract interface for BOARD_ITEMs capable of storing other items inside.
#define DISALLOW_BB_VIAS
Definition: drc_rule.h:43
class ZONE_CONTAINER, managed by a footprint
Definition: typeinfo.h:95
EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
int m_HatchFillTypeGap
Grid style shape: dist between center of lines (grid size) (0 -> solid shape)
Definition: class_zone.h:819
VIEW.
Definition: view.h:61
void SetIsKeepout(bool aEnable)
Definition: class_zone.h:677
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
Message panel definition file.
BOARD_ITEM_CONTAINER * GetParent() const
bool m_forceVisible
Definition: base_struct.h:179
#define DISALLOW_ZONES
Definition: drc_rule.h:46
wxString GetLayerName() const
Function GetLayerName returns the name of the PCB layer on which the item resides.
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
const BOX2I BBox(int aClearance=0) const override
Function BBox()
const VECTOR2I & GetCornerPosition(int aCornerIndex) const
Definition: class_zone.h:494
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)
virtual void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Function Flip Flip this object, i.e.
Definition: class_zone.cpp:734
bool IsOnCopperLayer() const override
Function IsOnCopperLayer.
Definition: class_zone.cpp:225
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
int GetLocalFlags() const
Definition: class_zone.h:246
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
bool m_FilledPolysUseThickness
outline of filled polygons have thickness.
Definition: class_zone.h:791
KICAD_T Type() const
Function Type()
Definition: base_struct.h:197
bool IsLayerVisible(int aLayer) const
Function IsLayerVisible() Returns information about visibility of a particular layer.
Definition: view.h:416
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
VECTOR2I B
Definition: seg.h:48
Definition: colors.h:62
void SetNeedRefill(bool aNeedRefill)
Definition: class_zone.h:179