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-2023 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 <pcb_edit_frame.h>
30#include <pcb_screen.h>
31#include <board.h>
33#include <pad.h>
34#include <zone.h>
35#include <string_utils.h>
36#include <math_for_graphics.h>
39#include <trigo.h>
40#include <i18n_utility.h>
41
42
43ZONE::ZONE( BOARD_ITEM_CONTAINER* aParent, bool aInFP ) :
44 BOARD_CONNECTED_ITEM( aParent, aInFP ? PCB_FP_ZONE_T : PCB_ZONE_T ),
45 m_area( 0.0 ),
46 m_outlinearea( 0.0 )
47{
48 m_Poly = new SHAPE_POLY_SET(); // Outlines
51 m_zoneName = wxEmptyString;
52 m_CornerSelection = nullptr; // no corner is selected
53 m_isFilled = false; // fill status : true when the zone is filled
58 m_priority = 0;
59 SetIsRuleArea( aInFP ); // Zones living in footprints have the rule area option
60 SetLocalFlags( 0 ); // flags temporary used in zone calculations
61 m_fillVersion = 5; // set the "old" way to build filled polygon areas (< 6.0.x)
62
66
67 aParent->GetZoneSettings().ExportSetting( *this );
68
69 m_needRefill = false; // True only after edits.
70}
71
72
73ZONE::ZONE( const ZONE& aZone ) :
74 BOARD_CONNECTED_ITEM( aZone ),
75 m_Poly( nullptr ),
76 m_CornerSelection( nullptr )
77{
79}
80
81
82ZONE& ZONE::operator=( const ZONE& aOther )
83{
85
87
88 return *this;
89}
90
91
93{
94 delete m_Poly;
95 delete m_CornerSelection;
96
97 if( BOARD* board = GetBoard() )
98 board->IncrementTimeStamp();
99}
100
101
103{
104 // members are expected non initialize in this.
105 // InitDataFromSrcInCopyCtor() is expected to be called only from a copy constructor.
106
107 // Copy only useful EDA_ITEM flags:
108 m_flags = aZone.m_flags;
110
111 // Replace the outlines for aZone outlines.
112 delete m_Poly;
113 m_Poly = new SHAPE_POLY_SET( *aZone.m_Poly );
114
117 m_zoneName = aZone.m_zoneName;
118 m_priority = aZone.m_priority;
120 SetLayerSet( aZone.GetLayerSet() );
121
127
129 m_ZoneClearance = aZone.m_ZoneClearance; // clearance value
134
135 m_isFilled = aZone.m_isFilled;
138
141
142 m_fillMode = aZone.m_fillMode; // solid vs. hatched
144 m_hatchGap = aZone.m_hatchGap;
150
151 // For corner moving, corner index to drag, or nullptr if no selection
152 delete m_CornerSelection;
153 m_CornerSelection = nullptr;
154
155 for( PCB_LAYER_ID layer : aZone.GetLayerSet().Seq() )
156 {
157 std::shared_ptr<SHAPE_POLY_SET> fill = aZone.m_FilledPolysList.at( layer );
158
159 if( fill )
160 m_FilledPolysList[layer] = std::make_shared<SHAPE_POLY_SET>( *fill );
161 else
162 m_FilledPolysList[layer] = std::make_shared<SHAPE_POLY_SET>();
163
164 m_filledPolysHash[layer] = aZone.m_filledPolysHash.at( layer );
165 m_insulatedIslands[layer] = aZone.m_insulatedIslands.at( layer );
166 }
167
171
172 SetLocalFlags( aZone.GetLocalFlags() );
173
174 m_netinfo = aZone.m_netinfo;
175 m_area = aZone.m_area;
177}
178
179
181{
182 return new ZONE( *this );
183}
184
185
186bool ZONE::HigherPriority( const ZONE* aOther ) const
187{
188 // Teardrops are always higher priority than regular zones, so if one zone is a teardrop
189 // and the other is not, then return higher priority as the teardrop
191 ^ ( aOther->m_teardropType == TEARDROP_TYPE::TD_NONE ) )
192 {
193 return static_cast<int>( m_teardropType ) > static_cast<int>( aOther->m_teardropType );
194 }
195
196 if( m_priority != aOther->m_priority )
197 return m_priority > aOther->m_priority;
198
199 return m_Uuid > aOther->m_Uuid;
200}
201
202
203bool ZONE::SameNet( const ZONE* aOther ) const
204{
205 return GetNetCode() == aOther->GetNetCode();
206}
207
208
210{
211 bool change = false;
212
213 for( std::pair<const PCB_LAYER_ID, std::shared_ptr<SHAPE_POLY_SET>>& pair : m_FilledPolysList )
214 {
215 change |= !pair.second->IsEmpty();
216 m_insulatedIslands[pair.first].clear();
217 pair.second->RemoveAllContours();
218 }
219
220 m_isFilled = false;
221 m_fillFlags.reset();
222
223 return change;
224}
225
226
228{
229 return HasFlag( COURTYARD_CONFLICT );
230}
231
232
234{
235 return GetCornerPosition( 0 );
236}
237
238
240{
241 return BOARD_ITEM::GetLayer();
242}
243
244
246{
247 if( m_layerSet.size() )
248 return m_layerSet.UIOrder()[0];
249 else
250 return UNDEFINED_LAYER;
251}
252
253
255{
256 return ( m_layerSet & LSET::AllCuMask() ).count() > 0;
257}
258
259
261{
262 SetLayerSet( LSET( aLayer ) );
263}
264
265
266void ZONE::SetLayerSet( LSET aLayerSet )
267{
268 if( aLayerSet.count() == 0 )
269 return;
270
271 if( m_layerSet != aLayerSet )
272 {
273 SetNeedRefill( true );
274
275 UnFill();
276
277 m_FilledPolysList.clear();
278 m_filledPolysHash.clear();
279 m_insulatedIslands.clear();
280
281 for( PCB_LAYER_ID layer : aLayerSet.Seq() )
282 {
283 m_FilledPolysList[layer] = std::make_shared<SHAPE_POLY_SET>();
284 m_filledPolysHash[layer] = {};
285 m_insulatedIslands[layer] = {};
286 }
287 }
288
289 m_layerSet = aLayerSet;
290}
291
292
293void ZONE::ViewGetLayers( int aLayers[], int& aCount ) const
294{
295 aCount = 0;
296 LSEQ layers = m_layerSet.Seq();
297
298 for( PCB_LAYER_ID layer : m_layerSet.Seq() )
299 {
300 aLayers[ aCount++ ] = layer; // For outline (always full opacity)
301 aLayers[ aCount++ ] = layer + LAYER_ZONE_START; // For fill (obeys global zone opacity)
302 }
303
304 if( IsConflicting() )
305 aLayers[ aCount++ ] = LAYER_CONFLICTS_SHADOW;
306}
307
308
309double ZONE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
310{
311 constexpr double HIDE = std::numeric_limits<double>::max();
312
313 return aView->IsLayerVisible( LAYER_ZONES ) ? 0.0 : HIDE;
314}
315
316
317bool ZONE::IsOnLayer( PCB_LAYER_ID aLayer ) const
318{
319 return m_layerSet.test( aLayer );
320}
321
322
324{
325 if( const BOARD* board = GetBoard() )
326 {
327 std::unordered_map<const ZONE*, BOX2I>& cache = board->m_ZoneBBoxCache;
328 auto cacheIter = cache.find( this );
329
330 if( cacheIter != cache.end() )
331 return cacheIter->second;
332
333 BOX2I bbox = m_Poly->BBox();
334
335 std::unique_lock<std::mutex> cacheLock( const_cast<BOARD*>( board )->m_CachesMutex );
336 cache[ this ] = bbox;
337
338 return bbox;
339 }
340
341 return m_Poly->BBox();
342}
343
344
346{
347 BOARD* board = GetBoard();
348 std::unordered_map<const ZONE*, BOX2I>& cache = board->m_ZoneBBoxCache;
349
350 auto cacheIter = cache.find( this );
351
352 if( cacheIter == cache.end() )
353 {
354 std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
355 cache[ this ] = m_Poly->BBox();
356 }
357}
358
359
360int ZONE::GetThermalReliefGap( PAD* aPad, wxString* aSource ) const
361{
362 if( aPad->GetLocalThermalGapOverride() == 0 )
363 {
364 if( aSource )
365 *aSource = _( "zone" );
366
367 return m_thermalReliefGap;
368 }
369
370 return aPad->GetLocalThermalGapOverride( aSource );
371
372}
373
374
375void ZONE::SetCornerRadius( unsigned int aRadius )
376{
377 if( m_cornerRadius != aRadius )
378 SetNeedRefill( true );
379
380 m_cornerRadius = aRadius;
381}
382
383
385
386
388{
389 if( !m_filledPolysHash.count( aLayer ) )
390 return g_nullPoly.GetHash();
391 else
392 return m_filledPolysHash.at( aLayer );
393}
394
395
397{
398 if( !m_FilledPolysList.count( aLayer ) )
400 else
401 m_filledPolysHash[aLayer] = m_FilledPolysList.at( aLayer )->GetHash();
402}
403
404
405bool ZONE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
406{
407 // When looking for an "exact" hit aAccuracy will be 0 which works poorly for very thin
408 // lines. Give it a floor.
409 int accuracy = std::max( aAccuracy, pcbIUScale.mmToIU( 0.1 ) );
410
411 return HitTestForCorner( aPosition, accuracy * 2 ) || HitTestForEdge( aPosition, accuracy );
412}
413
414
415bool ZONE::HitTestForCorner( const VECTOR2I& refPos, int aAccuracy,
416 SHAPE_POLY_SET::VERTEX_INDEX* aCornerHit ) const
417{
418 return m_Poly->CollideVertex( VECTOR2I( refPos ), aCornerHit, aAccuracy );
419}
420
421
422bool ZONE::HitTestForEdge( const VECTOR2I& refPos, int aAccuracy,
423 SHAPE_POLY_SET::VERTEX_INDEX* aCornerHit ) const
424{
425 return m_Poly->CollideEdge( VECTOR2I( refPos ), aCornerHit, aAccuracy );
426}
427
428
429bool ZONE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
430{
431 // Calculate bounding box for zone
432 BOX2I bbox = GetBoundingBox();
433 bbox.Normalize();
434
435 BOX2I arect = aRect;
436 arect.Normalize();
437 arect.Inflate( aAccuracy );
438
439 if( aContained )
440 {
441 return arect.Contains( bbox );
442 }
443 else
444 {
445 // Fast test: if aBox is outside the polygon bounding box, rectangles cannot intersect
446 if( !arect.Intersects( bbox ) )
447 return false;
448
449 int count = m_Poly->TotalVertices();
450
451 for( int ii = 0; ii < count; ii++ )
452 {
453 VECTOR2I vertex = m_Poly->CVertex( ii );
454 VECTOR2I vertexNext = m_Poly->CVertex( ( ii + 1 ) % count );
455
456 // Test if the point is within the rect
457 if( arect.Contains( vertex ) )
458 return true;
459
460 // Test if this edge intersects the rect
461 if( arect.Intersects( vertex, vertexNext ) )
462 return true;
463 }
464
465 return false;
466 }
467}
468
469
470int ZONE::GetLocalClearance( wxString* aSource ) const
471{
472 if( m_isRuleArea )
473 return 0;
474
475 if( aSource )
476 *aSource = _( "zone" );
477
478 return m_ZoneClearance;
479}
480
481
482bool ZONE::HitTestFilledArea( PCB_LAYER_ID aLayer, const VECTOR2I& aRefPos, int aAccuracy ) const
483{
484 // Rule areas have no filled area, but it's generally nice to treat their interior as if it were
485 // filled so that people don't have to select them by their outline (which is min-width)
486 if( GetIsRuleArea() )
487 return m_Poly->Contains( aRefPos, -1, aAccuracy );
488
489 if( !m_FilledPolysList.count( aLayer ) )
490 return false;
491
492 return m_FilledPolysList.at( aLayer )->Contains( aRefPos, -1, aAccuracy );
493}
494
495
496bool ZONE::HitTestCutout( const VECTOR2I& aRefPos, int* aOutlineIdx, int* aHoleIdx ) const
497{
498 // Iterate over each outline polygon in the zone and then iterate over
499 // each hole it has to see if the point is in it.
500 for( int i = 0; i < m_Poly->OutlineCount(); i++ )
501 {
502 for( int j = 0; j < m_Poly->HoleCount( i ); j++ )
503 {
504 if( m_Poly->Hole( i, j ).PointInside( aRefPos ) )
505 {
506 if( aOutlineIdx )
507 *aOutlineIdx = i;
508
509 if( aHoleIdx )
510 *aHoleIdx = j;
511
512 return true;
513 }
514 }
515 }
516
517 return false;
518}
519
520
521void ZONE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
522{
523 wxString msg = GetFriendlyName();
524
525 // Display Cutout instead of Outline for holes inside a zone (i.e. when num contour !=0).
526 // Check whether the selected corner is in a hole; i.e., in any contour but the first one.
527 if( m_CornerSelection != nullptr && m_CornerSelection->m_contour > 0 )
528 msg << wxT( " " ) << _( "Cutout" );
529
530 aList.emplace_back( _( "Type" ), msg );
531
532 if( GetIsRuleArea() )
533 {
534 msg.Empty();
535
536 if( GetDoNotAllowVias() )
537 AccumulateDescription( msg, _( "No vias" ) );
538
539 if( GetDoNotAllowTracks() )
540 AccumulateDescription( msg, _( "No tracks" ) );
541
542 if( GetDoNotAllowPads() )
543 AccumulateDescription( msg, _( "No pads" ) );
544
546 AccumulateDescription( msg, _( "No copper zones" ) );
547
549 AccumulateDescription( msg, _( "No footprints" ) );
550
551 if( !msg.IsEmpty() )
552 aList.emplace_back( _( "Restrictions" ), msg );
553 }
554 else if( IsOnCopperLayer() )
555 {
556 if( aFrame->GetName() == PCB_EDIT_FRAME_NAME )
557 {
558 aList.emplace_back( _( "Net" ), UnescapeString( GetNetname() ) );
559
560 aList.emplace_back( _( "Resolved Netclass" ),
561 UnescapeString( GetEffectiveNetClass()->GetName() ) );
562 }
563
564 // Display priority level
565 aList.emplace_back( _( "Priority" ),
566 wxString::Format( wxT( "%d" ), GetAssignedPriority() ) );
567 }
568
569 if( aFrame->GetName() == PCB_EDIT_FRAME_NAME )
570 {
571 if( IsLocked() )
572 aList.emplace_back( _( "Status" ), _( "Locked" ) );
573 }
574
575 wxString layerDesc;
576 int count = 0;
577
578 for( PCB_LAYER_ID layer : m_layerSet.Seq() )
579 {
580 if( count == 0 )
581 layerDesc = GetBoard()->GetLayerName( layer );
582
583 count++;
584 }
585
586 if( count > 1 )
587 layerDesc.Printf( _( "%s and %d more" ), layerDesc, count - 1 );
588
589 aList.emplace_back( _( "Layer" ), layerDesc );
590
591 if( !m_zoneName.empty() )
592 aList.emplace_back( _( "Name" ), m_zoneName );
593
594 switch( m_fillMode )
595 {
596 case ZONE_FILL_MODE::POLYGONS: msg = _( "Solid" ); break;
597 case ZONE_FILL_MODE::HATCH_PATTERN: msg = _( "Hatched" ); break;
598 default: msg = _( "Unknown" ); break;
599 }
600
601 aList.emplace_back( _( "Fill Mode" ), msg );
602
603 aList.emplace_back( _( "Filled Area" ),
605
606 wxString source;
607 int clearance = GetOwnClearance( UNDEFINED_LAYER, &source );
608
609 if( !source.IsEmpty() )
610 {
611 aList.emplace_back( wxString::Format( _( "Min Clearance: %s" ),
612 aFrame->MessageTextFromValue( clearance ) ),
613 wxString::Format( _( "(from %s)" ),
614 source ) );
615 }
616
617 if( !m_FilledPolysList.empty() )
618 {
619 count = 0;
620
621 for( std::pair<const PCB_LAYER_ID, std::shared_ptr<SHAPE_POLY_SET>>& ii: m_FilledPolysList )
622 count += ii.second->TotalVertices();
623
624 aList.emplace_back( _( "Corner Count" ), wxString::Format( wxT( "%d" ), count ) );
625 }
626}
627
628
629void ZONE::Move( const VECTOR2I& offset )
630{
631 /* move outlines */
632 m_Poly->Move( offset );
633
634 HatchBorder();
635
636 /* move fills */
637 for( std::pair<const PCB_LAYER_ID, std::shared_ptr<SHAPE_POLY_SET>>& pair : m_FilledPolysList )
638 pair.second->Move( offset );
639
640 /*
641 * move boundingbox cache
642 *
643 * While the cache will get nuked at the conclusion of the operation, we use it for some
644 * things (such as drawing the parent group) during the move.
645 */
646 if( GetBoard() )
647 {
648 auto it = GetBoard()->m_ZoneBBoxCache.find( this );
649
650 if( it != GetBoard()->m_ZoneBBoxCache.end() )
651 it->second.Move( offset );
652 }
653}
654
655
656wxString ZONE::GetFriendlyName() const
657{
658 if( GetIsRuleArea() )
659 return _( "Rule Area" );
660 else if( IsTeardropArea() )
661 return _( "Teardrop Area" );
662 else if( IsOnCopperLayer() )
663 return _( "Copper Zone" );
664 else
665 return _( "Non-copper Zone" );
666}
667
668
669void ZONE::MoveEdge( const VECTOR2I& offset, int aEdge )
670{
671 int next_corner;
672
673 if( m_Poly->GetNeighbourIndexes( aEdge, nullptr, &next_corner ) )
674 {
675 m_Poly->SetVertex( aEdge, m_Poly->CVertex( aEdge ) + VECTOR2I( offset ) );
676 m_Poly->SetVertex( next_corner, m_Poly->CVertex( next_corner ) + VECTOR2I( offset ) );
677 HatchBorder();
678
679 SetNeedRefill( true );
680 }
681}
682
683
684void ZONE::Rotate( const VECTOR2I& aCentre, const EDA_ANGLE& aAngle )
685{
686 m_Poly->Rotate( aAngle, VECTOR2I( aCentre ) );
687 HatchBorder();
688
689 /* rotate filled areas: */
690 for( std::pair<const PCB_LAYER_ID, std::shared_ptr<SHAPE_POLY_SET>>& pair : m_FilledPolysList )
691 pair.second->Rotate( aAngle, aCentre );
692}
693
694
695void ZONE::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
696{
697 Mirror( aCentre, aFlipLeftRight );
698
699 SetLayerSet( FlipLayerMask( GetLayerSet(), GetBoard()->GetCopperLayerCount() ) );
700}
701
702
703void ZONE::Mirror( const VECTOR2I& aMirrorRef, bool aMirrorLeftRight )
704{
705 m_Poly->Mirror( aMirrorLeftRight, !aMirrorLeftRight, aMirrorRef );
706
707 HatchBorder();
708
709 for( std::pair<const PCB_LAYER_ID, std::shared_ptr<SHAPE_POLY_SET>>& pair : m_FilledPolysList )
710 pair.second->Mirror( aMirrorLeftRight, !aMirrorLeftRight, aMirrorRef );
711}
712
713
714void ZONE::RemoveCutout( int aOutlineIdx, int aHoleIdx )
715{
716 // Ensure the requested cutout is valid
717 if( m_Poly->OutlineCount() < aOutlineIdx || m_Poly->HoleCount( aOutlineIdx ) < aHoleIdx )
718 return;
719
720 SHAPE_POLY_SET cutPoly( m_Poly->Hole( aOutlineIdx, aHoleIdx ) );
721
722 // Add the cutout back to the zone
724
725 SetNeedRefill( true );
726}
727
728
729void ZONE::AddPolygon( const SHAPE_LINE_CHAIN& aPolygon )
730{
731 wxASSERT( aPolygon.IsClosed() );
732
733 // Add the outline as a new polygon in the polygon set
734 if( m_Poly->OutlineCount() == 0 )
735 m_Poly->AddOutline( aPolygon );
736 else
737 m_Poly->AddHole( aPolygon );
738
739 SetNeedRefill( true );
740}
741
742
743void ZONE::AddPolygon( std::vector<VECTOR2I>& aPolygon )
744{
745 if( aPolygon.empty() )
746 return;
747
748 SHAPE_LINE_CHAIN outline;
749
750 // Create an outline and populate it with the points of aPolygon
751 for( const VECTOR2I& pt : aPolygon )
752 outline.Append( pt );
753
754 outline.SetClosed( true );
755
756 AddPolygon( outline );
757}
758
759
760bool ZONE::AppendCorner( VECTOR2I aPosition, int aHoleIdx, bool aAllowDuplication )
761{
762 // Ensure the main outline exists:
763 if( m_Poly->OutlineCount() == 0 )
765
766 // If aHoleIdx >= 0, the corner musty be added to the hole, index aHoleIdx.
767 // (remember: the index of the first hole is 0)
768 // Return error if it does not exist.
769 if( aHoleIdx >= m_Poly->HoleCount( 0 ) )
770 return false;
771
772 m_Poly->Append( aPosition.x, aPosition.y, -1, aHoleIdx, aAllowDuplication );
773
774 SetNeedRefill( true );
775
776 return true;
777}
778
779
780wxString ZONE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
781{
782 wxString layerDesc;
783 int count = 0;
784
785 for( PCB_LAYER_ID layer : m_layerSet.Seq() )
786 {
787 if( count == 0 )
788 layerDesc = GetBoard()->GetLayerName( layer );
789
790 count++;
791 }
792
793 if( count > 1 )
794 layerDesc.Printf( _( "%s and %d more" ), layerDesc, count - 1 );
795
796 // Check whether the selected contour is a hole (contour index > 0)
797 if( m_CornerSelection != nullptr && m_CornerSelection->m_contour > 0 )
798 {
799 if( GetIsRuleArea() )
800 return wxString::Format( _( "Rule Area Cutout on %s" ), layerDesc );
801 else
802 return wxString::Format( _( "Zone Cutout on %s" ), layerDesc );
803 }
804 else
805 {
806 if( GetIsRuleArea() )
807 return wxString::Format( _( "Rule Area on %s" ), layerDesc );
808 else
809 return wxString::Format( _( "Zone %s on %s" ), GetNetnameMsg(), layerDesc );
810 }
811}
812
813
815{
816 return m_borderHatchPitch;
817}
818
819
821 int aBorderHatchPitch, bool aRebuildBorderHatch )
822{
823 aBorderHatchPitch = std::max( aBorderHatchPitch,
825 aBorderHatchPitch = std::min( aBorderHatchPitch,
827 SetBorderHatchPitch( aBorderHatchPitch );
828 m_borderStyle = aBorderHatchStyle;
829
830 if( aRebuildBorderHatch )
831 HatchBorder();
832}
833
834
836{
837 m_borderHatchPitch = aPitch;
838}
839
840
842{
843 m_borderHatchLines.clear();
844}
845
846
847// Creates hatch lines inside the outline of the complex polygon
848// sort function used in ::HatchBorder to sort points by descending VECTOR2I.x values
849bool sortEndsByDescendingX( const VECTOR2I& ref, const VECTOR2I& tst )
850{
851 return tst.x < ref.x;
852}
853
854
856{
858
860 || m_borderHatchPitch == 0
861 || m_Poly->IsEmpty() )
862 {
863 return;
864 }
865
866 // define range for hatch lines
867 int min_x = m_Poly->CVertex( 0 ).x;
868 int max_x = m_Poly->CVertex( 0 ).x;
869 int min_y = m_Poly->CVertex( 0 ).y;
870 int max_y = m_Poly->CVertex( 0 ).y;
871
872 for( auto iterator = m_Poly->IterateWithHoles(); iterator; iterator++ )
873 {
874 if( iterator->x < min_x )
875 min_x = iterator->x;
876
877 if( iterator->x > max_x )
878 max_x = iterator->x;
879
880 if( iterator->y < min_y )
881 min_y = iterator->y;
882
883 if( iterator->y > max_y )
884 max_y = iterator->y;
885 }
886
887 // Calculate spacing between 2 hatch lines
888 int spacing;
889
891 spacing = m_borderHatchPitch;
892 else
893 spacing = m_borderHatchPitch * 2;
894
895 // set the "length" of hatch lines (the length on horizontal axis)
896 int hatch_line_len = m_borderHatchPitch;
897
898 // To have a better look, give a slope depending on the layer
899 int layer = GetFirstLayer();
900 int slope_flag = (layer & 1) ? 1 : -1; // 1 or -1
901 double slope = 0.707106 * slope_flag; // 45 degrees slope
902 int max_a, min_a;
903
904 if( slope_flag == 1 )
905 {
906 max_a = KiROUND( max_y - slope * min_x );
907 min_a = KiROUND( min_y - slope * max_x );
908 }
909 else
910 {
911 max_a = KiROUND( max_y - slope * max_x );
912 min_a = KiROUND( min_y - slope * min_x );
913 }
914
915 min_a = (min_a / spacing) * spacing;
916
917 // calculate an offset depending on layer number,
918 // for a better look of hatches on a multilayer board
919 int offset = (layer * 7) / 8;
920 min_a += offset;
921
922 // loop through hatch lines
923 std::vector<VECTOR2I> pointbuffer;
924 pointbuffer.reserve( 256 );
925
926 for( int a = min_a; a < max_a; a += spacing )
927 {
928 pointbuffer.clear();
929
930 // Iterate through all vertices
931 for( auto iterator = m_Poly->IterateSegmentsWithHoles(); iterator; iterator++ )
932 {
933 const SEG seg = *iterator;
934 double x, y;
935
936 if( FindLineSegmentIntersection( a, slope, seg.A.x, seg.A.y, seg.B.x, seg.B.y, x, y ) )
937 pointbuffer.emplace_back( KiROUND( x ), KiROUND( y ) );
938 }
939
940 // sort points in order of descending x (if more than 2) to
941 // ensure the starting point and the ending point of the same segment
942 // are stored one just after the other.
943 if( pointbuffer.size() > 2 )
944 sort( pointbuffer.begin(), pointbuffer.end(), sortEndsByDescendingX );
945
946 // creates lines or short segments inside the complex polygon
947 for( size_t ip = 0; ip + 1 < pointbuffer.size(); ip += 2 )
948 {
949 int dx = pointbuffer[ip + 1].x - pointbuffer[ip].x;
950
951 // Push only one line for diagonal hatch,
952 // or for small lines < twice the line length
953 // else push 2 small lines
955 || std::abs( dx ) < 2 * hatch_line_len )
956 {
957 m_borderHatchLines.emplace_back( SEG( pointbuffer[ip], pointbuffer[ ip + 1] ) );
958 }
959 else
960 {
961 double dy = pointbuffer[ip + 1].y - pointbuffer[ip].y;
962 slope = dy / dx;
963
964 if( dx > 0 )
965 dx = hatch_line_len;
966 else
967 dx = -hatch_line_len;
968
969 int x1 = KiROUND( pointbuffer[ip].x + dx );
970 int x2 = KiROUND( pointbuffer[ip + 1].x - dx );
971 int y1 = KiROUND( pointbuffer[ip].y + dx * slope );
972 int y2 = KiROUND( pointbuffer[ip + 1].y - dx * slope );
973
974 m_borderHatchLines.emplace_back( SEG( pointbuffer[ip].x, pointbuffer[ip].y,
975 x1, y1 ) );
976
977 m_borderHatchLines.emplace_back( SEG( pointbuffer[ip+1].x, pointbuffer[ip+1].y,
978 x2, y2 ) );
979 }
980 }
981 }
982}
983
984
986{
988}
989
990
992{
993 return BITMAPS::add_zone;
994}
995
996
998{
999 assert( aImage->Type() == PCB_ZONE_T || aImage->Type() == PCB_FP_ZONE_T );
1000
1001 std::swap( *static_cast<ZONE*>( this ), *static_cast<ZONE*>( aImage) );
1002}
1003
1004
1006{
1007 if( aLayer == UNDEFINED_LAYER )
1008 {
1009 for( auto& [ layer, poly ] : m_FilledPolysList )
1010 poly->CacheTriangulation();
1011
1012 m_Poly->CacheTriangulation( false );
1013 }
1014 else
1015 {
1016 if( m_FilledPolysList.count( aLayer ) )
1017 m_FilledPolysList[ aLayer ]->CacheTriangulation();
1018 }
1019}
1020
1021
1022bool ZONE::IsIsland( PCB_LAYER_ID aLayer, int aPolyIdx ) const
1023{
1024 if( GetNetCode() < 1 )
1025 return true;
1026
1027 if( !m_insulatedIslands.count( aLayer ) )
1028 return false;
1029
1030 return m_insulatedIslands.at( aLayer ).count( aPolyIdx );
1031}
1032
1033
1034void ZONE::GetInteractingZones( PCB_LAYER_ID aLayer, std::vector<ZONE*>* aSameNetCollidingZones,
1035 std::vector<ZONE*>* aOtherNetIntersectingZones ) const
1036{
1037 int epsilon = pcbIUScale.mmToIU( 0.001 );
1038 BOX2I bbox = GetBoundingBox();
1039
1040 bbox.Inflate( epsilon );
1041
1042 for( ZONE* candidate : GetBoard()->Zones() )
1043 {
1044 if( candidate == this )
1045 continue;
1046
1047 if( !candidate->GetLayerSet().test( aLayer ) )
1048 continue;
1049
1050 if( candidate->GetIsRuleArea() || candidate->IsTeardropArea() )
1051 continue;
1052
1053 if( !candidate->GetBoundingBox().Intersects( bbox ) )
1054 continue;
1055
1056 if( candidate->GetNetCode() == GetNetCode() )
1057 {
1058 if( m_Poly->Collide( candidate->m_Poly ) )
1059 aSameNetCollidingZones->push_back( candidate );
1060 }
1061 else
1062 {
1063 aOtherNetIntersectingZones->push_back( candidate );
1064 }
1065 }
1066}
1067
1068
1070 SHAPE_POLY_SET* aBoardOutline,
1071 SHAPE_POLY_SET* aSmoothedPolyWithApron ) const
1072{
1073 if( GetNumCorners() <= 2 ) // malformed zone. polygon calculations will not like it ...
1074 return false;
1075
1076 // Processing of arc shapes in zones is not yet supported because Clipper can't do boolean
1077 // operations on them. The poly outline must be converted to segments first.
1079 flattened.ClearArcs();
1080
1081 if( GetIsRuleArea() )
1082 {
1083 // We like keepouts just the way they are....
1084 aSmoothedPoly = flattened;
1085 return true;
1086 }
1087
1088 const BOARD* board = GetBoard();
1089 int maxError = ARC_HIGH_DEF;
1090 bool keepExternalFillets = false;
1093
1094 if( IsTeardropArea() )
1095 {
1096 // We use teardrop shapes with no smoothing; these shapes are already optimized
1097 smooth_requested = false;
1098 }
1099
1100 if( board )
1101 {
1103
1104 maxError = bds.m_MaxError;
1105 keepExternalFillets = bds.m_ZoneKeepExternalFillets;
1106 }
1107
1108 auto smooth = [&]( SHAPE_POLY_SET& aPoly )
1109 {
1110 if( !smooth_requested )
1111 return;
1112
1113 switch( m_cornerSmoothingType )
1114 {
1116 aPoly = aPoly.Chamfer( (int) m_cornerRadius );
1117 break;
1118
1120 {
1121 aPoly = aPoly.Fillet( (int) m_cornerRadius, maxError );
1122 break;
1123 }
1124
1125 default:
1126 break;
1127 }
1128 };
1129
1130 SHAPE_POLY_SET* maxExtents = &flattened;
1131 SHAPE_POLY_SET withFillets;
1132
1133 aSmoothedPoly = flattened;
1134
1135 // Should external fillets (that is, those applied to concave corners) be kept? While it
1136 // seems safer to never have copper extend outside the zone outline, 5.1.x and prior did
1137 // indeed fill them so we leave the mode available.
1138 if( keepExternalFillets && smooth_requested )
1139 {
1140 withFillets = flattened;
1141 smooth( withFillets );
1142 withFillets.BooleanAdd( flattened, SHAPE_POLY_SET::PM_FAST );
1143 maxExtents = &withFillets;
1144 }
1145
1146 // We now add in the areas of any same-net, intersecting zones. This keeps us from smoothing
1147 // corners at an intersection (which often produces undesired divots between the intersecting
1148 // zones -- see #2752).
1149 //
1150 // After smoothing, we'll subtract back out everything outside of our zone.
1151 std::vector<ZONE*> sameNetCollidingZones;
1152 std::vector<ZONE*> otherNetIntersectingZones;
1153 GetInteractingZones( aLayer, &sameNetCollidingZones, &otherNetIntersectingZones );
1154
1155 for( ZONE* sameNetZone : sameNetCollidingZones )
1156 {
1157 BOX2I sameNetBoundingBox = sameNetZone->GetBoundingBox();
1158 SHAPE_POLY_SET sameNetPoly = sameNetZone->Outline()->CloneDropTriangulation();
1159
1160 sameNetPoly.ClearArcs();
1161
1162 // Of course there's always a wrinkle. The same-net intersecting zone *might* get knocked
1163 // out along the border by a higher-priority, different-net zone. #12797
1164 for( ZONE* otherNetZone : otherNetIntersectingZones )
1165 {
1166 if( otherNetZone->HigherPriority( sameNetZone )
1167 && otherNetZone->GetBoundingBox().Intersects( sameNetBoundingBox ) )
1168 {
1169 sameNetPoly.BooleanSubtract( *otherNetZone->Outline(), SHAPE_POLY_SET::PM_FAST );
1170 }
1171 }
1172
1173 aSmoothedPoly.BooleanAdd( sameNetPoly, SHAPE_POLY_SET::PM_FAST );
1174 }
1175
1176 if( aBoardOutline )
1177 aSmoothedPoly.BooleanIntersection( *aBoardOutline, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
1178
1179 smooth( aSmoothedPoly );
1180
1181 if( aSmoothedPolyWithApron )
1182 {
1183 SHAPE_POLY_SET poly = maxExtents->CloneDropTriangulation();
1184 poly.Inflate( m_ZoneMinThickness, 64 );
1185 *aSmoothedPolyWithApron = aSmoothedPoly;
1186 aSmoothedPolyWithApron->BooleanIntersection( poly, SHAPE_POLY_SET::PM_FAST );
1187 }
1188
1189 aSmoothedPoly.BooleanIntersection( *maxExtents, SHAPE_POLY_SET::PM_FAST );
1190
1191 return true;
1192}
1193
1194
1196{
1197 m_area = 0.0;
1198
1199 // Iterate over each outline polygon in the zone and then iterate over
1200 // each hole it has to compute the total area.
1201 for( std::pair<const PCB_LAYER_ID, std::shared_ptr<SHAPE_POLY_SET>>& pair : m_FilledPolysList )
1202 {
1203 std::shared_ptr<SHAPE_POLY_SET>& poly = pair.second;
1204
1205 for( int i = 0; i < poly->OutlineCount(); i++ )
1206 {
1207 m_area += poly->Outline( i ).Area();
1208
1209 for( int j = 0; j < poly->HoleCount( i ); j++ )
1210 m_area -= poly->Hole( i, j ).Area();
1211 }
1212 }
1213
1214 return m_area;
1215}
1216
1217
1219{
1221 return m_outlinearea;
1222}
1223
1224
1226 int aMaxError, ERROR_LOC aErrorLoc,
1227 SHAPE_POLY_SET* aBoardOutline ) const
1228{
1229 // Creates the zone outline polygon (with holes if any)
1230 SHAPE_POLY_SET polybuffer;
1231
1232 // TODO: using GetFirstLayer() means it only works for single-layer zones....
1233 BuildSmoothedPoly( polybuffer, GetFirstLayer(), aBoardOutline );
1234
1235 // Calculate the polygon with clearance
1236 // holes are linked to the main outline, so only one polygon is created.
1237 if( aClearance )
1238 {
1239 const BOARD* board = GetBoard();
1240 int maxError = ARC_HIGH_DEF;
1241
1242 if( board )
1243 maxError = board->GetDesignSettings().m_MaxError;
1244
1245 int segCount = GetArcToSegmentCount( aClearance, maxError, FULL_CIRCLE );
1246
1247 if( aErrorLoc == ERROR_OUTSIDE )
1248 aClearance += aMaxError;
1249
1250 polybuffer.Inflate( aClearance, segCount );
1251 }
1252
1253 polybuffer.Fracture( SHAPE_POLY_SET::PM_FAST );
1254 aBuffer.Append( polybuffer );
1255}
1256
1257
1259 ZONE( aParent, true )
1260{
1261 // in a footprint, net classes are not managed.
1262 // so set the net to NETINFO_LIST::ORPHANED_ITEM
1263 SetNetCode( -1, true );
1264}
1265
1266
1267FP_ZONE::FP_ZONE( const FP_ZONE& aZone ) :
1268 ZONE( aZone )
1269{
1271}
1272
1273
1275{
1276 ZONE::operator=( aOther );
1277 return *this;
1278}
1279
1280
1282{
1283 return new FP_ZONE( *this );
1284}
1285
1286
1287double FP_ZONE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
1288{
1289 constexpr double HIDE = (double)std::numeric_limits<double>::max();
1290
1291 if( !aView )
1292 return 0;
1293
1294 if( !aView->IsLayerVisible( LAYER_ZONES ) )
1295 return HIDE;
1296
1297 bool flipped = GetParent() && GetParent()->GetLayer() == B_Cu;
1298
1299 // Handle Render tab switches
1300 if( !flipped && !aView->IsLayerVisible( LAYER_MOD_FR ) )
1301 return HIDE;
1302
1303 if( flipped && !aView->IsLayerVisible( LAYER_MOD_BK ) )
1304 return HIDE;
1305
1306 // Other layers are shown without any conditions
1307 return 0.0;
1308}
1309
1310
1311std::shared_ptr<SHAPE> ZONE::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
1312{
1313 if( m_FilledPolysList.find( aLayer ) == m_FilledPolysList.end() )
1314 return std::make_shared<SHAPE_NULL>();
1315 else
1316 return m_FilledPolysList.at( aLayer );
1317}
1318
1319
1320void ZONE::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
1321 int aError, ERROR_LOC aErrorLoc, bool aIgnoreLineWidth ) const
1322{
1323 wxASSERT_MSG( !aIgnoreLineWidth, wxT( "IgnoreLineWidth has no meaning for zones." ) );
1324
1325 if( !m_FilledPolysList.count( aLayer ) )
1326 return;
1327
1328 if( !aClearance )
1329 {
1330 aBuffer.Append( *m_FilledPolysList.at( aLayer ) );
1331 return;
1332 }
1333
1334 SHAPE_POLY_SET temp_buf = m_FilledPolysList.at( aLayer )->CloneDropTriangulation();
1335
1336 // Rebuild filled areas only if clearance is not 0
1337 int numSegs = GetArcToSegmentCount( aClearance, aError, FULL_CIRCLE );
1338
1339 if( aErrorLoc == ERROR_OUTSIDE )
1340 aClearance += aError;
1341
1342 temp_buf.InflateWithLinkedHoles( aClearance, numSegs, SHAPE_POLY_SET::PM_FAST );
1343
1344 aBuffer.Append( temp_buf );
1345}
1346
1347
1349{
1350 if( m_FilledPolysList.count( aLayer ) && !m_FilledPolysList.at( aLayer )->IsEmpty() )
1351 aBuffer.Append( *m_FilledPolysList.at( aLayer ) );
1352}
1353
1354
1355static struct ZONE_DESC
1356{
1358 {
1360
1361 if( layerEnum.Choices().GetCount() == 0 )
1362 {
1363 layerEnum.Undefined( UNDEFINED_LAYER );
1364
1365 for( LSEQ seq = LSET::AllLayersMask().Seq(); seq; ++seq )
1366 layerEnum.Map( *seq, LSET::Name( *seq ) );
1367 }
1368
1370
1371 if( zcMap.Choices().GetCount() == 0 )
1372 {
1374 zcMap.Map( ZONE_CONNECTION::INHERITED, _HKI( "Inherited" ) )
1375 .Map( ZONE_CONNECTION::NONE, _HKI( "None" ) )
1376 .Map( ZONE_CONNECTION::THERMAL, _HKI( "Thermal reliefs" ) )
1377 .Map( ZONE_CONNECTION::FULL, _HKI( "Solid" ) )
1378 .Map( ZONE_CONNECTION::THT_THERMAL, _HKI( "Thermal reliefs for PTH" ) );
1379 }
1380
1382
1383 if( zfmMap.Choices().GetCount() == 0 )
1384 {
1386 zfmMap.Map( ZONE_FILL_MODE::POLYGONS, _HKI( "Solid fill" ) )
1387 .Map( ZONE_FILL_MODE::HATCH_PATTERN, _HKI( "Hatch pattern" ) );
1388 }
1389
1393
1394 // Mask layer and position properties; they aren't useful in current form
1395 auto posX = new PROPERTY<ZONE, int>( _HKI( "Position X" ),
1396 NO_SETTER( ZONE, int ),
1397 reinterpret_cast<int (ZONE::*)() const>( &ZONE::GetX ),
1400 posX->SetIsInternal( true );
1401
1402 auto posY = new PROPERTY<ZONE, int>( _HKI( "Position Y" ), NO_SETTER( ZONE, int ),
1403 reinterpret_cast<int (ZONE::*)() const>( &ZONE::GetY ),
1406 posY->SetIsInternal( true );
1407
1408 propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Position X" ), posX );
1409 propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Position Y" ), posY );
1410
1411 auto isCopperZone =
1412 []( INSPECTABLE* aItem ) -> bool
1413 {
1414 if( ZONE* zone = dynamic_cast<ZONE*>( aItem ) )
1415 return !zone->GetIsRuleArea() && IsCopperLayer( zone->GetFirstLayer() );
1416
1417 return false;
1418 };
1419
1420 auto isHatchedFill =
1421 []( INSPECTABLE* aItem ) -> bool
1422 {
1423 if( ZONE* zone = dynamic_cast<ZONE*>( aItem ) )
1424 return zone->GetFillMode() == ZONE_FILL_MODE::HATCH_PATTERN;
1425
1426 return false;
1427 };
1428
1429 auto layer = new PROPERTY_ENUM<ZONE, PCB_LAYER_ID>( _HKI( "Layer" ),
1431 layer->SetIsInternal( true );
1432 propMgr.ReplaceProperty( TYPE_HASH( BOARD_CONNECTED_ITEM ), _HKI( "Layer" ), layer );
1433
1435 _HKI( "Net" ), isCopperZone );
1437 _HKI( "Net Class" ), isCopperZone );
1438
1439 auto priority = new PROPERTY<ZONE, unsigned>( _HKI( "Priority" ),
1441 priority->SetAvailableFunc( isCopperZone );
1442 propMgr.AddProperty( priority );
1443
1444 propMgr.AddProperty( new PROPERTY<ZONE, wxString>( _HKI( "Name" ),
1446
1447 const wxString groupFill = _HKI( "Fill Style" );
1448
1449 propMgr.AddProperty( new PROPERTY_ENUM<ZONE, ZONE_FILL_MODE>( _HKI( "Fill Mode" ),
1450 &ZONE::SetFillMode, &ZONE::GetFillMode ), groupFill );
1451
1452 auto hatchOrientation = new PROPERTY<ZONE, EDA_ANGLE>( _HKI( "Orientation" ),
1455 hatchOrientation->SetWriteableFunc( isHatchedFill );
1456 propMgr.AddProperty( hatchOrientation, groupFill );
1457
1458 //TODO: Switch to translated
1459 auto hatchWidth = new PROPERTY<ZONE, int>( wxT( "Hatch Width" ),
1462 hatchWidth->SetWriteableFunc( isHatchedFill );
1463 propMgr.AddProperty( hatchWidth, groupFill );
1464
1465 //TODO: Switch to translated
1466 auto hatchGap = new PROPERTY<ZONE, int>( wxT( "Hatch Gap" ),
1469 hatchGap->SetWriteableFunc( isHatchedFill );
1470 propMgr.AddProperty( hatchGap, groupFill );
1471
1472 // TODO: Smoothing effort needs to change to enum (in dialog too)
1473 // TODO: Smoothing amount (double)
1474 // Unexposed properties (HatchHoleMinArea / HatchBorderAlgorithm)?
1475
1476 const wxString groupOverrides = _HKI( "Overrides" );
1477
1478 auto clearanceOverride = new PROPERTY<ZONE, int>( _HKI( "Clearance Override" ),
1481 clearanceOverride->SetAvailableFunc( isCopperZone );
1482
1483 auto minWidth = new PROPERTY<ZONE, int>( _HKI( "Minimum Width" ),
1486 minWidth->SetAvailableFunc( isCopperZone );
1487
1488 auto padConnections = new PROPERTY_ENUM<ZONE, ZONE_CONNECTION>( _HKI( "Pad Connections" ),
1490 padConnections->SetAvailableFunc( isCopperZone );
1491
1492 auto thermalGap = new PROPERTY<ZONE, int>( _HKI( "Thermal Relief Gap" ),
1495 thermalGap->SetAvailableFunc( isCopperZone );
1496
1497 auto thermalSpokeWidth = new PROPERTY<ZONE, int>( _HKI( "Thermal Relief Spoke Width" ),
1500 thermalSpokeWidth->SetAvailableFunc( isCopperZone );
1501
1502 propMgr.AddProperty( clearanceOverride, groupOverrides );
1503 propMgr.AddProperty( minWidth, groupOverrides );
1504 propMgr.AddProperty( padConnections, groupOverrides );
1505 propMgr.AddProperty( thermalGap, groupOverrides );
1506 propMgr.AddProperty( thermalSpokeWidth, groupOverrides );
1507 }
1509
constexpr int ARC_HIGH_DEF
Definition: base_units.h:121
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
wxString GetNetnameMsg() const
virtual NETCLASS * GetEffectiveNetClass() const
Return the NETCLASS for this item.
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
NETINFO_ITEM * m_netinfo
Store all information about the net that item belongs to.
virtual int GetOwnClearance(PCB_LAYER_ID aLayer, wxString *aSource=nullptr) const
Return an item's "own" clearance in internal units.
Container for design settings for a BOARD object.
Abstract interface for BOARD_ITEMs capable of storing other items inside.
virtual const ZONE_SETTINGS & GetZoneSettings() const
Fetch the zone settings for this container.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:58
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:180
int GetY() const
Definition: board_item.h:82
int GetX() const
Definition: board_item.h:76
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:43
virtual bool IsLocked() const
Definition: board_item.cpp:71
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:163
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:265
std::unordered_map< const ZONE *, BOX2I > m_ZoneBBoxCache
Definition: board.h:1147
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:456
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:686
std::mutex m_CachesMutex
Definition: board.h:1138
BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition: box2.h:119
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:269
bool Contains(const Vec &aPoint) const
Definition: box2.h:141
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:506
The base class for create windows for drawing purpose.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Assign the members of aItem to another object.
Definition: eda_item.cpp:240
const KIID m_Uuid
Definition: eda_item.h:492
bool m_forceVisible
Definition: eda_item.h:497
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:498
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
Definition: eda_item.h:143
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition: property.h:579
static ENUM_MAP< T > & Instance()
Definition: property.h:573
ENUM_MAP & Undefined(T aValue)
Definition: property.h:586
wxPGChoices & Choices()
Definition: property.h:622
A specialization of ZONE for use in footprints.
Definition: zone.h:910
FP_ZONE(BOARD_ITEM_CONTAINER *aParent)
Definition: zone.cpp:1258
FP_ZONE & operator=(const FP_ZONE &aOther)
Definition: zone.cpp:1274
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: zone.cpp:1287
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: zone.cpp:1281
Class that other classes need to inherit from, in order to be inspectable.
Definition: inspectable.h:36
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:69
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:410
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
Definition: layer_ids.h:491
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:530
LSEQ UIOrder() const
Definition: lset.cpp:922
static LSET AllLayersMask()
Definition: lset.cpp:808
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
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:773
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:82
Definition: pad.h:59
int GetLocalThermalGapOverride(wxString *aSource=nullptr) const
Definition: pad.cpp:962
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:74
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:76
void AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
void OverrideAvailability(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName, std::function< bool(INSPECTABLE *)> aFunc)
Sets an override availability functor for a base class property of a given derived class.
void ReplaceProperty(size_t aBase, const wxString &aName, PROPERTY_BASE *aNew, const wxString &aGroup=wxEmptyString)
Replace an existing property for a specific type.
Definition: seg.h:42
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
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.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
bool IsClosed() const override
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
Represent a set of closed polygons.
void Rotate(const EDA_ANGLE &aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
bool CollideEdge(const VECTOR2I &aPoint, VERTEX_INDEX *aClosestVertex=nullptr, int aClearance=0) const
Check whether aPoint collides with any edge of any of the contours of the polygon.
void BooleanSubtract(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset intersection For aFastMode meaning, see function booleanOp.
ITERATOR IterateWithHoles(int aOutline)
void Fracture(POLYGON_MODE aFastMode)
Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.
void ClearArcs()
Appends a vertex at the end of the given outline/hole (default: the last outline)
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
double Area()
Count the number of arc shapes present.
void SetVertex(const VERTEX_INDEX &aIndex, const VECTOR2I &aPos)
Accessor function to set the position of a specific point.
bool IsEmpty() const
void BooleanAdd(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset difference For aFastMode meaning, see function booleanOp.
void CacheTriangulation(bool aPartition=true, bool aSimplify=false)
Build a polygon triangulation, needed to draw a polygon on OpenGL and in some other calculations.
bool Collide(const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the shape aShape than aClearance,...
int TotalVertices() const
Delete aIdx-th polygon from the set.
void Inflate(int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
Perform outline inflation/deflation.
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,...
MD5_HASH GetHash() const
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.
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...
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...
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Return the area of this poly set.
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirror the line points about y or x (or both)
SHAPE_LINE_CHAIN & Outline(int aIndex)
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the aIndex-th subpolygon in the set.
int NewOutline()
Creates a new hole in a given outline.
bool CollideVertex(const VECTOR2I &aPoint, VERTEX_INDEX *aClosestVertex=nullptr, int aClearance=0) const
Check whether aPoint collides with any vertex of any of the contours of the polygon.
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the aGlobalIndex-th vertex in the poly set.
int OutlineCount() const
Return the number of vertices in a given outline/hole.
void Move(const VECTOR2I &aVector) override
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.
SHAPE_POLY_SET CloneDropTriangulation() const
Creates a new empty polygon in the set and returns its index.
void InflateWithLinkedHoles(int aFactor, int aCircleSegmentsCount, POLYGON_MODE aFastMode)
Perform outline inflation/deflation, using round corners.
SEGMENT_ITERATOR IterateSegmentsWithHoles()
Return an iterator object, for the aOutline-th outline in the set (with holes).
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
A lower-precision version of StringFromValue().
void ExportSetting(ZONE &aTarget, bool aFullExport=true) const
Function ExportSetting copy settings to a given zone.
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
void SetHatchThickness(int aThickness)
Definition: zone.h:261
SHAPE_POLY_SET::VERTEX_INDEX * m_CornerSelection
The index of the corner being moved or nullptr if no corner is selected.
Definition: zone.h:871
void SetNeedRefill(bool aNeedRefill)
Definition: zone.h:246
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if a point is near an outline edge or a corner of this zone.
Definition: zone.cpp:405
int m_borderHatchPitch
Definition: zone.h:892
bool m_isRuleArea
Definition: zone.h:807
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const override
Return a user-visible description string of this item.
Definition: zone.cpp:780
ZONE & operator=(const ZONE &aOther)
Definition: zone.cpp:82
int m_cornerSmoothingType
Definition: zone.h:790
void Mirror(const VECTOR2I &aMirrorRef, bool aMirrorLeftRight)
Mirror the outlines relative to a given horizontal axis the layer is not changed.
Definition: zone.cpp:703
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition: zone.h:697
bool m_doNotAllowVias
Definition: zone.h:819
bool UnFill()
Removes the zone filling.
Definition: zone.cpp:209
bool GetDoNotAllowVias() const
Definition: zone.h:699
void TransformSolidAreasShapesToPolygon(PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aBuffer) const
Convert solid areas full shapes to polygon set (the full shape is the polygon area with a thick outli...
Definition: zone.cpp:1348
void SetCornerRadius(unsigned int aRadius)
Definition: zone.cpp:375
ZONE_FILL_MODE m_fillMode
How to fill areas:
Definition: zone.h:857
bool m_doNotAllowFootprints
Definition: zone.h:822
int m_ZoneMinThickness
Definition: zone.h:826
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:293
void AddPolygon(std::vector< VECTOR2I > &aPolygon)
Add a polygon to the zone outline.
Definition: zone.cpp:743
double m_hatchSmoothingValue
Definition: zone.h:865
void SetLocalFlags(int aFlags)
Definition: zone.h:310
void TransformSmoothedOutlineToPolygon(SHAPE_POLY_SET &aBuffer, int aClearance, int aError, ERROR_LOC aErrorLoc, SHAPE_POLY_SET *aBoardOutline) const
Convert the outlines shape to a polygon with no holes inflated (optional) by max( aClearanceValue,...
Definition: zone.cpp:1225
int m_thermalReliefSpokeWidth
Definition: zone.h:848
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:496
EDA_ANGLE m_hatchOrientation
Definition: zone.h:860
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:1005
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:896
wxString m_zoneName
An optional unique name for this zone, used for identifying it in DRC checking.
Definition: zone.h:794
void HatchBorder()
Compute the hatch lines depending on the hatch parameters and stores it in the zone's attribute m_bor...
Definition: zone.cpp:855
std::map< PCB_LAYER_ID, std::shared_ptr< SHAPE_POLY_SET > > m_FilledPolysList
Definition: zone.h:883
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aBorderHatchStyle, int aBorderHatchPitch, bool aRebuilBorderdHatch)
Set all hatch parameters for the zone.
Definition: zone.cpp:820
MD5_HASH GetHashValue(PCB_LAYER_ID aLayer)
Definition: zone.cpp:387
bool GetDoNotAllowPads() const
Definition: zone.h:701
const BOX2I GetBoundingBox() const override
Definition: zone.cpp:323
void SetMinThickness(int aMinThickness)
Definition: zone.h:252
double m_outlinearea
Definition: zone.h:899
wxString GetFriendlyName() const override
Definition: zone.cpp:656
bool GetDoNotAllowTracks() const
Definition: zone.h:700
int GetLocalFlags() const
Definition: zone.h:309
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: zone.cpp:180
void SetHatchOrientation(const EDA_ANGLE &aStep)
Definition: zone.h:267
bool m_doNotAllowCopperPour
Definition: zone.h:818
bool m_needRefill
False when a zone was refilled, true after changes in zone params.
Definition: zone.h:845
virtual void Flip(const VECTOR2I &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
Definition: zone.cpp:695
bool HitTestForCorner(const VECTOR2I &refPos, int aAccuracy, SHAPE_POLY_SET::VERTEX_INDEX *aCornerHit=nullptr) const
Test if the given VECTOR2I is near a corner.
Definition: zone.cpp:415
bool m_doNotAllowTracks
Definition: zone.h:820
void SetThermalReliefSpokeWidth(int aThermalReliefSpokeWidth)
Definition: zone.h:187
virtual PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: zone.cpp:239
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition: zone.cpp:260
LSET m_fillFlags
Temp variables used while filling.
Definition: zone.h:886
bool m_doNotAllowPads
Definition: zone.h:821
void Move(const VECTOR2I &offset) override
Move the outlines.
Definition: zone.cpp:629
bool IsIsland(PCB_LAYER_ID aLayer, int aPolyIdx) const
Check if a given filled polygon is an insulated island.
Definition: zone.cpp:1022
SHAPE_POLY_SET * m_Poly
Outline of the zone.
Definition: zone.h:789
TEARDROP_TYPE m_teardropType
Definition: zone.h:813
~ZONE()
Definition: zone.cpp:92
int m_hatchSmoothingLevel
Definition: zone.h:861
int GetLocalClearance() const
Definition: zone.h:152
LSET m_layerSet
Definition: zone.h:796
void SetIsRuleArea(bool aEnable)
Definition: zone.h:704
int m_ZoneClearance
Definition: zone.h:825
wxString GetZoneName() const
Definition: zone.h:124
void CacheBoundingBox()
Used to preload the zone bounding box cache so we don't have to worry about mutex-locking it each tim...
Definition: zone.cpp:345
int GetMinThickness() const
Definition: zone.h:251
virtual void swapData(BOARD_ITEM *aImage) override
Definition: zone.cpp:997
bool HitTestForEdge(const VECTOR2I &refPos, int aAccuracy, SHAPE_POLY_SET::VERTEX_INDEX *aCornerHit=nullptr) const
Test if the given VECTOR2I is near a segment defined by 2 corners.
Definition: zone.cpp:422
void RemoveCutout(int aOutlineIdx, int aHoleIdx)
Remove a cutout from the zone.
Definition: zone.cpp:714
void Rotate(const VECTOR2I &aCentre, const EDA_ANGLE &aAngle) override
Rotate the outlines.
Definition: zone.cpp:684
bool HigherPriority(const ZONE *aOther) const
Definition: zone.cpp:186
bool HitTestFilledArea(PCB_LAYER_ID aLayer, const VECTOR2I &aRefPos, int aAccuracy=0) const
Test if the given VECTOR2I is within the bounds of a filled area of this zone.
Definition: zone.cpp:482
void SetFillMode(ZONE_FILL_MODE aFillMode)
Definition: zone.h:173
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: zone.cpp:991
int m_hatchGap
Definition: zone.h:859
ZONE_CONNECTION GetPadConnection() const
Definition: zone.h:248
void InitDataFromSrcInCopyCtor(const ZONE &aZone)
Copy aZone data to me.
Definition: zone.cpp:102
int GetHatchThickness() const
Definition: zone.h:260
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:521
virtual bool IsOnLayer(PCB_LAYER_ID) const override
Test to see if this object is on the given layer.
Definition: zone.cpp:317
int m_hatchBorderAlgorithm
Definition: zone.h:867
bool IsTeardropArea() const
Definition: zone.h:681
std::vector< SEG > m_borderHatchLines
Definition: zone.h:893
VECTOR2I GetPosition() const override
Definition: zone.cpp:233
int GetThermalReliefSpokeWidth() const
Definition: zone.h:195
int GetBorderHatchPitch() const
HatchBorder related methods.
Definition: zone.cpp:814
void SetLocalClearance(int aClearance)
Definition: zone.h:153
void BuildHashValue(PCB_LAYER_ID aLayer)
Build the hash value of m_FilledPolysList, and store it internally in m_filledPolysHash.
Definition: zone.cpp:396
void SetThermalReliefGap(int aThermalReliefGap)
Definition: zone.h:176
EDA_ANGLE GetHatchOrientation() const
Definition: zone.h:266
void SetLayerSet(LSET aLayerSet) override
Definition: zone.cpp:266
bool BuildSmoothedPoly(SHAPE_POLY_SET &aSmoothedPoly, PCB_LAYER_ID aLayer, SHAPE_POLY_SET *aBoardOutline, SHAPE_POLY_SET *aSmoothedPolyWithApron=nullptr) const
Definition: zone.cpp:1069
int m_fillVersion
Definition: zone.h:827
const VECTOR2I & GetCornerPosition(int aCornerIndex) const
Definition: zone.h:530
bool GetDoNotAllowFootprints() const
Definition: zone.h:702
ZONE_FILL_MODE GetFillMode() const
Definition: zone.h:174
double m_hatchHoleMinArea
Definition: zone.h:866
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: zone.h:122
bool GetDoNotAllowCopperPour() const
Definition: zone.h:698
void SetBorderHatchPitch(int aPitch)
Set the hatch pitch parameter for the zone.
Definition: zone.cpp:835
void GetInteractingZones(PCB_LAYER_ID aLayer, std::vector< ZONE * > *aSameNetCollidingZones, std::vector< ZONE * > *aOtherNetIntersectingZones) const
Some intersecting zones, despite being on the same layer with the same net, cannot be merged due to o...
Definition: zone.cpp:1034
int GetHatchGap() const
Definition: zone.h:263
double CalculateOutlineArea()
Compute the area of the zone outline (not the filled area).
Definition: zone.cpp:1218
unsigned m_priority
Definition: zone.h:802
bool IsConflicting() const
For rule areas which exclude footprints (and therefore participate in courtyard conflicts during move...
Definition: zone.cpp:227
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:889
ISLAND_REMOVAL_MODE m_islandRemovalMode
Definition: zone.h:829
bool m_isFilled
True when a zone was filled, false after deleting the filled areas.
Definition: zone.h:838
ZONE(BOARD_ITEM_CONTAINER *parent, bool aInFP=false)
The ctor to build ZONE, but compatible with FP_ZONE requirement.
Definition: zone.cpp:43
bool AppendCorner(VECTOR2I aPosition, int aHoleIdx, bool aAllowDuplication=false)
Add a new corner to the zone outline (to the main outline or a hole)
Definition: zone.cpp:760
void MoveEdge(const VECTOR2I &offset, int aEdge)
Move the outline Edge.
Definition: zone.cpp:669
int m_thermalReliefGap
Definition: zone.h:847
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: zone.cpp:309
bool IsOnCopperLayer() const override
Definition: zone.cpp:254
double CalculateFilledArea()
Compute the area currently occupied by the zone fill.
Definition: zone.cpp:1195
int m_hatchThickness
Definition: zone.h:858
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, 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:1320
void SetAssignedPriority(unsigned aPriority)
Definition: zone.h:107
double m_area
Definition: zone.h:898
unsigned int m_cornerRadius
Definition: zone.h:791
void SetPadConnection(ZONE_CONNECTION aPadConnection)
Definition: zone.h:249
void SetZoneName(const wxString &aName)
Definition: zone.h:125
void UnHatchBorder()
Clear the zone's hatch.
Definition: zone.cpp:841
PCB_LAYER_ID GetFirstLayer() const
Definition: zone.cpp:245
ZONE_CONNECTION m_PadConnection
Definition: zone.h:824
int GetThermalReliefGap() const
Definition: zone.h:184
void SetHatchGap(int aStep)
Definition: zone.h:264
static int GetDefaultHatchPitch()
Definition: zone.cpp:985
unsigned GetAssignedPriority() const
Definition: zone.h:112
int GetNumCorners(void) const
Access to m_Poly parameters.
Definition: zone.h:490
bool SameNet(const ZONE *aOther) const
Definition: zone.cpp:203
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: zone.cpp:1311
ZONE_BORDER_DISPLAY_STYLE m_borderStyle
Definition: zone.h:891
long long int m_minIslandArea
When island removal mode is set to AREA, islands below this area will be removed.
Definition: zone.h:835
#define _HKI(x)
#define _(s)
static constexpr EDA_ANGLE & FULL_CIRCLE
Definition: eda_angle.h:421
#define PCB_EDIT_FRAME_NAME
#define COURTYARD_CONFLICT
temporary set when moving footprints having courtyard overlapping
a few functions useful in geometry calculations.
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
@ ERROR_OUTSIDE
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)
Some functions to handle hotkeys in KiCad.
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
Definition: layer_ids.h:147
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:825
@ LAYER_CONFLICTS_SHADOW
shadow layer for items flagged conficting
Definition: layer_ids.h:241
@ LAYER_ZONES
Control for copper zone opacity/visibility (color ignored)
Definition: layer_ids.h:231
@ LAYER_MOD_FR
show footprints on front
Definition: layer_ids.h:208
@ LAYER_ZONE_START
Virtual layers for stacking zones and tracks on a given copper layer.
Definition: layer_ids.h:253
@ LAYER_MOD_BK
show footprints on back
Definition: layer_ids.h:209
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
@ B_Cu
Definition: layer_ids.h:95
@ UNDEFINED_LAYER
Definition: layer_ids.h:60
LSET FlipLayerMask(LSET aMask, int aCopperLayersCount)
Calculate the mask layer when flipping a footprint.
Definition: lset.cpp:590
constexpr int Mils2IU(const EDA_IU_SCALE &aIuScale, int mils)
Definition: eda_units.h:123
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:412
#define TYPE_HASH(x)
Definition: property.h:62
#define IMPLEMENT_ENUM_TO_WXANY(type)
Definition: property.h:673
#define NO_SETTER(owner, type)
Definition: property.h:684
@ PT_DEGREE
Angle expressed in degrees.
Definition: property.h:57
@ PT_COORD
Coordinate expressed in distance units (mm/inch)
Definition: property.h:56
@ PT_SIZE
Size expressed in distance units (mm/inch)
Definition: property.h:55
#define REGISTER_TYPE(x)
Definition: property_mgr.h:328
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
wxString UnescapeString(const wxString &aSource)
void AccumulateDescription(wxString &aDesc, const wxString &aItem)
Utility to build comma separated lists in messages.
Definition: string_utils.h:322
constexpr int mmToIU(double mm) const
Definition: base_units.h:89
Structure to hold the necessary information in order to index a vertex on a SHAPE_POLY_SET object: th...
ZONE_DESC()
Definition: zone.cpp:1357
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition: typeinfo.h:112
@ PCB_FP_ZONE_T
class ZONE, managed by a footprint
Definition: typeinfo.h:100
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:85
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618
static SHAPE_POLY_SET g_nullPoly
Definition: zone.cpp:384
bool sortEndsByDescendingX(const VECTOR2I &ref, const VECTOR2I &tst)
Definition: zone.cpp:849
static struct ZONE_DESC _ZONE_DESC
ZONE_FILL_MODE
Definition: zone_settings.h:41
ZONE_BORDER_DISPLAY_STYLE
Zone border styles.
Definition: zone_settings.h:49
ZONE_CONNECTION
How pads are covered by copper in zone.
Definition: zones.h:50
@ THERMAL
Use thermal relief for pads.
@ THT_THERMAL
Thermal relief only for THT pads.
@ NONE
Pads are not covered.
@ FULL
pads are covered by copper
#define ZONE_BORDER_HATCH_MINDIST_MM
Definition: zones.h:40
#define ZONE_THICKNESS_MIL
Definition: zones.h:35
#define ZONE_THERMAL_RELIEF_GAP_MIL
Definition: zones.h:33
#define ZONE_BORDER_HATCH_DIST_MIL
Definition: zones.h:39
#define ZONE_THERMAL_RELIEF_COPPER_WIDTH_MIL
Definition: zones.h:34
#define ZONE_BORDER_HATCH_MAXDIST_MM
Definition: zones.h:41