KiCad PCB EDA Suite
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
pcb_track.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) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6 * Copyright (C) 2012 Wayne Stambaugh <stambaughw@gmail.com>
7 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include "pcb_track.h"
28
29#include <pcb_base_frame.h>
30#include <core/mirror.h>
32#include <board.h>
35#include <base_units.h>
36#include <layer_range.h>
37#include <lset.h>
38#include <string_utils.h>
39#include <view/view.h>
43#include <geometry/seg.h>
46#include <geometry/shape_arc.h>
47#include <drc/drc_engine.h>
48#include <pcb_painter.h>
49#include <trigo.h>
50
51#include <google/protobuf/any.pb.h>
52#include <api/api_enums.h>
53#include <api/api_utils.h>
54#include <api/api_pcb_utils.h>
55#include <api/board/board_types.pb.h>
56
59
61 BOARD_CONNECTED_ITEM( aParent, idtype )
62{
63 m_width = pcbIUScale.mmToIU( 0.2 ); // Gives a reasonable default width
64 m_hasSolderMask = false;
65}
66
67
69{
70 return new PCB_TRACK( *this );
71}
72
73
74void PCB_TRACK::CopyFrom( const BOARD_ITEM* aOther )
75{
76 wxCHECK( aOther && aOther->Type() == PCB_TRACE_T, /* void */ );
77 *this = *static_cast<const PCB_TRACK*>( aOther );
78}
79
80
81PCB_ARC::PCB_ARC( BOARD_ITEM* aParent, const SHAPE_ARC* aArc ) :
82 PCB_TRACK( aParent, PCB_ARC_T )
83{
84 m_Start = aArc->GetP0();
85 m_End = aArc->GetP1();
86 m_Mid = aArc->GetArcMid();
87}
88
89
91{
92 return new PCB_ARC( *this );
93}
94
95
96void PCB_ARC::CopyFrom( const BOARD_ITEM* aOther )
97{
98 wxCHECK( aOther && aOther->Type() == PCB_ARC_T, /* void */ );
99 *this = *static_cast<const PCB_ARC*>( aOther );
100}
101
102
104 PCB_TRACK( aParent, PCB_VIA_T ),
105 m_padStack( this )
106{
107 SetViaType( VIATYPE::THROUGH );
108 Padstack().Drill().start = F_Cu;
109 Padstack().Drill().end = B_Cu;
111
113
114 // Padstack layerset is not used for vias right now
116
117 // For now, vias are always circles
118 m_padStack.SetShape( PAD_SHAPE::CIRCLE, PADSTACK::ALL_LAYERS );
119
122
123 m_isFree = false;
124}
125
126
127PCB_VIA::PCB_VIA( const PCB_VIA& aOther ) :
128 PCB_TRACK( aOther.GetParent(), PCB_VIA_T ),
129 m_padStack( this )
130{
131 PCB_VIA::operator=( aOther );
132
133 const_cast<KIID&>( m_Uuid ) = aOther.m_Uuid;
135}
136
137
139{
141
142 m_Start = aOther.m_Start;
143 m_End = aOther.m_End;
144
145 m_viaType = aOther.m_viaType;
146 m_padStack = aOther.m_padStack;
147 m_isFree = aOther.m_isFree;
148
149 return *this;
150}
151
152
153void PCB_VIA::CopyFrom( const BOARD_ITEM* aOther )
154{
155 wxCHECK( aOther && aOther->Type() == PCB_VIA_T, /* void */ );
156 *this = *static_cast<const PCB_VIA*>( aOther );
157}
158
159
161{
162 return new PCB_VIA( *this );
163}
164
165
166wxString PCB_VIA::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
167{
168 wxString formatStr;
169
170 switch( GetViaType() )
171 {
172 case VIATYPE::BLIND_BURIED: formatStr = _( "Blind/Buried Via %s on %s" ); break;
173 case VIATYPE::MICROVIA: formatStr = _( "Micro Via %s on %s" ); break;
174 default: formatStr = _( "Via %s on %s" ); break;
175 }
176
177 return wxString::Format( formatStr, GetNetnameMsg(), layerMaskDescribe() );
178}
179
180
182{
183 return BITMAPS::via;
184}
185
186
187bool PCB_TRACK::operator==( const BOARD_ITEM& aBoardItem ) const
188{
189 if( aBoardItem.Type() != Type() )
190 return false;
191
192 const PCB_TRACK& other = static_cast<const PCB_TRACK&>( aBoardItem );
193
194 return *this == other;
195}
196
197
198bool PCB_TRACK::operator==( const PCB_TRACK& aOther ) const
199{
200 return m_Start == aOther.m_Start
201 && m_End == aOther.m_End
202 && m_layer == aOther.m_layer
203 && m_width == aOther.m_width
206}
207
208
209double PCB_TRACK::Similarity( const BOARD_ITEM& aOther ) const
210{
211 if( aOther.Type() != Type() )
212 return 0.0;
213
214 const PCB_TRACK& other = static_cast<const PCB_TRACK&>( aOther );
215
216 double similarity = 1.0;
217
218 if( m_layer != other.m_layer )
219 similarity *= 0.9;
220
221 if( m_width != other.m_width )
222 similarity *= 0.9;
223
224 if( m_Start != other.m_Start )
225 similarity *= 0.9;
226
227 if( m_End != other.m_End )
228 similarity *= 0.9;
229
230 if( m_hasSolderMask != other.m_hasSolderMask )
231 similarity *= 0.9;
232
234 similarity *= 0.9;
235
236 return similarity;
237}
238
239
240bool PCB_ARC::operator==( const BOARD_ITEM& aBoardItem ) const
241{
242 if( aBoardItem.Type() != Type() )
243 return false;
244
245 const PCB_ARC& other = static_cast<const PCB_ARC&>( aBoardItem );
246
247 return *this == other;
248}
249
250
251bool PCB_ARC::operator==( const PCB_TRACK& aOther ) const
252{
253 if( aOther.Type() != Type() )
254 return false;
255
256 const PCB_ARC& other = static_cast<const PCB_ARC&>( aOther );
257
258 return *this == other;
259}
260
261
262bool PCB_ARC::operator==( const PCB_ARC& aOther ) const
263{
264 return m_Start == aOther.m_Start
265 && m_End == aOther.m_End
266 && m_Mid == aOther.m_Mid
267 && m_layer == aOther.m_layer
268 && GetWidth() == aOther.GetWidth()
271}
272
273
274double PCB_ARC::Similarity( const BOARD_ITEM& aOther ) const
275{
276 if( aOther.Type() != Type() )
277 return 0.0;
278
279 const PCB_ARC& other = static_cast<const PCB_ARC&>( aOther );
280
281 double similarity = 1.0;
282
283 if( m_layer != other.m_layer )
284 similarity *= 0.9;
285
286 if( GetWidth() != other.GetWidth() )
287 similarity *= 0.9;
288
289 if( m_Start != other.m_Start )
290 similarity *= 0.9;
291
292 if( m_End != other.m_End )
293 similarity *= 0.9;
294
295 if( m_Mid != other.m_Mid )
296 similarity *= 0.9;
297
298 if( m_hasSolderMask != other.m_hasSolderMask )
299 similarity *= 0.9;
300
302 similarity *= 0.9;
303
304 return similarity;
305}
306
307
308bool PCB_VIA::operator==( const BOARD_ITEM& aBoardItem ) const
309{
310 if( aBoardItem.Type() != Type() )
311 return false;
312
313 const PCB_VIA& other = static_cast<const PCB_VIA&>( aBoardItem );
314
315 return *this == other;
316}
317
318
319bool PCB_VIA::operator==( const PCB_TRACK& aOther ) const
320{
321 if( aOther.Type() != Type() )
322 return false;
323
324 const PCB_VIA& other = static_cast<const PCB_VIA&>( aOther );
325
326 return *this == other;
327}
328
329
330bool PCB_VIA::operator==( const PCB_VIA& aOther ) const
331{
332 return m_Start == aOther.m_Start
333 && m_End == aOther.m_End
334 && m_layer == aOther.m_layer
335 && m_padStack == aOther.m_padStack
336 && m_viaType == aOther.m_viaType
338}
339
340
341double PCB_VIA::Similarity( const BOARD_ITEM& aOther ) const
342{
343 if( aOther.Type() != Type() )
344 return 0.0;
345
346 const PCB_VIA& other = static_cast<const PCB_VIA&>( aOther );
347
348 double similarity = 1.0;
349
350 if( m_layer != other.m_layer )
351 similarity *= 0.9;
352
353 if( m_Start != other.m_Start )
354 similarity *= 0.9;
355
356 if( m_End != other.m_End )
357 similarity *= 0.9;
358
359 if( m_padStack != other.m_padStack )
360 similarity *= 0.9;
361
362 if( m_viaType != other.m_viaType )
363 similarity *= 0.9;
364
366 similarity *= 0.9;
367
368 return similarity;
369}
370
371
372void PCB_VIA::SetWidth( int aWidth )
373{
374 // This is present because of the parent class. It should never be actually called on a via.
375 wxASSERT_MSG( false, "Warning: PCB_VIA::SetWidth called without a layer argument" );
376 m_padStack.SetSize( { aWidth, aWidth }, PADSTACK::ALL_LAYERS );
377}
378
379
381{
382 // This is present because of the parent class. It should never be actually called on a via.
383 wxASSERT_MSG( false, "Warning: PCB_VIA::GetWidth called without a layer argument" );
385}
386
387
388void PCB_VIA::SetWidth( PCB_LAYER_ID aLayer, int aWidth )
389{
390 m_padStack.SetSize( { aWidth, aWidth }, aLayer );
391}
392
393
395{
396 return m_padStack.Size( aLayer ).x;
397}
398
399
400void PCB_TRACK::Serialize( google::protobuf::Any &aContainer ) const
401{
402 kiapi::board::types::Track track;
403
404 track.mutable_id()->set_value( m_Uuid.AsStdString() );
405 track.mutable_start()->set_x_nm( GetStart().x );
406 track.mutable_start()->set_y_nm( GetStart().y );
407 track.mutable_end()->set_x_nm( GetEnd().x );
408 track.mutable_end()->set_y_nm( GetEnd().y );
409 track.mutable_width()->set_value_nm( GetWidth() );
410 track.set_layer( ToProtoEnum<PCB_LAYER_ID, kiapi::board::types::BoardLayer>( GetLayer() ) );
411 track.set_locked( IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
412 : kiapi::common::types::LockedState::LS_UNLOCKED );
413 track.mutable_net()->mutable_code()->set_value( GetNetCode() );
414 track.mutable_net()->set_name( GetNetname() );
415 // TODO m_hasSolderMask and m_solderMaskMargin
416
417 aContainer.PackFrom( track );
418}
419
420
421bool PCB_TRACK::Deserialize( const google::protobuf::Any &aContainer )
422{
423 kiapi::board::types::Track track;
424
425 if( !aContainer.UnpackTo( &track ) )
426 return false;
427
428 const_cast<KIID&>( m_Uuid ) = KIID( track.id().value() );
429 SetStart( VECTOR2I( track.start().x_nm(), track.start().y_nm() ) );
430 SetEnd( VECTOR2I( track.end().x_nm(), track.end().y_nm() ) );
431 SetWidth( track.width().value_nm() );
432 SetLayer( FromProtoEnum<PCB_LAYER_ID, kiapi::board::types::BoardLayer>( track.layer() ) );
433 SetNetCode( track.net().code().value() );
434 SetLocked( track.locked() == kiapi::common::types::LockedState::LS_LOCKED );
435 // TODO m_hasSolderMask and m_solderMaskMargin
436
437 return true;
438}
439
440
441void PCB_ARC::Serialize( google::protobuf::Any &aContainer ) const
442{
443 kiapi::board::types::Arc arc;
444
445 arc.mutable_id()->set_value( m_Uuid.AsStdString() );
446 arc.mutable_start()->set_x_nm( GetStart().x );
447 arc.mutable_start()->set_y_nm( GetStart().y );
448 arc.mutable_mid()->set_x_nm( GetMid().x );
449 arc.mutable_mid()->set_y_nm( GetMid().y );
450 arc.mutable_end()->set_x_nm( GetEnd().x );
451 arc.mutable_end()->set_y_nm( GetEnd().y );
452 arc.mutable_width()->set_value_nm( GetWidth() );
453 arc.set_layer( ToProtoEnum<PCB_LAYER_ID, kiapi::board::types::BoardLayer>( GetLayer() ) );
454 arc.set_locked( IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
455 : kiapi::common::types::LockedState::LS_UNLOCKED );
456 arc.mutable_net()->mutable_code()->set_value( GetNetCode() );
457 arc.mutable_net()->set_name( GetNetname() );
458 // TODO m_hasSolderMask and m_solderMaskMargin
459
460 aContainer.PackFrom( arc );
461}
462
463
464bool PCB_ARC::Deserialize( const google::protobuf::Any &aContainer )
465{
466 kiapi::board::types::Arc arc;
467
468 if( !aContainer.UnpackTo( &arc ) )
469 return false;
470
471 const_cast<KIID&>( m_Uuid ) = KIID( arc.id().value() );
472 SetStart( VECTOR2I( arc.start().x_nm(), arc.start().y_nm() ) );
473 SetMid( VECTOR2I( arc.mid().x_nm(), arc.mid().y_nm() ) );
474 SetEnd( VECTOR2I( arc.end().x_nm(), arc.end().y_nm() ) );
475 SetWidth( arc.width().value_nm() );
476 SetLayer( FromProtoEnum<PCB_LAYER_ID, kiapi::board::types::BoardLayer>( arc.layer() ) );
477 SetNetCode( arc.net().code().value() );
478 SetLocked( arc.locked() == kiapi::common::types::LockedState::LS_LOCKED );
479 // TODO m_hasSolderMask and m_solderMaskMargin
480
481 return true;
482}
483
484
485void PCB_VIA::Serialize( google::protobuf::Any &aContainer ) const
486{
487 kiapi::board::types::Via via;
488
489 via.mutable_id()->set_value( m_Uuid.AsStdString() );
490 via.mutable_position()->set_x_nm( GetPosition().x );
491 via.mutable_position()->set_y_nm( GetPosition().y );
492
493 PADSTACK padstack = Padstack();
494
495 google::protobuf::Any padStackWrapper;
496 padstack.Serialize( padStackWrapper );
497 padStackWrapper.UnpackTo( via.mutable_pad_stack() );
498
499 // PADSTACK::m_layerSet is not used by vias
500 via.mutable_pad_stack()->clear_layers();
501 kiapi::board::PackLayerSet( *via.mutable_pad_stack()->mutable_layers(), GetLayerSet() );
502
503 via.set_type( ToProtoEnum<VIATYPE, kiapi::board::types::ViaType>( GetViaType() ) );
504 via.set_locked( IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
505 : kiapi::common::types::LockedState::LS_UNLOCKED );
506 via.mutable_net()->mutable_code()->set_value( GetNetCode() );
507 via.mutable_net()->set_name( GetNetname() );
508
509 aContainer.PackFrom( via );
510}
511
512
513bool PCB_VIA::Deserialize( const google::protobuf::Any &aContainer )
514{
515 kiapi::board::types::Via via;
516
517 if( !aContainer.UnpackTo( &via ) )
518 return false;
519
520 const_cast<KIID&>( m_Uuid ) = KIID( via.id().value() );
521 SetStart( VECTOR2I( via.position().x_nm(), via.position().y_nm() ) );
522 SetEnd( GetStart() );
523
524 google::protobuf::Any padStackWrapper;
525 padStackWrapper.PackFrom( via.pad_stack() );
526
527 if( !m_padStack.Deserialize( padStackWrapper ) )
528 return false;
529
530 // PADSTACK::m_layerSet is not used by vias
532
533 SetViaType( FromProtoEnum<VIATYPE>( via.type() ) );
534 SetNetCode( via.net().code().value() );
535 SetLocked( via.locked() == kiapi::common::types::LockedState::LS_LOCKED );
536
537 return true;
538}
539
540
542{
543 SEG a( m_Start, m_End );
544 SEG b( aTrack.GetStart(), aTrack.GetEnd() );
545 return a.ApproxCollinear( b );
546}
547
548
550{
551 DRC_CONSTRAINT constraint;
552
553 if( GetBoard() && GetBoard()->GetDesignSettings().m_DRCEngine )
554 {
556
557 constraint = bds.m_DRCEngine->EvalRules( TRACK_WIDTH_CONSTRAINT, this, nullptr, m_layer );
558 }
559
560 if( aSource )
561 *aSource = constraint.GetName();
562
563 return constraint.Value();
564}
565
566
568{
569 DRC_CONSTRAINT constraint;
570
571 if( GetBoard() && GetBoard()->GetDesignSettings().m_DRCEngine )
572 {
574
575 constraint = bds.m_DRCEngine->EvalRules( VIA_DIAMETER_CONSTRAINT, this, nullptr, m_layer );
576 }
577
578 if( aSource )
579 *aSource = constraint.GetName();
580
581 return constraint.Value();
582}
583
584
586{
587 DRC_CONSTRAINT constraint;
588
589 if( GetBoard() && GetBoard()->GetDesignSettings().m_DRCEngine )
590 {
592
593 constraint = bds.m_DRCEngine->EvalRules( HOLE_SIZE_CONSTRAINT, this, nullptr, m_layer );
594 }
595
596 if( aSource )
597 *aSource = constraint.GetName();
598
599 return constraint.Value();
600}
601
602
603int PCB_VIA::GetMinAnnulus( PCB_LAYER_ID aLayer, wxString* aSource ) const
604{
605 if( !FlashLayer( aLayer ) )
606 {
607 if( aSource )
608 *aSource = _( "removed annular ring" );
609
610 return 0;
611 }
612
613 DRC_CONSTRAINT constraint;
614
615 if( GetBoard() && GetBoard()->GetDesignSettings().m_DRCEngine )
616 {
618
619 constraint = bds.m_DRCEngine->EvalRules( ANNULAR_WIDTH_CONSTRAINT, this, nullptr, aLayer );
620 }
621
622 if( constraint.Value().HasMin() )
623 {
624 if( aSource )
625 *aSource = constraint.GetName();
626
627 return constraint.Value().Min();
628 }
629
630 return 0;
631}
632
633
635{
636 if( m_padStack.Drill().size.x > 0 ) // Use the specific value.
637 return m_padStack.Drill().size.x;
638
639 // Use the default value from the Netclass
640 NETCLASS* netclass = GetEffectiveNetClass();
641
642 if( GetViaType() == VIATYPE::MICROVIA )
643 return netclass->GetuViaDrill();
644
645 return netclass->GetViaDrill();
646}
647
648
649EDA_ITEM_FLAGS PCB_TRACK::IsPointOnEnds( const VECTOR2I& point, int min_dist ) const
650{
651 EDA_ITEM_FLAGS result = 0;
652
653 if( min_dist < 0 )
654 min_dist = m_width / 2;
655
656 if( min_dist == 0 )
657 {
658 if( m_Start == point )
659 result |= STARTPOINT;
660
661 if( m_End == point )
662 result |= ENDPOINT;
663 }
664 else
665 {
666 double dist = m_Start.Distance( point );
667
668 if( min_dist >= dist )
669 result |= STARTPOINT;
670
671 dist = m_End.Distance( point );
672
673 if( min_dist >= dist )
674 result |= ENDPOINT;
675 }
676
677 return result;
678}
679
680
682{
683 // end of track is round, this is its radius, rounded up
684 int radius = ( m_width + 1 ) / 2;
685 int ymax, xmax, ymin, xmin;
686
687 if( Type() == PCB_VIA_T )
688 {
689 ymax = m_Start.y;
690 xmax = m_Start.x;
691
692 ymin = m_Start.y;
693 xmin = m_Start.x;
694 }
695 else if( Type() == PCB_ARC_T )
696 {
697 std::shared_ptr<SHAPE> arc = GetEffectiveShape();
698 BOX2I bbox = arc->BBox();
699
700 xmin = bbox.GetLeft();
701 xmax = bbox.GetRight();
702 ymin = bbox.GetTop();
703 ymax = bbox.GetBottom();
704 }
705 else
706 {
707 ymax = std::max( m_Start.y, m_End.y );
708 xmax = std::max( m_Start.x, m_End.x );
709
710 ymin = std::min( m_Start.y, m_End.y );
711 xmin = std::min( m_Start.x, m_End.x );
712 }
713
714 ymax += radius;
715 xmax += radius;
716
717 ymin -= radius;
718 xmin -= radius;
719
720 // return a rectangle which is [pos,dim) in nature. therefore the +1
721 return BOX2ISafe( VECTOR2I( xmin, ymin ),
722 VECTOR2L( (int64_t) xmax - xmin + 1, (int64_t) ymax - ymin + 1 ) );
723}
724
725
727{
728 int radius = 0;
729
731 [&]( PCB_LAYER_ID aLayer )
732 {
733 radius = std::max( radius, GetWidth( aLayer ) );
734 } );
735
736 // via is round, this is its radius, rounded up
737 radius = ( radius + 1 ) / 2;
738
739 int ymax = m_Start.y + radius;
740 int xmax = m_Start.x + radius;
741
742 int ymin = m_Start.y - radius;
743 int xmin = m_Start.x - radius;
744
745 // return a rectangle which is [pos,dim) in nature. therefore the +1
746 return BOX2ISafe( VECTOR2I( xmin, ymin ),
747 VECTOR2L( (int64_t) xmax - xmin + 1, (int64_t) ymax - ymin + 1 ) );
748}
749
750
752{
753 int radius = GetWidth( aLayer );
754
755 // via is round, this is its radius, rounded up
756 radius = ( radius + 1 ) / 2;
757
758 int ymax = m_Start.y + radius;
759 int xmax = m_Start.x + radius;
760
761 int ymin = m_Start.y - radius;
762 int xmin = m_Start.x - radius;
763
764 // return a rectangle which is [pos,dim) in nature. therefore the +1
765 return BOX2ISafe( VECTOR2I( xmin, ymin ),
766 VECTOR2L( (int64_t) xmax - xmin + 1, (int64_t) ymax - ymin + 1 ) );
767}
768
769
771{
772 return m_Start.Distance( m_End );
773}
774
775
776void PCB_TRACK::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
777{
778 RotatePoint( m_Start, aRotCentre, aAngle );
779 RotatePoint( m_End, aRotCentre, aAngle );
780}
781
782
783void PCB_ARC::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
784{
785 RotatePoint( m_Start, aRotCentre, aAngle );
786 RotatePoint( m_End, aRotCentre, aAngle );
787 RotatePoint( m_Mid, aRotCentre, aAngle );
788}
789
790
791void PCB_TRACK::Mirror( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
792{
793 MIRROR( m_Start, aCentre, aFlipDirection );
794 MIRROR( m_End, aCentre, aFlipDirection );
795}
796
797
798void PCB_ARC::Mirror( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
799{
800 MIRROR( m_Start, aCentre, aFlipDirection );
801 MIRROR( m_End, aCentre, aFlipDirection );
802 MIRROR( m_Mid, aCentre, aFlipDirection );
803}
804
805
806void PCB_TRACK::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
807{
808 if( aFlipDirection == FLIP_DIRECTION::LEFT_RIGHT )
809 {
810 m_Start.x = aCentre.x - ( m_Start.x - aCentre.x );
811 m_End.x = aCentre.x - ( m_End.x - aCentre.x );
812 }
813 else
814 {
815 m_Start.y = aCentre.y - ( m_Start.y - aCentre.y );
816 m_End.y = aCentre.y - ( m_End.y - aCentre.y );
817 }
818
820}
821
822
823void PCB_ARC::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
824{
825 if( aFlipDirection == FLIP_DIRECTION::LEFT_RIGHT )
826 {
827 m_Start.x = aCentre.x - ( m_Start.x - aCentre.x );
828 m_End.x = aCentre.x - ( m_End.x - aCentre.x );
829 m_Mid.x = aCentre.x - ( m_Mid.x - aCentre.x );
830 }
831 else
832 {
833 m_Start.y = aCentre.y - ( m_Start.y - aCentre.y );
834 m_End.y = aCentre.y - ( m_End.y - aCentre.y );
835 m_Mid.y = aCentre.y - ( m_Mid.y - aCentre.y );
836 }
837
839}
840
841
842bool PCB_ARC::IsCCW() const
843{
844 VECTOR2L start = m_Start;
845 VECTOR2L start_end = m_End - start;
846 VECTOR2L start_mid = m_Mid - start;
847
848 return start_end.Cross( start_mid ) < 0;
849}
850
851
852void PCB_VIA::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
853{
854 if( aFlipDirection == FLIP_DIRECTION::LEFT_RIGHT )
855 {
856 m_Start.x = aCentre.x - ( m_Start.x - aCentre.x );
857 m_End.x = aCentre.x - ( m_End.x - aCentre.x );
858 }
859 else
860 {
861 m_Start.y = aCentre.y - ( m_Start.y - aCentre.y );
862 m_End.y = aCentre.y - ( m_End.y - aCentre.y );
863 }
864
865 if( GetViaType() != VIATYPE::THROUGH )
866 {
867 PCB_LAYER_ID top_layer;
868 PCB_LAYER_ID bottom_layer;
869 LayerPair( &top_layer, &bottom_layer );
870 top_layer = GetBoard()->FlipLayer( top_layer );
871 bottom_layer = GetBoard()->FlipLayer( bottom_layer );
872 SetLayerPair( top_layer, bottom_layer );
873 }
874}
875
876
877INSPECT_RESULT PCB_TRACK::Visit( INSPECTOR inspector, void* testData,
878 const std::vector<KICAD_T>& aScanTypes )
879{
880 for( KICAD_T scanType : aScanTypes )
881 {
882 if( scanType == Type() )
883 {
884 if( INSPECT_RESULT::QUIT == inspector( this, testData ) )
885 return INSPECT_RESULT::QUIT;
886 }
887 }
888
889 return INSPECT_RESULT::CONTINUE;
890}
891
892
893std::shared_ptr<SHAPE_SEGMENT> PCB_VIA::GetEffectiveHoleShape() const
894{
895 return std::make_shared<SHAPE_SEGMENT>( SEG( m_Start, m_Start ), Padstack().Drill().size.x );
896}
897
898// clang-format off: the suggestion is slightly less readable
900{
901 switch( aMode )
902 {
903 case TENTING_MODE::FROM_RULES: m_padStack.FrontOuterLayers().has_solder_mask.reset(); break;
904 case TENTING_MODE::TENTED: m_padStack.FrontOuterLayers().has_solder_mask = true; break;
905 case TENTING_MODE::NOT_TENTED: m_padStack.FrontOuterLayers().has_solder_mask = false; break;
906 }
907}
908
909
911{
913 {
915 TENTING_MODE::TENTED : TENTING_MODE::NOT_TENTED;
916 }
917
918 return TENTING_MODE::FROM_RULES;
919}
920
921
923{
924 switch( aMode )
925 {
926 case TENTING_MODE::FROM_RULES: m_padStack.BackOuterLayers().has_solder_mask.reset(); break;
927 case TENTING_MODE::TENTED: m_padStack.BackOuterLayers().has_solder_mask = true; break;
928 case TENTING_MODE::NOT_TENTED: m_padStack.BackOuterLayers().has_solder_mask = false; break;
929 }
930}
931
932
934{
935 if( m_padStack.BackOuterLayers().has_solder_mask.has_value() )
936 {
938 TENTING_MODE::TENTED : TENTING_MODE::NOT_TENTED;
939 }
940
941 return TENTING_MODE::FROM_RULES;
942}
943
944
946{
947 switch( aMode )
948 {
949 case COVERING_MODE::FROM_RULES: m_padStack.FrontOuterLayers().has_covering.reset(); break;
950 case COVERING_MODE::COVERED: m_padStack.FrontOuterLayers().has_covering = true; break;
951 case COVERING_MODE::NOT_COVERED: m_padStack.FrontOuterLayers().has_covering = false; break;
952 }
953}
954
955
957{
958 if( m_padStack.FrontOuterLayers().has_covering.has_value() )
959 {
961 COVERING_MODE::COVERED : COVERING_MODE::NOT_COVERED;
962 }
963
964 return COVERING_MODE::FROM_RULES;
965}
966
967
969{
970 switch( aMode )
971 {
972 case COVERING_MODE::FROM_RULES: m_padStack.BackOuterLayers().has_covering.reset(); break;
973 case COVERING_MODE::COVERED: m_padStack.BackOuterLayers().has_covering = true; break;
974 case COVERING_MODE::NOT_COVERED: m_padStack.BackOuterLayers().has_covering = false; break;
975 }
976}
977
978
980{
981 if( m_padStack.BackOuterLayers().has_covering.has_value() )
982 {
984 COVERING_MODE::COVERED : COVERING_MODE::NOT_COVERED;
985 }
986
987 return COVERING_MODE::FROM_RULES;
988}
989
990
992{
993 switch( aMode )
994 {
995 case PLUGGING_MODE::FROM_RULES: m_padStack.FrontOuterLayers().has_plugging.reset(); break;
996 case PLUGGING_MODE::PLUGGED: m_padStack.FrontOuterLayers().has_plugging = true; break;
997 case PLUGGING_MODE::NOT_PLUGGED: m_padStack.FrontOuterLayers().has_plugging = false; break;
998 }
999}
1000
1001
1003{
1004 if( m_padStack.FrontOuterLayers().has_plugging.has_value() )
1005 {
1007 PLUGGING_MODE::PLUGGED : PLUGGING_MODE::NOT_PLUGGED;
1008 }
1009
1010 return PLUGGING_MODE::FROM_RULES;
1011}
1012
1013
1015{
1016 switch( aMode )
1017 {
1018 case PLUGGING_MODE::FROM_RULES: m_padStack.BackOuterLayers().has_plugging.reset(); break;
1019 case PLUGGING_MODE::PLUGGED: m_padStack.BackOuterLayers().has_plugging = true; break;
1020 case PLUGGING_MODE::NOT_PLUGGED: m_padStack.BackOuterLayers().has_plugging = false; break;
1021 }
1022}
1023
1024
1026{
1027 if( m_padStack.BackOuterLayers().has_plugging.has_value() )
1028 {
1030 PLUGGING_MODE::PLUGGED : PLUGGING_MODE::NOT_PLUGGED;
1031 }
1032
1033 return PLUGGING_MODE::FROM_RULES;
1034}
1035
1036
1038{
1039 switch( aMode )
1040 {
1041 case CAPPING_MODE::FROM_RULES: m_padStack.Drill().is_capped.reset(); break;
1042 case CAPPING_MODE::CAPPED: m_padStack.Drill().is_capped = true; break;
1043 case CAPPING_MODE::NOT_CAPPED: m_padStack.Drill().is_capped = false; break;
1044 }
1045}
1046
1047
1049{
1050 if( m_padStack.Drill().is_capped.has_value() )
1051 {
1052 return *m_padStack.Drill().is_capped ?
1053 CAPPING_MODE::CAPPED : CAPPING_MODE::NOT_CAPPED;
1054 }
1055
1056 return CAPPING_MODE::FROM_RULES;
1057}
1058
1059
1061{
1062 switch( aMode )
1063 {
1064 case FILLING_MODE::FROM_RULES: m_padStack.Drill().is_filled.reset(); break;
1065 case FILLING_MODE::FILLED: m_padStack.Drill().is_filled = true; break;
1066 case FILLING_MODE::NOT_FILLED: m_padStack.Drill().is_filled = false; break;
1067 }
1068}
1069
1070
1072{
1073 if( m_padStack.Drill().is_filled.has_value() )
1074 {
1075 return *m_padStack.Drill().is_filled ?
1076 FILLING_MODE::FILLED : FILLING_MODE::NOT_FILLED;
1077 }
1078
1079 return FILLING_MODE::FROM_RULES;
1080}
1081// clang-format on: the suggestion is slightly less readable
1082
1083
1085{
1086 wxCHECK_MSG( IsFrontLayer( aLayer ) || IsBackLayer( aLayer ), true,
1087 "Invalid layer passed to IsTented" );
1088
1089 bool front = IsFrontLayer( aLayer );
1090
1091 if( front && m_padStack.FrontOuterLayers().has_solder_mask.has_value() )
1093
1094 if( !front && m_padStack.BackOuterLayers().has_solder_mask.has_value() )
1096
1097 if( const BOARD* board = GetBoard() )
1098 {
1099 return front ? board->GetDesignSettings().m_TentViasFront
1100 : board->GetDesignSettings().m_TentViasBack;
1101 }
1102
1103 return true;
1104}
1105
1106
1108{
1109 if( const BOARD* board = GetBoard() )
1110 return board->GetDesignSettings().m_SolderMaskExpansion;
1111 else
1112 return 0;
1113}
1114
1115
1117{
1118 int margin = m_solderMaskMargin.value_or( 0 );
1119
1120 // If no local margin is set, get the board's solder mask expansion value
1121 if( !m_solderMaskMargin.has_value() )
1122 {
1123 const BOARD* board = GetBoard();
1124
1125 if( board )
1126 margin = board->GetDesignSettings().m_SolderMaskExpansion;
1127 }
1128
1129 // Ensure the resulting mask opening has a non-negative size
1130 if( margin < 0 )
1131 margin = std::max( margin, -m_width / 2 );
1132
1133 return margin;
1134}
1135
1136
1138{
1139 if( aLayer == m_layer )
1140 {
1141 return true;
1142 }
1143
1144 if( m_hasSolderMask
1145 && ( ( aLayer == F_Mask && m_layer == F_Cu )
1146 || ( aLayer == B_Mask && m_layer == B_Cu ) ) )
1147 {
1148 return true;
1149 }
1150
1151 return false;
1152}
1153
1154
1156{
1157#if 0
1158 // Nice and simple, but raises its ugly head in performance profiles....
1159 return GetLayerSet().test( aLayer );
1160#endif
1161 if( IsCopperLayer( aLayer ) &&
1162 LAYER_RANGE::Contains( Padstack().Drill().start, Padstack().Drill().end, aLayer ) )
1163 {
1164 return true;
1165 }
1166
1167 // Test for via on mask layers: a via on on a mask layer if not tented and if
1168 // it is on the corresponding external copper layer
1169 if( aLayer == F_Mask )
1170 return Padstack().Drill().start == F_Cu && !IsTented( F_Mask );
1171 else if( aLayer == B_Mask )
1172 return Padstack().Drill().end == B_Cu && !IsTented( B_Mask );
1173
1174 return false;
1175}
1176
1177
1178bool PCB_VIA::HasValidLayerPair( int aCopperLayerCount )
1179{
1180 // return true if top and bottom layers are valid, depending on the copper layer count
1181 // aCopperLayerCount is expected >= 2
1182
1183 int layer_id = aCopperLayerCount*2;
1184
1185 if( Padstack().Drill().start > B_Cu )
1186 {
1187 if( Padstack().Drill().start > layer_id )
1188 return false;
1189 }
1190 if( Padstack().Drill().end > B_Cu )
1191 {
1192 if( Padstack().Drill().end > layer_id )
1193 return false;
1194 }
1195
1196 return true;
1197}
1198
1199
1201{
1202 return Padstack().Drill().start;
1203}
1204
1205
1207{
1208 Padstack().Drill().start = aLayer;
1209}
1210
1211
1212void PCB_TRACK::SetLayerSet( const LSET& aLayerSet )
1213{
1214 aLayerSet.RunOnLayers(
1215 [&]( PCB_LAYER_ID layer )
1216 {
1217 if( IsCopperLayer( layer ) )
1218 SetLayer( layer );
1219 else if( IsSolderMaskLayer( layer ) )
1220 SetHasSolderMask( true );
1221 } );
1222}
1223
1224
1226{
1227 LSET layermask( { m_layer } );
1228
1229 if( m_hasSolderMask )
1230 {
1231 if( layermask.test( F_Cu ) )
1232 layermask.set( F_Mask );
1233 else if( layermask.test( B_Cu ) )
1234 layermask.set( B_Mask );
1235 }
1236
1237 return layermask;
1238}
1239
1240
1242{
1243 LSET layermask;
1244
1245 if( Padstack().Drill().start < PCBNEW_LAYER_ID_START )
1246 return layermask;
1247
1248 if( GetViaType() == VIATYPE::THROUGH )
1249 {
1250 layermask = LSET::AllCuMask( BoardCopperLayerCount() );
1251 }
1252 else
1253 {
1254 LAYER_RANGE range( Padstack().Drill().start, Padstack().Drill().end, BoardCopperLayerCount() );
1255
1256 int cnt = BoardCopperLayerCount();
1257 // PCB_LAYER_IDs are numbered from front to back, this is top to bottom.
1258 for( PCB_LAYER_ID id : range )
1259 {
1260 layermask.set( id );
1261
1262 if( --cnt <= 0 )
1263 break;
1264 }
1265 }
1266
1267 if( !IsTented( F_Mask ) && layermask.test( F_Cu ) )
1268 layermask.set( F_Mask );
1269
1270 if( !IsTented( B_Mask ) && layermask.test( B_Cu ) )
1271 layermask.set( B_Mask );
1272
1273 return layermask;
1274}
1275
1276
1277void PCB_VIA::SetLayerSet( const LSET& aLayerSet )
1278{
1279 // Vias do not use a LSET, just a top and bottom layer pair
1280 // So we need to set these 2 layers according to the allowed layers in aLayerSet
1281
1282 // For via through, only F_Cu and B_Cu are allowed. aLayerSet is ignored
1283 if( GetViaType() == VIATYPE::THROUGH )
1284 {
1285 Padstack().Drill().start = F_Cu;
1286 Padstack().Drill().end = B_Cu;
1287 return;
1288 }
1289
1290 // For blind buried vias, find the top and bottom layers
1291 bool top_found = false;
1292 bool bottom_found = false;
1293
1294 aLayerSet.RunOnLayers(
1295 [&]( PCB_LAYER_ID layer )
1296 {
1297 // tpo layer and bottom Layer are copper layers, so consider only copper layers
1298 if( IsCopperLayer( layer ) )
1299 {
1300 // The top layer is the first layer found in list and
1301 // cannot the B_Cu
1302 if( !top_found && layer != B_Cu )
1303 {
1304 Padstack().Drill().start = layer;
1305 top_found = true;
1306 }
1307
1308 // The bottom layer is the last layer found in list or B_Cu
1309 if( !bottom_found )
1310 Padstack().Drill().end = layer;
1311
1312 if( layer == B_Cu )
1313 bottom_found = true;
1314 }
1315 } );
1316}
1317
1318
1319void PCB_VIA::SetLayerPair( PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer )
1320{
1321
1322 Padstack().Drill().start = aTopLayer;
1323 Padstack().Drill().end = aBottomLayer;
1325}
1326
1327
1329{
1330 Padstack().Drill().start = aLayer;
1331}
1332
1333
1335{
1336 Padstack().Drill().end = aLayer;
1337}
1338
1339
1340void PCB_VIA::LayerPair( PCB_LAYER_ID* top_layer, PCB_LAYER_ID* bottom_layer ) const
1341{
1342 PCB_LAYER_ID t_layer = F_Cu;
1343 PCB_LAYER_ID b_layer = B_Cu;
1344
1345 if( GetViaType() != VIATYPE::THROUGH )
1346 {
1347 b_layer = Padstack().Drill().end;
1348 t_layer = Padstack().Drill().start;
1349
1350 if( !IsCopperLayerLowerThan( b_layer, t_layer ) )
1351 std::swap( b_layer, t_layer );
1352 }
1353
1354 if( top_layer )
1355 *top_layer = t_layer;
1356
1357 if( bottom_layer )
1358 *bottom_layer = b_layer;
1359}
1360
1361
1363{
1364 return Padstack().Drill().start;
1365}
1366
1367
1369{
1370 return Padstack().Drill().end;
1371}
1372
1373
1375{
1376 if( GetViaType() == VIATYPE::THROUGH )
1377 {
1378 Padstack().Drill().start = F_Cu;
1379 Padstack().Drill().end = B_Cu;
1380 }
1381
1382 if( !IsCopperLayerLowerThan( Padstack().Drill().end, Padstack().Drill().start) )
1383 std::swap( Padstack().Drill().end, Padstack().Drill().start );
1384}
1385
1386
1387bool PCB_VIA::FlashLayer( const LSET& aLayers ) const
1388{
1389 for( PCB_LAYER_ID layer : aLayers )
1390 {
1391 if( FlashLayer( layer ) )
1392 return true;
1393 }
1394
1395 return false;
1396}
1397
1398
1399bool PCB_VIA::FlashLayer( int aLayer ) const
1400{
1401 // Return the "normal" shape if the caller doesn't specify a particular layer
1402 if( aLayer == UNDEFINED_LAYER )
1403 return true;
1404
1405 const BOARD* board = GetBoard();
1406 PCB_LAYER_ID layer = static_cast<PCB_LAYER_ID>( aLayer );
1407
1408 if( !board )
1409 return true;
1410
1411 if( !IsOnLayer( layer ) )
1412 return false;
1413
1414 if( !IsCopperLayer( layer ) )
1415 return true;
1416
1417 switch( Padstack().UnconnectedLayerMode() )
1418 {
1420 return true;
1421
1423 {
1424 if( layer == Padstack().Drill().start || layer == Padstack().Drill().end )
1425 return true;
1426
1427 // Check for removal below
1428 break;
1429 }
1430
1432 // Check for removal below
1433 break;
1434 }
1435
1436 if( GetZoneLayerOverride( layer ) == ZLO_FORCE_FLASHED )
1437 {
1438 return true;
1439 }
1440 else
1441 {
1442 // Must be static to keep from raising its ugly head in performance profiles
1443 static std::initializer_list<KICAD_T> nonZoneTypes = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T,
1444 PCB_PAD_T };
1445
1446 return board->GetConnectivity()->IsConnectedOnLayer( this, layer, nonZoneTypes );
1447 }
1448}
1449
1450
1452{
1453 std::unique_lock<std::mutex> cacheLock( m_zoneLayerOverridesMutex );
1454
1457}
1458
1459
1461{
1462 static const ZONE_LAYER_OVERRIDE defaultOverride = ZLO_NONE;
1463 auto it = m_zoneLayerOverrides.find( aLayer );
1464 return it != m_zoneLayerOverrides.end() ? it->second : defaultOverride;
1465}
1466
1467
1469{
1470 std::unique_lock<std::mutex> cacheLock( m_zoneLayerOverridesMutex );
1471 m_zoneLayerOverrides[aLayer] = aOverride;
1472}
1473
1474
1476 PCB_LAYER_ID* aBottommost ) const
1477{
1478 *aTopmost = UNDEFINED_LAYER;
1479 *aBottommost = UNDEFINED_LAYER;
1480
1481 static std::initializer_list<KICAD_T> nonZoneTypes = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T,
1482 PCB_PAD_T };
1483
1484 for( int layer = TopLayer(); layer <= BottomLayer(); ++layer )
1485 {
1486 bool connected = false;
1487
1488 if( GetZoneLayerOverride( static_cast<PCB_LAYER_ID>( layer ) ) == ZLO_FORCE_FLASHED )
1489 {
1490 connected = true;
1491 }
1492 else if( GetBoard()->GetConnectivity()->IsConnectedOnLayer( this, layer, nonZoneTypes ) )
1493 {
1494 connected = true;
1495 }
1496
1497 if( connected )
1498 {
1499 if( *aTopmost == UNDEFINED_LAYER )
1500 *aTopmost = ToLAYER_ID( layer );
1501
1502 *aBottommost = ToLAYER_ID( layer );
1503 }
1504 }
1505
1506}
1507
1508
1509std::vector<int> PCB_TRACK::ViewGetLayers() const
1510{
1511 // Show the track and its netname on different layers
1512 const PCB_LAYER_ID layer = GetLayer();
1513 std::vector<int> layers{
1514 layer,
1515 GetNetnameLayer( layer ),
1516 LAYER_CLEARANCE_START + layer,
1517 };
1518
1519 layers.reserve( 6 );
1520
1521 if( m_hasSolderMask )
1522 {
1523 if( m_layer == F_Cu )
1524 layers.push_back( F_Mask );
1525 else if( m_layer == B_Cu )
1526 layers.push_back( B_Mask );
1527 }
1528
1529 if( IsLocked() )
1530 layers.push_back( LAYER_LOCKED_ITEM_SHADOW );
1531
1532 return layers;
1533}
1534
1535
1536double PCB_TRACK::ViewGetLOD( int aLayer, const KIGFX::VIEW* aView ) const
1537{
1538 PCB_PAINTER* painter = static_cast<PCB_PAINTER*>( aView->GetPainter() );
1539 PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings();
1540
1541 if( !aView->IsLayerVisible( LAYER_TRACKS ) )
1542 return LOD_HIDE;
1543
1544 if( IsNetnameLayer( aLayer ) )
1545 {
1547 return LOD_HIDE;
1548
1549 // Hide netnames on dimmed tracks
1550 if( renderSettings->GetHighContrast() )
1551 {
1552 if( m_layer != renderSettings->GetPrimaryHighContrastLayer() )
1553 return LOD_HIDE;
1554 }
1555
1556 VECTOR2I start( GetStart() );
1557 VECTOR2I end( GetEnd() );
1558
1559 // Calc the approximate size of the netname (assume square chars)
1560 SEG::ecoord nameSize = GetDisplayNetname().size() * GetWidth();
1561
1562 if( VECTOR2I( end - start ).SquaredEuclideanNorm() < nameSize * nameSize )
1563 return LOD_HIDE;
1564
1565 BOX2I clipBox = BOX2ISafe( aView->GetViewport() );
1566
1567 ClipLine( &clipBox, start.x, start.y, end.x, end.y );
1568
1569 if( VECTOR2I( end - start ).SquaredEuclideanNorm() == 0 )
1570 return LOD_HIDE;
1571
1572 // Netnames will be shown only if zoom is appropriate
1573 return lodScaleForThreshold( aView, m_width, pcbIUScale.mmToIU( 4.0 ) );
1574 }
1575
1576 if( aLayer == LAYER_LOCKED_ITEM_SHADOW )
1577 {
1578 // Hide shadow if the main layer is not shown
1579 if( !aView->IsLayerVisible( m_layer ) )
1580 return LOD_HIDE;
1581
1582 // Hide shadow on dimmed tracks
1583 if( renderSettings->GetHighContrast() )
1584 {
1585 if( m_layer != renderSettings->GetPrimaryHighContrastLayer() )
1586 return LOD_HIDE;
1587 }
1588 }
1589
1590 // Other layers are shown without any conditions
1591 return LOD_SHOW;
1592}
1593
1594
1596{
1597 BOX2I bbox = GetBoundingBox();
1598
1599 if( const BOARD* board = GetBoard() )
1600 bbox.Inflate( 2 * board->GetDesignSettings().GetBiggestClearanceValue() );
1601 else
1602 bbox.Inflate( GetWidth() ); // Add a bit extra for safety
1603
1604 return bbox;
1605}
1606
1607
1608std::vector<int> PCB_VIA::ViewGetLayers() const
1609{
1610 LAYER_RANGE layers( Padstack().Drill().start, Padstack().Drill().end, MAX_CU_LAYERS );
1611 std::vector<int> ret_layers{ LAYER_VIA_HOLES, LAYER_VIA_HOLEWALLS, LAYER_VIA_NETNAMES };
1612 ret_layers.reserve( MAX_CU_LAYERS + 6 );
1613
1614 // TODO(JE) Rendering order issue
1615#if 0
1616 // Blind/buried vias (and microvias) use a different net name layer
1617 PCB_LAYER_ID layerTop, layerBottom;
1618 LayerPair( &layerTop, &layerBottom );
1619
1620 bool isBlindBuried =
1621 m_viaType == VIATYPE::BLIND_BURIED
1622 || ( m_viaType == VIATYPE::MICROVIA && ( layerTop != F_Cu || layerBottom != B_Cu ) );
1623#endif
1624 LSET cuMask = LSET::AllCuMask();
1625
1626 if( const BOARD* board = GetBoard() )
1627 cuMask = board->GetEnabledLayers();
1628
1629 for( PCB_LAYER_ID layer : layers )
1630 {
1631 if( !cuMask.Contains( layer ) )
1632 continue;
1633
1634 ret_layers.push_back( LAYER_VIA_COPPER_START + layer );
1635 ret_layers.push_back( LAYER_CLEARANCE_START + layer );
1636 }
1637
1638 if( IsLocked() )
1639 ret_layers.push_back( LAYER_LOCKED_ITEM_SHADOW );
1640
1641 // Vias can also be on a solder mask layer. They are on these layers or not,
1642 // depending on the plot and solder mask options
1643 if( IsOnLayer( F_Mask ) )
1644 ret_layers.push_back( F_Mask );
1645
1646 if( IsOnLayer( B_Mask ) )
1647 ret_layers.push_back( B_Mask );
1648
1649 return ret_layers;
1650}
1651
1652
1653double PCB_VIA::ViewGetLOD( int aLayer, const KIGFX::VIEW* aView ) const
1654{
1655 PCB_PAINTER* painter = static_cast<PCB_PAINTER*>( aView->GetPainter() );
1656 PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings();
1657 LSET visible = LSET::AllLayersMask();
1658
1659 // Meta control for hiding all vias
1660 if( !aView->IsLayerVisible( LAYER_VIAS ) )
1661 return LOD_HIDE;
1662
1663 // Handle board visibility
1664 if( const BOARD* board = GetBoard() )
1665 visible = board->GetVisibleLayers() & board->GetEnabledLayers();
1666
1667 int width = GetWidth( ToLAYER_ID( aLayer ) );
1668
1669 // In high contrast mode don't show vias that don't cross the high-contrast layer
1670 if( renderSettings->GetHighContrast() )
1671 {
1672 PCB_LAYER_ID highContrastLayer = renderSettings->GetPrimaryHighContrastLayer();
1673
1674 if( LSET::FrontTechMask().Contains( highContrastLayer ) )
1675 highContrastLayer = F_Cu;
1676 else if( LSET::BackTechMask().Contains( highContrastLayer ) )
1677 highContrastLayer = B_Cu;
1678
1679 if( IsCopperLayer( highContrastLayer ) && GetViaType() != VIATYPE::THROUGH )
1680 {
1681 if( IsCopperLayerLowerThan( Padstack().Drill().start, highContrastLayer )
1682 || IsCopperLayerLowerThan( highContrastLayer, Padstack().Drill().end ) )
1683 {
1684 return LOD_HIDE;
1685 }
1686 }
1687 }
1688
1689 if( IsHoleLayer( aLayer ) )
1690 {
1691 if( m_viaType == VIATYPE::THROUGH )
1692 {
1693 // Show a through via's hole if any physical layer is shown
1694 if( !( visible & LSET::PhysicalLayersMask() ).any() )
1695 return LOD_HIDE;
1696 }
1697 else
1698 {
1699 // Show a blind or micro via's hole if it crosses a visible layer
1700 if( !( visible & GetLayerSet() ).any() )
1701 return LOD_HIDE;
1702 }
1703
1704 // The hole won't be visible anyway at this scale
1705 return lodScaleForThreshold( aView, GetDrillValue(), pcbIUScale.mmToIU( 0.25 ) );
1706 }
1707 else if( IsNetnameLayer( aLayer ) )
1708 {
1709 if( renderSettings->GetHighContrast() )
1710 {
1711 // Hide netnames unless via is flashed to a high-contrast layer
1712 if( !FlashLayer( renderSettings->GetPrimaryHighContrastLayer() ) )
1713 return LOD_HIDE;
1714 }
1715 else
1716 {
1717 // Hide netnames unless pad is flashed to a visible layer
1718 if( !FlashLayer( visible ) )
1719 return LOD_HIDE;
1720 }
1721
1722 // Netnames will be shown only if zoom is appropriate
1723 return lodScaleForThreshold( aView, width, pcbIUScale.mmToIU( 10 ) );
1724 }
1725
1726 if( !IsCopperLayer( aLayer ) )
1727 return lodScaleForThreshold( aView, width, pcbIUScale.mmToIU( 0.6 ) );
1728
1729 return LOD_SHOW;
1730}
1731
1732
1734{
1735 switch( Type() )
1736 {
1737 case PCB_ARC_T: return _( "Track (arc)" );
1738 case PCB_VIA_T: return _( "Via" );
1739 case PCB_TRACE_T:
1740 default: return _( "Track" );
1741 }
1742}
1743
1744
1745void PCB_TRACK::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1746{
1747 wxString msg;
1748 BOARD* board = GetBoard();
1749
1750 aList.emplace_back( _( "Type" ), GetFriendlyName() );
1751
1752 GetMsgPanelInfoBase_Common( aFrame, aList );
1753
1754 aList.emplace_back( _( "Layer" ), layerMaskDescribe() );
1755
1756 aList.emplace_back( _( "Width" ), aFrame->MessageTextFromValue( m_width ) );
1757
1758 if( Type() == PCB_ARC_T )
1759 {
1760 double radius = static_cast<PCB_ARC*>( this )->GetRadius();
1761 aList.emplace_back( _( "Radius" ), aFrame->MessageTextFromValue( radius ) );
1762 }
1763
1764 aList.emplace_back( _( "Segment Length" ), aFrame->MessageTextFromValue( GetLength() ) );
1765
1766 // Display full track length (in Pcbnew)
1767 if( board && GetNetCode() > 0 )
1768 {
1769 int count;
1770 double trackLen;
1771 double lenPadToDie;
1772
1773 std::tie( count, trackLen, lenPadToDie ) = board->GetTrackLength( *this );
1774
1775 aList.emplace_back( _( "Routed Length" ), aFrame->MessageTextFromValue( trackLen ) );
1776
1777 if( lenPadToDie != 0 )
1778 {
1779 msg = aFrame->MessageTextFromValue( lenPadToDie );
1780 aList.emplace_back( _( "Pad To Die Length" ), msg );
1781
1782 msg = aFrame->MessageTextFromValue( trackLen + lenPadToDie );
1783 aList.emplace_back( _( "Full Length" ), msg );
1784 }
1785 }
1786
1787 SHAPE_POLY_SET copper;
1789 aList.emplace_back( _( "Copper Area" ),
1790 aFrame->MessageTextFromValue( copper.Area(), true, EDA_DATA_TYPE::AREA ) );
1791
1792 wxString source;
1793 int clearance = GetOwnClearance( GetLayer(), &source );
1794
1795 aList.emplace_back( wxString::Format( _( "Min Clearance: %s" ),
1796 aFrame->MessageTextFromValue( clearance ) ),
1797 wxString::Format( _( "(from %s)" ), source ) );
1798
1799 MINOPTMAX<int> constraintValue = GetWidthConstraint( &source );
1800 msg = aFrame->MessageTextFromMinOptMax( constraintValue );
1801
1802 if( !msg.IsEmpty() )
1803 {
1804 aList.emplace_back( wxString::Format( _( "Width Constraints: %s" ), msg ),
1805 wxString::Format( _( "(from %s)" ), source ) );
1806 }
1807}
1808
1809
1810void PCB_VIA::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1811{
1812 wxString msg;
1813
1814 switch( GetViaType() )
1815 {
1816 case VIATYPE::MICROVIA: msg = _( "Micro Via" ); break;
1817 case VIATYPE::BLIND_BURIED: msg = _( "Blind/Buried Via" ); break;
1818 case VIATYPE::THROUGH: msg = _( "Through Via" ); break;
1819 default: msg = _( "Via" ); break;
1820 }
1821
1822 aList.emplace_back( _( "Type" ), msg );
1823
1824 GetMsgPanelInfoBase_Common( aFrame, aList );
1825
1826 aList.emplace_back( _( "Layer" ), layerMaskDescribe() );
1827 // TODO(JE) padstacks
1828 aList.emplace_back( _( "Diameter" ),
1830 aList.emplace_back( _( "Hole" ), aFrame->MessageTextFromValue( GetDrillValue() ) );
1831
1832 wxString source;
1833 int clearance = GetOwnClearance( GetLayer(), &source );
1834
1835 aList.emplace_back( wxString::Format( _( "Min Clearance: %s" ),
1836 aFrame->MessageTextFromValue( clearance ) ),
1837 wxString::Format( _( "(from %s)" ), source ) );
1838
1839 int minAnnulus = GetMinAnnulus( GetLayer(), &source );
1840
1841 aList.emplace_back( wxString::Format( _( "Min Annular Width: %s" ),
1842 aFrame->MessageTextFromValue( minAnnulus ) ),
1843 wxString::Format( _( "(from %s)" ), source ) );
1844}
1845
1846
1848 std::vector<MSG_PANEL_ITEM>& aList ) const
1849{
1850 aList.emplace_back( _( "Net" ), UnescapeString( GetNetname() ) );
1851
1852 aList.emplace_back( _( "Resolved Netclass" ),
1853 UnescapeString( GetEffectiveNetClass()->GetHumanReadableName() ) );
1854
1855#if 0 // Enable for debugging
1856 if( GetBoard() )
1857 aList.emplace_back( _( "NetCode" ), fmt::format( "{}", GetNetCode() ) );
1858
1859 aList.emplace_back( wxT( "Flags" ), fmt::format( "#08X", m_flags ) );
1860
1861 aList.emplace_back( wxT( "Start pos" ), fmt::format( "{} {}", m_Start.x, m_Start.y ) );
1862 aList.emplace_back( wxT( "End pos" ), fmt::format( "{} {}", m_End.x, m_End.y ) );
1863#endif
1864
1865 if( aFrame->GetName() == PCB_EDIT_FRAME_NAME && IsLocked() )
1866 aList.emplace_back( _( "Status" ), _( "Locked" ) );
1867}
1868
1869
1871{
1872 const BOARD* board = GetBoard();
1873 PCB_LAYER_ID top_layer;
1874 PCB_LAYER_ID bottom_layer;
1875
1876 LayerPair( &top_layer, &bottom_layer );
1877
1878 return board->GetLayerName( top_layer ) + wxT( " - " ) + board->GetLayerName( bottom_layer );
1879}
1880
1881
1882bool PCB_TRACK::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1883{
1884 return TestSegmentHit( aPosition, m_Start, m_End, aAccuracy + ( m_width / 2 ) );
1885}
1886
1887
1888bool PCB_ARC::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1889{
1890 double max_dist = aAccuracy + ( GetWidth() / 2.0 );
1891
1892 // Short-circuit common cases where the arc is connected to a track or via at an endpoint
1893 if( GetStart().Distance( aPosition ) <= max_dist || GetEnd().Distance( aPosition ) <= max_dist )
1894 {
1895 return true;
1896 }
1897
1899 VECTOR2L relpos = aPosition - center;
1900 int64_t dist = relpos.EuclideanNorm();
1901 double radius = GetRadius();
1902
1903 if( std::abs( dist - radius ) > max_dist )
1904 return false;
1905
1906 EDA_ANGLE arc_angle = GetAngle();
1907 EDA_ANGLE arc_angle_start = GetArcAngleStart(); // Always 0.0 ... 360 deg
1908 EDA_ANGLE arc_hittest( relpos );
1909
1910 // Calculate relative angle between the starting point of the arc, and the test point
1911 arc_hittest -= arc_angle_start;
1912
1913 // Normalise arc_hittest between 0 ... 360 deg
1914 arc_hittest.Normalize();
1915
1916 if( arc_angle < ANGLE_0 )
1917 return arc_hittest >= ANGLE_360 + arc_angle;
1918
1919 return arc_hittest <= arc_angle;
1920}
1921
1922
1923bool PCB_VIA::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1924{
1925 bool hit = false;
1926
1928 [&]( PCB_LAYER_ID aLayer )
1929 {
1930 if( hit )
1931 return;
1932
1933 int max_dist = aAccuracy + ( GetWidth( aLayer ) / 2 );
1934
1935 // rel_pos is aPosition relative to m_Start (or the center of the via)
1936 VECTOR2D rel_pos = aPosition - m_Start;
1937 double dist = rel_pos.x * rel_pos.x + rel_pos.y * rel_pos.y;
1938
1939 if( dist <= static_cast<double>( max_dist ) * max_dist )
1940 hit = true;
1941 } );
1942
1943 return hit;
1944}
1945
1946
1947bool PCB_TRACK::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1948{
1949 BOX2I arect = aRect;
1950 arect.Inflate( aAccuracy );
1951
1952 if( aContained )
1953 return arect.Contains( GetStart() ) && arect.Contains( GetEnd() );
1954 else
1955 return arect.Intersects( GetStart(), GetEnd() );
1956}
1957
1958
1959bool PCB_ARC::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1960{
1961 BOX2I arect = aRect;
1962 arect.Inflate( aAccuracy );
1963
1964 BOX2I box( GetStart() );
1965 box.Merge( GetMid() );
1966 box.Merge( GetEnd() );
1967
1968 box.Inflate( GetWidth() / 2 );
1969
1970 if( aContained )
1971 return arect.Contains( box );
1972 else
1973 return arect.Intersects( box );
1974}
1975
1976
1977bool PCB_VIA::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1978{
1979 BOX2I arect = aRect;
1980 arect.Inflate( aAccuracy );
1981
1982 bool hit = false;
1983
1985 [&]( PCB_LAYER_ID aLayer )
1986 {
1987 if( hit )
1988 return;
1989
1990 BOX2I box( GetStart() );
1991 box.Inflate( GetWidth( aLayer ) / 2 );
1992
1993 if( aContained )
1994 hit = arect.Contains( box );
1995 else
1996 hit = arect.IntersectsCircle( GetStart(), GetWidth( aLayer ) / 2 );
1997 } );
1998
1999 return hit;
2000}
2001
2002
2003wxString PCB_TRACK::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
2004{
2005 return wxString::Format( Type() == PCB_ARC_T ? _("Track (arc) %s on %s, length %s" )
2006 : _("Track %s on %s, length %s" ),
2007 GetNetnameMsg(),
2008 GetLayerName(),
2009 aUnitsProvider->MessageTextFromValue( GetLength() ) );
2010}
2011
2012
2014{
2015 return BITMAPS::add_tracks;
2016}
2017
2019{
2020 assert( aImage->Type() == PCB_TRACE_T );
2021
2022 std::swap( *((PCB_TRACK*) this), *((PCB_TRACK*) aImage) );
2023}
2024
2026{
2027 assert( aImage->Type() == PCB_ARC_T );
2028
2029 std::swap( *this, *static_cast<PCB_ARC*>( aImage ) );
2030}
2031
2033{
2034 assert( aImage->Type() == PCB_VIA_T );
2035
2036 std::swap( *((PCB_VIA*) this), *((PCB_VIA*) aImage) );
2037}
2038
2039
2041{
2043 return center;
2044}
2045
2046
2048{
2049 auto center = CalcArcCenter( m_Start, m_Mid , m_End );
2050 return center.Distance( m_Start );
2051}
2052
2053
2055{
2057 EDA_ANGLE angle1 = EDA_ANGLE( m_Mid - center ) - EDA_ANGLE( m_Start - center );
2058 EDA_ANGLE angle2 = EDA_ANGLE( m_End - center ) - EDA_ANGLE( m_Mid - center );
2059
2060 return angle1.Normalize180() + angle2.Normalize180();
2061}
2062
2063
2065{
2066 VECTOR2D pos( GetPosition() );
2067 EDA_ANGLE angleStart( m_Start - pos );
2068
2069 return angleStart.Normalize();
2070}
2071
2072
2073// Note: used in python tests. Ignore CLion's claim that it's unused....
2075{
2076 VECTOR2D pos( GetPosition() );
2077 EDA_ANGLE angleEnd( m_End - pos );
2078
2079 return angleEnd.Normalize();
2080}
2081
2082bool PCB_ARC::IsDegenerated( int aThreshold ) const
2083{
2084 // Too small arcs cannot be really handled: arc center (and arc radius)
2085 // cannot be safely computed if the distance between mid and end points
2086 // is too small (a few internal units)
2087
2088 // len of both segments must be < aThreshold to be a very small degenerated arc
2089 return ( GetMid() - GetStart() ).EuclideanNorm() < aThreshold
2090 && ( GetMid() - GetEnd() ).EuclideanNorm() < aThreshold;
2091}
2092
2093
2095{
2096 if( a->GetNetCode() != b->GetNetCode() )
2097 return a->GetNetCode() < b->GetNetCode();
2098
2099 if( a->GetLayer() != b->GetLayer() )
2100 return a->GetLayer() < b->GetLayer();
2101
2102 if( a->Type() != b->Type() )
2103 return a->Type() < b->Type();
2104
2105 if( a->m_Uuid != b->m_Uuid )
2106 return a->m_Uuid < b->m_Uuid;
2107
2108 return a < b;
2109}
2110
2111
2112std::shared_ptr<SHAPE> PCB_TRACK::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
2113{
2114 int width = m_width;
2115
2116 if( IsSolderMaskLayer( aLayer ) )
2117 width += 2 * GetSolderMaskExpansion();
2118
2119 return std::make_shared<SHAPE_SEGMENT>( m_Start, m_End, width );
2120}
2121
2122
2123std::shared_ptr<SHAPE> PCB_VIA::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
2124{
2125 if( aFlash == FLASHING::ALWAYS_FLASHED
2126 || ( aFlash == FLASHING::DEFAULT && FlashLayer( aLayer ) ) )
2127 {
2128 int width = 0;
2129
2130 if( aLayer == UNDEFINED_LAYER )
2131 {
2132 Padstack().ForEachUniqueLayer(
2133 [&]( PCB_LAYER_ID layer )
2134 {
2135 width = std::max( width, GetWidth( layer ) );
2136 } );
2137
2138 width /= 2;
2139 }
2140 else
2141 {
2142 PCB_LAYER_ID cuLayer = m_padStack.EffectiveLayerFor( aLayer );
2143 width = GetWidth( cuLayer ) / 2;
2144 }
2145
2146 return std::make_shared<SHAPE_CIRCLE>( m_Start, width );
2147 }
2148 else
2149 {
2150 return std::make_shared<SHAPE_CIRCLE>( m_Start, GetDrillValue() / 2 );
2151 }
2152}
2153
2154
2155std::shared_ptr<SHAPE> PCB_ARC::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
2156{
2157 int width = GetWidth();
2158
2159 if( IsSolderMaskLayer( aLayer ) )
2160 width += 2 * GetSolderMaskExpansion();
2161
2162 SHAPE_ARC arc( GetStart(), GetMid(), GetEnd(), width );
2163
2164 if( arc.IsEffectiveLine() )
2165 return std::make_shared<SHAPE_SEGMENT>( GetStart(), GetEnd(), width );
2166
2167 return std::make_shared<SHAPE_ARC>( arc );
2168}
2169
2170
2172 int aClearance, int aError, ERROR_LOC aErrorLoc,
2173 bool ignoreLineWidth ) const
2174{
2175 wxASSERT_MSG( !ignoreLineWidth, wxT( "IgnoreLineWidth has no meaning for tracks." ) );
2176
2177
2178 switch( Type() )
2179 {
2180 case PCB_VIA_T:
2181 {
2182 int radius = ( static_cast<const PCB_VIA*>( this )->GetWidth( aLayer ) / 2 ) + aClearance;
2183 TransformCircleToPolygon( aBuffer, m_Start, radius, aError, aErrorLoc );
2184 break;
2185 }
2186
2187 case PCB_ARC_T:
2188 {
2189 const PCB_ARC* arc = static_cast<const PCB_ARC*>( this );
2190 int width = m_width + ( 2 * aClearance );
2191
2192 if( IsSolderMaskLayer( aLayer ) )
2193 width += 2 * GetSolderMaskExpansion();
2194
2195 TransformArcToPolygon( aBuffer, arc->GetStart(), arc->GetMid(), arc->GetEnd(), width,
2196 aError, aErrorLoc );
2197 break;
2198 }
2199
2200 default:
2201 {
2202 int width = m_width + ( 2 * aClearance );
2203
2204 if( IsSolderMaskLayer( aLayer ) )
2205 width += 2 * GetSolderMaskExpansion();
2206
2207 TransformOvalToPolygon( aBuffer, m_Start, m_End, width, aError, aErrorLoc );
2208
2209 break;
2210 }
2211 }
2212}
2213
2214
2215static struct TRACK_VIA_DESC
2216{
2218 {
2219 // clang-format off: the suggestion is less readable
2221 .Undefined( VIATYPE::NOT_DEFINED )
2222 .Map( VIATYPE::THROUGH, _HKI( "Through" ) )
2223 .Map( VIATYPE::BLIND_BURIED, _HKI( "Blind/buried" ) )
2224 .Map( VIATYPE::MICROVIA, _HKI( "Micro" ) );
2225
2227 .Undefined( TENTING_MODE::FROM_RULES )
2228 .Map( TENTING_MODE::FROM_RULES, _HKI( "From design rules" ) )
2229 .Map( TENTING_MODE::TENTED, _HKI( "Tented" ) )
2230 .Map( TENTING_MODE::NOT_TENTED, _HKI( "Not tented" ) );
2231
2233 .Undefined( COVERING_MODE::FROM_RULES )
2234 .Map( COVERING_MODE::FROM_RULES, _HKI( "From design rules" ) )
2235 .Map( COVERING_MODE::COVERED, _HKI( "Covered" ) )
2236 .Map( COVERING_MODE::NOT_COVERED, _HKI( "Not covered" ) );
2237
2239 .Undefined( PLUGGING_MODE::FROM_RULES )
2240 .Map( PLUGGING_MODE::FROM_RULES, _HKI( "From design rules" ) )
2241 .Map( PLUGGING_MODE::PLUGGED, _HKI( "Plugged" ) )
2242 .Map( PLUGGING_MODE::NOT_PLUGGED, _HKI( "Not plugged" ) );
2243
2245 .Undefined( CAPPING_MODE::FROM_RULES )
2246 .Map( CAPPING_MODE::FROM_RULES, _HKI( "From design rules" ) )
2247 .Map( CAPPING_MODE::CAPPED, _HKI( "Capped" ) )
2248 .Map( CAPPING_MODE::NOT_CAPPED, _HKI( "Not capped" ) );
2249
2251 .Undefined( FILLING_MODE::FROM_RULES )
2252 .Map( FILLING_MODE::FROM_RULES, _HKI( "From design rules" ) )
2253 .Map( FILLING_MODE::FILLED, _HKI( "Filled" ) )
2254 .Map( FILLING_MODE::NOT_FILLED, _HKI( "Not filled" ) );
2255 // clang-format on: the suggestion is less readable
2256
2258
2259 if( layerEnum.Choices().GetCount() == 0 )
2260 {
2261 layerEnum.Undefined( UNDEFINED_LAYER );
2262
2263 for( PCB_LAYER_ID layer : LSET::AllLayersMask().Seq() )
2264 layerEnum.Map( layer, LSET::Name( layer ) );
2265 }
2266
2268
2269 // Track
2272
2273 propMgr.AddProperty( new PROPERTY<PCB_TRACK, int>( _HKI( "Width" ),
2274 &PCB_TRACK::SetWidth, &PCB_TRACK::GetWidth, PROPERTY_DISPLAY::PT_SIZE ) );
2275 propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Position X" ),
2276 new PROPERTY<PCB_TRACK, int>( _HKI( "Start X" ),
2277 &PCB_TRACK::SetStartX, &PCB_TRACK::GetStartX, PROPERTY_DISPLAY::PT_COORD,
2279 propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Position Y" ),
2280 new PROPERTY<PCB_TRACK, int>( _HKI( "Start Y" ),
2281 &PCB_TRACK::SetStartY, &PCB_TRACK::GetStartY, PROPERTY_DISPLAY::PT_COORD,
2283 propMgr.AddProperty( new PROPERTY<PCB_TRACK, int>( _HKI( "End X" ),
2284 &PCB_TRACK::SetEndX, &PCB_TRACK::GetEndX, PROPERTY_DISPLAY::PT_COORD,
2286 propMgr.AddProperty( new PROPERTY<PCB_TRACK, int>( _HKI( "End Y" ),
2287 &PCB_TRACK::SetEndY, &PCB_TRACK::GetEndY, PROPERTY_DISPLAY::PT_COORD,
2289
2290 const wxString groupTechLayers = _HKI( "Technical Layers" );
2291
2292 auto isExternalLayerTrack =
2293 []( INSPECTABLE* aItem )
2294 {
2295 if( auto track = dynamic_cast<PCB_TRACK*>( aItem ) )
2296 return track->GetLayer() == F_Cu || track->GetLayer() == B_Cu;
2297
2298 return false;
2299 };
2300
2301 propMgr.AddProperty( new PROPERTY<PCB_TRACK, bool>( _HKI( "Soldermask" ),
2303 .SetAvailableFunc( isExternalLayerTrack );
2304 propMgr.AddProperty( new PROPERTY<PCB_TRACK, std::optional<int>>( _HKI( "Soldermask Margin Override" ),
2306 PROPERTY_DISPLAY::PT_SIZE ), groupTechLayers )
2307 .SetAvailableFunc( isExternalLayerTrack );
2308
2309 // Arc
2312
2313 // Via
2316
2317 // TODO test drill, use getdrillvalue?
2318 const wxString groupVia = _HKI( "Via Properties" );
2319
2320 propMgr.Mask( TYPE_HASH( PCB_VIA ), TYPE_HASH( BOARD_CONNECTED_ITEM ), _HKI( "Layer" ) );
2321
2322 // clang-format off: the suggestion is less readable
2323 propMgr.AddProperty( new PROPERTY<PCB_VIA, int>( _HKI( "Diameter" ),
2324 &PCB_VIA::SetFrontWidth, &PCB_VIA::GetFrontWidth, PROPERTY_DISPLAY::PT_SIZE ), groupVia );
2325 propMgr.AddProperty( new PROPERTY<PCB_VIA, int>( _HKI( "Hole" ),
2326 &PCB_VIA::SetDrill, &PCB_VIA::GetDrillValue, PROPERTY_DISPLAY::PT_SIZE ), groupVia );
2327 propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, PCB_LAYER_ID>( _HKI( "Layer Top" ),
2328 &PCB_VIA::SetLayer, &PCB_VIA::GetLayer ), groupVia );
2329 propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, PCB_LAYER_ID>( _HKI( "Layer Bottom" ),
2331 propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, VIATYPE>( _HKI( "Via Type" ),
2333 propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, TENTING_MODE>( _HKI( "Front tenting" ),
2335 propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, TENTING_MODE>( _HKI( "Back tenting" ),
2337 propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, COVERING_MODE>( _HKI( "Front covering" ),
2339 propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, COVERING_MODE>( _HKI( "Back covering" ),
2341 propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, PLUGGING_MODE>( _HKI( "Front plugging" ),
2343 propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, PLUGGING_MODE>( _HKI( "Back plugging" ),
2345 propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, CAPPING_MODE>( _HKI( "Capping" ),
2347 propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, FILLING_MODE>( _HKI( "Filling" ),
2349 // clang-format on: the suggestion is less readable
2350 }
2352
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
Definition: approximation.h:32
@ ERROR_INSIDE
Definition: approximation.h:34
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
constexpr int ARC_LOW_DEF
Definition: base_units.h:119
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
ZONE_LAYER_OVERRIDE
Conditionally flashed vias and pads that interact with zones of different priority can be very squirr...
Definition: board_item.h:66
@ ZLO_NONE
Definition: board_item.h:67
@ ZLO_FORCE_FLASHED
Definition: board_item.h:68
constexpr BOX2I BOX2ISafe(const BOX2D &aInput)
Definition: box2.h:929
BASE_SET & reset(size_t pos)
Definition: base_set.h:143
BASE_SET & set(size_t pos)
Definition: base_set.h:116
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
wxString GetNetnameMsg() const
virtual NETCLASS * GetEffectiveNetClass() const
Return the NETCLASS for this item.
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
const wxString & GetDisplayNetname() const
virtual int GetOwnClearance(PCB_LAYER_ID aLayer, wxString *aSource=nullptr) const
Return an item's "own" clearance in internal units.
Container for design settings for a BOARD object.
std::shared_ptr< DRC_ENGINE > m_DRCEngine
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:78
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:229
virtual void TransformShapeToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc) const
Convert the item shape to a polyset.
Definition: board_item.h:420
virtual void SetLocked(bool aLocked)
Definition: board_item.h:320
PCB_LAYER_ID m_layer
Definition: board_item.h:445
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:280
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:48
virtual bool IsLocked() const
Definition: board_item.cpp:76
virtual int BoardCopperLayerCount() const
Return the total number of copper layers for the board that this item resides on.
Definition: board_item.cpp:118
virtual wxString layerMaskDescribe() const
Return a string (to be shown to the user) describing a layer mask.
Definition: board_item.cpp:167
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Definition: board_item.cpp:140
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:297
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayer) const
Definition: board.cpp:774
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:614
std::tuple< int, double, double > GetTrackLength(const PCB_TRACK &aTrack) const
Return data on the length and number of track segments connected to a given track.
Definition: board.cpp:2380
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:946
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:495
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 BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:658
bool IntersectsCircle(const Vec &aCenter, const int aRadius) const
Definition: box2.h:504
constexpr coord_type GetLeft() const
Definition: box2.h:228
constexpr bool Contains(const Vec &aPoint) const
Definition: box2.h:168
constexpr coord_type GetRight() const
Definition: box2.h:217
constexpr coord_type GetTop() const
Definition: box2.h:229
constexpr bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:311
constexpr coord_type GetBottom() const
Definition: box2.h:222
wxString GetName() const
Definition: drc_rule.h:160
MINOPTMAX< int > & Value()
Definition: drc_rule.h:153
EDA_ANGLE Normalize()
Definition: eda_angle.h:221
EDA_ANGLE Normalize180()
Definition: eda_angle.h:260
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:96
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Assign the members of aItem to another object.
Definition: eda_item.cpp:303
const KIID m_Uuid
Definition: eda_item.h:498
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:108
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:509
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition: property.h:686
static ENUM_MAP< T > & Instance()
Definition: property.h:680
ENUM_MAP & Undefined(T aValue)
Definition: property.h:693
wxPGChoices & Choices()
Definition: property.h:729
Class that other classes need to inherit from, in order to be inspectable.
Definition: inspectable.h:37
Contains methods for drawing PCB-specific items.
Definition: pcb_painter.h:181
virtual PCB_RENDER_SETTINGS * GetSettings() override
Return a pointer to current settings that are going to be used when drawing items.
Definition: pcb_painter.h:186
PCB specific render settings.
Definition: pcb_painter.h:79
PCB_LAYER_ID GetPrimaryHighContrastLayer() const
Return the board layer which is in high-contrast mode.
bool GetHighContrast() const
static double lodScaleForThreshold(const KIGFX::VIEW *aView, int aWhatIu, int aThresholdIu)
Get the scale at which aWhatIu would be drawn at the same size as aThresholdIu on screen.
Definition: view_item.cpp:39
static constexpr double LOD_HIDE
Return this constant from ViewGetLOD() to hide the item unconditionally.
Definition: view_item.h:174
static constexpr double LOD_SHOW
Return this constant from ViewGetLOD() to show the item unconditionally.
Definition: view_item.h:179
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:67
BOX2D GetViewport() const
Return the current viewport visible area rectangle.
Definition: view.cpp:520
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:418
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:216
Definition: kiid.h:49
std::string AsStdString() const
Definition: kiid.cpp:252
static bool Contains(int aStart_layer, int aEnd_layer, int aTest_layer)
Definition: layer_range.h:131
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:255
static const LSET & BackTechMask()
Return a mask holding all technical layers (no CU layer) on back side.
Definition: lset.cpp:634
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:583
static const LSET & AllLayersMask()
Definition: lset.cpp:627
static const LSET & PhysicalLayersMask()
Return a mask holding all layers which are physically realized.
Definition: lset.cpp:683
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:188
bool Contains(PCB_LAYER_ID aLayer) const
See if the layer set contains a PCB layer.
Definition: lset.h:63
static const LSET & FrontTechMask()
Return a mask holding all technical layers (no CU layer) on front side.
Definition: lset.cpp:648
T Min() const
Definition: minoptmax.h:33
bool HasMin() const
Definition: minoptmax.h:37
A collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:45
int GetViaDrill() const
Definition: netclass.h:138
int GetuViaDrill() const
Definition: netclass.h:154
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:381
A PADSTACK defines the characteristics of a single or multi-layer pad, in the IPC sense of the word.
Definition: padstack.h:124
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: padstack.cpp:211
MASK_LAYER_PROPS & FrontOuterLayers()
Definition: padstack.h:318
void ForEachUniqueLayer(const std::function< void(PCB_LAYER_ID)> &aMethod) const
Runs the given callable for each active unique copper layer in this padstack, meaning F_Cu for MODE::...
Definition: padstack.cpp:881
void SetUnconnectedLayerMode(UNCONNECTED_LAYER_MODE aMode)
Definition: padstack.h:313
const LSET & LayerSet() const
Definition: padstack.h:280
void SetShape(PAD_SHAPE aShape, PCB_LAYER_ID aLayer)
Definition: padstack.cpp:1059
UNCONNECTED_LAYER_MODE UnconnectedLayerMode() const
Definition: padstack.h:312
DRILL_PROPS & Drill()
Definition: padstack.h:306
const VECTOR2I & Size(PCB_LAYER_ID aLayer) const
Definition: padstack.cpp:1074
MASK_LAYER_PROPS & BackOuterLayers()
Definition: padstack.h:321
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: padstack.cpp:413
void SetSize(const VECTOR2I &aSize, PCB_LAYER_ID aLayer)
Definition: padstack.cpp:1065
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
Definition: padstack.h:144
virtual VECTOR2I GetPosition() const override
Definition: pcb_track.cpp:2040
bool IsDegenerated(int aThreshold=5) const
Definition: pcb_track.cpp:2082
virtual void swapData(BOARD_ITEM *aImage) override
Definition: pcb_track.cpp:2025
bool IsCCW() const
Definition: pcb_track.cpp:842
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: pcb_track.cpp:441
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: pcb_track.cpp:90
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
Definition: pcb_track.cpp:823
EDA_ANGLE GetArcAngleStart() const
Definition: pcb_track.cpp:2064
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_track.cpp:798
virtual bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition: pcb_track.cpp:1888
EDA_ANGLE GetArcAngleEnd() const
Definition: pcb_track.cpp:2074
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: pcb_track.cpp:464
void SetMid(const VECTOR2I &aMid)
Definition: pcb_track.h:336
double GetRadius() const
Definition: pcb_track.cpp:2047
EDA_ANGLE GetAngle() const
Definition: pcb_track.cpp:2054
const VECTOR2I & GetMid() const
Definition: pcb_track.h:337
PCB_ARC(BOARD_ITEM *aParent)
Definition: pcb_track.h:310
double Similarity(const BOARD_ITEM &aOther) const override
Return a measure of how likely the other object is to represent the same object.
Definition: pcb_track.cpp:274
VECTOR2I m_Mid
Arc mid point, halfway between start and end.
Definition: pcb_track.h:401
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
Definition: pcb_track.cpp:783
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: pcb_track.cpp:2155
bool operator==(const PCB_ARC &aOther) const
Definition: pcb_track.cpp:262
void CopyFrom(const BOARD_ITEM *aOther) override
Definition: pcb_track.cpp:96
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: pcb_track.cpp:1225
virtual void SetLayerSet(const LSET &aLayers) override
Definition: pcb_track.cpp:1212
int GetSolderMaskExpansion() const
Definition: pcb_track.cpp:1116
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
Definition: pcb_track.cpp:776
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: pcb_track.cpp:400
void SetEndY(int aY)
Definition: pcb_track.h:161
void SetHasSolderMask(bool aVal)
Definition: pcb_track.h:175
virtual double GetLength() const
Get the length of the track using the hypotenuse calculation.
Definition: pcb_track.cpp:770
double ViewGetLOD(int aLayer, const KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: pcb_track.cpp:1536
virtual void swapData(BOARD_ITEM *aImage) override
Definition: pcb_track.cpp:2018
void SetEnd(const VECTOR2I &aEnd)
Definition: pcb_track.h:148
bool HasSolderMask() const
Definition: pcb_track.h:176
void SetStart(const VECTOR2I &aStart)
Definition: pcb_track.h:151
const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
Definition: pcb_track.cpp:1595
int GetStartY() const
Definition: pcb_track.h:158
int GetEndX() const
Definition: pcb_track.h:163
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
Definition: pcb_track.cpp:2003
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_track.cpp:791
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: pcb_track.cpp:421
INSPECT_RESULT Visit(INSPECTOR inspector, void *testData, const std::vector< KICAD_T > &aScanTypes) override
May be re-implemented for each derived class in order to handle all the types given by its member dat...
Definition: pcb_track.cpp:877
bool ApproxCollinear(const PCB_TRACK &aTrack)
Definition: pcb_track.cpp:541
VECTOR2I m_End
Line end point.
Definition: pcb_track.h:297
void SetLocalSolderMaskMargin(std::optional< int > aMargin)
Definition: pcb_track.h:178
std::optional< int > m_solderMaskMargin
Definition: pcb_track.h:300
void CopyFrom(const BOARD_ITEM *aOther) override
Definition: pcb_track.cpp:74
std::optional< int > GetLocalSolderMaskMargin() const
Definition: pcb_track.h:179
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_track.cpp:1745
virtual EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: pcb_track.cpp:68
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: pcb_track.cpp:681
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the track shape to a closed polygon.
Definition: pcb_track.cpp:2171
const VECTOR2I & GetStart() const
Definition: pcb_track.h:152
virtual bool operator==(const BOARD_ITEM &aOther) const override
Definition: pcb_track.cpp:187
VECTOR2I m_Start
Line start point.
Definition: pcb_track.h:296
int GetEndY() const
Definition: pcb_track.h:164
wxString GetFriendlyName() const override
Definition: pcb_track.cpp:1733
virtual std::vector< int > ViewGetLayers() const override
Return the all the layers within the VIEW the object is painted on.
Definition: pcb_track.cpp:1509
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: pcb_track.cpp:2013
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition: pcb_track.cpp:1882
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
Definition: pcb_track.cpp:806
virtual double Similarity(const BOARD_ITEM &aOther) const override
Return a measure of how likely the other object is to represent the same object.
Definition: pcb_track.cpp:209
bool m_hasSolderMask
Definition: pcb_track.h:299
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: pcb_track.cpp:2112
void SetStartX(int aX)
Definition: pcb_track.h:154
const VECTOR2I & GetEnd() const
Definition: pcb_track.h:149
PCB_TRACK(BOARD_ITEM *aParent, KICAD_T idtype=PCB_TRACE_T)
Definition: pcb_track.cpp:60
void SetStartY(int aY)
Definition: pcb_track.h:155
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
Definition: pcb_track.cpp:1137
virtual MINOPTMAX< int > GetWidthConstraint(wxString *aSource=nullptr) const
Definition: pcb_track.cpp:549
void SetEndX(int aX)
Definition: pcb_track.h:160
int GetStartX() const
Definition: pcb_track.h:157
int m_width
Thickness of track (or arc) – no longer the width of a via.
Definition: pcb_track.h:303
EDA_ITEM_FLAGS IsPointOnEnds(const VECTOR2I &point, int min_dist=0) const
Return STARTPOINT if point if near (dist = min_dist) start point, ENDPOINT if point if near (dist = m...
Definition: pcb_track.cpp:649
virtual void SetWidth(int aWidth)
Definition: pcb_track.h:145
virtual int GetWidth() const
Definition: pcb_track.h:146
void GetMsgPanelInfoBase_Common(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) const
Definition: pcb_track.cpp:1847
PCB_LAYER_ID BottomLayer() const
Definition: pcb_track.cpp:1368
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: pcb_track.cpp:181
PLUGGING_MODE GetFrontPluggingMode() const
Definition: pcb_track.cpp:1002
VECTOR2I GetPosition() const override
Definition: pcb_track.h:544
bool IsTented(PCB_LAYER_ID aLayer) const override
Checks if the given object is tented (its copper shape is covered by solder mask) on a given side of ...
Definition: pcb_track.cpp:1084
void CopyFrom(const BOARD_ITEM *aOther) override
Definition: pcb_track.cpp:153
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: pcb_track.cpp:2123
void SetCappingMode(CAPPING_MODE aMode)
Definition: pcb_track.cpp:1037
void SetFrontCoveringMode(COVERING_MODE aMode)
Definition: pcb_track.cpp:945
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: pcb_track.cpp:513
COVERING_MODE GetBackCoveringMode() const
Definition: pcb_track.cpp:979
bool FlashLayer(int aLayer) const
Check to see whether the via should have a pad on the specific layer.
Definition: pcb_track.cpp:1399
void SetDrillDefault()
Set the drill value for vias to the default value UNDEFINED_DRILL_DIAMETER.
Definition: pcb_track.h:681
std::map< PCB_LAYER_ID, ZONE_LAYER_OVERRIDE > m_zoneLayerOverrides
Definition: pcb_track.h:730
void ClearZoneLayerOverrides()
Definition: pcb_track.cpp:1451
CAPPING_MODE GetCappingMode() const
Definition: pcb_track.cpp:1048
const PADSTACK & Padstack() const
Definition: pcb_track.h:446
void SetFrontTentingMode(TENTING_MODE aMode)
Definition: pcb_track.cpp:899
bool m_isFree
"Free" vias don't get their nets auto-updated
Definition: pcb_track.h:727
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition: pcb_track.cpp:1923
TENTING_MODE GetFrontTentingMode() const
Definition: pcb_track.cpp:910
void SetBottomLayer(PCB_LAYER_ID aLayer)
Definition: pcb_track.cpp:1334
int GetSolderMaskExpansion() const
Definition: pcb_track.cpp:1107
void SetDrill(int aDrill)
Set the drill value for vias.
Definition: pcb_track.h:659
PLUGGING_MODE GetBackPluggingMode() const
Definition: pcb_track.cpp:1025
void SetBackPluggingMode(PLUGGING_MODE aMode)
Definition: pcb_track.cpp:1014
MINOPTMAX< int > GetDrillConstraint(wxString *aSource=nullptr) const
Definition: pcb_track.cpp:585
void SetBackTentingMode(TENTING_MODE aMode)
Definition: pcb_track.cpp:922
void SetFrontPluggingMode(PLUGGING_MODE aMode)
Definition: pcb_track.cpp:991
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
Definition: pcb_track.cpp:852
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_track.cpp:1810
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: pcb_track.cpp:160
bool operator==(const PCB_VIA &aOther) const
Definition: pcb_track.cpp:330
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: pcb_track.cpp:1200
std::mutex m_zoneLayerOverridesMutex
Definition: pcb_track.h:729
void SetTopLayer(PCB_LAYER_ID aLayer)
Definition: pcb_track.cpp:1328
FILLING_MODE GetFillingMode() const
Definition: pcb_track.cpp:1071
std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const override
Definition: pcb_track.cpp:893
int GetFrontWidth() const
Definition: pcb_track.h:461
void SetLayerPair(PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer)
For a via m_layer contains the top layer, the other layer is in m_bottomLayer/.
Definition: pcb_track.cpp:1319
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
Definition: pcb_track.cpp:166
double Similarity(const BOARD_ITEM &aOther) const override
Return a measure of how likely the other object is to represent the same object.
Definition: pcb_track.cpp:341
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition: pcb_track.cpp:1206
virtual void SetLayerSet(const LSET &aLayers) override
Note SetLayerSet() initialize the first and last copper layers connected by the via.
Definition: pcb_track.cpp:1277
void GetOutermostConnectedLayers(PCB_LAYER_ID *aTopmost, PCB_LAYER_ID *aBottommost) const
Return the top-most and bottom-most connected layers.
Definition: pcb_track.cpp:1475
void SanitizeLayers()
Check so that the layers are correct depending on the type of via, and so that the top actually is on...
Definition: pcb_track.cpp:1374
int GetWidth() const override
Definition: pcb_track.cpp:380
PCB_VIA & operator=(const PCB_VIA &aOther)
Definition: pcb_track.cpp:138
void swapData(BOARD_ITEM *aImage) override
Definition: pcb_track.cpp:2032
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: pcb_track.cpp:485
void SetFillingMode(FILLING_MODE aMode)
Definition: pcb_track.cpp:1060
PCB_VIA(BOARD_ITEM *aParent)
Definition: pcb_track.cpp:103
wxString layerMaskDescribe() const override
Return a string (to be shown to the user) describing a layer mask.
Definition: pcb_track.cpp:1870
std::vector< int > ViewGetLayers() const override
Return the all the layers within the VIEW the object is painted on.
Definition: pcb_track.cpp:1608
void SetViaType(VIATYPE aViaType)
Definition: pcb_track.h:444
int GetMinAnnulus(PCB_LAYER_ID aLayer, wxString *aSource) const
Definition: pcb_track.cpp:603
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
Definition: pcb_track.cpp:1155
TENTING_MODE GetBackTentingMode() const
Definition: pcb_track.cpp:933
PCB_LAYER_ID TopLayer() const
Definition: pcb_track.cpp:1362
VIATYPE m_viaType
through, blind/buried or micro
Definition: pcb_track.h:723
PADSTACK m_padStack
Definition: pcb_track.h:725
COVERING_MODE GetFrontCoveringMode() const
Definition: pcb_track.cpp:956
int GetDrillValue() const
Calculate the drill value for vias (m_drill if > 0, or default drill value for the board).
Definition: pcb_track.cpp:634
void SetZoneLayerOverride(PCB_LAYER_ID aLayer, ZONE_LAYER_OVERRIDE aOverride)
Definition: pcb_track.cpp:1468
void SetFrontWidth(int aWidth)
Definition: pcb_track.h:460
VIATYPE GetViaType() const
Definition: pcb_track.h:443
double ViewGetLOD(int aLayer, const KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: pcb_track.cpp:1653
MINOPTMAX< int > GetWidthConstraint(wxString *aSource=nullptr) const override
Definition: pcb_track.cpp:567
void SetWidth(int aWidth) override
Definition: pcb_track.cpp:372
void SetBackCoveringMode(COVERING_MODE aMode)
Definition: pcb_track.cpp:968
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: pcb_track.cpp:1241
const ZONE_LAYER_OVERRIDE & GetZoneLayerOverride(PCB_LAYER_ID aLayer) const
Definition: pcb_track.cpp:1460
void LayerPair(PCB_LAYER_ID *top_layer, PCB_LAYER_ID *bottom_layer) const
Return the 2 layers used by the via (the via actually uses all layers between these 2 layers)
Definition: pcb_track.cpp:1340
bool HasValidLayerPair(int aCopperLayerCount)
Definition: pcb_track.cpp:1178
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: pcb_track.cpp:726
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.
PROPERTY_BASE & ReplaceProperty(size_t aBase, const wxString &aName, PROPERTY_BASE *aNew, const wxString &aGroup=wxEmptyString)
Replace an existing property for a specific type.
Definition: seg.h:42
VECTOR2I::extended_type ecoord
Definition: seg.h:44
bool ApproxCollinear(const SEG &aSeg, int aDistanceThreshold=1) const
Definition: seg.cpp:533
const VECTOR2I & GetArcMid() const
Definition: shape_arc.h:118
const VECTOR2I & GetP1() const
Definition: shape_arc.h:117
bool IsEffectiveLine() const
Definition: shape_arc.cpp:245
const VECTOR2I & GetP0() const
Definition: shape_arc.h:116
Represent a set of closed polygons.
double Area()
Return the area of this poly set.
wxString MessageTextFromMinOptMax(const MINOPTMAX< int > &aValue) const
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
constexpr extended_type Cross(const VECTOR2< T > &aVector) const
Compute cross product of self with aVector.
Definition: vector2d.h:546
double Distance(const VECTOR2< extended_type > &aVector) const
Compute the distance between two vectors.
Definition: vector2d.h:561
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:283
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aBuffer, const VECTOR2I &aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a circle to a polygon, using multiple straight lines.
void TransformArcToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc)
Convert arc to multiple straight segments.
void TransformOvalToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a oblong shape to a polygon, using multiple segments.
#define _HKI(x)
@ ANNULAR_WIDTH_CONSTRAINT
Definition: drc_rule.h:61
@ VIA_DIAMETER_CONSTRAINT
Definition: drc_rule.h:67
@ TRACK_WIDTH_CONSTRAINT
Definition: drc_rule.h:59
@ HOLE_SIZE_CONSTRAINT
Definition: drc_rule.h:54
#define _(s)
static constexpr EDA_ANGLE ANGLE_0
Definition: eda_angle.h:401
static constexpr EDA_ANGLE ANGLE_360
Definition: eda_angle.h:407
#define PCB_EDIT_FRAME_NAME
INSPECT_RESULT
Definition: eda_item.h:43
const INSPECTOR_FUNC & INSPECTOR
std::function passed to nested users by ref, avoids copying std::function.
Definition: eda_item.h:89
#define ENDPOINT
ends. (Used to support dragging.)
std::uint32_t EDA_ITEM_FLAGS
#define STARTPOINT
When a line is selected, these flags indicate which.
a few functions useful in geometry calculations.
bool ClipLine(const BOX2I *aClipBox, int &x1, int &y1, int &x2, int &y2)
Test if any part of a line falls within the bounds of a rectangle.
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition: layer_id.cpp:169
bool IsSolderMaskLayer(int aLayer)
Definition: layer_ids.h:733
@ LAYER_VIA_NETNAMES
Definition: layer_ids.h:203
bool IsCopperLayerLowerThan(PCB_LAYER_ID aLayerA, PCB_LAYER_ID aLayerB)
Return true if copper aLayerA is placed lower than aLayerB, false otherwise.
Definition: layer_ids.h:809
constexpr PCB_LAYER_ID PCBNEW_LAYER_ID_START
Definition: layer_ids.h:174
bool IsFrontLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a front layer.
Definition: layer_ids.h:765
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:788
#define MAX_CU_LAYERS
Definition: layer_ids.h:176
int GetNetnameLayer(int aLayer)
Return a netname layer corresponding to the given layer.
Definition: layer_ids.h:839
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
Definition: layer_ids.h:663
@ LAYER_LOCKED_ITEM_SHADOW
Shadow layer for locked items.
Definition: layer_ids.h:306
@ LAYER_VIA_HOLEWALLS
Definition: layer_ids.h:297
@ LAYER_VIA_COPPER_START
Virtual layers for via copper on a given copper layer.
Definition: layer_ids.h:335
@ LAYER_TRACKS
Definition: layer_ids.h:266
@ LAYER_CLEARANCE_START
Virtual layers for pad/via/track clearance outlines for a given copper layer.
Definition: layer_ids.h:339
@ LAYER_VIA_HOLES
Draw via holes (pad holes do not use this layer).
Definition: layer_ids.h:273
@ LAYER_VIAS
Meta control for all vias opacity/visibility.
Definition: layer_ids.h:232
bool IsNetnameLayer(int aLayer)
Test whether a layer is a netname layer.
Definition: layer_ids.h:854
bool IsHoleLayer(int aLayer)
Definition: layer_ids.h:724
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ 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
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:747
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
void PackLayerSet(google::protobuf::RepeatedField< int > &aOutput, const LSET &aLayerSet)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:390
static struct TRACK_VIA_DESC _TRACK_VIA_DESC
FILLING_MODE
Definition: pcb_track.h:103
VIATYPE
Definition: pcb_track.h:66
TENTING_MODE
Definition: pcb_track.h:75
COVERING_MODE
Definition: pcb_track.h:82
PLUGGING_MODE
Definition: pcb_track.h:89
CAPPING_MODE
Definition: pcb_track.h:96
#define TYPE_HASH(x)
Definition: property.h:71
#define ENUM_TO_WXANY(type)
Macro to define read-only fields (no setter method available)
Definition: property.h:782
#define REGISTER_TYPE(x)
Definition: property_mgr.h:371
wxString UnescapeString(const wxString &aSource)
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
PCB_LAYER_ID start
Definition: padstack.h:245
PCB_LAYER_ID end
Definition: padstack.h:246
VECTOR2I size
Drill diameter (x == y) or slot dimensions (x != y)
Definition: padstack.h:243
std::optional< bool > is_capped
True if the drill hole should be capped.
Definition: padstack.h:249
std::optional< bool > is_filled
True if the drill hole should be filled completely.
Definition: padstack.h:248
std::optional< bool > has_covering
True if the pad on this side should have covering.
Definition: padstack.h:234
std::optional< bool > has_solder_mask
True if this outer layer has mask (is not tented)
Definition: padstack.h:232
std::optional< bool > has_plugging
True if the drill hole should be plugged on this side.
Definition: padstack.h:235
bool operator()(const PCB_TRACK *aFirst, const PCB_TRACK *aSecond) const
Definition: pcb_track.cpp:2094
VECTOR2I center
int radius
VECTOR2I end
int clearance
bool TestSegmentHit(const VECTOR2I &aRefPoint, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
Definition: trigo.cpp:175
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition: trigo.cpp:229
const VECTOR2I CalcArcCenter(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Determine the center of an arc or circle given three points on its circumference.
Definition: trigo.cpp:521
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695
VECTOR2< int64_t > VECTOR2L
Definition: vector2d.h:696