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>
41#include <drc/drc_engine.h>
46#include <pcb_painter.h>
47#include <api/board/board_types.pb.h>
48#include <api/api_enums.h>
49#include <api/api_utils.h>
50#include <properties/property.h>
52
53
54PCB_SHAPE::PCB_SHAPE( BOARD_ITEM* aParent, KICAD_T aItemType, SHAPE_T aShapeType ) :
55 BOARD_CONNECTED_ITEM( aParent, aItemType ),
56 EDA_SHAPE( aShapeType, pcbIUScale.mmToIU( DEFAULT_LINE_WIDTH ), FILL_T::NO_FILL )
57{
58 m_hasSolderMask = false;
59}
60
61
62PCB_SHAPE::PCB_SHAPE( BOARD_ITEM* aParent, SHAPE_T shapetype ) :
64 EDA_SHAPE( shapetype, pcbIUScale.mmToIU( DEFAULT_LINE_WIDTH ), FILL_T::NO_FILL )
65{
66 m_hasSolderMask = false;
67}
68
69
73
74
75void PCB_SHAPE::CopyFrom( const BOARD_ITEM* aOther )
76{
77 wxCHECK( aOther && aOther->Type() == PCB_SHAPE_T, /* void */ );
78 *this = *static_cast<const PCB_SHAPE*>( aOther );
79}
80
81
82void PCB_SHAPE::Serialize( google::protobuf::Any &aContainer ) const
83{
84 using namespace kiapi::common;
85 using namespace kiapi::board::types;
86 BoardGraphicShape msg;
87
89 PackNet( msg.mutable_net() );
90 msg.mutable_id()->set_value( m_Uuid.AsStdString() );
91 msg.set_locked( IsLocked() ? types::LockedState::LS_LOCKED : types::LockedState::LS_UNLOCKED );
92
93 google::protobuf::Any any;
95 any.UnpackTo( msg.mutable_shape() );
96
97 // TODO m_hasSolderMask and m_solderMaskMargin
98
99 aContainer.PackFrom( msg );
100}
101
102
103bool PCB_SHAPE::Deserialize( const google::protobuf::Any &aContainer )
104{
105 using namespace kiapi::common;
106 using namespace kiapi::board::types;
107
108 BoardGraphicShape msg;
109
110 if( !aContainer.UnpackTo( &msg ) )
111 return false;
112
113 // Initialize everything to a known state that doesn't get touched by every
114 // codepath below, to make sure the equality operator is consistent
115 m_start = {};
116 m_end = {};
117 m_arcCenter = {};
118 m_arcMidData = {};
119 m_bezierC1 = {};
120 m_bezierC2 = {};
121 m_editState = 0;
122 m_proxyItem = false;
123 m_endsSwapped = false;
124
125 SetUuidDirect( KIID( msg.id().value() ) );
126 SetLocked( msg.locked() == types::LS_LOCKED );
128 UnpackNet( msg.net() );
129
130 google::protobuf::Any any;
131 any.PackFrom( msg.shape() );
133
134 // TODO m_hasSolderMask and m_solderMaskMargin
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 else if( scanType == PCB_SHAPE_LOCATE_ELLIPSE_T )
164 sametype = m_shape == SHAPE_T::ELLIPSE;
165 else if( scanType == PCB_SHAPE_LOCATE_ELLIPSE_ARC_T )
166 sametype = m_shape == SHAPE_T::ELLIPSE_ARC;
167
168 if( sametype )
169 return true;
170 }
171
172 return false;
173}
174
175
177{
178 // Only board-level copper shapes are connectable
179 return IsOnCopperLayer() && !GetParentFootprint();
180}
181
182
184{
185 BOARD_ITEM::SetLayer( aLayer );
186
187 if( !IsOnCopperLayer() )
188 SetNetCode( -1 );
189}
190
191
193{
194 int margin = 0;
195
196 if( GetBoard() && GetBoard()->GetDesignSettings().m_DRCEngine
197 && GetBoard()->GetDesignSettings().m_DRCEngine->HasRulesForConstraintType(
199 {
200 DRC_CONSTRAINT constraint;
201 std::shared_ptr<DRC_ENGINE> drcEngine = GetBoard()->GetDesignSettings().m_DRCEngine;
202
203 constraint = drcEngine->EvalRules( SOLDER_MASK_EXPANSION_CONSTRAINT, this, nullptr, m_layer );
204
205 if( constraint.m_Value.HasOpt() )
206 margin = constraint.m_Value.Opt();
207 }
208 else if( m_solderMaskMargin.has_value() )
209 {
210 margin = m_solderMaskMargin.value();
211 }
212 else if( const BOARD* board = GetBoard() )
213 {
214 margin = board->GetDesignSettings().m_SolderMaskExpansion;
215 }
216
217 // Ensure the resulting mask opening has a non-negative size
218 if( margin < 0 && !IsSolidFill() )
219 margin = std::max( margin, -GetWidth() / 2 );
220
221 return margin;
222}
223
224
226{
227 if( aLayer == m_layer )
228 {
229 return true;
230 }
231
233 && ( ( aLayer == F_Mask && m_layer == F_Cu )
234 || ( aLayer == B_Mask && m_layer == B_Cu ) ) )
235 {
236 return true;
237 }
238
239 return false;
240}
241
242
244{
245 LSET layermask( { m_layer } );
246
247 if( m_hasSolderMask )
248 {
249 if( layermask.test( F_Cu ) )
250 layermask.set( F_Mask );
251
252 if( layermask.test( B_Cu ) )
253 layermask.set( B_Mask );
254 }
255
256 return layermask;
257}
258
259
260void PCB_SHAPE::SetLayerSet( const LSET& aLayerSet )
261{
262 aLayerSet.RunOnLayers(
263 [&]( PCB_LAYER_ID layer )
264 {
265 if( IsCopperLayer( layer ) )
266 SetLayer( layer );
267 else if( IsSolderMaskLayer( layer ) )
268 SetHasSolderMask( true );
269 } );
270}
271
272
273std::vector<VECTOR2I> PCB_SHAPE::GetConnectionPoints() const
274{
275 std::vector<VECTOR2I> ret;
276
277 // For filled shapes, we may as well use a centroid
278 if( IsSolidFill() )
279 {
280 ret.emplace_back( GetCenter() );
281 return ret;
282 }
283
284 switch( m_shape )
285 {
286 case SHAPE_T::CIRCLE:
287 {
288 const CIRCLE circle( GetCenter(), GetRadius() );
289
290 for( const TYPED_POINT2I& pt : KIGEOM::GetCircleKeyPoints( circle, false ) )
291 ret.emplace_back( pt.m_point );
292
293 break;
294 }
295
296 case SHAPE_T::ARC:
297 ret.emplace_back( GetArcMid() );
299 case SHAPE_T::SEGMENT:
300 case SHAPE_T::BEZIER:
301 ret.emplace_back( GetStart() );
302 ret.emplace_back( GetEnd() );
303 break;
304
305 case SHAPE_T::POLY:
306 for( auto iter = GetPolyShape().CIterate(); iter; ++iter )
307 ret.emplace_back( *iter );
308
309 break;
310
312 for( const VECTOR2I& pt : GetRectCorners() )
313 ret.emplace_back( pt );
314
315 break;
316
317 case SHAPE_T::ELLIPSE:
318 {
319 // +/- major and +/- minor axis endpoints.
320 const double phi = GetEllipseRotation().AsRadians();
321 const double cosPhi = std::cos( phi );
322 const double sinPhi = std::sin( phi );
323 const int a = GetEllipseMajorRadius();
324 const int b = GetEllipseMinorRadius();
325 const VECTOR2I c = GetEllipseCenter();
326
327 ret.emplace_back( c + VECTOR2I( KiROUND( a * cosPhi ), KiROUND( a * sinPhi ) ) );
328 ret.emplace_back( c + VECTOR2I( KiROUND( -a * cosPhi ), KiROUND( -a * sinPhi ) ) );
329 ret.emplace_back( c + VECTOR2I( KiROUND( -b * sinPhi ), KiROUND( b * cosPhi ) ) );
330 ret.emplace_back( c + VECTOR2I( KiROUND( b * sinPhi ), KiROUND( -b * cosPhi ) ) );
331 break;
332 }
333
335 {
336 // Start, end, and midpoint of the arc curve.
337 const double a = GetEllipseMajorRadius();
338 const double b = GetEllipseMinorRadius();
339 const double phi = GetEllipseRotation().AsRadians();
340 const double cosPhi = std::cos( phi );
341 const double sinPhi = std::sin( phi );
342 const VECTOR2I c = GetEllipseCenter();
343
344 auto eval = [&]( double theta ) -> VECTOR2I
345 {
346 const double lx = a * std::cos( theta );
347 const double ly = b * std::sin( theta );
348 return c + VECTOR2I( KiROUND( lx * cosPhi - ly * sinPhi ), KiROUND( lx * sinPhi + ly * cosPhi ) );
349 };
350
351 double thetaStart = GetEllipseStartAngle().AsRadians();
352 double thetaEnd = GetEllipseEndAngle().AsRadians();
353
354 if( thetaEnd < thetaStart )
355 thetaEnd += 2.0 * M_PI;
356
357 ret.emplace_back( eval( thetaStart ) );
358 ret.emplace_back( eval( thetaEnd ) );
359 ret.emplace_back( eval( 0.5 * ( thetaStart + thetaEnd ) ) );
360 break;
361 }
362
365 break;
366 }
367
368 return ret;
369}
370
371
373{
374 // Force update; we don't bother to propagate damage from all the things that might
375 // knock-out parts of our hatching.
376 m_hatchingDirty = true;
377
379}
380
381
383{
384 SHAPE_POLY_SET knockouts;
385 PCB_LAYER_ID layer = GetLayer();
386 BOX2I bbox = GetBoundingBox();
387 int maxError = ARC_LOW_DEF;
388
389 auto knockoutItem =
390 [&]( BOARD_ITEM* item )
391 {
392 int margin = GetHatchLineSpacing() / 2;
393
394 if( item->Type() == PCB_TEXTBOX_T )
395 margin = 0;
396
397 item->TransformShapeToPolygon( knockouts, layer, margin, maxError, ERROR_OUTSIDE );
398 };
399
400 for( BOARD_ITEM* item : GetBoard()->Drawings() )
401 {
402 if( item == this )
403 continue;
404
405 if( item->Type() == PCB_FIELD_T
406 || item->Type() == PCB_TEXT_T
407 || item->Type() == PCB_TEXTBOX_T
408 || item->Type() == PCB_SHAPE_T )
409 {
410 if( item->GetLayer() == layer && item->GetBoundingBox().Intersects( bbox ) )
411 knockoutItem( item );
412 }
413 }
414
415 for( FOOTPRINT* footprint : GetBoard()->Footprints() )
416 {
417 if( footprint == GetParentFootprint() )
418 continue;
419
420 // GetCourtyard() returns the front courtyard for any non-back layer, so only knock it
421 // out when the hatched shape actually lives on a courtyard layer.
422 if( layer == F_CrtYd || layer == B_CrtYd )
423 knockouts.Append( footprint->GetCourtyard( layer ) );
424
425 // Knockout footprint fields
426 footprint->RunOnChildren(
427 [&]( BOARD_ITEM* item )
428 {
429 if( ( item->Type() == PCB_FIELD_T || item->Type() == PCB_SHAPE_T )
430 && item->GetLayer() == layer
431 && !( item->Type() == PCB_FIELD_T && !static_cast<PCB_FIELD*>(item)->IsVisible() )
432 && item->GetBoundingBox().Intersects( bbox ) )
433 {
434 knockoutItem( item );
435 }
436 },
438 }
439
440 return knockouts;
441}
442
443
445{
446 // A stroke width of 0 in PCBNew means no-border, but negative stroke-widths are only used
447 // in EEschema (see SCH_SHAPE::GetPenWidth()).
448 // Since negative stroke widths can trip up down-stream code (such as the Gerber plotter), we
449 // weed them out here.
450 return std::max( EDA_SHAPE::GetWidth(), 0 );
451}
452
453
454void PCB_SHAPE::StyleFromSettings( const BOARD_DESIGN_SETTINGS& settings, bool aCheckSide )
455{
456 m_stroke.SetWidth( settings.GetLineThickness( GetLayer() ) );
457}
458
459
461{
462 // For some shapes return the visual center, but for not filled polygonal shapes,
463 // the center is usually far from the shape: a point on the outline is better
464
465 switch( m_shape )
466 {
467 case SHAPE_T::CIRCLE:
468 if( !IsAnyFill() )
469 return VECTOR2I( GetCenter().x + GetRadius(), GetCenter().y );
470 else
471 return GetCenter();
472
474 if( !IsAnyFill() )
475 return GetStart();
476 else
477 return GetCenter();
478
479 case SHAPE_T::POLY:
480 if( !IsAnyFill() )
481 {
482 VECTOR2I pos = GetPolyShape().Outline(0).CPoint(0);
483 return VECTOR2I( pos.x, pos.y );
484 }
485 else
486 {
487 return GetCenter();
488 }
489
490 case SHAPE_T::ARC:
491 return GetArcMid();
492
493 case SHAPE_T::BEZIER:
494 return GetStart();
495
496 default:
497 return GetCenter();
498 }
499}
500
501
502std::vector<VECTOR2I> PCB_SHAPE::GetCorners() const
503{
504 std::vector<VECTOR2I> pts;
505
507 {
508 pts = GetRectCorners();
509 }
510 else if( GetShape() == SHAPE_T::POLY )
511 {
512 for( int ii = 0; ii < GetPolyShape().OutlineCount(); ++ii )
513 {
514 for( const VECTOR2I& pt : GetPolyShape().Outline( ii ).CPoints() )
515 pts.emplace_back( pt );
516 }
517 }
518 else
519 {
521 }
522
523 while( pts.size() < 4 )
524 pts.emplace_back( pts.back() + VECTOR2I( 10, 10 ) );
525
526 return pts;
527}
528
529
530void PCB_SHAPE::Move( const VECTOR2I& aMoveVector )
531{
532 move( aMoveVector );
533}
534
535
536void PCB_SHAPE::Scale( double aScale )
537{
538 scale( aScale );
539}
540
541
543{
545 {
546 VECTOR2I start = GetStart();
547 VECTOR2I end = GetEnd();
548
549 BOX2I rect( start, end - start );
550 rect.Normalize();
551
552 SetStart( rect.GetPosition() );
553 SetEnd( rect.GetEnd() );
554 }
555 else if( m_shape == SHAPE_T::POLY )
556 {
557 auto horizontal =
558 []( const SEG& seg )
559 {
560 return seg.A.y == seg.B.y;
561 };
562
563 auto vertical =
564 []( const SEG& seg )
565 {
566 return seg.A.x == seg.B.x;
567 };
568
569 // Convert a poly back to a rectangle if appropriate
570 if( GetPolyShape().OutlineCount() == 1 && GetPolyShape().Outline( 0 ).SegmentCount() == 4 )
571 {
572 SHAPE_LINE_CHAIN& outline = GetPolyShape().Outline( 0 );
573
574 if( horizontal( outline.Segment( 0 ) )
575 && vertical( outline.Segment( 1 ) )
576 && horizontal( outline.Segment( 2 ) )
577 && vertical( outline.Segment( 3 ) ) )
578 {
580 m_start.x = std::min( outline.Segment( 0 ).A.x, outline.Segment( 0 ).B.x );
581 m_start.y = std::min( outline.Segment( 1 ).A.y, outline.Segment( 1 ).B.y );
582 m_end.x = std::max( outline.Segment( 0 ).A.x, outline.Segment( 0 ).B.x );
583 m_end.y = std::max( outline.Segment( 1 ).A.y, outline.Segment( 1 ).B.y );
584 }
585 else if( vertical( outline.Segment( 0 ) )
586 && horizontal( outline.Segment( 1 ) )
587 && vertical( outline.Segment( 2 ) )
588 && horizontal( outline.Segment( 3 ) ) )
589 {
591 m_start.x = std::min( outline.Segment( 1 ).A.x, outline.Segment( 1 ).B.x );
592 m_start.y = std::min( outline.Segment( 0 ).A.y, outline.Segment( 0 ).B.y );
593 m_end.x = std::max( outline.Segment( 1 ).A.x, outline.Segment( 1 ).B.x );
594 m_end.y = std::max( outline.Segment( 0 ).A.y, outline.Segment( 0 ).B.y );
595 }
596 }
597 }
598}
599
600
602{
604 {
605 // we want start point the top left point and end point the bottom right
606 // (more easy to compare 2 segments: we are seeing them as equivalent if
607 // they have the same end points, not necessary the same order)
608 VECTOR2I start = GetStart();
609 VECTOR2I end = GetEnd();
610
611 if( ( start.x > end.x )
612 || ( start.x == end.x && start.y < end.y ) )
613 {
614 SetStart( end );
615 SetEnd( start );
616 }
617 }
618 else
619 Normalize();
620}
621
622
623void PCB_SHAPE::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
624{
625 rotate( aRotCentre, aAngle );
626}
627
628
629void PCB_SHAPE::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
630{
631 flip( aCentre, aFlipDirection );
632
634}
635
636
637void PCB_SHAPE::Mirror( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
638{
639 flip( aCentre, aFlipDirection );
640}
641
642
643void PCB_SHAPE::SetIsProxyItem( bool aIsProxy )
644{
645 PAD* parentPad = nullptr;
646
647 if( GetBoard() && GetBoard()->IsFootprintHolder() )
648 {
649 for( FOOTPRINT* fp : GetBoard()->Footprints() )
650 {
651 for( PAD* pad : fp->Pads() )
652 {
653 if( pad->IsEntered() )
654 {
655 parentPad = pad;
656 break;
657 }
658 }
659 }
660 }
661
662 if( aIsProxy && !m_proxyItem )
663 {
664 if( GetShape() == SHAPE_T::SEGMENT )
665 {
666 if( parentPad && parentPad->GetLocalThermalSpokeWidthOverride().has_value() )
667 SetWidth( parentPad->GetLocalThermalSpokeWidthOverride().value() );
668 else
670 }
671 else
672 {
673 SetWidth( 1 );
674 }
675 }
676 else if( m_proxyItem && !aIsProxy )
677 {
679 }
680
681 m_proxyItem = aIsProxy;
682}
683
684
685double PCB_SHAPE::ViewGetLOD( int aLayer, const KIGFX::VIEW* aView ) const
686{
687 KIGFX::PCB_PAINTER& painter = static_cast<KIGFX::PCB_PAINTER&>( *aView->GetPainter() );
688 KIGFX::PCB_RENDER_SETTINGS& renderSettings = *painter.GetSettings();
689
690 if( aLayer == LAYER_LOCKED_ITEM_SHADOW )
691 {
692 // Hide shadow if the main layer is not shown
693 if( !aView->IsLayerVisibleCached( m_layer ) )
694 return LOD_HIDE;
695
696 // Hide shadow on dimmed tracks
697 if( renderSettings.GetHighContrast() )
698 {
699 if( m_layer != renderSettings.GetPrimaryHighContrastLayer() )
700 return LOD_HIDE;
701 }
702 }
703
704 if( FOOTPRINT* parent = GetParentFootprint() )
705 {
706 PCB_LAYER_ID checkLayer = m_layer;
707
708 if( !IsFrontLayer( checkLayer ) && !IsBackLayer( checkLayer ) )
709 checkLayer = parent->GetLayer();
710
711 if( IsFrontLayer( checkLayer ) && !aView->IsLayerVisibleCached( LAYER_FOOTPRINTS_FR ) )
712 return LOD_HIDE;
713
714 if( IsBackLayer( checkLayer ) && !aView->IsLayerVisibleCached( LAYER_FOOTPRINTS_BK ) )
715 return LOD_HIDE;
716 }
717
718 return LOD_SHOW;
719}
720
721
722std::vector<int> PCB_SHAPE::ViewGetLayers() const
723{
724 std::vector<int> layers;
725 layers.reserve( 4 );
726
727 layers.push_back( GetLayer() );
728
729 if( IsOnCopperLayer() )
730 {
731 layers.push_back( GetNetnameLayer( GetLayer() ) );
732
733 if( m_hasSolderMask )
734 {
735 if( m_layer == F_Cu )
736 layers.push_back( F_Mask );
737 else if( m_layer == B_Cu )
738 layers.push_back( B_Mask );
739 }
740 }
741
743 layers.push_back( LAYER_LOCKED_ITEM_SHADOW );
744
745 return layers;
746}
747
748
749void PCB_SHAPE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
750{
751 if( aFrame->GetName() == PCB_EDIT_FRAME_NAME )
752 {
753 if( FOOTPRINT* parent = GetParentFootprint() )
754 aList.emplace_back( _( "Footprint" ), parent->GetReference() );
755 }
756
757 aList.emplace_back( _( "Type" ), _( "Drawing" ) );
758
759 if( aFrame->GetName() == PCB_EDIT_FRAME_NAME && IsLocked() )
760 aList.emplace_back( _( "Status" ), _( "Locked" ) );
761
762 ShapeGetMsgPanelInfo( aFrame, aList );
763
764 aList.emplace_back( _( "Layer" ), GetLayerName() );
765
766 if( IsOnCopperLayer() )
767 {
768 if( GetNetCode() > 0 ) // Only graphics connected to a net have a netcode > 0
769 aList.emplace_back( _( "Net" ), GetNetname() );
770 }
771}
772
773
774wxString PCB_SHAPE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
775{
776 FOOTPRINT* parentFP = GetParentFootprint();
777
778 // Don't report parent footprint info from footprint editor, viewer, etc.
779 if( GetBoard() && GetBoard()->GetBoardUse() == BOARD_USE::FPHOLDER )
780 parentFP = nullptr;
781
782 if( IsOnCopperLayer() )
783 {
784 if( parentFP )
785 {
786 return wxString::Format( _( "%s %s of %s on %s" ),
789 parentFP->GetReference(),
790 GetLayerName() );
791 }
792 else
793 {
794 return wxString::Format( _( "%s %s on %s" ),
797 GetLayerName() );
798 }
799 }
800 else
801 {
802 if( parentFP )
803 {
804 return wxString::Format( _( "%s of %s on %s" ),
806 parentFP->GetReference(),
807 GetLayerName() );
808 }
809 else
810 {
811 return wxString::Format( _( "%s on %s" ),
813 GetLayerName() );
814 }
815 }
816}
817
818
820{
821 if( GetParentFootprint() )
823 else
825}
826
827
829{
830 return new PCB_SHAPE( *this );
831}
832
833
835{
836 BOX2I return_box = EDA_ITEM::ViewBBox();
837
838 // Inflate the bounding box by just a bit more for safety.
839 return_box.Inflate( GetWidth() );
840
841 return return_box;
842}
843
844
845std::shared_ptr<SHAPE> PCB_SHAPE::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
846{
847 return std::make_shared<SHAPE_COMPOUND>( MakeEffectiveShapes() );
848}
849
850
852{
853 return GetMaxError();
854}
855
856
858{
859 PCB_SHAPE* image = dynamic_cast<PCB_SHAPE*>( aImage );
860 wxCHECK( image, /* void */ );
861
862 SwapShape( image );
863
864 // Swap params not handled by SwapShape( image )
865 std::swap( m_layer, image->m_layer );
866 std::swap( m_isKnockout, image->m_isKnockout );
867 std::swap( m_isLocked, image->m_isLocked );
868 std::swap( m_flags, image->m_flags );
869 std::swap( m_parent, image->m_parent );
870 std::swap( m_forceVisible, image->m_forceVisible );
871 std::swap( m_netinfo, image->m_netinfo );
872 std::swap( m_hasSolderMask, image->m_hasSolderMask );
873 std::swap( m_solderMaskMargin, image->m_solderMaskMargin );
874}
875
876
878 const BOARD_ITEM* aSecond ) const
879{
880 if( aFirst->Type() != aSecond->Type() )
881 return aFirst->Type() < aSecond->Type();
882
883 if( aFirst->GetLayer() != aSecond->GetLayer() )
884 return aFirst->GetLayer() < aSecond->GetLayer();
885
886 if( aFirst->Type() == PCB_SHAPE_T )
887 {
888 const PCB_SHAPE* dwgA = static_cast<const PCB_SHAPE*>( aFirst );
889 const PCB_SHAPE* dwgB = static_cast<const PCB_SHAPE*>( aSecond );
890
891 if( dwgA->GetShape() != dwgB->GetShape() )
892 return dwgA->GetShape() < dwgB->GetShape();
893 }
894
895 return aFirst->m_Uuid < aSecond->m_Uuid;
896}
897
898
900 int aClearance, int aError, ERROR_LOC aErrorLoc,
901 bool ignoreLineWidth ) const
902{
903 EDA_SHAPE::TransformShapeToPolygon( aBuffer, aClearance, aError, aErrorLoc, ignoreLineWidth,
904 false );
905}
906
907
909 int aClearance, int aError, ERROR_LOC aErrorLoc,
910 KIGFX::RENDER_SETTINGS* aRenderSettings ) const
911{
912 EDA_SHAPE::TransformShapeToPolygon( aBuffer, aClearance, aError, aErrorLoc, false, true );
913}
914
915
916bool PCB_SHAPE::operator==( const BOARD_ITEM& aOther ) const
917{
918 if( aOther.Type() != Type() )
919 return false;
920
921 const PCB_SHAPE& other = static_cast<const PCB_SHAPE&>( aOther );
922
923 return *this == other;
924}
925
926
927bool PCB_SHAPE::operator==( const PCB_SHAPE& aOther ) const
928{
929 if( aOther.Type() != Type() )
930 return false;
931
932 const PCB_SHAPE& other = static_cast<const PCB_SHAPE&>( aOther );
933
934 if( m_layer != other.m_layer )
935 return false;
936
937 if( m_isKnockout != other.m_isKnockout )
938 return false;
939
940 if( m_isLocked != other.m_isLocked )
941 return false;
942
943 if( m_flags != other.m_flags )
944 return false;
945
946 if( m_forceVisible != other.m_forceVisible )
947 return false;
948
949 if( m_netinfo->GetNetCode() != other.m_netinfo->GetNetCode() )
950 return false;
951
952 if( m_hasSolderMask != other.m_hasSolderMask )
953 return false;
954
956 return false;
957
958 return EDA_SHAPE::operator==( other );
959}
960
961
962double PCB_SHAPE::Similarity( const BOARD_ITEM& aOther ) const
963{
964 if( aOther.Type() != Type() )
965 return 0.0;
966
967 const PCB_SHAPE& other = static_cast<const PCB_SHAPE&>( aOther );
968
969 double similarity = 1.0;
970
971 if( GetLayer() != other.GetLayer() )
972 similarity *= 0.9;
973
974 if( m_isKnockout != other.m_isKnockout )
975 similarity *= 0.9;
976
977 if( m_isLocked != other.m_isLocked )
978 similarity *= 0.9;
979
980 if( m_flags != other.m_flags )
981 similarity *= 0.9;
982
983 if( m_forceVisible != other.m_forceVisible )
984 similarity *= 0.9;
985
986 if( m_netinfo->GetNetCode() != other.m_netinfo->GetNetCode() )
987 similarity *= 0.9;
988
989 if( m_hasSolderMask != other.m_hasSolderMask )
990 similarity *= 0.9;
991
993 similarity *= 0.9;
994
995 similarity *= EDA_SHAPE::Similarity( other );
996
997 return similarity;
998}
999
1000
1001static struct PCB_SHAPE_DESC
1002{
1004 {
1011
1012 // Need to initialise enum_map before we can use a Property enum for it
1014
1015 if( layerEnum.Choices().GetCount() == 0 )
1016 {
1017 layerEnum.Undefined( UNDEFINED_LAYER );
1018
1019 for( PCB_LAYER_ID layer : LSET::AllLayersMask() )
1020 layerEnum.Map( layer, LSET::Name( layer ) );
1021 }
1022
1023 void ( PCB_SHAPE::*shapeLayerSetter )( PCB_LAYER_ID ) = &PCB_SHAPE::SetLayer;
1024 PCB_LAYER_ID ( PCB_SHAPE::*shapeLayerGetter )() const = &PCB_SHAPE::GetLayer;
1025
1026 auto layerProperty = new PROPERTY_ENUM<PCB_SHAPE, PCB_LAYER_ID>(
1027 _HKI( "Layer" ), shapeLayerSetter, shapeLayerGetter );
1028
1029 propMgr.ReplaceProperty( TYPE_HASH( BOARD_CONNECTED_ITEM ), _HKI( "Layer" ), layerProperty );
1030
1031 // Polygons and ellipses have Position properties (first vertex / center).
1032 auto isPolygonOrEllipse = []( INSPECTABLE* aItem ) -> bool
1033 {
1034 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1035 {
1036 const SHAPE_T t = shape->GetShape();
1037 return t == SHAPE_T::POLY || t == SHAPE_T::ELLIPSE || t == SHAPE_T::ELLIPSE_ARC;
1038 }
1039 return false;
1040 };
1041
1042 propMgr.OverrideAvailability( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( BOARD_ITEM ), _HKI( "Position X" ),
1043 isPolygonOrEllipse );
1044 propMgr.OverrideAvailability( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( BOARD_ITEM ), _HKI( "Position Y" ),
1045 isPolygonOrEllipse );
1046
1047 propMgr.Mask( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Color" ) );
1048 propMgr.Mask( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ), _HKI( "Fill Color" ) );
1049
1050 // BEZIER curves and ELLIPTICAL_ARC are not closed shapes, and fill
1051 // is not supported in board editor, only in schematic editor.
1052 auto isNotBezierOrEllipseArc = []( INSPECTABLE* aItem ) -> bool
1053 {
1054 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1055 {
1056 const SHAPE_T t = shape->GetShape();
1057 return t != SHAPE_T::BEZIER && t != SHAPE_T::ELLIPSE_ARC;
1058 }
1059 return true;
1060 };
1061
1063 isNotBezierOrEllipseArc );
1064
1065 auto isCircle =
1066 []( INSPECTABLE* aItem ) -> bool
1067 {
1068 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1069 return shape->GetShape() == SHAPE_T::CIRCLE;
1070
1071 return false;
1072 };
1073
1074 auto isNotCircleOrEllipse = []( INSPECTABLE* aItem ) -> bool
1075 {
1076 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1077 {
1078 const SHAPE_T t = shape->GetShape();
1079 return t != SHAPE_T::CIRCLE && t != SHAPE_T::ELLIPSE && t != SHAPE_T::ELLIPSE_ARC;
1080 }
1081 return true;
1082 };
1083
1084 propMgr.OverrideAvailability( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ), _HKI( "Start X" ),
1085 isNotCircleOrEllipse );
1086 propMgr.OverrideAvailability( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ), _HKI( "Start Y" ),
1087 isNotCircleOrEllipse );
1088 propMgr.OverrideAvailability( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ), _HKI( "End X" ),
1089 isNotCircleOrEllipse );
1090 propMgr.OverrideAvailability( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ), _HKI( "End Y" ),
1091 isNotCircleOrEllipse );
1093 _HKI( "Center X" ), isCircle );
1095 _HKI( "Center Y" ), isCircle );
1097 _HKI( "Radius" ), isCircle );
1098
1099 auto isCopper =
1100 []( INSPECTABLE* aItem ) -> bool
1101 {
1102 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1103 return shape->IsOnCopperLayer();
1104
1105 return false;
1106 };
1107
1109 _HKI( "Net" ), isCopper );
1110
1111 auto isPadEditMode =
1112 []( BOARD* aBoard ) -> bool
1113 {
1114 if( aBoard && aBoard->IsFootprintHolder() )
1115 {
1116 for( FOOTPRINT* fp : aBoard->Footprints() )
1117 {
1118 for( PAD* pad : fp->Pads() )
1119 {
1120 if( pad->IsEntered() )
1121 return true;
1122 }
1123 }
1124 }
1125
1126 return false;
1127 };
1128
1129 auto showNumberBoxProperty =
1130 [&]( INSPECTABLE* aItem ) -> bool
1131 {
1132 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1133 {
1134 if( shape->GetShape() == SHAPE_T::RECTANGLE )
1135 return isPadEditMode( shape->GetBoard() );
1136 }
1137
1138 return false;
1139 };
1140
1141 auto showSpokeTemplateProperty =
1142 [&]( INSPECTABLE* aItem ) -> bool
1143 {
1144 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1145 {
1146 if( shape->GetShape() == SHAPE_T::SEGMENT )
1147 return isPadEditMode( shape->GetBoard() );
1148 }
1149
1150 return false;
1151 };
1152
1153 const wxString groupPadPrimitives = _HKI( "Pad Primitives" );
1154
1155 propMgr.AddProperty( new PROPERTY<PCB_SHAPE, bool>( _HKI( "Number Box" ),
1158 groupPadPrimitives )
1159 .SetAvailableFunc( showNumberBoxProperty )
1161
1162 propMgr.AddProperty( new PROPERTY<PCB_SHAPE, bool>( _HKI( "Thermal Spoke Template" ),
1164 groupPadPrimitives )
1165 .SetAvailableFunc( showSpokeTemplateProperty )
1167
1168 const wxString groupTechLayers = _HKI( "Technical Layers" );
1169
1170 auto isExternalCuLayer =
1171 []( INSPECTABLE* aItem )
1172 {
1173 if( auto shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1174 return IsExternalCopperLayer( shape->GetLayer() );
1175
1176 return false;
1177 };
1178
1179 propMgr.AddProperty( new PROPERTY<PCB_SHAPE, bool>( _HKI( "Soldermask" ),
1181 groupTechLayers )
1182 .SetAvailableFunc( isExternalCuLayer );
1183
1184 propMgr.AddProperty( new PROPERTY<PCB_SHAPE, std::optional<int>>( _HKI( "Soldermask Margin Override" ),
1187 groupTechLayers )
1188 .SetAvailableFunc( isExternalCuLayer );
1189 }
types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
Definition api_enums.cpp:47
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
@ ERROR_OUTSIDE
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:125
constexpr int ARC_LOW_DEF
Definition base_units.h:140
BITMAPS
A list of all bitmap identifiers.
@ add_dashed_line
@ FPHOLDER
Definition board.h:315
#define DEFAULT_LINE_WIDTH
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:990
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
virtual bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
BOARD_CONNECTED_ITEM(BOARD_ITEM *aParent, KICAD_T idtype)
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.
std::shared_ptr< DRC_ENGINE > m_DRCEngine
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:84
BOARD_ITEM(BOARD_ITEM *aParent, KICAD_T idtype, PCB_LAYER_ID aLayer=F_Cu)
Definition board_item.h:86
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition board_item.h:268
friend class BOARD
Definition board_item.h:494
void SetUuidDirect(const KIID &aUuid)
Raw UUID assignment.
void SetLocked(bool aLocked) override
Definition board_item.h:359
bool m_isKnockout
Definition board_item.h:491
PCB_LAYER_ID m_layer
Definition board_item.h:490
bool m_isLocked
Definition board_item.h:492
bool IsLocked() const override
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition board_item.h:316
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
FOOTPRINT * GetParentFootprint() const
virtual bool IsOnCopperLayer() const
Definition board_item.h:175
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
int GetMaxError() const
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:323
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1101
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:244
double AsRadians() const
Definition eda_angle.h:120
The base class for create windows for drawing purpose.
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition eda_item.cpp:139
const KIID m_Uuid
Definition eda_item.h:535
bool m_forceVisible
Definition eda_item.h:552
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:112
EDA_ITEM_FLAGS m_flags
Definition eda_item.h:546
virtual bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
Definition eda_item.h:206
virtual const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
Definition eda_item.cpp:374
EDA_ITEM * m_parent
Owner.
Definition eda_item.h:547
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:41
virtual int GetHatchLineSpacing() const
Definition eda_shape.h:180
SHAPE_T m_shape
Definition eda_shape.h:587
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.
int GetEllipseMinorRadius() const
Definition eda_shape.h:306
bool m_proxyItem
Definition eda_shape.h:613
bool m_hatchingDirty
Definition eda_shape.h:593
bool m_endsSwapped
Definition eda_shape.h:586
const VECTOR2I & GetEllipseCenter() const
Definition eda_shape.h:288
int m_editState
Definition eda_shape.h:612
void rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle)
EDA_ANGLE GetEllipseEndAngle() const
Definition eda_shape.h:334
int GetEllipseMajorRadius() const
Definition eda_shape.h:297
virtual std::vector< SHAPE * > MakeEffectiveShapes(bool aEdgeOnly=false) const
Make a set of SHAPE objects representing the EDA_SHAPE.
Definition eda_shape.h:457
SHAPE_POLY_SET & GetPolyShape()
EDA_ANGLE GetEllipseRotation() const
Definition eda_shape.h:315
void ShapeGetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList)
bool operator==(const EDA_SHAPE &aOther) const
int GetRadius() const
SHAPE_T GetShape() const
Definition eda_shape.h:189
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
VECTOR2I m_arcCenter
Definition eda_shape.h:602
ARC_MID m_arcMidData
Definition eda_shape.h:603
bool IsSolidFill() const
Definition eda_shape.h:137
void flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection)
EDA_SHAPE(SHAPE_T aType, int aLineWidth, FILL_T aFill)
Definition eda_shape.cpp:57
VECTOR2I m_start
Definition eda_shape.h:599
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition eda_shape.h:236
void SetStart(const VECTOR2I &aStart)
Definition eda_shape.h:198
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition eda_shape.h:194
void SwapShape(EDA_SHAPE *aImage)
std::vector< VECTOR2I > GetRectCorners() const
bool IsAnyFill() const
Definition eda_shape.h:132
EDA_ANGLE GetEllipseStartAngle() const
Definition eda_shape.h:325
virtual void UpdateHatching() const
void SetEnd(const VECTOR2I &aEnd)
Definition eda_shape.h:240
wxString SHAPE_T_asString() const
double Similarity(const EDA_SHAPE &aOther) const
VECTOR2I m_end
Definition eda_shape.h:600
virtual int GetWidth() const
Definition eda_shape.h:177
STROKE_PARAMS m_stroke
Definition eda_shape.h:588
VECTOR2I m_bezierC1
Definition eda_shape.h:605
void SetWidth(int aWidth)
VECTOR2I m_bezierC2
Definition eda_shape.h:606
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
VECTOR2I GetArcMid() const
virtual bool IsVisible() const
Definition eda_text.h:212
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition property.h:727
static ENUM_MAP< T > & Instance()
Definition property.h:721
ENUM_MAP & Undefined(T aValue)
Definition property.h:734
wxPGChoices & Choices()
Definition property.h:770
const wxString & GetReference() const
Definition footprint.h:829
Class that other classes need to inherit from, in order to be inspectable.
Definition inspectable.h:38
Contains methods for drawing PCB-specific items.
virtual PCB_RENDER_SETTINGS * GetSettings() override
Return a pointer to current settings that are going to be used when drawing items.
PCB specific render settings.
Definition pcb_painter.h:82
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
PCB_LAYER_ID GetPrimaryHighContrastLayer() const
Return the board layer which is in high-contrast mode.
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:67
bool IsLayerVisibleCached(int aLayer) const
Definition view.h:441
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition view.h:229
Definition kiid.h:48
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:263
static const LSET & AllLayersMask()
Definition lset.cpp:641
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:98
Definition pad.h:65
std::optional< int > GetLocalThermalSpokeWidthOverride() const
Definition pad.h:757
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition pcb_shape.h:127
virtual void Mirror(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Mirror this object relative to a given horizontal axis the layer is not changed.
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.
void StyleFromSettings(const BOARD_DESIGN_SETTINGS &settings, bool aCheckSide) override
void swapData(BOARD_ITEM *aImage) override
bool IsConnected() const override
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
double ViewGetLOD(int aLayer, const KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
SHAPE_POLY_SET getHatchingKnockouts() const override
std::optional< int > GetLocalSolderMaskMargin() const
Definition pcb_shape.h:216
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.
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
PCB_SHAPE(BOARD_ITEM *aParent, KICAD_T aItemType, SHAPE_T aShapeType)
Definition pcb_shape.cpp:54
int GetWidth() const override
const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
bool HasSolderMask() const
Definition pcb_shape.h:213
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.
void SetHasSolderMask(bool aVal)
Definition pcb_shape.h:212
std::optional< int > m_solderMaskMargin
Definition pcb_shape.h:240
int GetSolderMaskExpansion() const
void NormalizeForCompare() override
Normalize coordinates to compare 2 similar PCB_SHAPES similat to Normalize(), but also normalize SEGM...
void TransformShapeToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, KIGFX::RENDER_SETTINGS *aRenderSettings=nullptr) const override
Convert the item shape to a polyset.
const VECTOR2I GetFocusPosition() const override
Allows items to return their visual center rather than their anchor.
virtual void SetLayerSet(const LSET &aLayers) override
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
virtual std::vector< VECTOR2I > GetCorners() const
Return 4 corners for a rectangle or rotated rectangle (stored as a poly).
bool IsProxyItem() const override
Definition pcb_shape.h:122
bool m_hasSolderMask
Definition pcb_shape.h:239
~PCB_SHAPE() override
Definition pcb_shape.cpp:70
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
bool operator==(const PCB_SHAPE &aShape) const
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
wxString GetFriendlyName() const override
Definition pcb_shape.h:66
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.
void SetIsProxyItem(bool aIsProxy=true) override
void SetLocalSolderMaskMargin(std::optional< int > aMargin)
Definition pcb_shape.h:215
void Move(const VECTOR2I &aMoveVector) override
Move this object.
std::vector< VECTOR2I > GetConnectionPoints() const
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
int getMaxError() const override
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
void UpdateHatching() const override
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
void Scale(double aScale)
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition pcb_shape.cpp:82
void Normalize() override
Perform any normalization required after a user rotate and/or flip.
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
void CopyFrom(const BOARD_ITEM *aOther) override
Definition pcb_shape.cpp:75
std::vector< int > ViewGetLayers() const override
double Similarity(const BOARD_ITEM &aBoardItem) const override
Return a measure of how likely the other object is to represent the same object.
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:262
PROPERTY_BASE & SetIsHiddenFromRulesEditor(bool aHide=true)
Definition property.h:326
Provide class metadata.Helper macro to map type hashes to names.
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()
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.
Represent a set of closed polygons.
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.
A type-safe container of any type.
Definition ki_any.h:93
@ SOLDER_MASK_EXPANSION_CONSTRAINT
Definition drc_rule.h:72
#define _(s)
#define PCB_EDIT_FRAME_NAME
@ RECURSE
Definition eda_item.h:53
SHAPE_T
Definition eda_shape.h:48
@ UNDEFINED
Definition eda_shape.h:49
@ ELLIPSE
Definition eda_shape.h:56
@ SEGMENT
Definition eda_shape.h:50
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
Definition eda_shape.h:51
@ ELLIPSE_ARC
Definition eda_shape.h:57
FILL_T
Definition eda_shape.h:63
@ NO_FILL
Definition eda_shape.h:64
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition layer_id.cpp:173
bool IsSolderMaskLayer(int aLayer)
Definition layer_ids.h:750
bool IsFrontLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a front layer.
Definition layer_ids.h:782
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
Definition layer_ids.h:184
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
Definition layer_ids.h:805
int GetNetnameLayer(int aLayer)
Return a netname layer corresponding to the given layer.
Definition layer_ids.h:856
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
Definition layer_ids.h:679
@ LAYER_LOCKED_ITEM_SHADOW
Shadow layer for locked items.
Definition layer_ids.h:307
@ LAYER_FOOTPRINTS_FR
Show footprints on front.
Definition layer_ids.h:259
@ LAYER_FOOTPRINTS_BK
Show footprints on back.
Definition layer_ids.h:260
bool IsExternalCopperLayer(int aLayerId)
Test whether a layer is an external (F_Cu or B_Cu) copper layer.
Definition layer_ids.h:690
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
@ F_CrtYd
Definition layer_ids.h:116
@ 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
@ B_CrtYd
Definition layer_ids.h:115
@ 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.
#define _HKI(x)
Definition page_info.cpp:44
static struct PCB_SHAPE_DESC _PCB_SHAPE_DESC
static bool isCopper(const PNS::ITEM *aItem)
#define TYPE_HASH(x)
Definition property.h:74
@ PT_SIZE
Size expressed in distance units (mm/inch)
Definition property.h:63
#define REGISTER_TYPE(x)
Utility functions for working with shapes.
const int scale
bool operator()(const BOARD_ITEM *aFirst, const BOARD_ITEM *aSecond) const
VECTOR2I end
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
#define M_PI
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:75
@ PCB_SHAPE_LOCATE_ELLIPSE_ARC_T
Definition typeinfo.h:241
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition typeinfo.h:85
@ PCB_LOCATE_BOARD_EDGE_T
Definition typeinfo.h:131
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition typeinfo.h:90
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition typeinfo.h:89
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
Definition typeinfo.h:87
@ 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_ELLIPSE_T
Definition typeinfo.h:240
@ 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:687
#define ZONE_THERMAL_RELIEF_COPPER_WIDTH_MM
Definition zones.h:33