45#include <wx/choicdlg.h>
90 wxString
name = aName;
123 return bci->GetNetCode();
137 bci->SetNetCode( aNet );
151 return present( aStart ) && present( aEnd ) && aStart != aEnd;
160 m_hops->Move( aMoveVector );
169 m_hops->Rotate( aAngle, aRotCentre );
178 m_hops->Mirror( aCentre, aFlipDirection );
190 m_hops->Mirror( aCentre, aFlipDirection );
197 aCommit->
Add( aItem );
207 std::vector<BOARD_ITEM*> members;
213 std::vector<PCB_LAYER_ID> layers;
216 layers.push_back( layer );
218 if( layers.size() < 2 )
221 const int nHops = (int) layers.size() - 1;
241 auto hopPos = [&](
int aIndex ) ->
VECTOR2I
246 return m_hops->CPoint( aIndex );
250 int last =
m_hops->PointCount() - 1;
254 return m_hops->CPoint( last ) + step * ( aIndex - last );
264 for(
int i = 0; i < nHops; ++i )
267 via->SetNetCode( aNetCode );
269 via->SetLayerPair( layers[i], layers[i + 1] );
271 via->SetDrill( viaDrill );
272 via->SetPosition( hopPos( i ) );
280 via->Padstack().Drill().is_filled = filled;
281 via->Padstack().Drill().is_capped = capped;
283 members.push_back(
via );
295 for(
int i = 0; i < nHops - 1; ++i )
310 members.push_back( trace );
325 return std::make_tuple( (
int)
PCB_VIA_T, (
int)
via->TopLayer(), (
int)
via->BottomLayer() );
337 if( aRebuilt.empty() || aRebuilt.size() !=
GetItems().size() )
340 std::map<std::tuple<int, int, int>,
BOARD_ITEM*> live;
344 std::optional<std::tuple<int, int, int>> key =
memberKey( item );
346 if( !key || !live.emplace( *key, item ).second )
350 std::vector<std::pair<BOARD_ITEM*, BOARD_ITEM*>> matched;
354 std::optional<std::tuple<int, int, int>> key =
memberKey( fresh );
359 auto it = live.find( *key );
361 if( it == live.end() )
364 matched.emplace_back( it->second, fresh );
368 for(
const auto& [item, fresh] : matched )
404 std::vector<BOARD_ITEM*> rebuilt =
BuildMembers( aBoard, net );
449 aCommit->
Add(
this );
467 if( !aBoard || !aCommit )
506 for(
PAD*
pad : footprint->Pads() )
512 if(
pad->IsOnLayer( aLayer ) &&
pad->HitTest( aPosition ) )
513 return pad->GetNetCode();
519 if( track->IsOnLayer( aLayer ) && track->HitTest( aPosition ) )
520 return track->GetNetCode();
525 if( !zone->GetIsRuleArea() && zone->IsOnLayer( aLayer ) && zone->HitTestFilledArea( aLayer, aPosition ) )
527 return zone->GetNetCode();
582static void layerOrder(
BOARD* aBoard, std::vector<PCB_LAYER_ID>& aOrder, std::map<int, int>& aOrdinals )
588 aOrder.push_back( layer );
589 aOrdinals[layer] = n++;
595 std::vector<BOARD_ITEM*>* aMembers )
597 std::vector<PCB_VIA*> vias;
598 std::vector<PCB_TRACK*> traces;
612 if( !vias.empty() &&
via->GetNetCode() != vias.front()->GetNetCode() )
615 vias.push_back(
via );
619 traces.push_back(
static_cast<PCB_TRACK*
>( item ) );
627 if( vias.size() < 2 )
630 std::vector<PCB_LAYER_ID> order;
631 std::map<int, int> ordinals;
635 std::map<int, PCB_VIA*> hopByUpper;
639 auto top = ordinals.find(
via->TopLayer() );
640 auto bot = ordinals.find(
via->BottomLayer() );
642 if(
top == ordinals.end() || bot == ordinals.end() )
648 int upper = std::min(
top->second, bot->second );
650 if( hopByUpper.count( upper ) )
653 hopByUpper[upper] =
via;
656 int first = hopByUpper.begin()->first;
657 int last = hopByUpper.rbegin()->first;
659 if( (
int) hopByUpper.size() != last - first + 1 )
662 PCB_VIA* topVia = hopByUpper.begin()->second;
687 capped = capped ||
via->Padstack().Drill().is_capped.value_or(
false );
704 for(
const auto& [upper,
via] : hopByUpper )
715 std::set<int> landing;
716 std::set<VECTOR2I> viaPositions;
718 for(
int i = first + 1; i <= last; ++i )
719 landing.insert( order[i] );
722 viaPositions.insert(
via->GetPosition() );
725 aMembers->push_back(
via );
729 if( landing.count( trace->GetLayer() ) && trace->GetStart() != trace->GetEnd()
730 && trace->GetNetCode() == stack->
GetNetCode() && viaPositions.count( trace->GetStart() )
731 && viaPositions.count( trace->GetEnd() ) )
733 aMembers->push_back( trace );
751 if(
top == aOrdinals.end() || bot == aOrdinals.end() )
760 std::vector<PCB_LAYER_ID> order;
761 std::map<int, int> ordinals;
769 ids.insert( track->m_Uuid );
779 std::vector<PCB_LAYER_ID> order;
780 std::map<int, int> ordinals;
783 std::vector<std::pair<PCB_VIA*, const VIA_STACK_PRESET*>> candidates;
799 preset = aMatcher(
via );
805 candidates.push_back( {
via, preset } );
808 for(
const auto& [
via, preset] : candidates )
812 via->LayerPair( &
top, &bottom );
831 aCommit->
Add( stack );
843 return (
int) candidates.size();
872 for(
int i = 1; i <
m_hops->PointCount(); ++i )
879 rescaled.
Append( rescaled.
CPoint( i - 1 ) + dir,
true );
936 if( aProps.
get_to(
"start_layer", layerName ) )
939 if( aProps.
get_to(
"end_layer", layerName ) )
944 if( aProps.
get_to(
"style", style ) )
993 const std::vector<VIA_STACK_PRESET>& presets =
board->GetDesignSettings().m_ViaStackPresets;
994 int idx =
board->GetDesignSettings().GetViaStackIndex();
996 if( !presets.empty() )
998 settings.
ApplyPreset( presets[std::clamp( idx, 0, (
int) presets.size() - 1 )] );
1023 m_frame->ShowInfoBarError(
_(
"The microvia stack layers are not present on this board." ) );
1028 std::vector<PCB_LAYER_ID> spanLayers;
1032 spanLayers.push_back( layer );
1037 spanSet.
set( layer );
1039 int nHops = (int) spanLayers.size() - 1;
1042 if( staggered && settings.
GetPitch() <= 0 )
1056 std::vector<BOARD_ITEM*> previewItems;
1057 std::vector<VECTOR2I> hops;
1059 bool resumeRouting =
false;
1065 hops.push_back( seedPos );
1069 auto clearPreview = [&]()
1076 previewItems.clear();
1081 std::shared_ptr<DRC_ENGINE> drcEngine =
board->GetDesignSettings().m_DRCEngine;
1082 int drcEpsilon =
board->GetDesignSettings().GetDRCEpsilon();
1084 bool allowDRCViolations =
false;
1087 allowDRCViolations = router->Router()->Settings().AllowDRCViolations();
1089 auto updatePreview = [&](
const VECTOR2I& aCursor )
1098 chain.Append( p,
true );
1100 chain.Append( aCursor,
true );
1102 settings.
SetPosition( hops.empty() ? aCursor : hops.front() );
1106 int previewHops = std::min( (
int) hops.size() + 1, nHops );
1117 preview.
Add( item );
1119 m_view->Update( &preview );
1122 auto placeStack = [&](
const VECTOR2I& aCursor ) ->
bool
1140 chain.Append( p,
true );
1158 bool violates =
false;
1175 if( violates && !allowDRCViolations )
1177 m_frame->ShowInfoBarError(
_(
"Microvia stack location violates DRC." ),
true,
1178 WX_INFOBAR::MESSAGE_TYPE::DRC_VIOLATION );
1196 lastViaPos =
via->GetPosition();
1201 commit.
Push(
_(
"Place Microvia Stack" ) );
1215 auto snapToCopper = [&](
const VECTOR2I& aCursor,
bool aItemSnap ) ->
VECTOR2I
1221 grid.SetSnap( aItemSnap );
1223 if( aItemSnap && mag )
1228 return grid.AlignToSegment( aCursor,
SEG( track->GetStart(), track->GetEnd() ) );
1234 return pad->GetPosition();
1238 return grid.ResolveSnap( aCursor,
nullptr ).position;
1241 auto setCursor = [&]()
1256 grid.SetSnap(
false );
1257 grid.SetUseGrid(
getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
1259 bool allowItemSnap = !evt->Modifier(
MD_SHIFT );
1263 if( staggered && !hops.empty() )
1267 VECTOR2I dir = rawCursor - hops.back();
1274 if( evt->Modifier(
MD_CTRL ) )
1280 double ang = atan2( (
double) dir.
y, (
double) dir.
x );
1281 ang = round( ang / step ) * step;
1283 cursorPos = hops.back()
1292 lastDir = cursorPos - hops.back();
1296 cursorPos = snapToCopper( rawCursor, allowItemSnap );
1302 if( staggered && !hops.empty() )
1303 m_controls->ForceCursorPosition(
true, cursorPos );
1307 if( evt->IsCancelInteractive() || evt->IsActivate() )
1317 hops.push_back( cursorPos );
1319 if( (
int) hops.size() >= nHops )
1321 if( !placeStack( cursorPos ) )
1334 resumeRouting =
true;
1335 resumePos = lastViaPos;
1345 m_controls->ForceCursorPosition(
true, cursorPos );
1346 updatePreview( cursorPos );
1351 if( placeStack( cursorPos ) )
1357 resumeRouting =
true;
1358 resumePos = lastViaPos;
1368 if( staggered && hops.size() > ( seeded ? 1u : 0u ) )
1372 updatePreview( cursorPos );
1380 else if( evt->IsMotion() )
1382 updatePreview( cursorPos );
1386 evt->SetPassEvent();
1391 m_view->Remove( &preview );
1405 router->SetViaStackResumeLayer( settings.
GetEndLayer() );
1407 m_controls->WarpMouseCursor( resumePos,
true,
false );
1439 if( layerEnum.
Choices().GetCount() == 0 )
1452 const wxString groupStack =
_HKI(
"Microvia Stack Properties" );
1456 startLayer->SetChoices( layerEnum.
Choices() );
1461 endLayer->SetChoices( layerEnum.
Choices() );
1485 auto isStaggered = [](
INSPECTABLE* aItem ) ->
bool
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static TOOL_ACTION doDelete
static TOOL_ACTION selectionClear
Clear the current selection.
BASE_SET & set(size_t pos)
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
virtual bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Container for design settings for a BOARD object.
int GetCurrentViaSize() const
int GetCurrentTrackWidth() const
int GetCurrentViaDrill() const
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
BOARD_ITEM(BOARD_ITEM *aParent, KICAD_T idtype, PCB_LAYER_ID aLayer=F_Cu)
void SetUuidDirect(const KIID &aUuid)
Raw UUID assignment.
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Information pertinent to a Pcbnew printed circuit board.
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
const ZONES & Zones() const
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayer) const
int GetCopperLayerCount() const
const FOOTPRINTS & Footprints() const
const TRACKS & Tracks() const
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
void Unmodify(EDA_ITEM *aItem, BASE_SCREEN *aScreen)
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
std::unordered_set< EDA_ITEM * > & GetItems()
void RemoveItem(EDA_ITEM *aItem)
Remove item from group.
void AddItem(EDA_ITEM *aItem)
Add item to group.
void SetFlags(EDA_ITEM_FLAGS aMask)
virtual EDA_GROUP * GetParentGroup() const
KICAD_T Type() const
Returns the type of object.
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
virtual void SetParent(EDA_ITEM *aParent)
EDA_ITEM_FLAGS GetFlags() const
ENUM_MAP & Map(T aValue, const wxString &aName)
static ENUM_MAP< T > & Instance()
ENUM_MAP & Undefined(T aValue)
Class that other classes need to inherit from, in order to be inspectable.
LSET is a set of PCB_LAYER_IDs.
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
LSEQ CuStack() const
Return a sequence of copper layers in starting from the front/top and extending to the back/bottom.
static int NameToLayer(wxString &aName)
Return the layer number from a layer name.
static const LSET & AllLayersMask()
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
A collection of nets and the parameters used to route or test these nets.
bool HasuViaDrill() const
bool HasuViaDiameter() const
int GetuViaDiameter() const
bool HasTrackWidth() const
int GetTrackWidth() const
Handle the data for a net.
static constexpr PCB_LAYER_ID ALL_LAYERS
! The layer identifier to use for the single defintion on normal padstacks
static TOOL_ACTION routeSingleTrack
Activation of the Push and Shove router.
Common, abstract interface for edit frames.
virtual void SetProperties(const STRING_ANY_MAP &aProps)
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
PCB_GENERATOR(BOARD_ITEM *aParent, PCB_LAYER_ID aLayer)
void Mirror(const VECTOR2I &aCentre, FLIP_DIRECTION aMirrorDirection) override
Mirror this object relative to a given horizontal axis the layer is not changed.
void SetPosition(const VECTOR2I &aPos) override
VECTOR2I GetPosition() const override
void Move(const VECTOR2I &aMoveVector) override
Move this object.
virtual const STRING_ANY_MAP GetProperties() const
std::unordered_set< BOARD_ITEM * > GetBoardItems() const
void SetEnd(const VECTOR2I &aEnd)
void SetStart(const VECTOR2I &aStart)
const VECTOR2I & GetStart() const
const VECTOR2I & GetEnd() const
virtual void SetWidth(int aWidth)
virtual int GetWidth() const
A microvia stack: several single hop microvias, plus connecting traces for staggered stacks,...
VIA_STACK_PRESET ToPreset() const
void SetHops(const SHAPE_LINE_CHAIN &aHops)
void EditCancel(GENERATOR_TOOL *aTool, BOARD *aBoard, BOARD_COMMIT *aCommit) override
bool Update(GENERATOR_TOOL *aTool, BOARD *aBoard, BOARD_COMMIT *aCommit) override
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
void ApplyPreset(const VIA_STACK_PRESET &aPreset)
static int ExpandMultiHopMicrovias(BOARD *aBoard, BOARD_COMMIT *aCommit, const std::function< const VIA_STACK_PRESET *(PCB_VIA *)> &aMatcher=nullptr)
Replace loose microvias spanning more than one hop with stacks of single hop microvias.
void SetProperties(const STRING_ANY_MAP &aProps) override
void SetPitch(int aPitch)
static PCB_VIA_STACK * CreateFromItems(const std::vector< BOARD_ITEM * > &aItems, BOARD *aBoard, std::vector< BOARD_ITEM * > *aMembers=nullptr)
Build a stack from existing board items (microvias plus optional connecting traces).
static std::set< KIID > CollectExpandableMicrovias(BOARD *aBoard)
Ids of the vias ExpandMultiHopMicrovias would consider right now.
static const wxString GENERATOR_TYPE
void EditStart(GENERATOR_TOOL *aTool, BOARD *aBoard, BOARD_COMMIT *aCommit) override
void Mirror(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Mirror this object relative to a given horizontal axis the layer is not changed.
static int FindNetAtPosition(BOARD *aBoard, const VECTOR2I &aPosition, PCB_LAYER_ID aLayer)
Net of the copper under a point on the given layer, pads first, then tracks, then filled zones.
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
std::optional< SHAPE_LINE_CHAIN > m_hops
void EditFinish(GENERATOR_TOOL *aTool, BOARD *aBoard, BOARD_COMMIT *aCommit) override
void Remove(GENERATOR_TOOL *aTool, BOARD *aBoard, BOARD_COMMIT *aCommit) override
void Regenerate(BOARD *aBoard, BOARD_COMMIT *aCommit)
Rebuild the member vias (and, for a staggered stack, the connecting traces) from the current stack se...
void addMember(BOARD *aBoard, BOARD_COMMIT *aCommit, BOARD_ITEM *aItem)
bool reuseMembers(BOARD_COMMIT *aCommit, const std::vector< BOARD_ITEM * > &aRebuilt)
static const wxString DISPLAY_NAME
VIA_STACK_STYLE GetStyle() const
void SetFilled(bool aFilled)
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
PCB_LAYER_ID m_startLayer
PCB_LAYER_ID GetStartLayer() const
void SetStartLayer(PCB_LAYER_ID aLayer)
PCB_LAYER_ID GetEndLayer() const
bool GetUseNetclass() const
std::vector< BOARD_ITEM * > BuildMembers(BOARD *aBoard, int aNetCode) const
Build the member vias/traces for the current settings and return them without adding them anywhere.
static bool IsSpanValid(BOARD *aBoard, PCB_LAYER_ID aStart, PCB_LAYER_ID aEnd)
True when both span ends are copper layers within the board's copper layer count.
void SetViaSize(int aSize)
void SetCapped(bool aCapped)
void SetViaDrill(int aDrill)
void ShowPropertiesDialog(PCB_BASE_EDIT_FRAME *aEditFrame) override
const STRING_ANY_MAP GetProperties() const override
void SetStyle(VIA_STACK_STYLE aStyle)
wxString GetCommitMessage() const override
PCB_VIA_STACK(BOARD_ITEM *aParent=nullptr, PCB_LAYER_ID aLayer=F_Cu)
void Move(const VECTOR2I &aMoveVector) override
Move this object.
void SetEndLayer(PCB_LAYER_ID aLayer)
void SetNetCode(int aNet)
PCB_LAYER_ID BottomLayer() const
VECTOR2I GetPosition() const override
const PADSTACK & Padstack() const
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/.
int GetWidth() const override
void SetViaType(VIATYPE aViaType)
PCB_LAYER_ID TopLayer() const
int GetDrillValue() const
Calculate the drill value for vias (m_drill if > 0, or default drill value for the board).
VIATYPE GetViaType() const
void SetWidth(int aWidth) override
PROPERTY_BASE & SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Set a callback function to determine whether an object provides this property.
Provide class metadata.Helper macro to map type hashes to names.
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
void Mask(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName)
Sets a base class property as masked in a derived class.
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
RAII class that sets an value at construction and resets it to the original value at destruction.
virtual void Add(EDA_ITEM *aItem)
A null aItem is ignored; the selection never holds null members.
virtual void Clear() override
Remove all the stored items from the group.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
A name/value tuple with unique names and wxAny values.
void set_iu(const std::string &aKey, const T &aVar)
bool get_to(const std::string &aKey, T &aVar) const
std::optional< T > get_opt(const std::string &aKey) const
void set(const std::string &aKey, const T &aVar)
bool get_to_iu(const std::string &aKey, T &aVar) const
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Handle a list of polygons defining a copper zone.
static bool empty(const wxTextEntryBase *aCtrl)
#define IS_NEW
New item, just created.
#define IN_EDIT
Item currently edited.
a few functions useful in geometry calculations.
LEADER_MODE
The kind of the leader line.
@ DIRECT
Unconstrained point-to-point.
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
bool IsExternalCopperLayer(int aLayerId)
Test whether a layer is an external (F_Cu or B_Cu) copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
PCB_LAYER_ID ToLAYER_ID(int aLayer)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
static GENERATORS_MGR::REGISTER< PCB_TUNING_PATTERN > registerMe
static VIA_STACK_STYLE styleFromString(const wxString &aStr)
static struct PCB_VIA_STACK_DESC _PCB_VIA_STACK_DESC
static PCB_LAYER_ID layerFromName(const wxString &aName, PCB_LAYER_ID aFallback)
static wxString styleToString(VIA_STACK_STYLE aStyle)
static void layerOrder(BOARD *aBoard, std::vector< PCB_LAYER_ID > &aOrder, std::map< int, int > &aOrdinals)
static std::optional< std::tuple< int, int, int > > memberKey(BOARD_ITEM *aItem)
static bool isExpandableMicrovia(const std::map< int, int > &aOrdinals, PCB_VIA *aVia)
#define IMPLEMENT_ENUM_TO_WXANY(type)
#define NO_SETTER(owner, type)
@ PT_SIZE
Size expressed in distance units (mm/inch)
@ PT_NET
Net selection property.
Static helper to register a generator.
std::optional< bool > is_capped
True if the drill hole should be capped.
std::optional< bool > is_filled
True if the drill hole should be filled completely.
A named microvia stack definition, chosen while routing instead of entering the values each time.
PCB_LAYER_ID m_StartLayer
KIBIS top(path, &reporter)
const SHAPE_LINE_CHAIN chain
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
VECTOR2< int32_t > VECTOR2I