KiCad PCB EDA Suite
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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 <dick@softplc.com>
6 * Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
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 msg.mutable_net()->mutable_code()->set_value( GetNetCode() );
87 msg.mutable_net()->set_name( GetNetname() );
88 msg.mutable_id()->set_value( m_Uuid.AsStdString() );
89 msg.set_locked( IsLocked() ? types::LockedState::LS_LOCKED : types::LockedState::LS_UNLOCKED );
90
91 google::protobuf::Any any;
93 any.UnpackTo( msg.mutable_shape() );
94
95 // TODO m_hasSolderMask and m_solderMaskMargin
96
97 aContainer.PackFrom( msg );
98}
99
100
101bool PCB_SHAPE::Deserialize( const google::protobuf::Any &aContainer )
102{
103 using namespace kiapi::common;
104 using namespace kiapi::board::types;
105
106 BoardGraphicShape msg;
107
108 if( !aContainer.UnpackTo( &msg ) )
109 return false;
110
111 // Initialize everything to a known state that doesn't get touched by every
112 // codepath below, to make sure the equality operator is consistent
113 m_start = {};
114 m_end = {};
115 m_arcCenter = {};
116 m_arcMidData = {};
117 m_bezierC1 = {};
118 m_bezierC2 = {};
119 m_editState = 0;
120 m_proxyItem = false;
121 m_endsSwapped = false;
122
123 const_cast<KIID&>( m_Uuid ) = KIID( msg.id().value() );
124 SetLocked( msg.locked() == types::LS_LOCKED );
125 SetLayer( FromProtoEnum<PCB_LAYER_ID, BoardLayer>( msg.layer() ) );
126 SetNetCode( msg.net().code().value() );
127
128 google::protobuf::Any any;
129 any.PackFrom( msg.shape() );
131
132 // TODO m_hasSolderMask and m_solderMaskMargin
133
134 m_hatchingDirty = true;
135
136 return true;
137}
138
139
140bool PCB_SHAPE::IsType( const std::vector<KICAD_T>& aScanTypes ) const
141{
142 if( BOARD_ITEM::IsType( aScanTypes ) )
143 return true;
144
145 bool sametype = false;
146
147 for( KICAD_T scanType : aScanTypes )
148 {
149 if( scanType == PCB_LOCATE_BOARD_EDGE_T )
150 sametype = m_layer == Edge_Cuts;
151 else if( scanType == PCB_SHAPE_LOCATE_ARC_T )
152 sametype = m_shape == SHAPE_T::ARC;
153 else if( scanType == PCB_SHAPE_LOCATE_CIRCLE_T )
154 sametype = m_shape == SHAPE_T::CIRCLE;
155 else if( scanType == PCB_SHAPE_LOCATE_RECT_T )
156 sametype = m_shape == SHAPE_T::RECTANGLE;
157 else if( scanType == PCB_SHAPE_LOCATE_SEGMENT_T )
158 sametype = m_shape == SHAPE_T::SEGMENT;
159 else if( scanType == PCB_SHAPE_LOCATE_POLY_T )
160 sametype = m_shape == SHAPE_T::POLY;
161 else if( scanType == PCB_SHAPE_LOCATE_BEZIER_T )
162 sametype = m_shape == SHAPE_T::BEZIER;
163
164 if( sametype )
165 return true;
166 }
167
168 return false;
169}
170
171
173{
174 // Only board-level copper shapes are connectable
175 return IsOnCopperLayer() && !GetParentFootprint();
176}
177
178
180{
181 BOARD_ITEM::SetLayer( aLayer );
182
183 if( !IsOnCopperLayer() )
184 SetNetCode( -1 );
185}
186
187
189{
190 int margin = m_solderMaskMargin.value_or( 0 );
191
192 // If no local margin is set, get the board's solder mask expansion value
193 if( !m_solderMaskMargin.has_value() )
194 {
195 const BOARD* board = GetBoard();
196
197 if( board )
199 }
200
201 // Ensure the resulting mask opening has a non-negative size
202 if( margin < 0 && !IsSolidFill() )
203 margin = std::max( margin, -GetWidth() / 2 );
204
205 return margin;
206}
207
208
210{
211 if( aLayer == m_layer )
212 {
213 return true;
214 }
215
217 && ( ( aLayer == F_Mask && m_layer == F_Cu )
218 || ( aLayer == B_Mask && m_layer == B_Cu ) ) )
219 {
220 return true;
221 }
222
223 return false;
224}
225
226
228{
229 LSET layermask( { m_layer } );
230
231 if( m_hasSolderMask )
232 {
233 if( layermask.test( F_Cu ) )
234 layermask.set( F_Mask );
235
236 if( layermask.test( B_Cu ) )
237 layermask.set( B_Mask );
238 }
239
240 return layermask;
241}
242
243
244void PCB_SHAPE::SetLayerSet( const LSET& aLayerSet )
245{
246 aLayerSet.RunOnLayers(
247 [&]( PCB_LAYER_ID layer )
248 {
249 if( IsCopperLayer( layer ) )
250 SetLayer( layer );
251 else if( IsSolderMaskLayer( layer ) )
252 SetHasSolderMask( true );
253 } );
254}
255
256
257std::vector<VECTOR2I> PCB_SHAPE::GetConnectionPoints() const
258{
259 std::vector<VECTOR2I> ret;
260
261 // For filled shapes, we may as well use a centroid
262 if( IsSolidFill() )
263 {
264 ret.emplace_back( GetCenter() );
265 return ret;
266 }
267
268 switch( m_shape )
269 {
270 case SHAPE_T::CIRCLE:
271 {
272 const CIRCLE circle( GetCenter(), GetRadius() );
273
274 for( const TYPED_POINT2I& pt : KIGEOM::GetCircleKeyPoints( circle, false ) )
275 ret.emplace_back( pt.m_point );
276
277 break;
278 }
279
280 case SHAPE_T::ARC:
281 ret.emplace_back( GetArcMid() );
283 case SHAPE_T::SEGMENT:
284 case SHAPE_T::BEZIER:
285 ret.emplace_back( GetStart() );
286 ret.emplace_back( GetEnd() );
287 break;
288
289 case SHAPE_T::POLY:
290 for( auto iter = GetPolyShape().CIterate(); iter; ++iter )
291 ret.emplace_back( *iter );
292
293 break;
294
295 case SHAPE_T::RECTANGLE:
296 for( const VECTOR2I& pt : GetRectCorners() )
297 ret.emplace_back( pt );
298
299 break;
300
301 case SHAPE_T::UNDEFINED:
303 break;
304 }
305
306 return ret;
307}
308
309
311{
313
314 if( !m_hatching.IsEmpty() )
315 {
316 PCB_LAYER_ID layer = GetLayer();
317 BOX2I bbox = GetBoundingBox();
318 SHAPE_POLY_SET holes;
319 int maxError = ARC_LOW_DEF;
320
321 auto knockoutItem =
322 [&]( BOARD_ITEM* item )
323 {
324 int margin = GetHatchLineSpacing() / 2;
325
326 if( item->Type() == PCB_TEXTBOX_T )
327 margin = 0;
328
329 item->TransformShapeToPolygon( holes, layer, margin, maxError, ERROR_OUTSIDE );
330 };
331
332 for( BOARD_ITEM* item : GetBoard()->Drawings() )
333 {
334 if( item == this )
335 continue;
336
337 if( item->Type() == PCB_FIELD_T
338 || item->Type() == PCB_TEXT_T
339 || item->Type() == PCB_TEXTBOX_T
340 || item->Type() == PCB_SHAPE_T )
341 {
342 if( item->GetLayer() == layer && item->GetBoundingBox().Intersects( bbox ) )
343 knockoutItem( item );
344 }
345 }
346
347 for( FOOTPRINT* footprint : GetBoard()->Footprints() )
348 {
349 if( footprint == GetParentFootprint() )
350 continue;
351
352 // Knockout footprint courtyard
353 holes.Append( footprint->GetCourtyard( layer ) );
354
355 // Knockout footprint fields
356 footprint->RunOnChildren(
357 [&]( BOARD_ITEM* item )
358 {
359 if( item->Type() == PCB_FIELD_T
360 && item->GetLayer() == layer
361 && item->GetBoundingBox().Intersects( bbox ) )
362 {
363 knockoutItem( item );
364 }
365 },
366 RECURSE_MODE::RECURSE );
367 }
368
371 }
372}
373
374
376{
377 // A stroke width of 0 in PCBNew means no-border, but negative stroke-widths are only used
378 // in EEschema (see SCH_SHAPE::GetPenWidth()).
379 // Since negative stroke widths can trip up down-stream code (such as the Gerber plotter), we
380 // weed them out here.
381 return std::max( EDA_SHAPE::GetWidth(), 0 );
382}
383
384
386{
388}
389
390
392{
393 // For some shapes return the visual center, but for not filled polygonal shapes,
394 // the center is usually far from the shape: a point on the outline is better
395
396 switch( m_shape )
397 {
398 case SHAPE_T::CIRCLE:
399 if( !IsAnyFill() )
400 return VECTOR2I( GetCenter().x + GetRadius(), GetCenter().y );
401 else
402 return GetCenter();
403
404 case SHAPE_T::RECTANGLE:
405 if( !IsAnyFill() )
406 return GetStart();
407 else
408 return GetCenter();
409
410 case SHAPE_T::POLY:
411 if( !IsAnyFill() )
412 {
413 VECTOR2I pos = GetPolyShape().Outline(0).CPoint(0);
414 return VECTOR2I( pos.x, pos.y );
415 }
416 else
417 {
418 return GetCenter();
419 }
420
421 case SHAPE_T::ARC:
422 return GetArcMid();
423
424 case SHAPE_T::BEZIER:
425 return GetStart();
426
427 default:
428 return GetCenter();
429 }
430}
431
432
433std::vector<VECTOR2I> PCB_SHAPE::GetCorners() const
434{
435 std::vector<VECTOR2I> pts;
436
437 if( GetShape() == SHAPE_T::RECTANGLE )
438 {
439 pts = GetRectCorners();
440 }
441 else if( GetShape() == SHAPE_T::POLY )
442 {
443 for( int ii = 0; ii < GetPolyShape().OutlineCount(); ++ii )
444 {
445 for( const VECTOR2I& pt : GetPolyShape().Outline( ii ).CPoints() )
446 pts.emplace_back( pt );
447 }
448 }
449 else
450 {
452 }
453
454 while( pts.size() < 4 )
455 pts.emplace_back( pts.back() + VECTOR2I( 10, 10 ) );
456
457 return pts;
458}
459
460
461void PCB_SHAPE::Move( const VECTOR2I& aMoveVector )
462{
463 move( aMoveVector );
464}
465
466
467void PCB_SHAPE::Scale( double aScale )
468{
469 scale( aScale );
470}
471
472
474{
475 if( m_shape == SHAPE_T::RECTANGLE )
476 {
477 VECTOR2I start = GetStart();
478 VECTOR2I end = GetEnd();
479
480 BOX2I rect( start, end - start );
481 rect.Normalize();
482
483 SetStart( rect.GetPosition() );
484 SetEnd( rect.GetEnd() );
485 }
486 else if( m_shape == SHAPE_T::POLY )
487 {
488 auto horizontal =
489 []( const SEG& seg )
490 {
491 return seg.A.y == seg.B.y;
492 };
493
494 auto vertical =
495 []( const SEG& seg )
496 {
497 return seg.A.x == seg.B.x;
498 };
499
500 // Convert a poly back to a rectangle if appropriate
501 if( m_poly.OutlineCount() == 1 && m_poly.Outline( 0 ).SegmentCount() == 4 )
502 {
503 SHAPE_LINE_CHAIN& outline = m_poly.Outline( 0 );
504
505 if( horizontal( outline.Segment( 0 ) )
506 && vertical( outline.Segment( 1 ) )
507 && horizontal( outline.Segment( 2 ) )
508 && vertical( outline.Segment( 3 ) ) )
509 {
510 m_shape = SHAPE_T::RECTANGLE;
511 m_start.x = std::min( outline.Segment( 0 ).A.x, outline.Segment( 0 ).B.x );
512 m_start.y = std::min( outline.Segment( 1 ).A.y, outline.Segment( 1 ).B.y );
513 m_end.x = std::max( outline.Segment( 0 ).A.x, outline.Segment( 0 ).B.x );
514 m_end.y = std::max( outline.Segment( 1 ).A.y, outline.Segment( 1 ).B.y );
515 }
516 else if( vertical( outline.Segment( 0 ) )
517 && horizontal( outline.Segment( 1 ) )
518 && vertical( outline.Segment( 2 ) )
519 && horizontal( outline.Segment( 3 ) ) )
520 {
521 m_shape = SHAPE_T::RECTANGLE;
522 m_start.x = std::min( outline.Segment( 1 ).A.x, outline.Segment( 1 ).B.x );
523 m_start.y = std::min( outline.Segment( 0 ).A.y, outline.Segment( 0 ).B.y );
524 m_end.x = std::max( outline.Segment( 1 ).A.x, outline.Segment( 1 ).B.x );
525 m_end.y = std::max( outline.Segment( 0 ).A.y, outline.Segment( 0 ).B.y );
526 }
527 }
528 }
529}
530
531
533{
534 if( m_shape == SHAPE_T::SEGMENT )
535 {
536 // we want start point the top left point and end point the bottom right
537 // (more easy to compare 2 segments: we are seeing them as equivalent if
538 // they have the same end points, not necessary the same order)
539 VECTOR2I start = GetStart();
540 VECTOR2I end = GetEnd();
541
542 if( ( start.x > end.x )
543 || ( start.x == end.x && start.y < end.y ) )
544 {
545 SetStart( end );
546 SetEnd( start );
547 }
548 }
549 else
550 Normalize();
551}
552
553
554void PCB_SHAPE::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
555{
556 rotate( aRotCentre, aAngle );
557}
558
559
560void PCB_SHAPE::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
561{
562 flip( aCentre, aFlipDirection );
563
565}
566
567
568void PCB_SHAPE::Mirror( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
569{
570 // Mirror an edge of the footprint. the layer is not modified
571 // This is a footprint shape modification.
572
573 switch( GetShape() )
574 {
575 case SHAPE_T::ARC:
576 case SHAPE_T::SEGMENT:
577 case SHAPE_T::RECTANGLE:
578 case SHAPE_T::CIRCLE:
579 case SHAPE_T::BEZIER:
580 MIRROR( m_start, aCentre, aFlipDirection );
581 MIRROR( m_end, aCentre, aFlipDirection );
582 MIRROR( m_arcCenter, aCentre, aFlipDirection );
583 MIRROR( m_bezierC1, aCentre, aFlipDirection );
584 MIRROR( m_bezierC2, aCentre, aFlipDirection );
585
586 if( GetShape() == SHAPE_T::ARC )
587 std::swap( m_start, m_end );
588
589 if( GetShape() == SHAPE_T::BEZIER )
591
592 break;
593
594 case SHAPE_T::POLY:
595 m_poly.Mirror( aCentre, aFlipDirection );
596 break;
597
598 default:
600 }
601
602 m_hatchingDirty = true;
603}
604
605
606void PCB_SHAPE::SetIsProxyItem( bool aIsProxy )
607{
608 PAD* parentPad = nullptr;
609
610 if( GetBoard() && GetBoard()->IsFootprintHolder() )
611 {
612 for( FOOTPRINT* fp : GetBoard()->Footprints() )
613 {
614 for( PAD* pad : fp->Pads() )
615 {
616 if( pad->IsEntered() )
617 {
618 parentPad = pad;
619 break;
620 }
621 }
622 }
623 }
624
625 if( aIsProxy && !m_proxyItem )
626 {
627 if( GetShape() == SHAPE_T::SEGMENT )
628 {
629 if( parentPad && parentPad->GetLocalThermalSpokeWidthOverride().has_value() )
630 SetWidth( parentPad->GetLocalThermalSpokeWidthOverride().value() );
631 else
633 }
634 else
635 {
636 SetWidth( 1 );
637 }
638 }
639 else if( m_proxyItem && !aIsProxy )
640 {
642 }
643
644 m_proxyItem = aIsProxy;
645}
646
647
648double PCB_SHAPE::ViewGetLOD( int aLayer, const KIGFX::VIEW* aView ) const
649{
650 KIGFX::PCB_PAINTER& painter = static_cast<KIGFX::PCB_PAINTER&>( *aView->GetPainter() );
651 KIGFX::PCB_RENDER_SETTINGS& renderSettings = *painter.GetSettings();
652
653 if( aLayer == LAYER_LOCKED_ITEM_SHADOW )
654 {
655 // Hide shadow if the main layer is not shown
656 if( !aView->IsLayerVisible( m_layer ) )
657 return LOD_HIDE;
658
659 // Hide shadow on dimmed tracks
660 if( renderSettings.GetHighContrast() )
661 {
662 if( m_layer != renderSettings.GetPrimaryHighContrastLayer() )
663 return LOD_HIDE;
664 }
665 }
666
667 if( FOOTPRINT* parent = GetParentFootprint() )
668 {
669 if( parent->GetLayer() == F_Cu && !aView->IsLayerVisible( LAYER_FOOTPRINTS_FR ) )
670 return LOD_HIDE;
671
672 if( parent->GetLayer() == B_Cu && !aView->IsLayerVisible( LAYER_FOOTPRINTS_BK ) )
673 return LOD_HIDE;
674 }
675
676 return LOD_SHOW;
677}
678
679
680std::vector<int> PCB_SHAPE::ViewGetLayers() const
681{
682 std::vector<int> layers;
683 layers.reserve( 4 );
684
685 layers.push_back( GetLayer() );
686
687 if( IsOnCopperLayer() )
688 {
689 layers.push_back( GetNetnameLayer( GetLayer() ) );
690
691 if( m_hasSolderMask )
692 {
693 if( m_layer == F_Cu )
694 layers.push_back( F_Mask );
695 else if( m_layer == B_Cu )
696 layers.push_back( B_Mask );
697 }
698 }
699
700 if( IsLocked() )
701 layers.push_back( LAYER_LOCKED_ITEM_SHADOW );
702
703 return layers;
704}
705
706
707void PCB_SHAPE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
708{
709 if( aFrame->GetName() == PCB_EDIT_FRAME_NAME )
710 {
711 if( FOOTPRINT* parent = GetParentFootprint() )
712 aList.emplace_back( _( "Footprint" ), parent->GetReference() );
713 }
714
715 aList.emplace_back( _( "Type" ), _( "Drawing" ) );
716
717 if( aFrame->GetName() == PCB_EDIT_FRAME_NAME && IsLocked() )
718 aList.emplace_back( _( "Status" ), _( "Locked" ) );
719
720 ShapeGetMsgPanelInfo( aFrame, aList );
721
722 aList.emplace_back( _( "Layer" ), GetLayerName() );
723}
724
725
726wxString PCB_SHAPE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
727{
728 FOOTPRINT* parentFP = GetParentFootprint();
729
730 // Don't report parent footprint info from footprint editor, viewer, etc.
731 if( GetBoard() && GetBoard()->GetBoardUse() == BOARD_USE::FPHOLDER )
732 parentFP = nullptr;
733
734 if( IsOnCopperLayer() )
735 {
736 if( parentFP )
737 {
738 return wxString::Format( _( "%s %s of %s on %s" ),
741 parentFP->GetReference(),
742 GetLayerName() );
743 }
744 else
745 {
746 return wxString::Format( _( "%s %s on %s" ),
749 GetLayerName() );
750 }
751 }
752 else
753 {
754 if( parentFP )
755 {
756 return wxString::Format( _( "%s of %s on %s" ),
758 parentFP->GetReference(),
759 GetLayerName() );
760 }
761 else
762 {
763 return wxString::Format( _( "%s on %s" ),
765 GetLayerName() );
766 }
767 }
768}
769
770
772{
773 if( GetParentFootprint() )
774 return BITMAPS::show_mod_edge;
775 else
776 return BITMAPS::add_dashed_line;
777}
778
779
781{
782 return new PCB_SHAPE( *this );
783}
784
785
787{
788 BOX2I return_box = EDA_ITEM::ViewBBox();
789
790 // Inflate the bounding box by just a bit more for safety.
791 return_box.Inflate( GetWidth() );
792
793 return return_box;
794}
795
796
797std::shared_ptr<SHAPE> PCB_SHAPE::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
798{
799 return std::make_shared<SHAPE_COMPOUND>( MakeEffectiveShapes() );
800}
801
802
804{
805 PCB_SHAPE* image = dynamic_cast<PCB_SHAPE*>( aImage );
806 wxCHECK( image, /* void */ );
807
808 SwapShape( image );
809
810 // Swap params not handled by SwapShape( image )
811 std::swap( m_layer, image->m_layer );
812 std::swap( m_isKnockout, image->m_isKnockout );
813 std::swap( m_isLocked, image->m_isLocked );
814 std::swap( m_flags, image->m_flags );
815 std::swap( m_parent, image->m_parent );
816 std::swap( m_forceVisible, image->m_forceVisible );
817 std::swap( m_netinfo, image->m_netinfo );
818 std::swap( m_hasSolderMask, image->m_hasSolderMask );
819 std::swap( m_solderMaskMargin, image->m_solderMaskMargin );
820}
821
822
824 const BOARD_ITEM* aSecond ) const
825{
826 if( aFirst->Type() != aSecond->Type() )
827 return aFirst->Type() < aSecond->Type();
828
829 if( aFirst->GetLayer() != aSecond->GetLayer() )
830 return aFirst->GetLayer() < aSecond->GetLayer();
831
832 if( aFirst->Type() == PCB_SHAPE_T )
833 {
834 const PCB_SHAPE* dwgA = static_cast<const PCB_SHAPE*>( aFirst );
835 const PCB_SHAPE* dwgB = static_cast<const PCB_SHAPE*>( aSecond );
836
837 if( dwgA->GetShape() != dwgB->GetShape() )
838 return dwgA->GetShape() < dwgB->GetShape();
839 }
840
841 return aFirst->m_Uuid < aSecond->m_Uuid;
842}
843
844
846 int aClearance, int aError, ERROR_LOC aErrorLoc,
847 bool ignoreLineWidth ) const
848{
849 EDA_SHAPE::TransformShapeToPolygon( aBuffer, aClearance, aError, aErrorLoc, ignoreLineWidth,
850 false );
851}
852
853
855 int aClearance, int aError, ERROR_LOC aErrorLoc ) const
856{
857 EDA_SHAPE::TransformShapeToPolygon( aBuffer, aClearance, aError, aErrorLoc, false, true );
858}
859
860
861bool PCB_SHAPE::operator==( const BOARD_ITEM& aOther ) const
862{
863 if( aOther.Type() != Type() )
864 return false;
865
866 const PCB_SHAPE& other = static_cast<const PCB_SHAPE&>( aOther );
867
868 return *this == other;
869}
870
871
872bool PCB_SHAPE::operator==( const PCB_SHAPE& aOther ) const
873{
874 if( aOther.Type() != Type() )
875 return false;
876
877 const PCB_SHAPE& other = static_cast<const PCB_SHAPE&>( aOther );
878
879 if( m_layer != other.m_layer )
880 return false;
881
882 if( m_isKnockout != other.m_isKnockout )
883 return false;
884
885 if( m_isLocked != other.m_isLocked )
886 return false;
887
888 if( m_flags != other.m_flags )
889 return false;
890
891 if( m_forceVisible != other.m_forceVisible )
892 return false;
893
894 if( m_netinfo->GetNetCode() != other.m_netinfo->GetNetCode() )
895 return false;
896
897 if( m_hasSolderMask != other.m_hasSolderMask )
898 return false;
899
901 return false;
902
903 return EDA_SHAPE::operator==( other );
904}
905
906
907double PCB_SHAPE::Similarity( const BOARD_ITEM& aOther ) const
908{
909 if( aOther.Type() != Type() )
910 return 0.0;
911
912 const PCB_SHAPE& other = static_cast<const PCB_SHAPE&>( aOther );
913
914 double similarity = 1.0;
915
916 if( GetLayer() != other.GetLayer() )
917 similarity *= 0.9;
918
919 if( m_isKnockout != other.m_isKnockout )
920 similarity *= 0.9;
921
922 if( m_isLocked != other.m_isLocked )
923 similarity *= 0.9;
924
925 if( m_flags != other.m_flags )
926 similarity *= 0.9;
927
928 if( m_forceVisible != other.m_forceVisible )
929 similarity *= 0.9;
930
931 if( m_netinfo->GetNetCode() != other.m_netinfo->GetNetCode() )
932 similarity *= 0.9;
933
934 if( m_hasSolderMask != other.m_hasSolderMask )
935 similarity *= 0.9;
936
938 similarity *= 0.9;
939
940 similarity *= EDA_SHAPE::Similarity( other );
941
942 return similarity;
943}
944
945
946static struct PCB_SHAPE_DESC
947{
949 {
956
957 // Need to initialise enum_map before we can use a Property enum for it
959
960 if( layerEnum.Choices().GetCount() == 0 )
961 {
962 layerEnum.Undefined( UNDEFINED_LAYER );
963
964 for( PCB_LAYER_ID layer : LSET::AllLayersMask().Seq() )
965 layerEnum.Map( layer, LSET::Name( layer ) );
966 }
967
968 void ( PCB_SHAPE::*shapeLayerSetter )( PCB_LAYER_ID ) = &PCB_SHAPE::SetLayer;
969 PCB_LAYER_ID ( PCB_SHAPE::*shapeLayerGetter )() const = &PCB_SHAPE::GetLayer;
970
971 auto layerProperty = new PROPERTY_ENUM<PCB_SHAPE, PCB_LAYER_ID>(
972 _HKI( "Layer" ), shapeLayerSetter, shapeLayerGetter );
973
974 propMgr.ReplaceProperty( TYPE_HASH( BOARD_CONNECTED_ITEM ), _HKI( "Layer" ), layerProperty );
975
976 // Only polygons have meaningful Position properties.
977 // On other shapes, these are duplicates of the Start properties.
978 auto isPolygon =
979 []( INSPECTABLE* aItem ) -> bool
980 {
981 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
982 return shape->GetShape() == SHAPE_T::POLY;
983
984 return false;
985 };
986
988 _HKI( "Position X" ), isPolygon );
990 _HKI( "Position Y" ), isPolygon );
991
992 propMgr.Mask( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Color" ) );
993 propMgr.Mask( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ), _HKI( "Fill Color" ) );
994
995 auto isCopper =
996 []( INSPECTABLE* aItem ) -> bool
997 {
998 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
999 return shape->IsOnCopperLayer();
1000
1001 return false;
1002 };
1003
1005 _HKI( "Net" ), isCopper );
1006
1007 auto isPadEditMode =
1008 []( BOARD* aBoard ) -> bool
1009 {
1010 if( aBoard && aBoard->IsFootprintHolder() )
1011 {
1012 for( FOOTPRINT* fp : aBoard->Footprints() )
1013 {
1014 for( PAD* pad : fp->Pads() )
1015 {
1016 if( pad->IsEntered() )
1017 return true;
1018 }
1019 }
1020 }
1021
1022 return false;
1023 };
1024
1025 auto showNumberBoxProperty =
1026 [&]( INSPECTABLE* aItem ) -> bool
1027 {
1028 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1029 {
1030 if( shape->GetShape() == SHAPE_T::RECTANGLE )
1031 return isPadEditMode( shape->GetBoard() );
1032 }
1033
1034 return false;
1035 };
1036
1037 auto showSpokeTemplateProperty =
1038 [&]( INSPECTABLE* aItem ) -> bool
1039 {
1040 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1041 {
1042 if( shape->GetShape() == SHAPE_T::SEGMENT )
1043 return isPadEditMode( shape->GetBoard() );
1044 }
1045
1046 return false;
1047 };
1048
1049 const wxString groupPadPrimitives = _HKI( "Pad Primitives" );
1050
1051 propMgr.AddProperty( new PROPERTY<PCB_SHAPE, bool>( _HKI( "Number Box" ),
1054 groupPadPrimitives )
1055 .SetAvailableFunc( showNumberBoxProperty )
1057
1058 propMgr.AddProperty( new PROPERTY<PCB_SHAPE, bool>( _HKI( "Thermal Spoke Template" ),
1061 groupPadPrimitives )
1062 .SetAvailableFunc( showSpokeTemplateProperty )
1064
1065 const wxString groupTechLayers = _HKI( "Technical Layers" );
1066
1067 auto isExternalCuLayer =
1068 []( INSPECTABLE* aItem )
1069 {
1070 if( auto shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1071 return IsExternalCopperLayer( shape->GetLayer() );
1072
1073 return false;
1074 };
1075
1076 propMgr.AddProperty( new PROPERTY<PCB_SHAPE, bool>( _HKI( "Soldermask" ),
1079 groupTechLayers )
1080 .SetAvailableFunc( isExternalCuLayer );
1081
1082 propMgr.AddProperty( new PROPERTY<PCB_SHAPE, std::optional<int>>(
1083 _HKI( "Soldermask Margin Override" ),
1086 PROPERTY_DISPLAY::PT_SIZE ),
1087 groupTechLayers )
1088 .SetAvailableFunc( isExternalCuLayer );
1089 }
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 int ARC_HIGH_DEF
Definition: base_units.h:120
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
constexpr int ARC_LOW_DEF
Definition: base_units.h:119
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.
NETINFO_ITEM * m_netinfo
Store all information about the net that item belongs to.
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:78
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:235
bool m_isKnockout
Definition: board_item.h:452
virtual void SetLocked(bool aLocked)
Definition: board_item.h:326
PCB_LAYER_ID m_layer
Definition: board_item.h:451
bool m_isLocked
Definition: board_item.h:454
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:286
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:54
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:305
virtual bool IsLocked() const
Definition: board_item.cpp:82
virtual bool IsOnCopperLayer() const
Definition: board_item.h:154
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Definition: board_item.cpp:146
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:297
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:946
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
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:95
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition: eda_item.cpp:81
const KIID m_Uuid
Definition: eda_item.h:494
bool m_forceVisible
Definition: eda_item.h:507
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:107
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:505
virtual bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
Definition: eda_item.h:180
virtual const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
Definition: eda_item.cpp:315
EDA_ITEM * m_parent
Linked list: Link (parent struct).
Definition: eda_item.h:506
virtual int GetHatchLineSpacing() const
Definition: eda_shape.h:159
SHAPE_T m_shape
Definition: eda_shape.h:484
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:2176
bool m_proxyItem
Definition: eda_shape.h:511
bool m_hatchingDirty
Definition: eda_shape.h:490
bool m_endsSwapped
Definition: eda_shape.h:483
int m_editState
Definition: eda_shape.h:510
void rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle)
Definition: eda_shape.cpp:751
SHAPE_POLY_SET m_hatching
Definition: eda_shape.h:489
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:1103
bool operator==(const EDA_SHAPE &aOther) const
Definition: eda_shape.cpp:2325
int GetRadius() const
Definition: eda_shape.cpp:961
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:234
virtual void updateHatching() const
Definition: eda_shape.cpp:581
VECTOR2I m_arcCenter
Definition: eda_shape.h:501
ARC_MID m_arcMidData
Definition: eda_shape.h:502
void RebuildBezierToSegmentsPointsList(int aMaxError)
Rebuild the m_bezierPoints vertex list that approximate the Bezier curve by a list of segments.
Definition: eda_shape.cpp:859
bool IsSolidFill() const
Definition: eda_shape.h:117
void flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection)
Definition: eda_shape.cpp:814
VECTOR2I m_start
Definition: eda_shape.h:498
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:2110
std::vector< VECTOR2I > GetRectCorners() const
Definition: eda_shape.cpp:1544
bool IsAnyFill() const
Definition: eda_shape.h:112
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:219
wxString SHAPE_T_asString() const
Definition: eda_shape.cpp:340
double Similarity(const EDA_SHAPE &aOther) const
Definition: eda_shape.cpp:2370
VECTOR2I m_end
Definition: eda_shape.h:499
SHAPE_POLY_SET m_poly
Definition: eda_shape.h:508
virtual int GetWidth() const
Definition: eda_shape.h:156
STROKE_PARAMS m_stroke
Definition: eda_shape.h:485
VECTOR2I m_bezierC1
Definition: eda_shape.h:504
void SetWidth(int aWidth)
Definition: eda_shape.cpp:2303
VECTOR2I m_bezierC2
Definition: eda_shape.h:505
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: eda_shape.cpp:146
VECTOR2I GetArcMid() const
Definition: eda_shape.cpp:931
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition: property.h:686
static ENUM_MAP< T > & Instance()
Definition: property.h:680
ENUM_MAP & Undefined(T aValue)
Definition: property.h:693
wxPGChoices & Choices()
Definition: property.h:729
const wxString & GetReference() const
Definition: footprint.h:619
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:181
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:186
PCB specific render settings.
Definition: pcb_painter.h:79
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:174
static constexpr double LOD_SHOW
Return this constant from ViewGetLOD() to show the item unconditionally.
Definition: view_item.h:179
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:67
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:418
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:216
Definition: kiid.h:49
std::string AsStdString() const
Definition: kiid.cpp:252
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:37
static LSET AllLayersMask()
Definition: lset.cpp:601
void RunOnLayers(const std::function< void(PCB_LAYER_ID)> &aFunction) const
Execute a function on each layer of the LSET.
Definition: lset.h:255
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:188
int GetNetCode() const
Definition: netinfo.h:108
Definition: pad.h:54
std::optional< int > GetLocalThermalSpokeWidthOverride() const
Definition: pad.h:606
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:568
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:707
void swapData(BOARD_ITEM *aImage) override
Definition: pcb_shape.cpp:803
bool IsConnected() const override
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
Definition: pcb_shape.cpp:172
double ViewGetLOD(int aLayer, const KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: pcb_shape.cpp:648
void updateHatching() const override
Definition: pcb_shape.cpp:310
std::optional< int > GetLocalSolderMaskMargin() const
Definition: pcb_shape.h:191
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:554
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: pcb_shape.cpp:771
PCB_SHAPE(BOARD_ITEM *aParent, KICAD_T aItemType, SHAPE_T aShapeType)
Definition: pcb_shape.cpp:51
int GetWidth() const override
Definition: pcb_shape.cpp:375
const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
Definition: pcb_shape.cpp:786
bool HasSolderMask() const
Definition: pcb_shape.h:188
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:797
void SetHasSolderMask(bool aVal)
Definition: pcb_shape.h:187
std::optional< int > m_solderMaskMargin
Definition: pcb_shape.h:211
int GetSolderMaskExpansion() const
Definition: pcb_shape.cpp:188
void NormalizeForCompare() override
Normalize coordinates to compare 2 similar PCB_SHAPES similat to Normalize(), but also normalize SEGM...
Definition: pcb_shape.cpp:532
const VECTOR2I GetFocusPosition() const override
Allows items to return their visual center rather than their anchor.
Definition: pcb_shape.cpp:391
virtual void SetLayerSet(const LSET &aLayers) override
Definition: pcb_shape.cpp:244
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
Definition: pcb_shape.cpp:560
virtual std::vector< VECTOR2I > GetCorners() const
Return 4 corners for a rectangle or rotated rectangle (stored as a poly).
Definition: pcb_shape.cpp:433
bool IsProxyItem() const override
Definition: pcb_shape.h:116
bool m_hasSolderMask
Definition: pcb_shape.h:210
~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:227
bool operator==(const PCB_SHAPE &aShape) const
Definition: pcb_shape.cpp:872
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition: pcb_shape.cpp:179
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:854
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:845
void SetIsProxyItem(bool aIsProxy=true) override
Definition: pcb_shape.cpp:606
void StyleFromSettings(const BOARD_DESIGN_SETTINGS &settings) override
Definition: pcb_shape.cpp:385
void SetLocalSolderMaskMargin(std::optional< int > aMargin)
Definition: pcb_shape.h:190
void Move(const VECTOR2I &aMoveVector) override
Move this object.
Definition: pcb_shape.cpp:461
std::vector< VECTOR2I > GetConnectionPoints() const
Definition: pcb_shape.cpp:257
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: pcb_shape.cpp:101
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: pcb_shape.cpp:780
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
Definition: pcb_shape.cpp:209
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
Definition: pcb_shape.cpp:726
void Scale(double aScale)
Definition: pcb_shape.cpp:467
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:473
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition: pcb_shape.cpp:140
void CopyFrom(const BOARD_ITEM *aOther) override
Definition: pcb_shape.cpp:72
std::vector< int > ViewGetLayers() const override
Definition: pcb_shape.cpp:680
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:907
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:257
PROPERTY_BASE & SetIsHiddenFromRulesEditor(bool aHide=true)
Definition: property.h:307
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:85
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:87
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.
void Mirror(const VECTOR2I &aRef, FLIP_DIRECTION aFlipDirection)
Mirror the line points about y or x (or both)
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)
#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:169
bool IsSolderMaskLayer(int aLayer)
Definition: layer_ids.h:733
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:839
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
Definition: layer_ids.h:663
@ 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:674
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
constexpr void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:45
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:71
#define REGISTER_TYPE(x)
Definition: property_mgr.h:371
Utility functions for working with shapes.
const int scale
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
bool operator()(const BOARD_ITEM *aFirst, const BOARD_ITEM *aSecond) const
Definition: pcb_shape.cpp:823
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:130
@ 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:135
@ PCB_SHAPE_LOCATE_SEGMENT_T
Definition: typeinfo.h:133
@ PCB_SHAPE_LOCATE_RECT_T
Definition: typeinfo.h:134
@ PCB_SHAPE_LOCATE_BEZIER_T
Definition: typeinfo.h:138
@ PCB_SHAPE_LOCATE_POLY_T
Definition: typeinfo.h:137
@ PCB_SHAPE_LOCATE_ARC_T
Definition: typeinfo.h:136
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695
#define ZONE_THERMAL_RELIEF_COPPER_WIDTH_MM
Definition: zones.h:34