KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_shape.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) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
6 * Copyright (C) 2011 Wayne Stambaugh <[email protected]>
7 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include "pcb_shape.h"
28
29#include <google/protobuf/any.pb.h>
30#include <magic_enum.hpp>
31
32#include <bitmaps.h>
33#include <macros.h>
34#include <pcb_edit_frame.h>
36#include <board.h>
37#include <footprint.h>
38#include <lset.h>
39#include <pad.h>
40#include <base_units.h>
45#include <pcb_painter.h>
46#include <api/board/board_types.pb.h>
47#include <api/api_enums.h>
48#include <api/api_utils.h>
49
50
51PCB_SHAPE::PCB_SHAPE( BOARD_ITEM* aParent, KICAD_T aItemType, SHAPE_T aShapeType ) :
52 BOARD_CONNECTED_ITEM( aParent, aItemType ),
53 EDA_SHAPE( aShapeType, pcbIUScale.mmToIU( DEFAULT_LINE_WIDTH ), FILL_T::NO_FILL )
54{
55 m_hasSolderMask = false;
56}
57
58
59PCB_SHAPE::PCB_SHAPE( BOARD_ITEM* aParent, SHAPE_T shapetype ) :
61 EDA_SHAPE( shapetype, pcbIUScale.mmToIU( DEFAULT_LINE_WIDTH ), FILL_T::NO_FILL )
62{
63 m_hasSolderMask = false;
64}
65
66
68{
69}
70
71
72void PCB_SHAPE::CopyFrom( const BOARD_ITEM* aOther )
73{
74 wxCHECK( aOther && aOther->Type() == PCB_SHAPE_T, /* void */ );
75 *this = *static_cast<const PCB_SHAPE*>( aOther );
76}
77
78
79void PCB_SHAPE::Serialize( google::protobuf::Any &aContainer ) const
80{
81 using namespace kiapi::common;
82 using namespace kiapi::board::types;
83 BoardGraphicShape msg;
84
85 msg.set_layer( ToProtoEnum<PCB_LAYER_ID, BoardLayer>( GetLayer() ) );
86 PackNet( msg.mutable_net() );
87 msg.mutable_id()->set_value( m_Uuid.AsStdString() );
88 msg.set_locked( IsLocked() ? types::LockedState::LS_LOCKED : types::LockedState::LS_UNLOCKED );
89
90 google::protobuf::Any any;
92 any.UnpackTo( msg.mutable_shape() );
93
94 // TODO m_hasSolderMask and m_solderMaskMargin
95
96 aContainer.PackFrom( msg );
97}
98
99
100bool PCB_SHAPE::Deserialize( const google::protobuf::Any &aContainer )
101{
102 using namespace kiapi::common;
103 using namespace kiapi::board::types;
104
105 BoardGraphicShape msg;
106
107 if( !aContainer.UnpackTo( &msg ) )
108 return false;
109
110 // Initialize everything to a known state that doesn't get touched by every
111 // codepath below, to make sure the equality operator is consistent
112 m_start = {};
113 m_end = {};
114 m_arcCenter = {};
115 m_arcMidData = {};
116 m_bezierC1 = {};
117 m_bezierC2 = {};
118 m_editState = 0;
119 m_proxyItem = false;
120 m_endsSwapped = false;
121
122 const_cast<KIID&>( m_Uuid ) = KIID( msg.id().value() );
123 SetLocked( msg.locked() == types::LS_LOCKED );
124 SetLayer( FromProtoEnum<PCB_LAYER_ID, BoardLayer>( msg.layer() ) );
125 UnpackNet( msg.net() );
126
127 google::protobuf::Any any;
128 any.PackFrom( msg.shape() );
130
131 // TODO m_hasSolderMask and m_solderMaskMargin
132
133 return true;
134}
135
136
137bool PCB_SHAPE::IsType( const std::vector<KICAD_T>& aScanTypes ) const
138{
139 if( BOARD_ITEM::IsType( aScanTypes ) )
140 return true;
141
142 bool sametype = false;
143
144 for( KICAD_T scanType : aScanTypes )
145 {
146 if( scanType == PCB_LOCATE_BOARD_EDGE_T )
147 sametype = m_layer == Edge_Cuts;
148 else if( scanType == PCB_SHAPE_LOCATE_ARC_T )
149 sametype = m_shape == SHAPE_T::ARC;
150 else if( scanType == PCB_SHAPE_LOCATE_CIRCLE_T )
151 sametype = m_shape == SHAPE_T::CIRCLE;
152 else if( scanType == PCB_SHAPE_LOCATE_RECT_T )
153 sametype = m_shape == SHAPE_T::RECTANGLE;
154 else if( scanType == PCB_SHAPE_LOCATE_SEGMENT_T )
155 sametype = m_shape == SHAPE_T::SEGMENT;
156 else if( scanType == PCB_SHAPE_LOCATE_POLY_T )
157 sametype = m_shape == SHAPE_T::POLY;
158 else if( scanType == PCB_SHAPE_LOCATE_BEZIER_T )
159 sametype = m_shape == SHAPE_T::BEZIER;
160
161 if( sametype )
162 return true;
163 }
164
165 return false;
166}
167
168
170{
171 // Only board-level copper shapes are connectable
172 return IsOnCopperLayer() && !GetParentFootprint();
173}
174
175
177{
178 BOARD_ITEM::SetLayer( aLayer );
179
180 if( !IsOnCopperLayer() )
181 SetNetCode( -1 );
182}
183
184
186{
187 int margin = 0;
188
189 if( const BOARD* board = GetBoard() )
190 {
191 DRC_CONSTRAINT constraint;
192 std::shared_ptr<DRC_ENGINE> drcEngine = board->GetDesignSettings().m_DRCEngine;
193
194 constraint = drcEngine->EvalRules( SOLDER_MASK_EXPANSION_CONSTRAINT, this, nullptr, m_layer );
195
196 if( constraint.m_Value.HasOpt() )
197 margin = constraint.m_Value.Opt();
198 }
199 else if( m_solderMaskMargin.has_value() )
200 {
201 margin = m_solderMaskMargin.value();
202 }
203
204 // Ensure the resulting mask opening has a non-negative size
205 if( margin < 0 && !IsSolidFill() )
206 margin = std::max( margin, -GetWidth() / 2 );
207
208 return margin;
209}
210
211
213{
214 if( aLayer == m_layer )
215 {
216 return true;
217 }
218
220 && ( ( aLayer == F_Mask && m_layer == F_Cu )
221 || ( aLayer == B_Mask && m_layer == B_Cu ) ) )
222 {
223 return true;
224 }
225
226 return false;
227}
228
229
231{
232 LSET layermask( { m_layer } );
233
234 if( m_hasSolderMask )
235 {
236 if( layermask.test( F_Cu ) )
237 layermask.set( F_Mask );
238
239 if( layermask.test( B_Cu ) )
240 layermask.set( B_Mask );
241 }
242
243 return layermask;
244}
245
246
247void PCB_SHAPE::SetLayerSet( const LSET& aLayerSet )
248{
249 aLayerSet.RunOnLayers(
250 [&]( PCB_LAYER_ID layer )
251 {
252 if( IsCopperLayer( layer ) )
253 SetLayer( layer );
254 else if( IsSolderMaskLayer( layer ) )
255 SetHasSolderMask( true );
256 } );
257}
258
259
260std::vector<VECTOR2I> PCB_SHAPE::GetConnectionPoints() const
261{
262 std::vector<VECTOR2I> ret;
263
264 // For filled shapes, we may as well use a centroid
265 if( IsSolidFill() )
266 {
267 ret.emplace_back( GetCenter() );
268 return ret;
269 }
270
271 switch( m_shape )
272 {
273 case SHAPE_T::CIRCLE:
274 {
275 const CIRCLE circle( GetCenter(), GetRadius() );
276
277 for( const TYPED_POINT2I& pt : KIGEOM::GetCircleKeyPoints( circle, false ) )
278 ret.emplace_back( pt.m_point );
279
280 break;
281 }
282
283 case SHAPE_T::ARC:
284 ret.emplace_back( GetArcMid() );
286 case SHAPE_T::SEGMENT:
287 case SHAPE_T::BEZIER:
288 ret.emplace_back( GetStart() );
289 ret.emplace_back( GetEnd() );
290 break;
291
292 case SHAPE_T::POLY:
293 for( auto iter = GetPolyShape().CIterate(); iter; ++iter )
294 ret.emplace_back( *iter );
295
296 break;
297
298 case SHAPE_T::RECTANGLE:
299 for( const VECTOR2I& pt : GetRectCorners() )
300 ret.emplace_back( pt );
301
302 break;
303
304 case SHAPE_T::UNDEFINED:
306 break;
307 }
308
309 return ret;
310}
311
312
314{
315 // Force update; we don't bother to propagate damage from all the things that might
316 // knock-out parts of our hatching.
317 m_hatchingDirty = true;
318
320
321 if( !m_hatching.IsEmpty() )
322 {
323 PCB_LAYER_ID layer = GetLayer();
324 BOX2I bbox = GetBoundingBox();
325 SHAPE_POLY_SET holes;
326 int maxError = ARC_LOW_DEF;
327
328 auto knockoutItem =
329 [&]( BOARD_ITEM* item )
330 {
331 int margin = GetHatchLineSpacing() / 2;
332
333 if( item->Type() == PCB_TEXTBOX_T )
334 margin = 0;
335
336 item->TransformShapeToPolygon( holes, layer, margin, maxError, ERROR_OUTSIDE );
337 };
338
339 for( BOARD_ITEM* item : GetBoard()->Drawings() )
340 {
341 if( item == this )
342 continue;
343
344 if( item->Type() == PCB_FIELD_T
345 || item->Type() == PCB_TEXT_T
346 || item->Type() == PCB_TEXTBOX_T
347 || item->Type() == PCB_SHAPE_T )
348 {
349 if( item->GetLayer() == layer && item->GetBoundingBox().Intersects( bbox ) )
350 knockoutItem( item );
351 }
352 }
353
354 for( FOOTPRINT* footprint : GetBoard()->Footprints() )
355 {
356 if( footprint == GetParentFootprint() )
357 continue;
358
359 // Knockout footprint courtyard
360 holes.Append( footprint->GetCourtyard( layer ) );
361
362 // Knockout footprint fields
363 footprint->RunOnChildren(
364 [&]( BOARD_ITEM* item )
365 {
366 if( ( item->Type() == PCB_FIELD_T || item->Type() == PCB_SHAPE_T )
367 && item->GetLayer() == layer
368 && item->GetBoundingBox().Intersects( bbox ) )
369 {
370 knockoutItem( item );
371 }
372 },
373 RECURSE_MODE::RECURSE );
374 }
375
376 if( !holes.IsEmpty() )
377 {
380 }
381 }
382}
383
384
386{
387 // A stroke width of 0 in PCBNew means no-border, but negative stroke-widths are only used
388 // in EEschema (see SCH_SHAPE::GetPenWidth()).
389 // Since negative stroke widths can trip up down-stream code (such as the Gerber plotter), we
390 // weed them out here.
391 return std::max( EDA_SHAPE::GetWidth(), 0 );
392}
393
394
396{
398}
399
400
402{
403 // For some shapes return the visual center, but for not filled polygonal shapes,
404 // the center is usually far from the shape: a point on the outline is better
405
406 switch( m_shape )
407 {
408 case SHAPE_T::CIRCLE:
409 if( !IsAnyFill() )
410 return VECTOR2I( GetCenter().x + GetRadius(), GetCenter().y );
411 else
412 return GetCenter();
413
414 case SHAPE_T::RECTANGLE:
415 if( !IsAnyFill() )
416 return GetStart();
417 else
418 return GetCenter();
419
420 case SHAPE_T::POLY:
421 if( !IsAnyFill() )
422 {
423 VECTOR2I pos = GetPolyShape().Outline(0).CPoint(0);
424 return VECTOR2I( pos.x, pos.y );
425 }
426 else
427 {
428 return GetCenter();
429 }
430
431 case SHAPE_T::ARC:
432 return GetArcMid();
433
434 case SHAPE_T::BEZIER:
435 return GetStart();
436
437 default:
438 return GetCenter();
439 }
440}
441
442
443std::vector<VECTOR2I> PCB_SHAPE::GetCorners() const
444{
445 std::vector<VECTOR2I> pts;
446
447 if( GetShape() == SHAPE_T::RECTANGLE )
448 {
449 pts = GetRectCorners();
450 }
451 else if( GetShape() == SHAPE_T::POLY )
452 {
453 for( int ii = 0; ii < GetPolyShape().OutlineCount(); ++ii )
454 {
455 for( const VECTOR2I& pt : GetPolyShape().Outline( ii ).CPoints() )
456 pts.emplace_back( pt );
457 }
458 }
459 else
460 {
462 }
463
464 while( pts.size() < 4 )
465 pts.emplace_back( pts.back() + VECTOR2I( 10, 10 ) );
466
467 return pts;
468}
469
470
471void PCB_SHAPE::Move( const VECTOR2I& aMoveVector )
472{
473 move( aMoveVector );
474}
475
476
477void PCB_SHAPE::Scale( double aScale )
478{
479 scale( aScale );
480}
481
482
484{
485 if( m_shape == SHAPE_T::RECTANGLE )
486 {
487 VECTOR2I start = GetStart();
488 VECTOR2I end = GetEnd();
489
490 BOX2I rect( start, end - start );
491 rect.Normalize();
492
493 SetStart( rect.GetPosition() );
494 SetEnd( rect.GetEnd() );
495 }
496 else if( m_shape == SHAPE_T::POLY )
497 {
498 auto horizontal =
499 []( const SEG& seg )
500 {
501 return seg.A.y == seg.B.y;
502 };
503
504 auto vertical =
505 []( const SEG& seg )
506 {
507 return seg.A.x == seg.B.x;
508 };
509
510 // Convert a poly back to a rectangle if appropriate
511 if( m_poly.OutlineCount() == 1 && m_poly.Outline( 0 ).SegmentCount() == 4 )
512 {
513 SHAPE_LINE_CHAIN& outline = m_poly.Outline( 0 );
514
515 if( horizontal( outline.Segment( 0 ) )
516 && vertical( outline.Segment( 1 ) )
517 && horizontal( outline.Segment( 2 ) )
518 && vertical( outline.Segment( 3 ) ) )
519 {
520 m_shape = SHAPE_T::RECTANGLE;
521 m_start.x = std::min( outline.Segment( 0 ).A.x, outline.Segment( 0 ).B.x );
522 m_start.y = std::min( outline.Segment( 1 ).A.y, outline.Segment( 1 ).B.y );
523 m_end.x = std::max( outline.Segment( 0 ).A.x, outline.Segment( 0 ).B.x );
524 m_end.y = std::max( outline.Segment( 1 ).A.y, outline.Segment( 1 ).B.y );
525 }
526 else if( vertical( outline.Segment( 0 ) )
527 && horizontal( outline.Segment( 1 ) )
528 && vertical( outline.Segment( 2 ) )
529 && horizontal( outline.Segment( 3 ) ) )
530 {
531 m_shape = SHAPE_T::RECTANGLE;
532 m_start.x = std::min( outline.Segment( 1 ).A.x, outline.Segment( 1 ).B.x );
533 m_start.y = std::min( outline.Segment( 0 ).A.y, outline.Segment( 0 ).B.y );
534 m_end.x = std::max( outline.Segment( 1 ).A.x, outline.Segment( 1 ).B.x );
535 m_end.y = std::max( outline.Segment( 0 ).A.y, outline.Segment( 0 ).B.y );
536 }
537 }
538 }
539}
540
541
543{
544 if( m_shape == SHAPE_T::SEGMENT )
545 {
546 // we want start point the top left point and end point the bottom right
547 // (more easy to compare 2 segments: we are seeing them as equivalent if
548 // they have the same end points, not necessary the same order)
549 VECTOR2I start = GetStart();
550 VECTOR2I end = GetEnd();
551
552 if( ( start.x > end.x )
553 || ( start.x == end.x && start.y < end.y ) )
554 {
555 SetStart( end );
556 SetEnd( start );
557 }
558 }
559 else
560 Normalize();
561}
562
563
564void PCB_SHAPE::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
565{
566 rotate( aRotCentre, aAngle );
567}
568
569
570void PCB_SHAPE::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
571{
572 flip( aCentre, aFlipDirection );
573
575}
576
577
578void PCB_SHAPE::Mirror( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
579{
580 flip( aCentre, aFlipDirection );
581}
582
583
584void PCB_SHAPE::SetIsProxyItem( bool aIsProxy )
585{
586 PAD* parentPad = nullptr;
587
588 if( GetBoard() && GetBoard()->IsFootprintHolder() )
589 {
590 for( FOOTPRINT* fp : GetBoard()->Footprints() )
591 {
592 for( PAD* pad : fp->Pads() )
593 {
594 if( pad->IsEntered() )
595 {
596 parentPad = pad;
597 break;
598 }
599 }
600 }
601 }
602
603 if( aIsProxy && !m_proxyItem )
604 {
605 if( GetShape() == SHAPE_T::SEGMENT )
606 {
607 if( parentPad && parentPad->GetLocalThermalSpokeWidthOverride().has_value() )
608 SetWidth( parentPad->GetLocalThermalSpokeWidthOverride().value() );
609 else
611 }
612 else
613 {
614 SetWidth( 1 );
615 }
616 }
617 else if( m_proxyItem && !aIsProxy )
618 {
620 }
621
622 m_proxyItem = aIsProxy;
623}
624
625
626double PCB_SHAPE::ViewGetLOD( int aLayer, const KIGFX::VIEW* aView ) const
627{
628 KIGFX::PCB_PAINTER& painter = static_cast<KIGFX::PCB_PAINTER&>( *aView->GetPainter() );
629 KIGFX::PCB_RENDER_SETTINGS& renderSettings = *painter.GetSettings();
630
631 if( aLayer == LAYER_LOCKED_ITEM_SHADOW )
632 {
633 // Hide shadow if the main layer is not shown
634 if( !aView->IsLayerVisible( m_layer ) )
635 return LOD_HIDE;
636
637 // Hide shadow on dimmed tracks
638 if( renderSettings.GetHighContrast() )
639 {
640 if( m_layer != renderSettings.GetPrimaryHighContrastLayer() )
641 return LOD_HIDE;
642 }
643 }
644
645 if( FOOTPRINT* parent = GetParentFootprint() )
646 {
647 if( parent->GetLayer() == F_Cu && !aView->IsLayerVisible( LAYER_FOOTPRINTS_FR ) )
648 return LOD_HIDE;
649
650 if( parent->GetLayer() == B_Cu && !aView->IsLayerVisible( LAYER_FOOTPRINTS_BK ) )
651 return LOD_HIDE;
652 }
653
654 return LOD_SHOW;
655}
656
657
658std::vector<int> PCB_SHAPE::ViewGetLayers() const
659{
660 std::vector<int> layers;
661 layers.reserve( 4 );
662
663 layers.push_back( GetLayer() );
664
665 if( IsOnCopperLayer() )
666 {
667 layers.push_back( GetNetnameLayer( GetLayer() ) );
668
669 if( m_hasSolderMask )
670 {
671 if( m_layer == F_Cu )
672 layers.push_back( F_Mask );
673 else if( m_layer == B_Cu )
674 layers.push_back( B_Mask );
675 }
676 }
677
679 layers.push_back( LAYER_LOCKED_ITEM_SHADOW );
680
681 return layers;
682}
683
684
685void PCB_SHAPE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
686{
687 if( aFrame->GetName() == PCB_EDIT_FRAME_NAME )
688 {
689 if( FOOTPRINT* parent = GetParentFootprint() )
690 aList.emplace_back( _( "Footprint" ), parent->GetReference() );
691 }
692
693 aList.emplace_back( _( "Type" ), _( "Drawing" ) );
694
695 if( aFrame->GetName() == PCB_EDIT_FRAME_NAME && IsLocked() )
696 aList.emplace_back( _( "Status" ), _( "Locked" ) );
697
698 ShapeGetMsgPanelInfo( aFrame, aList );
699
700 aList.emplace_back( _( "Layer" ), GetLayerName() );
701}
702
703
704wxString PCB_SHAPE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
705{
706 FOOTPRINT* parentFP = GetParentFootprint();
707
708 // Don't report parent footprint info from footprint editor, viewer, etc.
709 if( GetBoard() && GetBoard()->GetBoardUse() == BOARD_USE::FPHOLDER )
710 parentFP = nullptr;
711
712 if( IsOnCopperLayer() )
713 {
714 if( parentFP )
715 {
716 return wxString::Format( _( "%s %s of %s on %s" ),
719 parentFP->GetReference(),
720 GetLayerName() );
721 }
722 else
723 {
724 return wxString::Format( _( "%s %s on %s" ),
727 GetLayerName() );
728 }
729 }
730 else
731 {
732 if( parentFP )
733 {
734 return wxString::Format( _( "%s of %s on %s" ),
736 parentFP->GetReference(),
737 GetLayerName() );
738 }
739 else
740 {
741 return wxString::Format( _( "%s on %s" ),
743 GetLayerName() );
744 }
745 }
746}
747
748
750{
751 if( GetParentFootprint() )
752 return BITMAPS::show_mod_edge;
753 else
754 return BITMAPS::add_dashed_line;
755}
756
757
759{
760 return new PCB_SHAPE( *this );
761}
762
763
765{
766 BOX2I return_box = EDA_ITEM::ViewBBox();
767
768 // Inflate the bounding box by just a bit more for safety.
769 return_box.Inflate( GetWidth() );
770
771 return return_box;
772}
773
774
775std::shared_ptr<SHAPE> PCB_SHAPE::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
776{
777 return std::make_shared<SHAPE_COMPOUND>( MakeEffectiveShapes() );
778}
779
780
782{
783 return GetMaxError();
784}
785
786
788{
789 PCB_SHAPE* image = dynamic_cast<PCB_SHAPE*>( aImage );
790 wxCHECK( image, /* void */ );
791
792 SwapShape( image );
793
794 // Swap params not handled by SwapShape( image )
795 std::swap( m_layer, image->m_layer );
796 std::swap( m_isKnockout, image->m_isKnockout );
797 std::swap( m_isLocked, image->m_isLocked );
798 std::swap( m_flags, image->m_flags );
799 std::swap( m_parent, image->m_parent );
800 std::swap( m_forceVisible, image->m_forceVisible );
801 std::swap( m_netinfo, image->m_netinfo );
802 std::swap( m_hasSolderMask, image->m_hasSolderMask );
803 std::swap( m_solderMaskMargin, image->m_solderMaskMargin );
804}
805
806
808 const BOARD_ITEM* aSecond ) const
809{
810 if( aFirst->Type() != aSecond->Type() )
811 return aFirst->Type() < aSecond->Type();
812
813 if( aFirst->GetLayer() != aSecond->GetLayer() )
814 return aFirst->GetLayer() < aSecond->GetLayer();
815
816 if( aFirst->Type() == PCB_SHAPE_T )
817 {
818 const PCB_SHAPE* dwgA = static_cast<const PCB_SHAPE*>( aFirst );
819 const PCB_SHAPE* dwgB = static_cast<const PCB_SHAPE*>( aSecond );
820
821 if( dwgA->GetShape() != dwgB->GetShape() )
822 return dwgA->GetShape() < dwgB->GetShape();
823 }
824
825 return aFirst->m_Uuid < aSecond->m_Uuid;
826}
827
828
830 int aClearance, int aError, ERROR_LOC aErrorLoc,
831 bool ignoreLineWidth ) const
832{
833 EDA_SHAPE::TransformShapeToPolygon( aBuffer, aClearance, aError, aErrorLoc, ignoreLineWidth,
834 false );
835}
836
837
839 int aClearance, int aError, ERROR_LOC aErrorLoc ) const
840{
841 EDA_SHAPE::TransformShapeToPolygon( aBuffer, aClearance, aError, aErrorLoc, false, true );
842}
843
844
845bool PCB_SHAPE::operator==( const BOARD_ITEM& aOther ) const
846{
847 if( aOther.Type() != Type() )
848 return false;
849
850 const PCB_SHAPE& other = static_cast<const PCB_SHAPE&>( aOther );
851
852 return *this == other;
853}
854
855
856bool PCB_SHAPE::operator==( const PCB_SHAPE& aOther ) const
857{
858 if( aOther.Type() != Type() )
859 return false;
860
861 const PCB_SHAPE& other = static_cast<const PCB_SHAPE&>( aOther );
862
863 if( m_layer != other.m_layer )
864 return false;
865
866 if( m_isKnockout != other.m_isKnockout )
867 return false;
868
869 if( m_isLocked != other.m_isLocked )
870 return false;
871
872 if( m_flags != other.m_flags )
873 return false;
874
875 if( m_forceVisible != other.m_forceVisible )
876 return false;
877
878 if( m_netinfo->GetNetCode() != other.m_netinfo->GetNetCode() )
879 return false;
880
881 if( m_hasSolderMask != other.m_hasSolderMask )
882 return false;
883
885 return false;
886
887 return EDA_SHAPE::operator==( other );
888}
889
890
891double PCB_SHAPE::Similarity( const BOARD_ITEM& aOther ) const
892{
893 if( aOther.Type() != Type() )
894 return 0.0;
895
896 const PCB_SHAPE& other = static_cast<const PCB_SHAPE&>( aOther );
897
898 double similarity = 1.0;
899
900 if( GetLayer() != other.GetLayer() )
901 similarity *= 0.9;
902
903 if( m_isKnockout != other.m_isKnockout )
904 similarity *= 0.9;
905
906 if( m_isLocked != other.m_isLocked )
907 similarity *= 0.9;
908
909 if( m_flags != other.m_flags )
910 similarity *= 0.9;
911
912 if( m_forceVisible != other.m_forceVisible )
913 similarity *= 0.9;
914
915 if( m_netinfo->GetNetCode() != other.m_netinfo->GetNetCode() )
916 similarity *= 0.9;
917
918 if( m_hasSolderMask != other.m_hasSolderMask )
919 similarity *= 0.9;
920
922 similarity *= 0.9;
923
924 similarity *= EDA_SHAPE::Similarity( other );
925
926 return similarity;
927}
928
929
930static struct PCB_SHAPE_DESC
931{
933 {
940
941 // Need to initialise enum_map before we can use a Property enum for it
943
944 if( layerEnum.Choices().GetCount() == 0 )
945 {
946 layerEnum.Undefined( UNDEFINED_LAYER );
947
948 for( PCB_LAYER_ID layer : LSET::AllLayersMask() )
949 layerEnum.Map( layer, LSET::Name( layer ) );
950 }
951
952 void ( PCB_SHAPE::*shapeLayerSetter )( PCB_LAYER_ID ) = &PCB_SHAPE::SetLayer;
953 PCB_LAYER_ID ( PCB_SHAPE::*shapeLayerGetter )() const = &PCB_SHAPE::GetLayer;
954
955 auto layerProperty = new PROPERTY_ENUM<PCB_SHAPE, PCB_LAYER_ID>(
956 _HKI( "Layer" ), shapeLayerSetter, shapeLayerGetter );
957
958 propMgr.ReplaceProperty( TYPE_HASH( BOARD_CONNECTED_ITEM ), _HKI( "Layer" ), layerProperty );
959
960 // Only polygons have meaningful Position properties.
961 // On other shapes, these are duplicates of the Start properties.
962 auto isPolygon =
963 []( INSPECTABLE* aItem ) -> bool
964 {
965 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
966 return shape->GetShape() == SHAPE_T::POLY;
967
968 return false;
969 };
970
972 _HKI( "Position X" ), isPolygon );
974 _HKI( "Position Y" ), isPolygon );
975
976 propMgr.Mask( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Color" ) );
977 propMgr.Mask( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ), _HKI( "Fill Color" ) );
978
979 // BEZIER curves are not closed shapes, and fill is not supported in board editor,
980 // only in schematic editor.
981 // So disable Fill option for Bezier curves
982 auto isNotBezier =
983 []( INSPECTABLE* aItem ) -> bool
984 {
985 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
986 return shape->GetShape() != SHAPE_T::BEZIER;
987
988 return true;
989 };
990
992 _HKI( "Fill" ), isNotBezier );
993
994 auto isCopper =
995 []( INSPECTABLE* aItem ) -> bool
996 {
997 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
998 return shape->IsOnCopperLayer();
999
1000 return false;
1001 };
1002
1004 _HKI( "Net" ), isCopper );
1005
1006 auto isPadEditMode =
1007 []( BOARD* aBoard ) -> bool
1008 {
1009 if( aBoard && aBoard->IsFootprintHolder() )
1010 {
1011 for( FOOTPRINT* fp : aBoard->Footprints() )
1012 {
1013 for( PAD* pad : fp->Pads() )
1014 {
1015 if( pad->IsEntered() )
1016 return true;
1017 }
1018 }
1019 }
1020
1021 return false;
1022 };
1023
1024 auto showNumberBoxProperty =
1025 [&]( INSPECTABLE* aItem ) -> bool
1026 {
1027 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1028 {
1029 if( shape->GetShape() == SHAPE_T::RECTANGLE )
1030 return isPadEditMode( shape->GetBoard() );
1031 }
1032
1033 return false;
1034 };
1035
1036 auto showSpokeTemplateProperty =
1037 [&]( INSPECTABLE* aItem ) -> bool
1038 {
1039 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1040 {
1041 if( shape->GetShape() == SHAPE_T::SEGMENT )
1042 return isPadEditMode( shape->GetBoard() );
1043 }
1044
1045 return false;
1046 };
1047
1048 const wxString groupPadPrimitives = _HKI( "Pad Primitives" );
1049
1050 propMgr.AddProperty( new PROPERTY<PCB_SHAPE, bool>( _HKI( "Number Box" ),
1053 groupPadPrimitives )
1054 .SetAvailableFunc( showNumberBoxProperty )
1056
1057 propMgr.AddProperty( new PROPERTY<PCB_SHAPE, bool>( _HKI( "Thermal Spoke Template" ),
1060 groupPadPrimitives )
1061 .SetAvailableFunc( showSpokeTemplateProperty )
1063
1064 const wxString groupTechLayers = _HKI( "Technical Layers" );
1065
1066 auto isExternalCuLayer =
1067 []( INSPECTABLE* aItem )
1068 {
1069 if( auto shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1070 return IsExternalCopperLayer( shape->GetLayer() );
1071
1072 return false;
1073 };
1074
1075 propMgr.AddProperty( new PROPERTY<PCB_SHAPE, bool>( _HKI( "Soldermask" ),
1078 groupTechLayers )
1079 .SetAvailableFunc( isExternalCuLayer );
1080
1081 propMgr.AddProperty( new PROPERTY<PCB_SHAPE, std::optional<int>>(
1082 _HKI( "Soldermask Margin Override" ),
1085 PROPERTY_DISPLAY::PT_SIZE ),
1086 groupTechLayers )
1087 .SetAvailableFunc( isExternalCuLayer );
1088 }
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
Definition: approximation.h:32
@ ERROR_OUTSIDE
Definition: approximation.h:33
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:112
constexpr int ARC_LOW_DEF
Definition: base_units.h:128
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
#define DEFAULT_LINE_WIDTH
BASE_SET & set(size_t pos)
Definition: base_set.h:116
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
wxString GetNetnameMsg() const
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
void PackNet(kiapi::board::types::Net *aProto) const
NETINFO_ITEM * m_netinfo
Store all information about the net that item belongs to.
void UnpackNet(const kiapi::board::types::Net &aProto)
Assigns a net to this item from an API message.
Container for design settings for a BOARD object.
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:79
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:232
void SetLocked(bool aLocked) override
Definition: board_item.h:323
bool m_isKnockout
Definition: board_item.h:454
PCB_LAYER_ID m_layer
Definition: board_item.h:453
bool m_isLocked
Definition: board_item.h:456
bool IsLocked() const override
Definition: board_item.cpp:103
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:280
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:79
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:97
virtual bool IsOnCopperLayer() const
Definition: board_item.h:151
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Definition: board_item.cpp:180
int GetMaxError() const
Definition: board_item.cpp:138
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:317
constexpr const Vec & GetPosition() const
Definition: box2.h:211
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:558
constexpr const Vec GetEnd() const
Definition: box2.h:212
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition: box2.h:146
constexpr bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:311
Represent basic circle geometry with utility geometry functions.
Definition: circle.h:33
MINOPTMAX< int > m_Value
Definition: drc_rule.h:202
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:98
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition: eda_item.cpp:110
const KIID m_Uuid
Definition: eda_item.h:516
bool m_forceVisible
Definition: eda_item.h:530
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:110
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:527
virtual bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
Definition: eda_item.h:192
virtual const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
Definition: eda_item.cpp:346
EDA_ITEM * m_parent
Owner.
Definition: eda_item.h:528
virtual int GetHatchLineSpacing() const
Definition: eda_shape.h:159
SHAPE_T m_shape
Definition: eda_shape.h:489
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false, bool includeFill=false) const
Convert the shape to a closed polygon.
Definition: eda_shape.cpp:2248
bool m_proxyItem
Definition: eda_shape.h:516
bool m_hatchingDirty
Definition: eda_shape.h:495
bool m_endsSwapped
Definition: eda_shape.h:488
int m_editState
Definition: eda_shape.h:515
void rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle)
Definition: eda_shape.cpp:795
SHAPE_POLY_SET m_hatching
Definition: eda_shape.h:494
virtual std::vector< SHAPE * > MakeEffectiveShapes(bool aEdgeOnly=false) const
Make a set of SHAPE objects representing the EDA_SHAPE.
Definition: eda_shape.h:379
SHAPE_POLY_SET & GetPolyShape()
Definition: eda_shape.h:337
void ShapeGetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList)
Definition: eda_shape.cpp:1150
bool operator==(const EDA_SHAPE &aOther) const
Definition: eda_shape.cpp:2397
int GetRadius() const
Definition: eda_shape.cpp:1005
SHAPE_T GetShape() const
Definition: eda_shape.h:168
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: eda_shape.cpp:237
VECTOR2I m_arcCenter
Definition: eda_shape.h:506
ARC_MID m_arcMidData
Definition: eda_shape.h:507
bool IsSolidFill() const
Definition: eda_shape.h:117
void flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection)
Definition: eda_shape.cpp:858
VECTOR2I m_start
Definition: eda_shape.h:503
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:215
void SetStart(const VECTOR2I &aStart)
Definition: eda_shape.h:177
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition: eda_shape.h:173
void SwapShape(EDA_SHAPE *aImage)
Definition: eda_shape.cpp:2182
std::vector< VECTOR2I > GetRectCorners() const
Definition: eda_shape.cpp:1599
bool IsAnyFill() const
Definition: eda_shape.h:112
virtual void UpdateHatching() const
Definition: eda_shape.cpp:573
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:219
wxString SHAPE_T_asString() const
Definition: eda_shape.cpp:343
double Similarity(const EDA_SHAPE &aOther) const
Definition: eda_shape.cpp:2442
VECTOR2I m_end
Definition: eda_shape.h:504
SHAPE_POLY_SET m_poly
Definition: eda_shape.h:513
virtual int GetWidth() const
Definition: eda_shape.h:156
STROKE_PARAMS m_stroke
Definition: eda_shape.h:490
VECTOR2I m_bezierC1
Definition: eda_shape.h:509
void SetWidth(int aWidth)
Definition: eda_shape.cpp:2375
VECTOR2I m_bezierC2
Definition: eda_shape.h:510
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: eda_shape.cpp:149
VECTOR2I GetArcMid() const
Definition: eda_shape.cpp:975
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition: property.h:703
static ENUM_MAP< T > & Instance()
Definition: property.h:697
ENUM_MAP & Undefined(T aValue)
Definition: property.h:710
wxPGChoices & Choices()
Definition: property.h:746
const wxString & GetReference() const
Definition: footprint.h:627
Class that other classes need to inherit from, in order to be inspectable.
Definition: inspectable.h:37
Contains methods for drawing PCB-specific items.
Definition: pcb_painter.h:182
virtual PCB_RENDER_SETTINGS * GetSettings() override
Return a pointer to current settings that are going to be used when drawing items.
Definition: pcb_painter.h:187
PCB specific render settings.
Definition: pcb_painter.h:80
PCB_LAYER_ID GetPrimaryHighContrastLayer() const
Return the board layer which is in high-contrast mode.
bool GetHighContrast() const
static constexpr double LOD_HIDE
Return this constant from ViewGetLOD() to hide the item unconditionally.
Definition: view_item.h:180
static constexpr double LOD_SHOW
Return this constant from ViewGetLOD() to show the item unconditionally.
Definition: view_item.h:185
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:66
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:422
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:220
Definition: kiid.h:49
std::string AsStdString() const
Definition: kiid.cpp:252
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:37
void RunOnLayers(const std::function< void(PCB_LAYER_ID)> &aFunction) const
Execute a function on each layer of the LSET.
Definition: lset.h:260
static const LSET & AllLayersMask()
Definition: lset.cpp:624
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:188
T Opt() const
Definition: minoptmax.h:35
bool HasOpt() const
Definition: minoptmax.h:39
int GetNetCode() const
Definition: netinfo.h:108
Definition: pad.h:54
std::optional< int > GetLocalThermalSpokeWidthOverride() const
Definition: pad.h:609
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: pcb_shape.h:121
virtual void Mirror(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Mirror this object relative to a given horizontal axis the layer is not changed.
Definition: pcb_shape.cpp:578
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: pcb_shape.cpp:685
void swapData(BOARD_ITEM *aImage) override
Definition: pcb_shape.cpp:787
bool IsConnected() const override
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
Definition: pcb_shape.cpp:169
double ViewGetLOD(int aLayer, const KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: pcb_shape.cpp:626
std::optional< int > GetLocalSolderMaskMargin() const
Definition: pcb_shape.h:198
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_shape.h:81
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
Definition: pcb_shape.cpp:564
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: pcb_shape.cpp:749
PCB_SHAPE(BOARD_ITEM *aParent, KICAD_T aItemType, SHAPE_T aShapeType)
Definition: pcb_shape.cpp:51
int GetWidth() const override
Definition: pcb_shape.cpp:385
const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
Definition: pcb_shape.cpp:764
bool HasSolderMask() const
Definition: pcb_shape.h:195
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const override
Make a set of SHAPE objects representing the PCB_SHAPE.
Definition: pcb_shape.cpp:775
void SetHasSolderMask(bool aVal)
Definition: pcb_shape.h:194
std::optional< int > m_solderMaskMargin
Definition: pcb_shape.h:220
int GetSolderMaskExpansion() const
Definition: pcb_shape.cpp:185
void NormalizeForCompare() override
Normalize coordinates to compare 2 similar PCB_SHAPES similat to Normalize(), but also normalize SEGM...
Definition: pcb_shape.cpp:542
const VECTOR2I GetFocusPosition() const override
Allows items to return their visual center rather than their anchor.
Definition: pcb_shape.cpp:401
virtual void SetLayerSet(const LSET &aLayers) override
Definition: pcb_shape.cpp:247
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
Definition: pcb_shape.cpp:570
virtual std::vector< VECTOR2I > GetCorners() const
Return 4 corners for a rectangle or rotated rectangle (stored as a poly).
Definition: pcb_shape.cpp:443
bool IsProxyItem() const override
Definition: pcb_shape.h:116
bool m_hasSolderMask
Definition: pcb_shape.h:219
~PCB_SHAPE() override
Definition: pcb_shape.cpp:67
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: pcb_shape.cpp:230
bool operator==(const PCB_SHAPE &aShape) const
Definition: pcb_shape.cpp:856
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition: pcb_shape.cpp:176
wxString GetFriendlyName() const override
Definition: pcb_shape.h:66
void TransformShapeToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc) const override
Convert the item shape to a polyset.
Definition: pcb_shape.cpp:838
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the shape to a closed polygon.
Definition: pcb_shape.cpp:829
void SetIsProxyItem(bool aIsProxy=true) override
Definition: pcb_shape.cpp:584
void StyleFromSettings(const BOARD_DESIGN_SETTINGS &settings) override
Definition: pcb_shape.cpp:395
void SetLocalSolderMaskMargin(std::optional< int > aMargin)
Definition: pcb_shape.h:197
void Move(const VECTOR2I &aMoveVector) override
Move this object.
Definition: pcb_shape.cpp:471
std::vector< VECTOR2I > GetConnectionPoints() const
Definition: pcb_shape.cpp:260
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: pcb_shape.cpp:100
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: pcb_shape.cpp:758
int getMaxError() const override
Definition: pcb_shape.cpp:781
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
Definition: pcb_shape.cpp:212
void UpdateHatching() const override
Definition: pcb_shape.cpp:313
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
Definition: pcb_shape.cpp:704
void Scale(double aScale)
Definition: pcb_shape.cpp:477
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: pcb_shape.cpp:79
void Normalize() override
Perform any normalization required after a user rotate and/or flip.
Definition: pcb_shape.cpp:483
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition: pcb_shape.cpp:137
void CopyFrom(const BOARD_ITEM *aOther) override
Definition: pcb_shape.cpp:72
std::vector< int > ViewGetLayers() const override
Definition: pcb_shape.cpp:658
double Similarity(const BOARD_ITEM &aBoardItem) const override
Return a measure of how likely the other object is to represent the same object.
Definition: pcb_shape.cpp:891
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: pcb_shape.h:71
PROPERTY_BASE & SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Set a callback function to determine whether an object provides this property.
Definition: property.h:258
PROPERTY_BASE & SetIsHiddenFromRulesEditor(bool aHide=true)
Definition: property.h:322
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.
void Mask(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName)
Sets a base class property as masked in a derived class.
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:76
PROPERTY_BASE & 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.
PROPERTY_BASE & ReplaceProperty(size_t aBase, const wxString &aName, PROPERTY_BASE *aNew, const wxString &aGroup=wxEmptyString)
Replace an existing property for a specific type.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
Definition: seg.h:42
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
SEG Segment(int aIndex) const
Return a copy of the aIndex-th segment in the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
int SegmentCount() const
Return the number of segments in this line chain.
const std::vector< VECTOR2I > & CPoints() const
Represent a set of closed polygons.
bool IsEmpty() const
Return true if the set is empty (no polygons at all)
void Fracture()
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
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)
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int OutlineCount() const
Return the number of outlines in the set.
void BooleanSubtract(const SHAPE_POLY_SET &b)
Perform boolean polyset difference.
void SetWidth(int aWidth)
#define _HKI(x)
@ SOLDER_MASK_EXPANSION_CONSTRAINT
Definition: drc_rule.h:66
#define _(s)
#define PCB_EDIT_FRAME_NAME
SHAPE_T
Definition: eda_shape.h:43
FILL_T
Definition: eda_shape.h:56
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition: layer_id.cpp:170
bool IsSolderMaskLayer(int aLayer)
Definition: layer_ids.h:735
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
Definition: layer_ids.h:184
int GetNetnameLayer(int aLayer)
Return a netname layer corresponding to the given layer.
Definition: layer_ids.h:841
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
Definition: layer_ids.h:665
@ LAYER_LOCKED_ITEM_SHADOW
Shadow layer for locked items.
Definition: layer_ids.h:306
@ LAYER_FOOTPRINTS_FR
Show footprints on front.
Definition: layer_ids.h:258
@ LAYER_FOOTPRINTS_BK
Show footprints on back.
Definition: layer_ids.h:259
bool IsExternalCopperLayer(int aLayerId)
Test whether a layer is an external (F_Cu or B_Cu) copper layer.
Definition: layer_ids.h:676
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ Edge_Cuts
Definition: layer_ids.h:112
@ B_Mask
Definition: layer_ids.h:98
@ B_Cu
Definition: layer_ids.h:65
@ F_Mask
Definition: layer_ids.h:97
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
@ F_Cu
Definition: layer_ids.h:64
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:96
FLIP_DIRECTION
Definition: mirror.h:27
std::vector< TYPED_POINT2I > GetCircleKeyPoints(const CIRCLE &aCircle, bool aIncludeCenter)
Get key points of an CIRCLE.
static struct PCB_SHAPE_DESC _PCB_SHAPE_DESC
static bool isCopper(const PNS::ITEM *aItem)
#define TYPE_HASH(x)
Definition: property.h:72
#define REGISTER_TYPE(x)
Definition: property_mgr.h:351
Utility functions for working with shapes.
const int scale
constexpr int mmToIU(double mm) const
Definition: base_units.h:92
bool operator()(const BOARD_ITEM *aFirst, const BOARD_ITEM *aSecond) const
Definition: pcb_shape.cpp:807
VECTOR2I end
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:88
@ PCB_LOCATE_BOARD_EDGE_T
Definition: typeinfo.h:131
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition: typeinfo.h:93
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition: typeinfo.h:92
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
Definition: typeinfo.h:90
@ PCB_SHAPE_LOCATE_CIRCLE_T
Definition: typeinfo.h:136
@ PCB_SHAPE_LOCATE_SEGMENT_T
Definition: typeinfo.h:134
@ PCB_SHAPE_LOCATE_RECT_T
Definition: typeinfo.h:135
@ PCB_SHAPE_LOCATE_BEZIER_T
Definition: typeinfo.h:139
@ PCB_SHAPE_LOCATE_POLY_T
Definition: typeinfo.h:138
@ PCB_SHAPE_LOCATE_ARC_T
Definition: typeinfo.h:137
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695
#define ZONE_THERMAL_RELIEF_COPPER_WIDTH_MM
Definition: zones.h:34