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 (C) 1992-2024 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::Serialize( google::protobuf::Any &aContainer ) const
73{
74 kiapi::board::types::GraphicShape msg;
75
76 msg.mutable_id()->set_value( m_Uuid.AsStdString() );
77 msg.set_layer( ToProtoEnum<PCB_LAYER_ID, kiapi::board::types::BoardLayer>( GetLayer() ) );
78 msg.set_locked( IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
79 : kiapi::common::types::LockedState::LS_UNLOCKED );
80 msg.mutable_net()->mutable_code()->set_value( GetNetCode() );
81 msg.mutable_net()->set_name( GetNetname() );
82
83 kiapi::common::types::StrokeAttributes* stroke
84 = msg.mutable_attributes()->mutable_stroke();
85 kiapi::common::types::GraphicFillAttributes* fill = msg.mutable_attributes()->mutable_fill();
86
87 stroke->mutable_width()->set_value_nm( GetWidth() );
88
89 switch( GetLineStyle() )
90 {
91 case LINE_STYLE::DEFAULT: stroke->set_style( kiapi::common::types::SLS_DEFAULT ); break;
92 case LINE_STYLE::SOLID: stroke->set_style( kiapi::common::types::SLS_SOLID ); break;
93 case LINE_STYLE::DASH: stroke->set_style( kiapi::common::types::SLS_DASH ); break;
94 case LINE_STYLE::DOT: stroke->set_style( kiapi::common::types::SLS_DOT ); break;
95 case LINE_STYLE::DASHDOT: stroke->set_style( kiapi::common::types::SLS_DASHDOT ); break;
96 case LINE_STYLE::DASHDOTDOT: stroke->set_style( kiapi::common::types::SLS_DASHDOTDOT ); break;
97 default: break;
98 }
99
100 switch( GetFillMode() )
101 {
102 case FILL_T::FILLED_SHAPE: fill->set_fill_type( kiapi::common::types::GFT_FILLED ); break;
103 default: fill->set_fill_type( kiapi::common::types::GFT_UNFILLED ); break;
104 }
105
106 switch( GetShape() )
107 {
108 case SHAPE_T::SEGMENT:
109 {
110 kiapi::board::types::GraphicSegmentAttributes* segment = msg.mutable_segment();
111 kiapi::common::PackVector2( *segment->mutable_start(), GetStart() );
112 kiapi::common::PackVector2( *segment->mutable_end(), GetEnd() );
113 break;
114 }
115
116 case SHAPE_T::RECTANGLE:
117 {
118 kiapi::board::types::GraphicRectangleAttributes* rectangle = msg.mutable_rectangle();
119 kiapi::common::PackVector2( *rectangle->mutable_top_left(), GetStart() );
120 kiapi::common::PackVector2( *rectangle->mutable_bottom_right(), GetEnd() );
121 break;
122 }
123
124 case SHAPE_T::ARC:
125 {
126 kiapi::board::types::GraphicArcAttributes* arc = msg.mutable_arc();
127 kiapi::common::PackVector2( *arc->mutable_start(), GetStart() );
128 kiapi::common::PackVector2( *arc->mutable_mid(), GetArcMid() );
129 kiapi::common::PackVector2( *arc->mutable_end(), GetEnd() );
130 break;
131 }
132
133 case SHAPE_T::CIRCLE:
134 {
135 kiapi::board::types::GraphicCircleAttributes* circle = msg.mutable_circle();
136 kiapi::common::PackVector2( *circle->mutable_center(), GetStart() );
137 kiapi::common::PackVector2( *circle->mutable_radius_point(), GetEnd() );
138 break;
139 }
140
141 case SHAPE_T::POLY:
142 {
143 kiapi::common::types::PolySet* polyset = msg.mutable_polygon();
144
145 for( int idx = 0; idx < GetPolyShape().OutlineCount(); ++idx )
146 {
147 const SHAPE_POLY_SET::POLYGON& poly = GetPolyShape().Polygon( idx );
148
149 if( poly.empty() )
150 continue;
151
152 kiapi::common::types::PolygonWithHoles* polyMsg = polyset->mutable_polygons()->Add();
153 kiapi::common::PackPolyLine( *polyMsg->mutable_outline(), poly.front() );
154
155 if( poly.size() > 1 )
156 {
157 for( size_t hole = 1; hole < poly.size(); ++hole )
158 {
159 kiapi::common::types::PolyLine* pl = polyMsg->mutable_holes()->Add();
160 kiapi::common::PackPolyLine( *pl, poly[hole] );
161 }
162 }
163 }
164 break;
165 }
166
167 case SHAPE_T::BEZIER:
168 {
169 kiapi::board::types::GraphicBezierAttributes* bezier = msg.mutable_bezier();
170 kiapi::common::PackVector2( *bezier->mutable_start(), GetStart() );
171 kiapi::common::PackVector2( *bezier->mutable_control1(), GetBezierC1() );
172 kiapi::common::PackVector2( *bezier->mutable_control2(), GetBezierC2() );
173 kiapi::common::PackVector2( *bezier->mutable_end(), GetEnd() );
174 break;
175 }
176
177 default:
178 wxASSERT_MSG( false, "Unhandled shape in PCB_SHAPE::Serialize" );
179 }
180
181 // TODO m_hasSolderMask and m_solderMaskMargin
182
183 aContainer.PackFrom( msg );
184}
185
186
187bool PCB_SHAPE::Deserialize( const google::protobuf::Any &aContainer )
188{
189 kiapi::board::types::GraphicShape msg;
190
191 if( !aContainer.UnpackTo( &msg ) )
192 return false;
193
194 // Initialize everything to a known state that doesn't get touched by every
195 // codepath below, to make sure the equality operator is consistent
196 m_start = {};
197 m_end = {};
198 m_arcCenter = {};
199 m_arcMidData = {};
200 m_bezierC1 = {};
201 m_bezierC2 = {};
202 m_editState = 0;
203 m_proxyItem = false;
204 m_endsSwapped = false;
205
206 const_cast<KIID&>( m_Uuid ) = KIID( msg.id().value() );
207 SetLocked( msg.locked() == kiapi::common::types::LS_LOCKED );
208 SetLayer( FromProtoEnum<PCB_LAYER_ID, kiapi::board::types::BoardLayer>( msg.layer() ) );
209 SetNetCode( msg.net().code().value() );
210
211 SetFilled( msg.attributes().fill().fill_type() == kiapi::common::types::GFT_FILLED );
212 SetWidth( msg.attributes().stroke().width().value_nm() );
213
214 switch( msg.attributes().stroke().style() )
215 {
216 case kiapi::common::types::SLS_DEFAULT: SetLineStyle( LINE_STYLE::DEFAULT ); break;
217 case kiapi::common::types::SLS_SOLID: SetLineStyle( LINE_STYLE::SOLID ); break;
218 case kiapi::common::types::SLS_DASH: SetLineStyle( LINE_STYLE::DASH ); break;
219 case kiapi::common::types::SLS_DOT: SetLineStyle( LINE_STYLE::DOT ); break;
220 case kiapi::common::types::SLS_DASHDOT: SetLineStyle( LINE_STYLE::DASHDOT ); break;
221 case kiapi::common::types::SLS_DASHDOTDOT: SetLineStyle( LINE_STYLE::DASHDOTDOT ); break;
222 default: break;
223 }
224
225 if( msg.has_segment() )
226 {
227 SetShape( SHAPE_T::SEGMENT );
228 SetStart( kiapi::common::UnpackVector2( msg.segment().start() ) );
229 SetEnd( kiapi::common::UnpackVector2( msg.segment().end() ) );
230 }
231 else if( msg.has_rectangle() )
232 {
233 SetShape( SHAPE_T::RECTANGLE );
234 SetStart( kiapi::common::UnpackVector2( msg.rectangle().top_left() ) );
235 SetEnd( kiapi::common::UnpackVector2( msg.rectangle().bottom_right() ) );
236 }
237 else if( msg.has_arc() )
238 {
239 SetShape( SHAPE_T::ARC );
240 SetArcGeometry( kiapi::common::UnpackVector2( msg.arc().start() ),
241 kiapi::common::UnpackVector2( msg.arc().mid() ),
242 kiapi::common::UnpackVector2( msg.arc().end() ) );
243 }
244 else if( msg.has_circle() )
245 {
246 SetShape( SHAPE_T::CIRCLE );
247 SetStart( kiapi::common::UnpackVector2( msg.circle().center() ) );
248 SetEnd( kiapi::common::UnpackVector2( msg.circle().radius_point() ) );
249 }
250 else if( msg.has_polygon() )
251 {
252 SetShape( SHAPE_T::POLY );
253 const auto& polyMsg = msg.polygon().polygons();
254
255 SHAPE_POLY_SET sps;
256
257 for( const kiapi::common::types::PolygonWithHoles& polygonWithHoles : polyMsg )
258 {
260
261 polygon.emplace_back( kiapi::common::UnpackPolyLine( polygonWithHoles.outline() ) );
262
263 for( const kiapi::common::types::PolyLine& holeMsg : polygonWithHoles.holes() )
264 polygon.emplace_back( kiapi::common::UnpackPolyLine( holeMsg ) );
265
266 sps.AddPolygon( polygon );
267 }
268
269 SetPolyShape( sps );
270 }
271 else if( msg.has_bezier() )
272 {
273 SetShape( SHAPE_T::BEZIER );
274 SetStart( kiapi::common::UnpackVector2( msg.bezier().start() ) );
275 SetBezierC1( kiapi::common::UnpackVector2( msg.bezier().control1() ) );
276 SetBezierC2( kiapi::common::UnpackVector2( msg.bezier().control2() ) );
277 SetEnd( kiapi::common::UnpackVector2( msg.bezier().end() ) );
279 }
280
281 // TODO m_hasSolderMask and m_solderMaskMargin
282
283 return true;
284}
285
286
287bool PCB_SHAPE::IsType( const std::vector<KICAD_T>& aScanTypes ) const
288{
289 if( BOARD_ITEM::IsType( aScanTypes ) )
290 return true;
291
292 bool sametype = false;
293
294 for( KICAD_T scanType : aScanTypes )
295 {
296 if( scanType == PCB_LOCATE_BOARD_EDGE_T )
297 sametype = m_layer == Edge_Cuts;
298 else if( scanType == PCB_SHAPE_LOCATE_ARC_T )
299 sametype = m_shape == SHAPE_T::ARC;
300 else if( scanType == PCB_SHAPE_LOCATE_CIRCLE_T )
301 sametype = m_shape == SHAPE_T::CIRCLE;
302 else if( scanType == PCB_SHAPE_LOCATE_RECT_T )
303 sametype = m_shape == SHAPE_T::RECTANGLE;
304 else if( scanType == PCB_SHAPE_LOCATE_SEGMENT_T )
305 sametype = m_shape == SHAPE_T::SEGMENT;
306 else if( scanType == PCB_SHAPE_LOCATE_POLY_T )
307 sametype = m_shape == SHAPE_T::POLY;
308 else if( scanType == PCB_SHAPE_LOCATE_BEZIER_T )
309 sametype = m_shape == SHAPE_T::BEZIER;
310
311 if( sametype )
312 return true;
313 }
314
315 return false;
316}
317
318
320{
321 // Only board-level copper shapes are connectable
322 return IsOnCopperLayer() && !GetParentFootprint();
323}
324
325
327{
328 BOARD_ITEM::SetLayer( aLayer );
329
330 if( !IsOnCopperLayer() )
331 SetNetCode( -1 );
332}
333
334
336{
337 int margin = m_solderMaskMargin.value_or( 0 );
338
339 // If no local margin is set, get the board's solder mask expansion value
340 if( !m_solderMaskMargin.has_value() )
341 {
342 const BOARD* board = GetBoard();
343
344 if( board )
346 }
347
348 // Ensure the resulting mask opening has a non-negative size
349 if( margin < 0 && !IsFilled() )
350 margin = std::max( margin, -GetWidth() / 2 );
351
352 return margin;
353}
354
355
357{
358 if( aLayer == m_layer )
359 {
360 return true;
361 }
362
364 && ( ( aLayer == F_Mask && m_layer == F_Cu )
365 || ( aLayer == B_Mask && m_layer == B_Cu ) ) )
366 {
367 return true;
368 }
369
370 return false;
371}
372
373
375{
376 LSET layermask( { m_layer } );
377
378 if( m_hasSolderMask )
379 {
380 if( layermask.test( F_Cu ) )
381 layermask.set( F_Mask );
382
383 if( layermask.test( B_Cu ) )
384 layermask.set( B_Mask );
385 }
386
387 return layermask;
388}
389
390
391void PCB_SHAPE::SetLayerSet( const LSET& aLayerSet )
392{
393 aLayerSet.RunOnLayers(
394 [&]( PCB_LAYER_ID layer )
395 {
396 if( IsCopperLayer( layer ) )
397 SetLayer( layer );
398 else if( IsSolderMaskLayer( layer ) )
399 SetHasSolderMask( true );
400 } );
401}
402
403
404std::vector<VECTOR2I> PCB_SHAPE::GetConnectionPoints() const
405{
406 std::vector<VECTOR2I> ret;
407
408 // For filled shapes, we may as well use a centroid
409 if( IsFilled() )
410 {
411 ret.emplace_back( GetCenter() );
412 return ret;
413 }
414
415 switch( m_shape )
416 {
417 case SHAPE_T::CIRCLE:
418 {
419 const CIRCLE circle( GetCenter(), GetRadius() );
420 for( const TYPED_POINT2I& pt : KIGEOM::GetCircleKeyPoints( circle, false ) )
421 {
422 ret.emplace_back( pt.m_point );
423 }
424 break;
425 }
426 case SHAPE_T::ARC:
427 ret.emplace_back( GetArcMid() );
429
430 case SHAPE_T::SEGMENT:
431 case SHAPE_T::BEZIER:
432 ret.emplace_back( GetStart() );
433 ret.emplace_back( GetEnd() );
434 break;
435
436 case SHAPE_T::POLY:
437 for( auto iter = GetPolyShape().CIterate(); iter; ++iter )
438 ret.emplace_back( *iter );
439
440 break;
441
442 case SHAPE_T::RECTANGLE:
443 for( const VECTOR2I& pt : GetRectCorners() )
444 ret.emplace_back( pt );
445
446 break;
447
448 case SHAPE_T::UNDEFINED:
449 // No default - handle all cases, even if just break
450 break;
451 }
452
453 return ret;
454}
455
456
458{
459 // A stroke width of 0 in PCBNew means no-border, but negative stroke-widths are only used
460 // in EEschema (see SCH_SHAPE::GetPenWidth()).
461 // Since negative stroke widths can trip up down-stream code (such as the Gerber plotter), we
462 // weed them out here.
463 return std::max( EDA_SHAPE::GetWidth(), 0 );
464}
465
466
468{
470}
471
472
474{
475 // For some shapes return the visual center, but for not filled polygonal shapes,
476 // the center is usually far from the shape: a point on the outline is better
477
478 switch( m_shape )
479 {
480 case SHAPE_T::CIRCLE:
481 if( !IsFilled() )
482 return VECTOR2I( GetCenter().x + GetRadius(), GetCenter().y );
483 else
484 return GetCenter();
485
486 case SHAPE_T::RECTANGLE:
487 if( !IsFilled() )
488 return GetStart();
489 else
490 return GetCenter();
491
492 case SHAPE_T::POLY:
493 if( !IsFilled() )
494 {
495 VECTOR2I pos = GetPolyShape().Outline(0).CPoint(0);
496 return VECTOR2I( pos.x, pos.y );
497 }
498 else
499 {
500 return GetCenter();
501 }
502
503 case SHAPE_T::ARC:
504 return GetArcMid();
505
506 case SHAPE_T::BEZIER:
507 return GetStart();
508
509 default:
510 return GetCenter();
511 }
512}
513
514
515std::vector<VECTOR2I> PCB_SHAPE::GetCorners() const
516{
517 std::vector<VECTOR2I> pts;
518
519 if( GetShape() == SHAPE_T::RECTANGLE )
520 {
521 pts = GetRectCorners();
522 }
523 else if( GetShape() == SHAPE_T::POLY )
524 {
525 for( int ii = 0; ii < GetPolyShape().OutlineCount(); ++ii )
526 {
527 for( const VECTOR2I& pt : GetPolyShape().Outline( ii ).CPoints() )
528 pts.emplace_back( pt );
529 }
530 }
531 else
532 {
534 }
535
536 while( pts.size() < 4 )
537 pts.emplace_back( pts.back() + VECTOR2I( 10, 10 ) );
538
539 return pts;
540}
541
542
543void PCB_SHAPE::Move( const VECTOR2I& aMoveVector )
544{
545 move( aMoveVector );
546}
547
548
549void PCB_SHAPE::Scale( double aScale )
550{
551 scale( aScale );
552}
553
554
556{
557 if( m_shape == SHAPE_T::RECTANGLE )
558 {
559 VECTOR2I start = GetStart();
560 VECTOR2I end = GetEnd();
561
562 BOX2I rect( start, end - start );
563 rect.Normalize();
564
565 SetStart( rect.GetPosition() );
566 SetEnd( rect.GetEnd() );
567 }
568 else if( m_shape == SHAPE_T::POLY )
569 {
570 auto horizontal =
571 []( const SEG& seg )
572 {
573 return seg.A.y == seg.B.y;
574 };
575
576 auto vertical =
577 []( const SEG& seg )
578 {
579 return seg.A.x == seg.B.x;
580 };
581
582 // Convert a poly back to a rectangle if appropriate
583 if( m_poly.OutlineCount() == 1 && m_poly.Outline( 0 ).SegmentCount() == 4 )
584 {
585 SHAPE_LINE_CHAIN& outline = m_poly.Outline( 0 );
586
587 if( horizontal( outline.Segment( 0 ) )
588 && vertical( outline.Segment( 1 ) )
589 && horizontal( outline.Segment( 2 ) )
590 && vertical( outline.Segment( 3 ) ) )
591 {
592 m_shape = SHAPE_T::RECTANGLE;
593 m_start.x = std::min( outline.Segment( 0 ).A.x, outline.Segment( 0 ).B.x );
594 m_start.y = std::min( outline.Segment( 1 ).A.y, outline.Segment( 1 ).B.y );
595 m_end.x = std::max( outline.Segment( 0 ).A.x, outline.Segment( 0 ).B.x );
596 m_end.y = std::max( outline.Segment( 1 ).A.y, outline.Segment( 1 ).B.y );
597 }
598 else if( vertical( outline.Segment( 0 ) )
599 && horizontal( outline.Segment( 1 ) )
600 && vertical( outline.Segment( 2 ) )
601 && horizontal( outline.Segment( 3 ) ) )
602 {
603 m_shape = SHAPE_T::RECTANGLE;
604 m_start.x = std::min( outline.Segment( 1 ).A.x, outline.Segment( 1 ).B.x );
605 m_start.y = std::min( outline.Segment( 0 ).A.y, outline.Segment( 0 ).B.y );
606 m_end.x = std::max( outline.Segment( 1 ).A.x, outline.Segment( 1 ).B.x );
607 m_end.y = std::max( outline.Segment( 0 ).A.y, outline.Segment( 0 ).B.y );
608 }
609 }
610 }
611}
612
613
615{
616 if( m_shape == SHAPE_T::SEGMENT )
617 {
618 // we want start point the top left point and end point the bottom right
619 // (more easy to compare 2 segments: we are seeing them as equivalent if
620 // they have the same end points, not necessary the same order)
621 VECTOR2I start = GetStart();
622 VECTOR2I end = GetEnd();
623
624 if( ( start.x > end.x )
625 || ( start.x == end.x && start.y < end.y ) )
626 {
627 SetStart( end );
628 SetEnd( start );
629 }
630 }
631 else
632 Normalize();
633}
634
635
636void PCB_SHAPE::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
637{
638 rotate( aRotCentre, aAngle );
639}
640
641
642void PCB_SHAPE::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
643{
644 flip( aCentre, aFlipDirection );
645
647}
648
649
650void PCB_SHAPE::Mirror( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
651{
652 // Mirror an edge of the footprint. the layer is not modified
653 // This is a footprint shape modification.
654
655 switch( GetShape() )
656 {
657 case SHAPE_T::ARC:
658 case SHAPE_T::SEGMENT:
659 case SHAPE_T::RECTANGLE:
660 case SHAPE_T::CIRCLE:
661 case SHAPE_T::BEZIER:
662 MIRROR( m_start, aCentre, aFlipDirection );
663 MIRROR( m_end, aCentre, aFlipDirection );
664 MIRROR( m_arcCenter, aCentre, aFlipDirection );
665 MIRROR( m_bezierC1, aCentre, aFlipDirection );
666 MIRROR( m_bezierC2, aCentre, aFlipDirection );
667
668 if( GetShape() == SHAPE_T::ARC )
669 std::swap( m_start, m_end );
670
671 if( GetShape() == SHAPE_T::BEZIER )
673
674 break;
675
676 case SHAPE_T::POLY:
677 m_poly.Mirror( aCentre, aFlipDirection );
678 break;
679
680 default:
682 }
683}
684
685
686void PCB_SHAPE::SetIsProxyItem( bool aIsProxy )
687{
688 PAD* parentPad = nullptr;
689
690 if( GetBoard() && GetBoard()->IsFootprintHolder() )
691 {
692 for( FOOTPRINT* fp : GetBoard()->Footprints() )
693 {
694 for( PAD* pad : fp->Pads() )
695 {
696 if( pad->IsEntered() )
697 {
698 parentPad = pad;
699 break;
700 }
701 }
702 }
703 }
704
705 if( aIsProxy && !m_proxyItem )
706 {
707 if( GetShape() == SHAPE_T::SEGMENT )
708 {
709 if( parentPad && parentPad->GetThermalSpokeWidth() )
710 SetWidth( parentPad->GetThermalSpokeWidth() );
711 else
713 }
714 else
715 {
716 SetWidth( 1 );
717 }
718 }
719 else if( m_proxyItem && !aIsProxy )
720 {
722 }
723
724 m_proxyItem = aIsProxy;
725}
726
727
728double PCB_SHAPE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
729{
730 constexpr double HIDE = std::numeric_limits<double>::max();
731 constexpr double SHOW = 0.0;
732
733 KIGFX::PCB_PAINTER* painter = static_cast<KIGFX::PCB_PAINTER*>( aView->GetPainter() );
734 KIGFX::PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings();
735
736 if( aLayer == LAYER_LOCKED_ITEM_SHADOW )
737 {
738 // Hide shadow if the main layer is not shown
739 if( !aView->IsLayerVisible( m_layer ) )
740 return HIDE;
741
742 // Hide shadow on dimmed tracks
743 if( renderSettings->GetHighContrast() )
744 {
745 if( m_layer != renderSettings->GetPrimaryHighContrastLayer() )
746 return HIDE;
747 }
748 }
749
750 if( FOOTPRINT* parent = GetParentFootprint() )
751 {
752 if( parent->GetLayer() == F_Cu && !aView->IsLayerVisible( LAYER_FOOTPRINTS_FR ) )
753 return HIDE;
754
755 if( parent->GetLayer() == B_Cu && !aView->IsLayerVisible( LAYER_FOOTPRINTS_BK ) )
756 return HIDE;
757 }
758
759 return SHOW;
760}
761
762
763void PCB_SHAPE::ViewGetLayers( int aLayers[], int& aCount ) const
764{
765 aLayers[0] = GetLayer();
766
767 if( IsOnCopperLayer() )
768 {
769 aLayers[1] = GetNetnameLayer( aLayers[0] );
770 aCount = 2;
771
772 if( m_hasSolderMask )
773 {
774 if( m_layer == F_Cu )
775 aLayers[ aCount++ ] = F_Mask;
776 else if( m_layer == B_Cu )
777 aLayers[ aCount++ ] = B_Mask;
778 }
779 }
780 else
781 {
782 aCount = 1;
783 }
784
785 if( IsLocked() )
786 aLayers[ aCount++ ] = LAYER_LOCKED_ITEM_SHADOW;
787}
788
789
790void PCB_SHAPE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
791{
792 if( aFrame->GetName() == PCB_EDIT_FRAME_NAME )
793 {
794 if( FOOTPRINT* parent = GetParentFootprint() )
795 aList.emplace_back( _( "Footprint" ), parent->GetReference() );
796 }
797
798 aList.emplace_back( _( "Type" ), _( "Drawing" ) );
799
800 if( aFrame->GetName() == PCB_EDIT_FRAME_NAME && IsLocked() )
801 aList.emplace_back( _( "Status" ), _( "Locked" ) );
802
803 ShapeGetMsgPanelInfo( aFrame, aList );
804
805 aList.emplace_back( _( "Layer" ), GetLayerName() );
806}
807
808
809wxString PCB_SHAPE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
810{
811 FOOTPRINT* parentFP = nullptr;
812
813 if( EDA_DRAW_FRAME* frame = dynamic_cast<EDA_DRAW_FRAME*>( aUnitsProvider ) )
814 {
815 if( frame->GetName() == PCB_EDIT_FRAME_NAME )
816 parentFP = GetParentFootprint();
817 }
818
819 if( IsOnCopperLayer() )
820 {
821 if( parentFP )
822 {
823 return wxString::Format( _( "%s %s of %s on %s" ),
826 parentFP->GetReference(),
827 GetLayerName() );
828 }
829 else
830 {
831 return wxString::Format( _( "%s %s on %s" ),
834 GetLayerName() );
835 }
836 }
837 else
838 {
839 if( parentFP )
840 {
841 return wxString::Format( _( "%s of %s on %s" ),
843 parentFP->GetReference(),
844 GetLayerName() );
845 }
846 else
847 {
848 return wxString::Format( _( "%s on %s" ),
850 GetLayerName() );
851 }
852 }
853}
854
855
857{
858 if( GetParentFootprint() )
859 return BITMAPS::show_mod_edge;
860 else
861 return BITMAPS::add_dashed_line;
862}
863
864
866{
867 return new PCB_SHAPE( *this );
868}
869
870
872{
873 BOX2I return_box = EDA_ITEM::ViewBBox();
874
875 // Inflate the bounding box by just a bit more for safety.
876 return_box.Inflate( GetWidth() );
877
878 return return_box;
879}
880
881
882std::shared_ptr<SHAPE> PCB_SHAPE::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
883{
884 return std::make_shared<SHAPE_COMPOUND>( MakeEffectiveShapes() );
885}
886
887
889{
890 PCB_SHAPE* image = dynamic_cast<PCB_SHAPE*>( aImage );
891 wxCHECK( image, /* void */ );
892
893 SwapShape( image );
894
895 // Swap params not handled by SwapShape( image )
896 std::swap( m_layer, image->m_layer );
897 std::swap( m_isKnockout, image->m_isKnockout );
898 std::swap( m_isLocked, image->m_isLocked );
899 std::swap( m_flags, image->m_flags );
900 std::swap( m_parent, image->m_parent );
901 std::swap( m_forceVisible, image->m_forceVisible );
902 std::swap( m_netinfo, image->m_netinfo );
903 std::swap( m_hasSolderMask, image->m_hasSolderMask );
904 std::swap( m_solderMaskMargin, image->m_solderMaskMargin );
905}
906
907
909 const BOARD_ITEM* aSecond ) const
910{
911 if( aFirst->Type() != aSecond->Type() )
912 return aFirst->Type() < aSecond->Type();
913
914 if( aFirst->GetLayer() != aSecond->GetLayer() )
915 return aFirst->GetLayer() < aSecond->GetLayer();
916
917 if( aFirst->Type() == PCB_SHAPE_T )
918 {
919 const PCB_SHAPE* dwgA = static_cast<const PCB_SHAPE*>( aFirst );
920 const PCB_SHAPE* dwgB = static_cast<const PCB_SHAPE*>( aSecond );
921
922 if( dwgA->GetShape() != dwgB->GetShape() )
923 return dwgA->GetShape() < dwgB->GetShape();
924 }
925
926 return aFirst->m_Uuid < aSecond->m_Uuid;
927}
928
929
931 int aClearance, int aError, ERROR_LOC aErrorLoc,
932 bool ignoreLineWidth ) const
933{
934 EDA_SHAPE::TransformShapeToPolygon( aBuffer, aClearance, aError, aErrorLoc, ignoreLineWidth );
935}
936
937
938bool PCB_SHAPE::operator==( const BOARD_ITEM& aOther ) const
939{
940 if( aOther.Type() != Type() )
941 return false;
942
943 const PCB_SHAPE& other = static_cast<const PCB_SHAPE&>( aOther );
944
945 return *this == other;
946}
947
948
949bool PCB_SHAPE::operator==( const PCB_SHAPE& aOther ) const
950{
951 if( aOther.Type() != Type() )
952 return false;
953
954 const PCB_SHAPE& other = static_cast<const PCB_SHAPE&>( aOther );
955
956 if( m_layer != other.m_layer )
957 return false;
958
959 if( m_isKnockout != other.m_isKnockout )
960 return false;
961
962 if( m_isLocked != other.m_isLocked )
963 return false;
964
965 if( m_flags != other.m_flags )
966 return false;
967
968 if( m_forceVisible != other.m_forceVisible )
969 return false;
970
971 if( m_netinfo->GetNetCode() != other.m_netinfo->GetNetCode() )
972 return false;
973
974 if( m_hasSolderMask != other.m_hasSolderMask )
975 return false;
976
978 return false;
979
980 return EDA_SHAPE::operator==( other );
981}
982
983
984double PCB_SHAPE::Similarity( const BOARD_ITEM& aOther ) const
985{
986 if( aOther.Type() != Type() )
987 return 0.0;
988
989 const PCB_SHAPE& other = static_cast<const PCB_SHAPE&>( aOther );
990
991 double similarity = 1.0;
992
993 if( GetLayer() != other.GetLayer() )
994 similarity *= 0.9;
995
996 if( m_isKnockout != other.m_isKnockout )
997 similarity *= 0.9;
998
999 if( m_isLocked != other.m_isLocked )
1000 similarity *= 0.9;
1001
1002 if( m_flags != other.m_flags )
1003 similarity *= 0.9;
1004
1005 if( m_forceVisible != other.m_forceVisible )
1006 similarity *= 0.9;
1007
1008 if( m_netinfo->GetNetCode() != other.m_netinfo->GetNetCode() )
1009 similarity *= 0.9;
1010
1011 if( m_hasSolderMask != other.m_hasSolderMask )
1012 similarity *= 0.9;
1013
1015 similarity *= 0.9;
1016
1017 similarity *= EDA_SHAPE::Similarity( other );
1018
1019 return similarity;
1020}
1021
1022
1023static struct PCB_SHAPE_DESC
1024{
1026 {
1033
1034 // Need to initialise enum_map before we can use a Property enum for it
1036
1037 if( layerEnum.Choices().GetCount() == 0 )
1038 {
1039 layerEnum.Undefined( UNDEFINED_LAYER );
1040
1041 for( PCB_LAYER_ID layer : LSET::AllLayersMask().Seq() )
1042 layerEnum.Map( layer, LSET::Name( layer ) );
1043 }
1044
1045 void ( PCB_SHAPE::*shapeLayerSetter )( PCB_LAYER_ID ) = &PCB_SHAPE::SetLayer;
1046 PCB_LAYER_ID ( PCB_SHAPE::*shapeLayerGetter )() const = &PCB_SHAPE::GetLayer;
1047
1048 auto layerProperty = new PROPERTY_ENUM<PCB_SHAPE, PCB_LAYER_ID>(
1049 _HKI( "Layer" ), shapeLayerSetter, shapeLayerGetter );
1050
1051 propMgr.ReplaceProperty( TYPE_HASH( BOARD_CONNECTED_ITEM ), _HKI( "Layer" ), layerProperty );
1052
1053 // Only polygons have meaningful Position properties.
1054 // On other shapes, these are duplicates of the Start properties.
1055 auto isPolygon =
1056 []( INSPECTABLE* aItem ) -> bool
1057 {
1058 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1059 return shape->GetShape() == SHAPE_T::POLY;
1060
1061 return false;
1062 };
1063
1065 _HKI( "Position X" ), isPolygon );
1067 _HKI( "Position Y" ), isPolygon );
1068
1069 propMgr.Mask( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Color" ) );
1070 propMgr.Mask( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ), _HKI( "Fill Color" ) );
1071
1072 auto isCopper =
1073 []( INSPECTABLE* aItem ) -> bool
1074 {
1075 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1076 return shape->IsOnCopperLayer();
1077
1078 return false;
1079 };
1080
1082 _HKI( "Net" ), isCopper );
1083
1084 auto isPadEditMode =
1085 []( BOARD* aBoard ) -> bool
1086 {
1087 if( aBoard && aBoard->IsFootprintHolder() )
1088 {
1089 for( FOOTPRINT* fp : aBoard->Footprints() )
1090 {
1091 for( PAD* pad : fp->Pads() )
1092 {
1093 if( pad->IsEntered() )
1094 return true;
1095 }
1096 }
1097 }
1098
1099 return false;
1100 };
1101
1102 auto showNumberBoxProperty =
1103 [&]( INSPECTABLE* aItem ) -> bool
1104 {
1105 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1106 {
1107 if( shape->GetShape() == SHAPE_T::RECTANGLE )
1108 return isPadEditMode( shape->GetBoard() );
1109 }
1110
1111 return false;
1112 };
1113
1114 auto showSpokeTemplateProperty =
1115 [&]( INSPECTABLE* aItem ) -> bool
1116 {
1117 if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1118 {
1119 if( shape->GetShape() == SHAPE_T::SEGMENT )
1120 return isPadEditMode( shape->GetBoard() );
1121 }
1122
1123 return false;
1124 };
1125
1126 const wxString groupPadPrimitives = _HKI( "Pad Primitives" );
1127
1128 propMgr.AddProperty( new PROPERTY<PCB_SHAPE, bool>( _HKI( "Number Box" ),
1131 groupPadPrimitives )
1132 .SetAvailableFunc( showNumberBoxProperty )
1134
1135 propMgr.AddProperty( new PROPERTY<PCB_SHAPE, bool>( _HKI( "Thermal Spoke Template" ),
1138 groupPadPrimitives )
1139 .SetAvailableFunc( showSpokeTemplateProperty )
1141
1142 const wxString groupTechLayers = _HKI( "Technical Layers" );
1143
1144 auto isExternalCuLayer =
1145 []( INSPECTABLE* aItem )
1146 {
1147 if( auto shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
1148 return IsExternalCopperLayer( shape->GetLayer() );
1149
1150 return false;
1151 };
1152
1153 propMgr.AddProperty( new PROPERTY<PCB_SHAPE, bool>( _HKI( "Soldermask" ),
1156 groupTechLayers )
1157 .SetAvailableFunc( isExternalCuLayer );
1158
1159 propMgr.AddProperty( new PROPERTY<PCB_SHAPE, std::optional<int>>(
1160 _HKI( "Soldermask Margin Override" ),
1163 PROPERTY_DISPLAY::PT_SIZE ),
1164 groupTechLayers )
1165 .SetAvailableFunc( isExternalCuLayer );
1166 }
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
constexpr int ARC_HIGH_DEF
Definition: base_units.h:120
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
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:115
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:79
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:237
bool m_isKnockout
Definition: board_item.h:437
virtual void SetLocked(bool aLocked)
Definition: board_item.h:328
PCB_LAYER_ID m_layer
Definition: board_item.h:436
bool m_isLocked
Definition: board_item.h:439
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:288
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:47
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:299
virtual bool IsLocked() const
Definition: board_item.cpp:75
virtual bool IsOnCopperLayer() const
Definition: board_item.h:150
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Definition: board_item.cpp:139
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:290
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:892
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
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:89
const KIID m_Uuid
Definition: eda_item.h:489
bool m_forceVisible
Definition: eda_item.h:501
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:101
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:499
virtual bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
Definition: eda_item.h:176
virtual const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
Definition: eda_item.cpp:276
EDA_ITEM * m_parent
Linked list: Link (parent struct)
Definition: eda_item.h:500
SHAPE_T m_shape
Definition: eda_shape.h:414
bool m_proxyItem
Definition: eda_shape.h:438
bool m_endsSwapped
Definition: eda_shape.h:413
const VECTOR2I & GetBezierC2() const
Definition: eda_shape.h:206
void SetBezierC2(const VECTOR2I &aPt)
Definition: eda_shape.h:205
int m_editState
Definition: eda_shape.h:437
void rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle)
Definition: eda_shape.cpp:374
FILL_T GetFillMode() const
Definition: eda_shape.h:107
void SetLineStyle(const LINE_STYLE aStyle)
Definition: eda_shape.cpp:1783
virtual std::vector< SHAPE * > MakeEffectiveShapes(bool aEdgeOnly=false) const
Make a set of SHAPE objects representing the EDA_SHAPE.
Definition: eda_shape.h:319
SHAPE_POLY_SET & GetPolyShape()
Definition: eda_shape.h:279
bool IsFilled() const
Definition: eda_shape.h:91
void ShapeGetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList)
Definition: eda_shape.cpp:715
void SetFilled(bool aFlag)
Definition: eda_shape.h:101
bool operator==(const EDA_SHAPE &aOther) const
Definition: eda_shape.cpp:1798
int GetRadius() const
Definition: eda_shape.cpp:575
SHAPE_T GetShape() const
Definition: eda_shape.h:125
void SetPolyShape(const SHAPE_POLY_SET &aShape)
Definition: eda_shape.h:287
VECTOR2I m_arcCenter
Definition: eda_shape.h:428
ARC_MID m_arcMidData
Definition: eda_shape.h:429
void RebuildBezierToSegmentsPointsList(int aMaxError)
Rebuild the m_bezierPoints vertex list that approximate the Bezier curve by a list of segments.
Definition: eda_shape.cpp:474
void flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection)
Definition: eda_shape.cpp:431
VECTOR2I m_start
Definition: eda_shape.h:425
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:167
void SetStart(const VECTOR2I &aStart)
Definition: eda_shape.h:134
LINE_STYLE GetLineStyle() const
Definition: eda_shape.cpp:1789
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition: eda_shape.h:130
void SetShape(SHAPE_T aShape)
Definition: eda_shape.h:124
void SwapShape(EDA_SHAPE *aImage)
Definition: eda_shape.cpp:1600
std::vector< VECTOR2I > GetRectCorners() const
Definition: eda_shape.cpp:1134
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:171
void SetBezierC1(const VECTOR2I &aPt)
Definition: eda_shape.h:202
void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
Definition: eda_shape.cpp:607
wxString SHAPE_T_asString() const
Definition: eda_shape.cpp:89
double Similarity(const EDA_SHAPE &aOther) const
Definition: eda_shape.cpp:1843
const VECTOR2I & GetBezierC1() const
Definition: eda_shape.h:203
VECTOR2I m_end
Definition: eda_shape.h:426
SHAPE_POLY_SET m_poly
Definition: eda_shape.h:435
virtual int GetWidth() const
Definition: eda_shape.h:115
STROKE_PARAMS m_stroke
Definition: eda_shape.h:415
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const
Convert the shape to a closed polygon.
Definition: eda_shape.cpp:1664
VECTOR2I m_bezierC1
Definition: eda_shape.h:431
void SetWidth(int aWidth)
Definition: eda_shape.h:114
VECTOR2I m_bezierC2
Definition: eda_shape.h:432
VECTOR2I GetArcMid() const
Definition: eda_shape.cpp:545
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition: property.h:669
static ENUM_MAP< T > & Instance()
Definition: property.h:663
ENUM_MAP & Undefined(T aValue)
Definition: property.h:676
wxPGChoices & Choices()
Definition: property.h:712
const wxString & GetReference() const
Definition: footprint.h:602
Class that other classes need to inherit from, in order to be inspectable.
Definition: inspectable.h:36
Contains methods for drawing PCB-specific items.
Definition: pcb_painter.h:173
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:178
PCB specific render settings.
Definition: pcb_painter.h:78
PCB_LAYER_ID GetPrimaryHighContrastLayer() const
Return the board layer which is in high-contrast mode.
bool GetHighContrast() const
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:68
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:221
Definition: kiid.h:49
std::string AsStdString() const
Definition: kiid.cpp:244
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:36
static LSET AllLayersMask()
Definition: lset.cpp:701
void RunOnLayers(const std::function< void(PCB_LAYER_ID)> &aFunction) const
Execute a function on each layer of the LSET.
Definition: lset.h:241
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:183
int GetNetCode() const
Definition: netinfo.h:108
Definition: pad.h:54
int GetThermalSpokeWidth() const
Definition: pad.h:602
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:650
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:790
void swapData(BOARD_ITEM *aImage) override
Definition: pcb_shape.cpp:888
bool IsConnected() const override
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
Definition: pcb_shape.cpp:319
std::optional< int > GetLocalSolderMaskMargin() const
Definition: pcb_shape.h:186
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_shape.h:79
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
Definition: pcb_shape.cpp:636
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: pcb_shape.cpp:856
PCB_SHAPE(BOARD_ITEM *aParent, KICAD_T aItemType, SHAPE_T aShapeType)
Definition: pcb_shape.cpp:51
int GetWidth() const override
Definition: pcb_shape.cpp:457
const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
Definition: pcb_shape.cpp:871
bool HasSolderMask() const
Definition: pcb_shape.h:183
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:882
void SetHasSolderMask(bool aVal)
Definition: pcb_shape.h:182
std::optional< int > m_solderMaskMargin
Definition: pcb_shape.h:203
int GetSolderMaskExpansion() const
Definition: pcb_shape.cpp:335
void NormalizeForCompare() override
Normalize coordinates to compare 2 similar PCB_SHAPES similat to Normalize(), but also normalize SEGM...
Definition: pcb_shape.cpp:614
void ViewGetLayers(int aLayers[], int &aCount) const override
Definition: pcb_shape.cpp:763
const VECTOR2I GetFocusPosition() const override
Allows items to return their visual center rather than their anchor.
Definition: pcb_shape.cpp:473
virtual void SetLayerSet(const LSET &aLayers) override
Definition: pcb_shape.cpp:391
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
Definition: pcb_shape.cpp:642
virtual std::vector< VECTOR2I > GetCorners() const
Return 4 corners for a rectangle or rotated rectangle (stored as a poly).
Definition: pcb_shape.cpp:515
bool IsProxyItem() const override
Definition: pcb_shape.h:114
bool m_hasSolderMask
Definition: pcb_shape.h:202
~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:374
bool operator==(const PCB_SHAPE &aShape) const
Definition: pcb_shape.cpp:949
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition: pcb_shape.cpp:326
wxString GetFriendlyName() const override
Definition: pcb_shape.h:64
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:930
void SetIsProxyItem(bool aIsProxy=true) override
Definition: pcb_shape.cpp:686
void StyleFromSettings(const BOARD_DESIGN_SETTINGS &settings) override
Definition: pcb_shape.cpp:467
void SetLocalSolderMaskMargin(std::optional< int > aMargin)
Definition: pcb_shape.h:185
void Move(const VECTOR2I &aMoveVector) override
Move this object.
Definition: pcb_shape.cpp:543
std::vector< VECTOR2I > GetConnectionPoints() const
Definition: pcb_shape.cpp:404
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: pcb_shape.cpp:187
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: pcb_shape.cpp:865
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: pcb_shape.cpp:728
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
Definition: pcb_shape.cpp:356
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
Definition: pcb_shape.cpp:809
void Scale(double aScale)
Definition: pcb_shape.cpp:549
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: pcb_shape.cpp:72
void Normalize() override
Perform any normalization required after a user rotate and/or flip.
Definition: pcb_shape.cpp:555
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition: pcb_shape.cpp:287
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:984
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: pcb_shape.h:69
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.
POLYGON & Polygon(int aIndex)
Return the aIndex-th subpolygon in the set.
int AddPolygon(const POLYGON &apolygon)
Adds a polygon to the set.
std::vector< SHAPE_LINE_CHAIN > POLYGON
represents a single polygon outline with holes.
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 SetWidth(int aWidth)
Definition: stroke_params.h:90
#define _HKI(x)
#define _(s)
#define PCB_EDIT_FRAME_NAME
SHAPE_T
Definition: eda_shape.h:42
FILL_T
Definition: eda_shape.h:55
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition: layer_id.cpp:208
bool IsSolderMaskLayer(int aLayer)
Definition: layer_ids.h:590
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
Definition: layer_ids.h:147
int GetNetnameLayer(int aLayer)
Returns a netname layer corresponding to the given layer.
Definition: layer_ids.h:695
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:531
@ LAYER_LOCKED_ITEM_SHADOW
shadow layer for locked items
Definition: layer_ids.h:240
@ LAYER_FOOTPRINTS_FR
show footprints on front
Definition: layer_ids.h:209
@ LAYER_FOOTPRINTS_BK
show footprints on back
Definition: layer_ids.h:210
bool IsExternalCopperLayer(int aLayerId)
Tests whether a layer is an external (F_Cu or B_Cu) copper layer.
Definition: layer_ids.h:542
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.
VECTOR2I UnpackVector2(const types::Vector2 &aInput)
Definition: api_utils.cpp:76
void PackVector2(types::Vector2 &aOutput, const VECTOR2I &aInput)
Definition: api_utils.cpp:69
void PackPolyLine(kiapi::common::types::PolyLine &aOutput, const SHAPE_LINE_CHAIN &aSlc)
Definition: api_utils.cpp:95
SHAPE_LINE_CHAIN UnpackPolyLine(const kiapi::common::types::PolyLine &aInput)
Definition: api_utils.cpp:125
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:908
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_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:691
#define ZONE_THERMAL_RELIEF_COPPER_WIDTH_MM
Definition: zones.h:34