KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 <[email protected]>
6 * Copyright (C) 2012 Wayne Stambaugh <[email protected]>
7 * Copyright (C) 1992-2023 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_base_frame.h>
28#include <core/mirror.h>
30#include <board.h>
33#include <pcb_track.h>
34#include <base_units.h>
35//#include <bitmaps.h>
36#include <string_utils.h>
37#include <view/view.h>
40//#include <i18n_utility.h>
41#include <geometry/seg.h>
44#include <geometry/shape_arc.h>
45#include <drc/drc_engine.h>
46#include <pcb_painter.h>
47#include <trigo.h>
48
51
53 BOARD_CONNECTED_ITEM( aParent, idtype )
54{
55 m_Width = pcbIUScale.mmToIU( 0.2 ); // Gives a reasonable default width
56 m_CachedScale = -1.0; // Set invalid to force update
57 m_CachedLOD = 0.0; // Set to always display
58}
59
60
62{
63 return new PCB_TRACK( *this );
64}
65
66
67PCB_ARC::PCB_ARC( BOARD_ITEM* aParent, const SHAPE_ARC* aArc ) :
68 PCB_TRACK( aParent, PCB_ARC_T )
69{
70 m_Start = aArc->GetP0();
71 m_End = aArc->GetP1();
72 m_Mid = aArc->GetArcMid();
73}
74
75
77{
78 return new PCB_ARC( *this );
79}
80
81
83 PCB_TRACK( aParent, PCB_VIA_T )
84{
85 SetViaType( VIATYPE::THROUGH );
88
91
93
94 m_isFree = false;
95}
96
97
98PCB_VIA::PCB_VIA( const PCB_VIA& aOther ) :
99 PCB_TRACK( aOther.GetParent(), PCB_VIA_T )
100{
101 PCB_VIA::operator=( aOther );
102
103 const_cast<KIID&>( m_Uuid ) = aOther.m_Uuid;
105}
106
107
109{
111
112 m_Width = aOther.m_Width;
113 m_Start = aOther.m_Start;
114 m_End = aOther.m_End;
115 m_CachedLOD = aOther.m_CachedLOD;
117
119 m_viaType = aOther.m_viaType;
120 m_drill = aOther.m_drill;
123 m_isFree = aOther.m_isFree;
124
125 return *this;
126}
127
128
130{
131 return new PCB_VIA( *this );
132}
133
134
135wxString PCB_VIA::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
136{
137 wxString formatStr;
138
139 switch( GetViaType() )
140 {
141 case VIATYPE::BLIND_BURIED: formatStr = _( "Blind/Buried Via %s on %s" ); break;
142 case VIATYPE::MICROVIA: formatStr = _( "Micro Via %s on %s" ); break;
143 default: formatStr = _( "Via %s on %s" ); break;
144 }
145
146 return wxString::Format( formatStr, GetNetnameMsg(), layerMaskDescribe() );
147}
148
149
151{
152 return BITMAPS::via;
153}
154
155
157{
158 SEG a( m_Start, m_End );
159 SEG b( aTrack.GetStart(), aTrack.GetEnd() );
160 return a.ApproxCollinear( b );
161}
162
163
164int PCB_TRACK::GetLocalClearance( wxString* aSource ) const
165{
166 // Not currently implemented
167 return 0;
168}
169
170
172{
173 DRC_CONSTRAINT constraint;
174
175 if( GetBoard() && GetBoard()->GetDesignSettings().m_DRCEngine )
176 {
178
179 constraint = bds.m_DRCEngine->EvalRules( TRACK_WIDTH_CONSTRAINT, this, nullptr, m_layer );
180 }
181
182 if( aSource )
183 *aSource = constraint.GetName();
184
185 return constraint.Value();
186}
187
188
189int PCB_VIA::GetMinAnnulus( PCB_LAYER_ID aLayer, wxString* aSource ) const
190{
191 if( !FlashLayer( aLayer ) )
192 {
193 if( aSource )
194 *aSource = _( "removed annular ring" );
195
196 return 0;
197 }
198
199 DRC_CONSTRAINT constraint;
200
201 if( GetBoard() && GetBoard()->GetDesignSettings().m_DRCEngine )
202 {
204
205 constraint = bds.m_DRCEngine->EvalRules( ANNULAR_WIDTH_CONSTRAINT, this, nullptr, aLayer );
206 }
207
208 if( constraint.Value().HasMin() )
209 {
210 if( aSource )
211 *aSource = constraint.GetName();
212
213 return constraint.Value().Min();
214 }
215
216 return 0;
217}
218
219
221{
222 if( m_drill > 0 ) // Use the specific value.
223 return m_drill;
224
225 // Use the default value from the Netclass
226 NETCLASS* netclass = GetEffectiveNetClass();
227
228 if( GetViaType() == VIATYPE::MICROVIA )
229 return netclass->GetuViaDrill();
230
231 return netclass->GetViaDrill();
232}
233
234
235EDA_ITEM_FLAGS PCB_TRACK::IsPointOnEnds( const VECTOR2I& point, int min_dist ) const
236{
237 EDA_ITEM_FLAGS result = 0;
238
239 if( min_dist < 0 )
240 min_dist = m_Width / 2;
241
242 if( min_dist == 0 )
243 {
244 if( m_Start == point )
245 result |= STARTPOINT;
246
247 if( m_End == point )
248 result |= ENDPOINT;
249 }
250 else
251 {
252 double dist = GetLineLength( m_Start, point );
253
254 if( min_dist >= KiROUND( dist ) )
255 result |= STARTPOINT;
256
257 dist = GetLineLength( m_End, point );
258
259 if( min_dist >= KiROUND( dist ) )
260 result |= ENDPOINT;
261 }
262
263 return result;
264}
265
266
268{
269 // end of track is round, this is its radius, rounded up
270 int radius = ( m_Width + 1 ) / 2;
271 int ymax, xmax, ymin, xmin;
272
273 if( Type() == PCB_VIA_T )
274 {
275 ymax = m_Start.y;
276 xmax = m_Start.x;
277
278 ymin = m_Start.y;
279 xmin = m_Start.x;
280 }
281 else if( Type() == PCB_ARC_T )
282 {
283 std::shared_ptr<SHAPE> arc = GetEffectiveShape();
284 BOX2I bbox = arc->BBox();
285
286 xmin = bbox.GetLeft();
287 xmax = bbox.GetRight();
288 ymin = bbox.GetTop();
289 ymax = bbox.GetBottom();
290 }
291 else
292 {
293 ymax = std::max( m_Start.y, m_End.y );
294 xmax = std::max( m_Start.x, m_End.x );
295
296 ymin = std::min( m_Start.y, m_End.y );
297 xmin = std::min( m_Start.x, m_End.x );
298 }
299
300 ymax += radius;
301 xmax += radius;
302
303 ymin -= radius;
304 xmin -= radius;
305
306 // return a rectangle which is [pos,dim) in nature. therefore the +1
307 BOX2I ret( VECTOR2I( xmin, ymin ), VECTOR2I( xmax - xmin + 1, ymax - ymin + 1 ) );
308
309 return ret;
310}
311
312
314{
315 return GetLineLength( m_Start, m_End );
316}
317
318
319void PCB_TRACK::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
320{
321 RotatePoint( m_Start, aRotCentre, aAngle );
322 RotatePoint( m_End, aRotCentre, aAngle );
323}
324
325
326void PCB_ARC::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
327{
328 RotatePoint( m_Start, aRotCentre, aAngle );
329 RotatePoint( m_End, aRotCentre, aAngle );
330 RotatePoint( m_Mid, aRotCentre, aAngle );
331}
332
333
334void PCB_TRACK::Mirror( const VECTOR2I& aCentre, bool aMirrorAroundXAxis )
335{
336 if( aMirrorAroundXAxis )
337 {
338 MIRROR( m_Start.y, aCentre.y );
339 MIRROR( m_End.y, aCentre.y );
340 }
341 else
342 {
343 MIRROR( m_Start.x, aCentre.x );
344 MIRROR( m_End.x, aCentre.x );
345 }
346}
347
348
349void PCB_ARC::Mirror( const VECTOR2I& aCentre, bool aMirrorAroundXAxis )
350{
351 if( aMirrorAroundXAxis )
352 {
353 MIRROR( m_Start.y, aCentre.y );
354 MIRROR( m_End.y, aCentre.y );
355 MIRROR( m_Mid.y, aCentre.y );
356 }
357 else
358 {
359 MIRROR( m_Start.x, aCentre.x );
360 MIRROR( m_End.x, aCentre.x );
361 MIRROR( m_Mid.x, aCentre.x );
362 }
363}
364
365
366void PCB_TRACK::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
367{
368 if( aFlipLeftRight )
369 {
370 m_Start.x = aCentre.x - ( m_Start.x - aCentre.x );
371 m_End.x = aCentre.x - ( m_End.x - aCentre.x );
372 }
373 else
374 {
375 m_Start.y = aCentre.y - ( m_Start.y - aCentre.y );
376 m_End.y = aCentre.y - ( m_End.y - aCentre.y );
377 }
378
379 int copperLayerCount = GetBoard()->GetCopperLayerCount();
380 SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
381}
382
383
384void PCB_ARC::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
385{
386 if( aFlipLeftRight )
387 {
388 m_Start.x = aCentre.x - ( m_Start.x - aCentre.x );
389 m_End.x = aCentre.x - ( m_End.x - aCentre.x );
390 m_Mid.x = aCentre.x - ( m_Mid.x - aCentre.x );
391 }
392 else
393 {
394 m_Start.y = aCentre.y - ( m_Start.y - aCentre.y );
395 m_End.y = aCentre.y - ( m_End.y - aCentre.y );
396 m_Mid.y = aCentre.y - ( m_Mid.y - aCentre.y );
397 }
398
399 int copperLayerCount = GetBoard()->GetCopperLayerCount();
400 SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
401}
402
403
404bool PCB_ARC::IsCCW() const
405{
406 VECTOR2I start_end = m_End - m_Start;
407 VECTOR2I start_mid = m_Mid - m_Start;
408
409 return start_end.Cross( start_mid ) < 0;
410}
411
412
413void PCB_VIA::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
414{
415 if( aFlipLeftRight )
416 {
417 m_Start.x = aCentre.x - ( m_Start.x - aCentre.x );
418 m_End.x = aCentre.x - ( m_End.x - aCentre.x );
419 }
420 else
421 {
422 m_Start.y = aCentre.y - ( m_Start.y - aCentre.y );
423 m_End.y = aCentre.y - ( m_End.y - aCentre.y );
424 }
425
426 if( GetViaType() != VIATYPE::THROUGH )
427 {
428 int copperLayerCount = GetBoard()->GetCopperLayerCount();
429 PCB_LAYER_ID top_layer;
430 PCB_LAYER_ID bottom_layer;
431 LayerPair( &top_layer, &bottom_layer );
432 top_layer = FlipLayer( top_layer, copperLayerCount );
433 bottom_layer = FlipLayer( bottom_layer, copperLayerCount );
434 SetLayerPair( top_layer, bottom_layer );
435 }
436}
437
438
439INSPECT_RESULT PCB_TRACK::Visit( INSPECTOR inspector, void* testData,
440 const std::vector<KICAD_T>& aScanTypes )
441{
442 for( KICAD_T scanType : aScanTypes )
443 {
444 if( scanType == Type() )
445 {
446 if( INSPECT_RESULT::QUIT == inspector( this, testData ) )
447 return INSPECT_RESULT::QUIT;
448 }
449 }
450
451 return INSPECT_RESULT::CONTINUE;
452}
453
454
455std::shared_ptr<SHAPE_SEGMENT> PCB_VIA::GetEffectiveHoleShape() const
456{
457 return std::make_shared<SHAPE_SEGMENT>( SEG( m_Start, m_Start ), m_drill );
458}
459
460
462{
463 if( const BOARD* board = GetBoard() )
464 return board->GetTentVias();
465 else
466 return true;
467}
468
469
471{
472 if( const BOARD* board = GetBoard() )
473 return board->GetDesignSettings().m_SolderMaskExpansion;
474 else
475 return 0;
476}
477
478
479bool PCB_VIA::IsOnLayer( PCB_LAYER_ID aLayer, bool aIncludeCourtyards ) const
480{
481#if 0
482 // Nice and simple, but raises its ugly head in performance profiles....
483 return GetLayerSet().test( aLayer );
484#endif
485
486 if( aLayer >= m_layer && aLayer <= m_bottomLayer )
487 return true;
488
489 if( !IsTented() )
490 {
491 if( aLayer == F_Mask )
492 return IsOnLayer( F_Cu );
493 else if( aLayer == B_Mask )
494 return IsOnLayer( B_Cu );
495 }
496
497 return false;
498}
499
500
502{
503 LSET layermask;
504
505 if( GetViaType() == VIATYPE::THROUGH )
506 layermask = LSET::AllCuMask();
507 else
508 wxASSERT( m_layer <= m_bottomLayer );
509
510 // PCB_LAYER_IDs are numbered from front to back, this is top to bottom.
511 for( int id = m_layer; id <= m_bottomLayer; ++id )
512 layermask.set( id );
513
514 if( !IsTented() )
515 {
516 if( layermask.test( F_Cu ) )
517 layermask.set( F_Mask );
518
519 if( layermask.test( B_Cu ) )
520 layermask.set( B_Mask );
521 }
522
523 return layermask;
524}
525
526
527void PCB_VIA::SetLayerSet( LSET aLayerSet )
528{
529 bool first = true;
530
531 for( PCB_LAYER_ID layer : aLayerSet.Seq() )
532 {
533 if( first )
534 {
535 m_layer = layer;
536 first = false;
537 }
538
539 m_bottomLayer = layer;
540 }
541}
542
543
544void PCB_VIA::SetLayerPair( PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer )
545{
546
547 m_layer = aTopLayer;
548 m_bottomLayer = aBottomLayer;
550}
551
552
554{
555 m_layer = aLayer;
556}
557
558
560{
561 m_bottomLayer = aLayer;
562}
563
564
565void PCB_VIA::LayerPair( PCB_LAYER_ID* top_layer, PCB_LAYER_ID* bottom_layer ) const
566{
567 PCB_LAYER_ID t_layer = F_Cu;
568 PCB_LAYER_ID b_layer = B_Cu;
569
570 if( GetViaType() != VIATYPE::THROUGH )
571 {
572 b_layer = m_bottomLayer;
573 t_layer = m_layer;
574
575 if( b_layer < t_layer )
576 std::swap( b_layer, t_layer );
577 }
578
579 if( top_layer )
580 *top_layer = t_layer;
581
582 if( bottom_layer )
583 *bottom_layer = b_layer;
584}
585
586
588{
589 return m_layer;
590}
591
592
594{
595 return m_bottomLayer;
596}
597
598
600{
601 if( GetViaType() == VIATYPE::THROUGH )
602 {
603 m_layer = F_Cu;
605 }
606
607 if( m_bottomLayer < m_layer )
608 std::swap( m_bottomLayer, m_layer );
609}
610
611
612bool PCB_VIA::FlashLayer( LSET aLayers ) const
613{
614 for( PCB_LAYER_ID layer : aLayers.Seq() )
615 {
616 if( FlashLayer( layer ) )
617 return true;
618 }
619
620 return false;
621}
622
623
624bool PCB_VIA::FlashLayer( int aLayer ) const
625{
626 // Return the "normal" shape if the caller doesn't specify a particular layer
627 if( aLayer == UNDEFINED_LAYER )
628 return true;
629
630 const BOARD* board = GetBoard();
631
632 if( !board )
633 return true;
634
635 if( !IsOnLayer( static_cast<PCB_LAYER_ID>( aLayer ) ) )
636 return false;
637
639 {
640 return true;
641 }
642
643 if( m_keepStartEndLayer && ( aLayer == m_layer || aLayer == m_bottomLayer ) )
644 return true;
645
646 // Must be static to keep from raising its ugly head in performance profiles
647 static std::initializer_list<KICAD_T> connectedTypes = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T,
648 PCB_PAD_T };
649
650 if( m_zoneLayerOverrides[ aLayer ] == ZLO_FORCE_FLASHED )
651 return true;
652 else
653 return board->GetConnectivity()->IsConnectedOnLayer( this, aLayer, connectedTypes );
654}
655
656
657void PCB_TRACK::ViewGetLayers( int aLayers[], int& aCount ) const
658{
659 // Show the track and its netname on different layers
660 aLayers[0] = GetLayer();
661 aLayers[1] = GetNetnameLayer( aLayers[0] );
662 aCount = 2;
663
664 if( IsLocked() )
665 aLayers[ aCount++ ] = LAYER_LOCKED_ITEM_SHADOW;
666}
667
668
669double PCB_TRACK::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
670{
671 constexpr double HIDE = std::numeric_limits<double>::max();
672
673 PCB_PAINTER* painter = static_cast<PCB_PAINTER*>( aView->GetPainter() );
674 PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings();
675
676 if( !aView->IsLayerVisible( LAYER_TRACKS ) )
677 return HIDE;
678
679 if( IsNetnameLayer( aLayer ) )
680 {
682 return HIDE;
683
684 // Hide netnames on dimmed tracks
685 if( renderSettings->GetHighContrast() )
686 {
687 if( m_layer != renderSettings->GetPrimaryHighContrastLayer() )
688 return HIDE;
689 }
690
691 // Pick the approximate size of the netname (square chars)
692 wxString netName = GetUnescapedShortNetname();
693 size_t num_chars = netName.size();
694
695 if( GetLength() < num_chars * GetWidth() )
696 return HIDE;
697
698 // When drawing netnames, clip the track to the viewport
699 VECTOR2I start( GetStart() );
700 VECTOR2I end( GetEnd() );
701 BOX2D viewport = aView->GetViewport();
702 BOX2I clipBox( viewport.GetOrigin(), viewport.GetSize() );
703
704 ClipLine( &clipBox, start.x, start.y, end.x, end.y );
705
706 VECTOR2I line = ( end - start );
707
708 if( line.EuclideanNorm() == 0 )
709 return HIDE;
710
711 // Netnames will be shown only if zoom is appropriate
712 return ( double ) pcbIUScale.mmToIU( 4 ) / ( m_Width + 1 );
713 }
714
715 if( aLayer == LAYER_LOCKED_ITEM_SHADOW )
716 {
717 // Hide shadow if the main layer is not shown
718 if( !aView->IsLayerVisible( m_layer ) )
719 return HIDE;
720
721 // Hide shadow on dimmed tracks
722 if( renderSettings->GetHighContrast() )
723 {
724 if( m_layer != renderSettings->GetPrimaryHighContrastLayer() )
725 return HIDE;
726 }
727 }
728
729 // Other layers are shown without any conditions
730 return 0.0;
731}
732
733
735{
736 BOX2I bbox = GetBoundingBox();
737
738 if( const BOARD* board = GetBoard() )
739 bbox.Inflate( 2 * board->GetDesignSettings().GetBiggestClearanceValue() );
740 else
741 bbox.Inflate( GetWidth() ); // Add a bit extra for safety
742
743 return bbox;
744}
745
746
747void PCB_VIA::ViewGetLayers( int aLayers[], int& aCount ) const
748{
749 aLayers[0] = LAYER_VIA_HOLES;
750 aLayers[1] = LAYER_VIA_HOLEWALLS;
751 aLayers[2] = LAYER_VIA_NETNAMES;
752
753 // Just show it on common via & via holes layers
754 switch( GetViaType() )
755 {
756 case VIATYPE::THROUGH: aLayers[3] = LAYER_VIA_THROUGH; break;
757 case VIATYPE::BLIND_BURIED: aLayers[3] = LAYER_VIA_BBLIND; break;
758 case VIATYPE::MICROVIA: aLayers[3] = LAYER_VIA_MICROVIA; break;
759 default: aLayers[3] = LAYER_GP_OVERLAY; break;
760 }
761
762 aCount = 4;
763
764 if( IsLocked() )
765 aLayers[ aCount++ ] = LAYER_LOCKED_ITEM_SHADOW;
766}
767
768
769double PCB_VIA::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
770{
771 constexpr double HIDE = (double)std::numeric_limits<double>::max();
772
773 PCB_PAINTER* painter = static_cast<PCB_PAINTER*>( aView->GetPainter() );
774 PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings();
775 LSET visible = LSET::AllLayersMask();
776
777 // Meta control for hiding all vias
778 if( !aView->IsLayerVisible( LAYER_VIAS ) )
779 return HIDE;
780
781 // Handle board visibility
782 if( const BOARD* board = GetBoard() )
783 visible = board->GetVisibleLayers() & board->GetEnabledLayers();
784
785 // In high contrast mode don't show vias that don't cross the high-contrast layer
786 if( renderSettings->GetHighContrast() )
787 {
788 PCB_LAYER_ID highContrastLayer = renderSettings->GetPrimaryHighContrastLayer();
789
790 if( LSET::FrontTechMask().Contains( highContrastLayer ) )
791 highContrastLayer = F_Cu;
792 else if( LSET::BackTechMask().Contains( highContrastLayer ) )
793 highContrastLayer = B_Cu;
794
795 if( !GetLayerSet().Contains( highContrastLayer ) )
796 return HIDE;
797 }
798
799 if( IsHoleLayer( aLayer ) )
800 {
801 if( m_viaType == VIATYPE::BLIND_BURIED || m_viaType == VIATYPE::MICROVIA )
802 {
803 // Show a blind or micro via's hole if it crosses a visible layer
804 if( !( visible & GetLayerSet() ).any() )
805 return HIDE;
806 }
807 else
808 {
809 // Show a through via's hole if any physical layer is shown
810 if( !( visible & LSET::PhysicalLayersMask() ).any() )
811 return HIDE;
812 }
813 }
814 else if( IsNetnameLayer( aLayer ) )
815 {
816 if( renderSettings->GetHighContrast() )
817 {
818 // Hide netnames unless via is flashed to a high-contrast layer
819 if( !FlashLayer( renderSettings->GetPrimaryHighContrastLayer() ) )
820 return HIDE;
821 }
822 else
823 {
824 // Hide netnames unless pad is flashed to a visible layer
825 if( !FlashLayer( visible ) )
826 return HIDE;
827 }
828
829 // Netnames will be shown only if zoom is appropriate
830 return m_Width == 0 ? HIDE : ( (double)pcbIUScale.mmToIU( 10 ) / m_Width );
831 }
832
833 // Passed all tests; show.
834 return 0.0;
835}
836
837
839{
840 switch( Type() )
841 {
842 case PCB_ARC_T: return _( "Track (arc)" );
843 case PCB_VIA_T: return _( "Via" );
844 case PCB_TRACE_T:
845 default: return _( "Track" );
846 }
847}
848
849
850void PCB_TRACK::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
851{
852 wxString msg;
853 BOARD* board = GetBoard();
854
855 aList.emplace_back( _( "Type" ), GetFriendlyName() );
856
857 GetMsgPanelInfoBase_Common( aFrame, aList );
858
859 aList.emplace_back( _( "Layer" ), layerMaskDescribe() );
860
861 aList.emplace_back( _( "Width" ), aFrame->MessageTextFromValue( m_Width ) );
862
863 if( Type() == PCB_ARC_T )
864 {
865 double radius = static_cast<PCB_ARC*>( this )->GetRadius();
866 aList.emplace_back( _( "Radius" ), aFrame->MessageTextFromValue( radius ) );
867 }
868
869 aList.emplace_back( _( "Segment Length" ), aFrame->MessageTextFromValue( GetLength() ) );
870
871 // Display full track length (in Pcbnew)
872 if( board && GetNetCode() > 0 )
873 {
874 int count;
875 double trackLen;
876 double lenPadToDie;
877
878 std::tie( count, trackLen, lenPadToDie ) = board->GetTrackLength( *this );
879
880 aList.emplace_back( _( "Routed Length" ), aFrame->MessageTextFromValue( trackLen ) );
881
882 if( lenPadToDie != 0 )
883 {
884 msg = aFrame->MessageTextFromValue( lenPadToDie );
885 aList.emplace_back( _( "Pad To Die Length" ), msg );
886
887 msg = aFrame->MessageTextFromValue( trackLen + lenPadToDie );
888 aList.emplace_back( _( "Full Length" ), msg );
889 }
890 }
891
892 wxString source;
893 int clearance = GetOwnClearance( GetLayer(), &source );
894
895 aList.emplace_back( wxString::Format( _( "Min Clearance: %s" ),
896 aFrame->MessageTextFromValue( clearance ) ),
897 wxString::Format( _( "(from %s)" ), source ) );
898
899 MINOPTMAX<int> c = GetWidthConstraint( &source );
900
901 if( c.HasMax() )
902 {
903 aList.emplace_back( wxString::Format( _( "Width Constraints: min %s, max %s" ),
904 aFrame->MessageTextFromValue( c.Min() ),
905 aFrame->MessageTextFromValue( c.Max() ) ),
906 wxString::Format( _( "(from %s)" ), source ) );
907 }
908 else
909 {
910 aList.emplace_back( wxString::Format( _( "Width Constraints: min %s" ),
911 aFrame->MessageTextFromValue( c.Min() ) ),
912 wxString::Format( _( "(from %s)" ), source ) );
913 }
914}
915
916
917void PCB_VIA::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
918{
919 wxString msg;
920
921 switch( GetViaType() )
922 {
923 case VIATYPE::MICROVIA: msg = _( "Micro Via" ); break;
924 case VIATYPE::BLIND_BURIED: msg = _( "Blind/Buried Via" ); break;
925 case VIATYPE::THROUGH: msg = _( "Through Via" ); break;
926 default: msg = _( "Via" ); break;
927 }
928
929 aList.emplace_back( _( "Type" ), msg );
930
931 GetMsgPanelInfoBase_Common( aFrame, aList );
932
933 aList.emplace_back( _( "Layer" ), layerMaskDescribe() );
934 aList.emplace_back( _( "Diameter" ), aFrame->MessageTextFromValue( m_Width ) );
935 aList.emplace_back( _( "Hole" ), aFrame->MessageTextFromValue( GetDrillValue() ) );
936
937 wxString source;
938 int clearance = GetOwnClearance( GetLayer(), &source );
939
940 aList.emplace_back( wxString::Format( _( "Min Clearance: %s" ),
941 aFrame->MessageTextFromValue( clearance ) ),
942 wxString::Format( _( "(from %s)" ), source ) );
943
944 int minAnnulus = GetMinAnnulus( GetLayer(), &source );
945
946 aList.emplace_back( wxString::Format( _( "Min Annular Width: %s" ),
947 aFrame->MessageTextFromValue( minAnnulus ) ),
948 wxString::Format( _( "(from %s)" ), source ) );
949}
950
951
953 std::vector<MSG_PANEL_ITEM>& aList ) const
954{
955 aList.emplace_back( _( "Net" ), UnescapeString( GetNetname() ) );
956
957 aList.emplace_back( _( "Resolved Netclass" ),
958 UnescapeString( GetEffectiveNetClass()->GetName() ) );
959
960#if 0 // Enable for debugging
961 if( GetBoard() )
962 aList.emplace_back( _( "NetCode" ), wxString::Format( wxT( "%d" ), GetNetCode() ) );
963
964 aList.emplace_back( wxT( "Flags" ), wxString::Format( wxT( "0x%08X" ), m_flags ) );
965
966 aList.emplace_back( wxT( "Start pos" ), wxString::Format( wxT( "%d %d" ),
967 m_Start.x,
968 m_Start.y ) );
969 aList.emplace_back( wxT( "End pos" ), wxString::Format( wxT( "%d %d" ),
970 m_End.x,
971 m_End.y ) );
972#endif
973
974 if( aFrame->GetName() == PCB_EDIT_FRAME_NAME && IsLocked() )
975 aList.emplace_back( _( "Status" ), _( "Locked" ) );
976}
977
978
980{
981 const BOARD* board = GetBoard();
982 PCB_LAYER_ID top_layer;
983 PCB_LAYER_ID bottom_layer;
984
985 LayerPair( &top_layer, &bottom_layer );
986
987 return board->GetLayerName( top_layer ) + wxT( " - " ) + board->GetLayerName( bottom_layer );
988}
989
990
991bool PCB_TRACK::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
992{
993 return TestSegmentHit( aPosition, m_Start, m_End, aAccuracy + ( m_Width / 2 ) );
994}
995
996
997bool PCB_ARC::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
998{
999 int max_dist = aAccuracy + ( m_Width / 2 );
1000
1001 // Short-circuit common cases where the arc is connected to a track or via at an endpoint
1002 if( EuclideanNorm( GetStart() - aPosition ) <= max_dist ||
1003 EuclideanNorm( GetEnd() - aPosition ) <= max_dist )
1004 {
1005 return true;
1006 }
1007
1008 VECTOR2I center = GetPosition();
1009 VECTOR2I relpos = aPosition - center;
1010 double dist = EuclideanNorm( relpos );
1011 double radius = GetRadius();
1012
1013 if( std::abs( dist - radius ) > max_dist )
1014 return false;
1015
1016 EDA_ANGLE arc_angle = GetAngle();
1017 EDA_ANGLE arc_angle_start = GetArcAngleStart(); // Always 0.0 ... 360 deg
1018 EDA_ANGLE arc_hittest( relpos );
1019
1020 // Calculate relative angle between the starting point of the arc, and the test point
1021 arc_hittest -= arc_angle_start;
1022
1023 // Normalise arc_hittest between 0 ... 360 deg
1024 arc_hittest.Normalize();
1025
1026 if( arc_angle < ANGLE_0 )
1027 return arc_hittest >= ANGLE_360 + arc_angle;
1028
1029 return arc_hittest <= arc_angle;
1030}
1031
1032
1033bool PCB_VIA::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1034{
1035 int max_dist = aAccuracy + ( m_Width / 2 );
1036
1037 // rel_pos is aPosition relative to m_Start (or the center of the via)
1038 VECTOR2I rel_pos = aPosition - m_Start;
1039 double dist = (double) rel_pos.x * rel_pos.x + (double) rel_pos.y * rel_pos.y;
1040 return dist <= (double) max_dist * max_dist;
1041}
1042
1043
1044bool PCB_TRACK::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1045{
1046 BOX2I arect = aRect;
1047 arect.Inflate( aAccuracy );
1048
1049 if( aContained )
1050 return arect.Contains( GetStart() ) && arect.Contains( GetEnd() );
1051 else
1052 return arect.Intersects( GetStart(), GetEnd() );
1053}
1054
1055
1056bool PCB_ARC::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1057{
1058 BOX2I arect = aRect;
1059 arect.Inflate( aAccuracy );
1060
1061 BOX2I box( GetStart() );
1062 box.Merge( GetMid() );
1063 box.Merge( GetEnd() );
1064
1065 box.Inflate( GetWidth() / 2 );
1066
1067 if( aContained )
1068 return arect.Contains( box );
1069 else
1070 return arect.Intersects( box );
1071}
1072
1073
1074bool PCB_VIA::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1075{
1076 BOX2I arect = aRect;
1077 arect.Inflate( aAccuracy );
1078
1079 BOX2I box( GetStart() );
1080 box.Inflate( GetWidth() / 2 );
1081
1082 if( aContained )
1083 return arect.Contains( box );
1084 else
1085 return arect.IntersectsCircle( GetStart(), GetWidth() / 2 );
1086}
1087
1088
1089wxString PCB_TRACK::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
1090{
1091 return wxString::Format( Type() == PCB_ARC_T ? _("Track (arc) %s on %s, length %s" )
1092 : _("Track %s on %s, length %s" ),
1093 GetNetnameMsg(),
1094 GetLayerName(),
1095 aUnitsProvider->MessageTextFromValue( GetLength() ) );
1096}
1097
1098
1100{
1101 return BITMAPS::add_tracks;
1102}
1103
1105{
1106 assert( aImage->Type() == PCB_TRACE_T );
1107
1108 std::swap( *((PCB_TRACK*) this), *((PCB_TRACK*) aImage) );
1109}
1110
1112{
1113 assert( aImage->Type() == PCB_ARC_T );
1114
1115 std::swap( *this, *static_cast<PCB_ARC*>( aImage ) );
1116}
1117
1119{
1120 assert( aImage->Type() == PCB_VIA_T );
1121
1122 std::swap( *((PCB_VIA*) this), *((PCB_VIA*) aImage) );
1123}
1124
1125
1127{
1129 return center;
1130}
1131
1132
1134{
1135 auto center = CalcArcCenter( m_Start, m_Mid , m_End );
1136 return GetLineLength( center, m_Start );
1137}
1138
1139
1141{
1142 VECTOR2I center = GetPosition();
1143 EDA_ANGLE angle1 = EDA_ANGLE( m_Mid - center ) - EDA_ANGLE( m_Start - center );
1144 EDA_ANGLE angle2 = EDA_ANGLE( m_End - center ) - EDA_ANGLE( m_Mid - center );
1145
1146 return angle1.Normalize180() + angle2.Normalize180();
1147}
1148
1149
1151{
1152 EDA_ANGLE angleStart( m_Start - GetPosition() );
1153 return angleStart.Normalize();
1154}
1155
1156
1157// Note: used in python tests. Ignore CLion's claim that it's unused....
1159{
1160 EDA_ANGLE angleEnd( m_End - GetPosition() );
1161 return angleEnd.Normalize();
1162}
1163
1164
1166{
1167 if( a->GetNetCode() != b->GetNetCode() )
1168 return a->GetNetCode() < b->GetNetCode();
1169
1170 if( a->GetLayer() != b->GetLayer() )
1171 return a->GetLayer() < b->GetLayer();
1172
1173 if( a->Type() != b->Type() )
1174 return a->Type() < b->Type();
1175
1176 if( a->m_Uuid != b->m_Uuid )
1177 return a->m_Uuid < b->m_Uuid;
1178
1179 return a < b;
1180}
1181
1182
1183std::shared_ptr<SHAPE> PCB_TRACK::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
1184{
1185 return std::make_shared<SHAPE_SEGMENT>( m_Start, m_End, m_Width );
1186}
1187
1188
1189std::shared_ptr<SHAPE> PCB_VIA::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
1190{
1191 if( aFlash == FLASHING::ALWAYS_FLASHED
1192 || ( aFlash == FLASHING::DEFAULT && FlashLayer( aLayer ) ) )
1193 {
1194 return std::make_shared<SHAPE_CIRCLE>( m_Start, m_Width / 2 );
1195 }
1196 else
1197 {
1198 return std::make_shared<SHAPE_CIRCLE>( m_Start, GetDrillValue() / 2 );
1199 }
1200}
1201
1202
1203std::shared_ptr<SHAPE> PCB_ARC::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
1204{
1205 return std::make_shared<SHAPE_ARC>( GetStart(), GetMid(), GetEnd(), GetWidth() );
1206}
1207
1208
1210 int aClearance, int aError, ERROR_LOC aErrorLoc,
1211 bool ignoreLineWidth ) const
1212{
1213 wxASSERT_MSG( !ignoreLineWidth, wxT( "IgnoreLineWidth has no meaning for tracks." ) );
1214
1215
1216 switch( Type() )
1217 {
1218 case PCB_VIA_T:
1219 {
1220 int radius = ( m_Width / 2 ) + aClearance;
1221 TransformCircleToPolygon( aBuffer, m_Start, radius, aError, aErrorLoc );
1222 break;
1223 }
1224
1225 case PCB_ARC_T:
1226 {
1227 const PCB_ARC* arc = static_cast<const PCB_ARC*>( this );
1228 int width = m_Width + ( 2 * aClearance );
1229
1230 TransformArcToPolygon( aBuffer, arc->GetStart(), arc->GetMid(), arc->GetEnd(), width,
1231 aError, aErrorLoc );
1232 break;
1233 }
1234
1235 default:
1236 {
1237 int width = m_Width + ( 2 * aClearance );
1238
1239 TransformOvalToPolygon( aBuffer, m_Start, m_End, width, aError, aErrorLoc );
1240 break;
1241 }
1242 }
1243}
1244
1245
1246static struct TRACK_VIA_DESC
1247{
1249 {
1251 .Undefined( VIATYPE::NOT_DEFINED )
1252 .Map( VIATYPE::THROUGH, _HKI( "Through" ) )
1253 .Map( VIATYPE::BLIND_BURIED, _HKI( "Blind/buried" ) )
1254 .Map( VIATYPE::MICROVIA, _HKI( "Micro" ) );
1255
1257
1258 if( layerEnum.Choices().GetCount() == 0 )
1259 {
1260 layerEnum.Undefined( UNDEFINED_LAYER );
1261
1262 for( LSEQ seq = LSET::AllLayersMask().Seq(); seq; ++seq )
1263 layerEnum.Map( *seq, LSET::Name( *seq ) );
1264 }
1265
1267
1268 // Track
1271
1272 propMgr.AddProperty( new PROPERTY<PCB_TRACK, int>( _HKI( "Width" ),
1273 &PCB_TRACK::SetWidth, &PCB_TRACK::GetWidth, PROPERTY_DISPLAY::PT_SIZE ) );
1274 propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Position X" ),
1276 &PCB_TRACK::SetX, &PCB_TRACK::GetX, PROPERTY_DISPLAY::PT_COORD,
1278 propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Position Y" ),
1280 &PCB_TRACK::SetY, &PCB_TRACK::GetY, PROPERTY_DISPLAY::PT_COORD,
1282 propMgr.AddProperty( new PROPERTY<PCB_TRACK, int>( _HKI( "End X" ),
1283 &PCB_TRACK::SetEndX, &PCB_TRACK::GetEndX, PROPERTY_DISPLAY::PT_COORD,
1285 propMgr.AddProperty( new PROPERTY<PCB_TRACK, int>( _HKI( "End Y" ),
1286 &PCB_TRACK::SetEndY, &PCB_TRACK::GetEndY, PROPERTY_DISPLAY::PT_COORD,
1288
1289 // Arc
1292
1293 // Via
1296
1297 // TODO test drill, use getdrillvalue?
1298 const wxString groupVia = _HKI( "Via Properties" );
1299
1300 propMgr.Mask( TYPE_HASH( PCB_VIA ), TYPE_HASH( BOARD_CONNECTED_ITEM ), _HKI( "Layer" ) );
1301
1302 propMgr.ReplaceProperty( TYPE_HASH( PCB_TRACK ), _HKI( "Width" ),
1303 new PROPERTY<PCB_VIA, int, PCB_TRACK>( _HKI( "Diameter" ),
1304 &PCB_VIA::SetWidth, &PCB_VIA::GetWidth, PROPERTY_DISPLAY::PT_SIZE ) );
1305 propMgr.AddProperty( new PROPERTY<PCB_VIA, int>( _HKI( "Hole" ),
1306 &PCB_VIA::SetDrill, &PCB_VIA::GetDrillValue, PROPERTY_DISPLAY::PT_SIZE ), groupVia );
1307 propMgr.ReplaceProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Layer" ),
1309 &PCB_VIA::SetLayer, &PCB_VIA::GetLayer ), groupVia );
1310 propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, PCB_LAYER_ID>( _HKI( "Layer Bottom" ),
1312 propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, VIATYPE>( _HKI( "Via Type" ),
1314 }
1316
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
@ ZLO_NONE
Definition: board_item.h:59
@ ZLO_FORCE_FLASHED
Definition: board_item.h:60
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.
virtual int GetOwnClearance(PCB_LAYER_ID aLayer, wxString *aSource=nullptr) const
Return an item's "own" clearance in internal units.
wxString GetUnescapedShortNetname() const
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:71
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:196
int GetY() const
Definition: board_item.h:95
PCB_LAYER_ID m_layer
Definition: board_item.h:345
int GetX() const
Definition: board_item.h:89
void SetX(int aX)
Definition: board_item.h:111
void SetY(int aY)
Definition: board_item.h:117
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:230
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:44
virtual bool IsLocked() const
Definition: board_item.cpp:72
virtual wxString layerMaskDescribe() const
Return a string (to be shown to the user) describing a layer mask.
Definition: board_item.cpp:107
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Definition: board_item.cpp:95
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:270
int GetCopperLayerCount() const
Definition: board.cpp:587
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:498
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:1835
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:728
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:432
const Vec & GetOrigin() const
Definition: box2.h:184
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:270
coord_type GetTop() const
Definition: box2.h:195
bool IntersectsCircle(const Vec &aCenter, const int aRadius) const
Definition: box2.h:453
bool Contains(const Vec &aPoint) const
Definition: box2.h:142
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:507
coord_type GetRight() const
Definition: box2.h:190
coord_type GetLeft() const
Definition: box2.h:194
const Vec & GetSize() const
Definition: box2.h:180
coord_type GetBottom() const
Definition: box2.h:191
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:589
wxString GetName() const
Definition: drc_rule.h:149
MINOPTMAX< int > & Value()
Definition: drc_rule.h:142
EDA_ANGLE Normalize()
Definition: eda_angle.h:249
EDA_ANGLE Normalize180()
Definition: eda_angle.h:288
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:85
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Assign the members of aItem to another object.
Definition: eda_item.cpp:239
const KIID m_Uuid
Definition: eda_item.h:475
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:480
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition: property.h:633
static ENUM_MAP< T > & Instance()
Definition: property.h:627
ENUM_MAP & Undefined(T aValue)
Definition: property.h:640
wxPGChoices & Choices()
Definition: property.h:676
Contains methods for drawing PCB-specific items.
Definition: pcb_painter.h:156
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:161
PCB specific render settings.
Definition: pcb_painter.h:70
PCB_LAYER_ID GetPrimaryHighContrastLayer() const
Return the board layer which is in high-contrast mode.
bool GetHighContrast() const
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:69
BOX2D GetViewport() const
Return the current viewport visible area rectangle.
Definition: view.cpp:508
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:410
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:213
Definition: kiid.h:48
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
Definition: layer_ids.h:497
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:536
static LSET AllLayersMask()
Definition: lset.cpp:808
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:411
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:773
static LSET PhysicalLayersMask()
Return a mask holding all layers which are physically realized.
Definition: lset.cpp:870
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:82
static LSET FrontTechMask()
Return a mask holding all technical layers (no CU layer) on front side.
Definition: lset.cpp:827
static LSET BackTechMask()
Return a mask holding all technical layers (no CU layer) on back side.
Definition: lset.cpp:815
T Min() const
Definition: minoptmax.h:33
bool HasMax() const
Definition: minoptmax.h:38
bool HasMin() const
Definition: minoptmax.h:37
T Max() const
Definition: minoptmax.h:34
A collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:47
int GetViaDrill() const
Definition: netclass.h:84
int GetuViaDrill() const
Definition: netclass.h:92
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:387
virtual VECTOR2I GetPosition() const override
Definition: pcb_track.cpp:1126
virtual void swapData(BOARD_ITEM *aImage) override
Definition: pcb_track.cpp:1111
bool IsCCW() const
Definition: pcb_track.cpp:404
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: pcb_track.cpp:76
EDA_ANGLE GetArcAngleStart() const
Definition: pcb_track.cpp:1150
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:997
EDA_ANGLE GetArcAngleEnd() const
Definition: pcb_track.cpp:1158
double GetRadius() const
Definition: pcb_track.cpp:1133
EDA_ANGLE GetAngle() const
Definition: pcb_track.cpp:1140
const VECTOR2I & GetMid() const
Definition: pcb_track.h:315
PCB_ARC(BOARD_ITEM *aParent)
Definition: pcb_track.h:290
void Flip(const VECTOR2I &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
Definition: pcb_track.cpp:384
VECTOR2I m_Mid
Arc mid point, halfway between start and end.
Definition: pcb_track.h:359
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
Definition: pcb_track.cpp:326
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:1203
void Mirror(const VECTOR2I &aCentre, bool aMirrorAroundXAxis) override
Definition: pcb_track.cpp:349
double m_CachedScale
Last zoom scale used to draw this track's net.
Definition: pcb_track.h:283
double m_CachedLOD
Last LOD used to draw this track's net.
Definition: pcb_track.h:282
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
Definition: pcb_track.cpp:319
virtual void ViewGetLayers(int aLayers[], int &aCount) const override
Return the all the layers within the VIEW the object is painted on.
Definition: pcb_track.cpp:657
int GetLocalClearance(wxString *aSource) const override
Return any local clearance overrides set in the "classic" (ie: pre-rule) system.
Definition: pcb_track.cpp:164
void SetEndY(int aY)
Definition: pcb_track.h:116
void SetWidth(int aWidth)
Definition: pcb_track.h:106
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: pcb_track.cpp:669
virtual double GetLength() const
Get the length of the track using the hypotenuse calculation.
Definition: pcb_track.cpp:313
int GetWidth() const
Definition: pcb_track.h:107
virtual void swapData(BOARD_ITEM *aImage) override
Definition: pcb_track.cpp:1104
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const override
Return a user-visible description string of this item.
Definition: pcb_track.cpp:1089
const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
Definition: pcb_track.cpp:734
int GetEndX() const
Definition: pcb_track.h:118
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:439
bool ApproxCollinear(const PCB_TRACK &aTrack)
Definition: pcb_track.cpp:156
VECTOR2I m_End
Line end point.
Definition: pcb_track.h:280
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:850
virtual EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: pcb_track.cpp:61
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: pcb_track.cpp:267
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:1209
const VECTOR2I & GetStart() const
Definition: pcb_track.h:113
VECTOR2I m_Start
Line start point.
Definition: pcb_track.h:279
int GetEndY() const
Definition: pcb_track.h:119
wxString GetFriendlyName() const override
Definition: pcb_track.cpp:838
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: pcb_track.cpp:1099
void Flip(const VECTOR2I &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
Definition: pcb_track.cpp:366
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:991
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:1183
const VECTOR2I & GetEnd() const
Definition: pcb_track.h:110
PCB_TRACK(BOARD_ITEM *aParent, KICAD_T idtype=PCB_TRACE_T)
Definition: pcb_track.cpp:52
int m_Width
Thickness of track, or via diameter.
Definition: pcb_track.h:278
MINOPTMAX< int > GetWidthConstraint(wxString *aSource=nullptr) const
Definition: pcb_track.cpp:171
void SetEndX(int aX)
Definition: pcb_track.h:115
virtual void Mirror(const VECTOR2I &aCentre, bool aMirrorAroundXAxis)
Definition: pcb_track.cpp:334
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:235
void GetMsgPanelInfoBase_Common(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) const
Definition: pcb_track.cpp:952
bool IsTented() const override
Definition: pcb_track.cpp:461
PCB_LAYER_ID BottomLayer() const
Definition: pcb_track.cpp:593
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: pcb_track.cpp:150
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:1189
bool FlashLayer(int aLayer) const
Check to see whether the via should have a pad on the specific layer.
Definition: pcb_track.cpp:624
void SetDrillDefault()
Set the drill value for vias to the default value UNDEFINED_DRILL_DIAMETER.
Definition: pcb_track.h:537
PCB_LAYER_ID m_bottomLayer
The bottom layer of the via (the top layer is in m_layer)
Definition: pcb_track.h:576
bool m_isFree
"Free" vias don't get their nets auto-updated
Definition: pcb_track.h:584
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:1033
virtual void SetLayerSet(LSET aLayers) override
Definition: pcb_track.cpp:527
void SetBottomLayer(PCB_LAYER_ID aLayer)
Definition: pcb_track.cpp:559
std::array< ZONE_LAYER_OVERRIDE, MAX_CU_LAYERS > m_zoneLayerOverrides
Definition: pcb_track.h:587
int GetSolderMaskExpansion() const
Definition: pcb_track.cpp:470
void SetDrill(int aDrill)
Set the drill value for vias.
Definition: pcb_track.h:518
bool IsOnLayer(PCB_LAYER_ID aLayer, bool aIncludeCourtyards=false) const override
Test to see if this object is on the given layer.
Definition: pcb_track.cpp:479
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:917
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: pcb_track.cpp:129
int m_drill
for vias: via drill (- 1 for default value)
Definition: pcb_track.h:580
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: pcb_track.cpp:769
void SetTopLayer(PCB_LAYER_ID aLayer)
Definition: pcb_track.cpp:553
std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const override
Definition: pcb_track.cpp:455
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:544
bool m_removeUnconnectedLayer
Remove annular rings on unconnected layers.
Definition: pcb_track.h:582
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the all the layers within the VIEW the object is painted on.
Definition: pcb_track.cpp:747
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:599
PCB_VIA & operator=(const PCB_VIA &aOther)
Definition: pcb_track.cpp:108
void swapData(BOARD_ITEM *aImage) override
Definition: pcb_track.cpp:1118
PCB_VIA(BOARD_ITEM *aParent)
Definition: pcb_track.cpp:82
wxString layerMaskDescribe() const override
Return a string (to be shown to the user) describing a layer mask.
Definition: pcb_track.cpp:979
void SetViaType(VIATYPE aViaType)
Definition: pcb_track.h:395
int GetMinAnnulus(PCB_LAYER_ID aLayer, wxString *aSource) const
Definition: pcb_track.cpp:189
PCB_LAYER_ID TopLayer() const
Definition: pcb_track.cpp:587
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const override
Return a user-visible description string of this item.
Definition: pcb_track.cpp:135
VIATYPE m_viaType
through, blind/buried or micro
Definition: pcb_track.h:578
bool m_keepStartEndLayer
Keep the start and end annular rings.
Definition: pcb_track.h:583
int GetDrillValue() const
Calculate the drill value for vias (m-Drill if > 0, or default drill value for the board.
Definition: pcb_track.cpp:220
VIATYPE GetViaType() const
Definition: pcb_track.h:394
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: pcb_track.cpp:501
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:565
void Flip(const VECTOR2I &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
Definition: pcb_track.cpp:413
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:74
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
void Mask(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName)
Sets a base class property as masked in a derived class.
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:76
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
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
bool ApproxCollinear(const SEG &aSeg, int aDistanceThreshold=1) const
Definition: seg.cpp:392
const VECTOR2I & GetArcMid() const
Definition: shape_arc.h:114
const VECTOR2I & GetP1() const
Definition: shape_arc.h:113
const VECTOR2I & GetP0() const
Definition: shape_arc.h:112
Represent a set of closed polygons.
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
A lower-precision version of StringFromValue().
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:265
extended_type Cross(const VECTOR2< T > &aVector) const
Compute cross product of self with aVector.
Definition: vector2d.h:457
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:57
@ TRACK_WIDTH_CONSTRAINT
Definition: drc_rule.h:56
#define _(s)
static constexpr EDA_ANGLE & ANGLE_360
Definition: eda_angle.h:435
static constexpr EDA_ANGLE & ANGLE_0
Definition: eda_angle.h:429
#define PCB_EDIT_FRAME_NAME
INSPECT_RESULT
Definition: eda_item.h:42
const INSPECTOR_FUNC & INSPECTOR
Definition: eda_item.h:78
#define ENDPOINT
ends. (Used to support dragging.)
std::uint32_t EDA_ITEM_FLAGS
#define STARTPOINT
When a line is selected, these flags indicate which.
static std::vector< KICAD_T > connectedTypes
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
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.
@ LAYER_VIA_NETNAMES
Definition: layer_ids.h:168
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
Definition: layer_ids.h:147
int GetNetnameLayer(int aLayer)
Returns a netname layer corresponding to the given layer.
Definition: layer_ids.h:972
@ LAYER_LOCKED_ITEM_SHADOW
shadow layer for locked items
Definition: layer_ids.h:239
@ LAYER_VIA_HOLEWALLS
Definition: layer_ids.h:234
@ LAYER_GP_OVERLAY
general purpose overlay
Definition: layer_ids.h:218
@ LAYER_TRACKS
Definition: layer_ids.h:212
@ LAYER_VIA_HOLES
to draw via holes (pad holes do not use this layer)
Definition: layer_ids.h:215
@ LAYER_VIA_MICROVIA
to draw micro vias
Definition: layer_ids.h:194
@ LAYER_VIA_THROUGH
to draw usual through hole vias
Definition: layer_ids.h:196
@ LAYER_VIAS
Meta control for all vias opacity/visibility.
Definition: layer_ids.h:193
@ LAYER_VIA_BBLIND
to draw blind/buried vias
Definition: layer_ids.h:195
bool IsNetnameLayer(int aLayer)
Test whether a layer is a netname layer.
Definition: layer_ids.h:995
bool IsHoleLayer(int aLayer)
Definition: layer_ids.h:870
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
@ B_Mask
Definition: layer_ids.h:106
@ B_Cu
Definition: layer_ids.h:95
@ F_Mask
Definition: layer_ids.h:107
@ UNDEFINED_LAYER
Definition: layer_ids.h:60
@ F_Cu
Definition: layer_ids.h:64
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition: lset.cpp:544
void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:40
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:418
static struct TRACK_VIA_DESC _TRACK_VIA_DESC
VIATYPE
Definition: pcb_track.h:64
#define TYPE_HASH(x)
Definition: property.h:63
#define ENUM_TO_WXANY(type)
Macro to define read-only fields (no setter method available)
Definition: property.h:729
#define REGISTER_TYPE(x)
Definition: property_mgr.h:328
wxString UnescapeString(const wxString &aSource)
constexpr int mmToIU(double mm) const
Definition: base_units.h:89
bool operator()(const PCB_TRACK *aFirst, const PCB_TRACK *aSecond) const
Definition: pcb_track.cpp:1165
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:129
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Definition: trigo.cpp:183
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:458
double GetLineLength(const VECTOR2I &aPointA, const VECTOR2I &aPointB)
Return the length of a line segment defined by aPointA and aPointB.
Definition: trigo.h:188
double EuclideanNorm(const VECTOR2I &vector)
Definition: trigo.h:129
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:93
@ 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:94
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:92
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:85
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588