27using namespace std::placeholders;
162 if( oldA && oldA->
m_Uuid == newId )
163 itemA->Enable(
false );
165 if( oldB && oldB->
m_Uuid == newId )
166 itemB->Enable(
false );
272 std::shared_ptr<SELECT_MENU> selectMenu = std::make_shared<SELECT_MENU>();
273 selectMenu->SetTool(
this );
274 m_menu->RegisterSubMenu( selectMenu );
276 std::shared_ptr<NET_CHAINS_MENU> netChainsMenu = std::make_shared<NET_CHAINS_MENU>();
277 netChainsMenu->SetTool(
this );
278 m_menu->RegisterSubMenu( netChainsMenu );
282 auto& menu =
m_menu->GetMenu();
284 auto activeToolCondition =
299 auto groupEnterCondition =
302 auto applyDesignBlockLayoutCondition = [](
const SELECTION& aSel )
315 auto inGroupCondition =
331 if( aSel.GetSize() != 1 )
341 menu.AddMenu( netChainsMenu.get(), netItemSelection );
342 menu.AddSeparator( 1000 );
354 menu.AddSeparator( haveHighlight, 1 );
360 menu.AddSeparator( 1 );
404 wxMouseState keyboardState = wxGetMouseState();
406 setModifiersState( keyboardState.ShiftDown(), keyboardState.ControlDown(), keyboardState.AltDown() );
429 trackDragAction = cfg->m_TrackDragAction;
443 else if( evt->IsMouseDown(
BUT_LEFT ) )
468 if( constraintTool->SelectConstraintAt( evt->Position() ) )
474 constraintTool->ClearConstraintSelection();
507 bool selectionCancelled =
false;
511 selectPoint( evt->Position(),
false, &selectionCancelled );
516 m_frame->GetCanvas()->ForceRefresh();
518 if( !selectionCancelled )
532 if( !item->IsBOARD_ITEM() )
534 allSameParent =
false;
542 allSameParent =
false;
550 else if( sharedParent != gen )
552 allSameParent =
false;
557 if( allSameParent && sharedParent )
618 const int delta = evt->Parameter<
int>();
669 wxASSERT_MSG(
false, wxT(
"Unknown selection mode" ) );
676 auto zoneFilledAreaFilter =
679 int accuracy = aCollector.GetGuide()->Accuracy();
680 std::set<EDA_ITEM*> remove;
686 ZONE* zone =
static_cast<ZONE*
>( item );
691 remove.insert( zone );
697 aCollector.Remove( item );
703 if( evt->HasPosition() )
706 &&
selectPoint( evt->DragOrigin(),
false,
nullptr, zoneFilledAreaFilter ) )
724 bool routable = ( segs >= 1 || arcs >= 1 || vias == 1 )
725 && ( segs + arcs + vias ==
m_selection.GetSize() );
735 if( !item->IsBOARD_ITEM() )
775 else if( evt->IsCancel() )
790 else if( evt->FirstResponder() ==
this && evt->GetCommandId() == (
int) WXK_ESCAPE )
802 if( controller &&
m_frame->GetPcbNewSettings()->m_ESCClearsNetHighlight )
805 catch(
const std::runtime_error& e )
807 wxCHECK_MSG(
false, 0, e.what() );
818 if(
m_frame->ToolStackIsEmpty() )
824 && evt->HasPosition()
848 wxT(
"EnterGroup called when selection is not a single group" ) );
914 enum DISPOSITION { BEFORE = 1, AFTER,
BOTH };
916 std::map<EDA_ITEM*, DISPOSITION> itemDispositions;
925 itemDispositions[ item ] = BEFORE;
928 aClientFilter(
VECTOR2I(), collector,
this );
934 m_frame->GetCanvas()->ForceRefresh();
941 if( itemDispositions.count( item ) )
942 itemDispositions[ item ] =
BOTH;
944 itemDispositions[ item ] = AFTER;
952 for( std::pair<EDA_ITEM* const, DISPOSITION> itemDisposition : itemDispositions )
954 EDA_ITEM* item = itemDisposition.first;
955 DISPOSITION disposition = itemDisposition.second;
957 if( disposition == BEFORE )
961 for( std::pair<EDA_ITEM* const, DISPOSITION> itemDisposition : itemDispositions )
963 EDA_ITEM* item = itemDisposition.first;
964 DISPOSITION disposition = itemDisposition.second;
968 if( disposition == AFTER || disposition ==
BOTH )
972 m_frame->GetCanvas()->ForceRefresh();
1018 rejected.
SetAll(
false );
1028 if( !
collectAtPoint( aWhere, collector, options, aClientFilter ) )
1036 editFrame->HighlightSelectionFilter( rejected );
1054 if( aSelectionCancelledFlag )
1055 *aSelectionCancelledFlag =
true;
1062 bool anySubtracted =
false;
1069 anySubtracted =
true;
1075 for(
int i = 0; i < collector.
GetCount(); ++i )
1080 anySubtracted =
true;
1090 if( addedCount == 1 )
1095 else if( addedCount > 1 )
1100 else if( anySubtracted )
1137 for(
int i = 0; aAllowedActions[i]; ++i )
1139 if( aEvent->
IsAction( aAllowedActions[i] ) )
1152 if( cell->IsSelected() )
1163 BOX2I selectionRect( aStart, aEnd );
1169 return ( aItem->GetFlags() &
CANDIDATE ) > 0;
1174 bool doSelect =
false;
1176 if( cell->HitTest( selectionRect,
false ) )
1181 doSelect = !wasSelected( cell );
1185 else if( wasSelected( cell ) )
1190 if( doSelect && !cell->IsSelected() )
1192 else if( !doSelect && cell->IsSelected() )
1240 std::set<EDA_ITEM*> previousSelection;
1243 previousSelection.insert( item );
1255 VECTOR2D topLeft( std::min( start.
x,
end.x ), std::min( start.
y,
end.y ) );
1256 VECTOR2D bottomRight( std::max( start.
x,
end.x ), std::max( start.
y,
end.y ) );
1260 bool anyAdded =
false;
1261 bool anySubtracted =
false;
1265 bool wasInPrevious = previousSelection.count( cell ) > 0;
1267 if( cell->IsSelected() && !wasInPrevious )
1269 else if( wasInPrevious && !cell->IsSelected() )
1270 anySubtracted =
true;
1321 if( !cell || cell->
GetParent() != selectedTable )
1333 if( clickedCell->
GetParent() != selectedTable )
1356 bool cancelled =
false;
1362 bool haveAnchorStart =
false;
1369 haveAnchorStart =
true;
1381 return ( aItem->GetFlags() &
CANDIDATE ) > 0;
1386 if( evt->IsCancelInteractive() || evt->IsActivate() )
1395 VECTOR2D start = haveAnchorStart ? anchorStart :
VECTOR2D( evt->DragOrigin() );
1400 else if( evt->IsMouseUp(
BUT_LEFT ) )
1404 bool anyAdded =
false;
1405 bool anySubtracted =
false;
1409 if( cell->IsSelected() && !wasSelected( cell ) )
1411 else if( wasSelected( cell ) && !cell->IsSelected() )
1412 anySubtracted =
true;
1450 bool cancelled =
false;
1463 if( &aTool !=
this )
1472 if(
view->IsMirroredX() )
1473 greedySelection = !greedySelection;
1478 if( evt->IsCancelInteractive() || evt->IsActivate() )
1497 area.
SetEnd( evt->Position() );
1503 view->SetVisible( &area,
true );
1504 view->Update( &area );
1516 view->SetVisible( &area,
false );
1530 view->Remove( &area );
1562 bool cancelled =
false;
1580 bool isClockwise = shapeArea > 0 ? true :
false;
1582 if(
getView()->IsMirroredX() && shapeArea != 0 )
1583 isClockwise = !isClockwise;
1587 if( evt->IsCancelInteractive() || evt->IsActivate() )
1590 evt->SetPassEvent(
false );
1597 points.
Append( evt->Position() );
1599 else if( evt->IsDblClick(
BUT_LEFT )
1605 evt->SetPassEvent(
false );
1641 area.
SetMode( selectionMode );
1673 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1675 if( !
Selectable( aCollector[i] ) || ( aOptions.
m_OnDrag && aCollector[i]->IsLocked() ) )
1686 aClientFilter( aWhere, aCollector,
this );
1693 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1695 if( !aCollector[i]->IsSelected() )
1707 catch(
const std::exception& exc )
1709 wxLogWarning( wxS(
"Exception '%s' occurred attempting to guess selection candidates." ),
1728 std::vector<BOARD_ITEM*> items;
1730 for(
int i = 0; i < collector.
GetCount(); ++i )
1731 items.push_back( collector[i] );
1747 std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR>
candidates;
1753 std::set<EDA_ITEM*> group_items;
1761 std::unordered_set<EDA_ITEM*>& newset =
group->GetItems();
1764 [&](
const BOX2I& aBox )
1766 return boxMode ? selectionBox.
Contains( aBox )
1772 if( containedMode && boxContained(
group->GetBoundingBox() ) && newset.size() )
1774 for(
EDA_ITEM* group_item : newset )
1776 if( !group_item->IsBOARD_ITEM() )
1780 collector.
Append( *newset.begin() );
1784 for(
EDA_ITEM* group_item : newset )
1785 group_items.emplace( group_item );
1791 return boxMode ? aItem->HitTest( selectionBox, containedMode )
1792 : aItem->HitTest( aArea.
GetPoly(), containedMode );
1795 for(
const auto& [item, layer] :
candidates )
1797 if( !item->IsBOARD_ITEM() )
1802 if(
Selectable( boardItem ) && hitTest( boardItem )
1803 && ( !containedMode || !group_items.count( boardItem ) ) )
1806 padsCollector.
Append( boardItem );
1808 collector.
Append( boardItem );
1820 collector = padsCollector;
1827 std::sort( collector.
begin(), collector.
end(),
1830 VECTOR2I aPos = a->GetPosition();
1831 VECTOR2I bPos = b->GetPosition();
1833 if( aPos.y == bPos.y )
1834 return aPos.x < bPos.x;
1836 return aPos.y < bPos.y;
1839 std::vector<BOARD_ITEM*> items;
1843 if( i->IsBOARD_ITEM() )
1844 items.push_back(
static_cast<BOARD_ITEM*
>( i ) );
1854 bool anyAdded =
false;
1855 bool anySubtracted =
false;
1859 if( aSubtractive || ( aExclusiveOr && item->IsSelected() ) )
1862 anySubtracted =
true;
1876 else if( anySubtracted )
1883 wxMouseState keyboardState = wxGetMouseState();
1885 setModifiersState( keyboardState.ShiftDown(), keyboardState.ControlDown(), keyboardState.AltDown() );
1929 collection.
Append( item );
1942 m_frame->GetCanvas()->ForceRefresh();
1970 m_frame->GetCanvas()->ForceRefresh();
1980 std::set<int> representedNets;
1982 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
1988 else if ( representedNets.count( item->
GetNetCode() ) )
1991 representedNets.insert( item->
GetNetCode() );
1998 std::deque<EDA_ITEM*> selectedItems =
m_selection.GetItems();
2001 std::vector<BOARD_CONNECTED_ITEM*> toUnroute;
2002 std::set<EDA_ITEM*> toDelete;
2004 for(
EDA_ITEM* item : selectedItems )
2009 toUnroute.push_back(
pad );
2013 toDelete.insert( item );
2029 std::set<int> selectedNets;
2032 if( item->GetNetCode() > 0 )
2033 selectedNets.insert( item->GetNetCode() );
2035 std::set<VECTOR2I> endpointSet;
2041 endpointSet.insert( track->GetStart() );
2042 endpointSet.insert( track->GetEnd() );
2046 endpointSet.insert( item->GetPosition() );
2050 endpointSet.insert( item->GetPosition() );
2054 bool expanded =
true;
2062 if( toDelete.count( gen ) )
2066 std::map<VECTOR2I, int> epCount;
2068 for(
BOARD_ITEM* child : gen->GetBoardItems() )
2072 if( track && selectedNets.count( track->
GetNetCode() ) )
2075 epCount[track->
GetEnd()]++;
2080 bool connected =
false;
2082 for(
auto& [pt, count] : epCount )
2084 if( count == 1 && endpointSet.count( pt ) )
2093 toDelete.insert( gen );
2107 endpointSet.insert( track->GetStart() );
2108 endpointSet.insert( track->GetEnd() );
2131 std::set<BOARD_ITEM*> removed;
2135 if( !item->IsBOARD_ITEM() )
2141 toDelete.insert( bi );
2144 removed.insert( bi );
2150 for(
BOARD_ITEM* child : gen->GetBoardItems() )
2152 if( removed.count( child ) )
2154 toDelete.insert( gen );
2162 if( !item->IsBOARD_ITEM() )
2170 if( removed.find( aItem ) == removed.end() )
2173 removed.insert( aItem );
2178 if( removed.find( boardItem ) == removed.end() )
2179 commit.
Remove( boardItem );
2183 commit.
Push(
_(
"Unroute Selected" ) );
2188 for(
EDA_ITEM* item : selectedItems )
2200 std::deque<EDA_ITEM*> selectedItems =
m_selection.GetItems();
2203 std::vector<BOARD_CONNECTED_ITEM*> toUnroute;
2205 std::set<EDA_ITEM*> toDelete;
2207 for(
EDA_ITEM* item : selectedItems )
2218 if( !toDelete.count( gen ) )
2220 toDelete.insert( gen );
2224 toDelete.insert( generatedItem );
2234 toDelete.insert( item );
2239 toDelete.insert( item );
2243 toDelete.insert( generatedItem );
2254 std::deque<EDA_ITEM*> toSelectAfter;
2258 if( !item->IsBOARD_ITEM() )
2261 if( toDelete.find( item ) == toDelete.end() )
2262 toSelectAfter.push_back( item );
2266 std::set<BOARD_ITEM*> removed;
2270 if( !item->IsBOARD_ITEM() )
2280 if( removed.insert( aItem ).second )
2285 if( removed.insert( boardItem ).second )
2286 commit.
Remove( boardItem );
2290 if( removed.insert( boardItem ).second )
2291 commit.
Remove( boardItem );
2295 commit.
Push(
_(
"Unroute Segment" ) );
2300 for(
EDA_ITEM* item : toSelectAfter )
2302 if( !toDelete.count( item ) )
2315 unsigned initialCount = 0;
2327 if( initialCount == 0 )
2330 std::vector<PCB_SHAPE*> startShapes;
2335 startShapes.push_back(
static_cast<PCB_SHAPE*
>( item ) );
2339 if( !startShapes.empty() )
2345 m_frame->SetStatusText(
_(
"Select/Expand Connection..." ) );
2349 std::deque<EDA_ITEM*> selectedItems =
m_selection.GetItems();
2351 for(
EDA_ITEM* item : selectedItems )
2352 item->ClearTempFlags();
2354 std::vector<BOARD_CONNECTED_ITEM*> startItems;
2356 for(
EDA_ITEM* item : selectedItems )
2363 startItems.push_back(
pad );
2381 if(
m_selection.GetItems().size() > initialCount )
2385 m_frame->SetStatusText( wxEmptyString );
2398 double refreshIntervalMs = 500;
2399 int lastSelectionSize = (int)
m_selection.GetSize();
2404 const auto inScope = [
this](
BOARD_ITEM* aItem )
2409 std::set<PAD*> startPadSet;
2410 std::vector<BOARD_CONNECTED_ITEM*> cleanupItems;
2416 startPadSet.insert(
static_cast<PAD*
>( startItem ) );
2419 if( startItem->IsType( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } ) )
2428 std::map<VECTOR2I, std::vector<PCB_TRACK*>> trackMap;
2429 std::map<VECTOR2I, std::vector<PCB_VIA*>> viaMap;
2430 std::map<VECTOR2I, PAD*> padMap;
2431 std::map<VECTOR2I, std::vector<PCB_SHAPE*>> shapeMap;
2432 std::vector<std::pair<VECTOR2I, LSET>> activePts;
2442 switch( item->Type() )
2448 trackMap[track->
GetStart()].push_back( track );
2449 trackMap[track->
GetEnd()].push_back( track );
2459 viaMap[
via->GetStart()].push_back(
via );
2466 padMap[
pad->GetPosition()] =
pad;
2475 shapeMap[point].push_back( shape );
2486 switch( startItem->Type() )
2499 activePts.push_back( { startItem->GetPosition(), startItem->GetLayerSet() } );
2503 activePts.push_back( { startItem->GetPosition(), startItem->GetLayerSet() } );
2511 activePts.push_back( { point, startItem->GetLayerSet() } );
2524 while( expand && failSafe++ < 100000 )
2528 for(
int i = (
int) activePts.size() - 1; i >= 0; --i )
2536 auto better = [&](
PCB_VIA* aCandidate )
2542 auto settled = [&]()
2548 auto exactIt = viaMap.find( pt );
2550 if( exactIt != viaMap.end() )
2554 if( (
via->GetLayerSet() & layerSetCu ).any() && better(
via ) )
2565 for(
auto& [pos, vias] : viaMap )
2569 if( !(
via->GetLayerSet() & layerSetCu ).any() || !better(
via ) )
2574 int radius =
via->GetWidth( layer ) / 2;
2575 int64_t radiusSq =
static_cast<int64_t
>(
radius ) *
radius;
2577 if( ( pt - pos ).SquaredEuclideanNorm() <= radiusSq )
2595 auto padIt = padMap.find( pt );
2597 bool gotVia = hitVia !=
nullptr;
2598 bool gotPad = padIt != padMap.end() && ( padIt->second->GetLayerSet() & layerSetCu ).any();
2599 bool gotNonStartPad = gotPad && ( startPadSet.find( padIt->second ) == startPadSet.end() );
2603 activePts.erase( activePts.begin() + i );
2609 activePts.erase( activePts.begin() + i );
2615 size_t pt_count = 0;
2619 if( track->GetStart() != track->GetEnd() && layerSetCu.
Contains( track->GetLayer() ) )
2623 if( pt_count > 2 || gotVia || gotNonStartPad )
2625 activePts.erase( activePts.begin() + i );
2631 if( gotNonStartPad )
2633 activePts.erase( activePts.begin() + i );
2640 PAD*
pad = padIt->second;
2645 cleanupItems.push_back(
pad );
2647 activePts.push_back( {
pad->GetPosition(),
pad->GetLayerSet() } );
2654 if( !layerSetCu.
Contains( track->GetLayer() ) )
2660 if( !track->IsSelected() && inScope( track ) )
2666 cleanupItems.push_back( track );
2668 if( track->GetStart() == pt )
2669 activePts.push_back( { track->GetEnd(), track->GetLayerSet() } );
2671 activePts.push_back( { track->GetStart(), track->GetLayerSet() } );
2680 if( !layerSetCu.
Contains( shape->GetLayer() ) )
2686 if( !shape->IsSelected() && inScope( shape ) )
2692 cleanupItems.push_back( shape );
2694 for(
const VECTOR2I& newPoint : shape->GetConnectionPoints() )
2696 if( newPoint == pt )
2699 activePts.push_back( { newPoint, shape->GetLayerSet() } );
2709 if( !hitVia->
IsSelected() && inScope( hitVia ) )
2715 cleanupItems.push_back( hitVia );
2722 maxRadius = std::max( maxRadius, hitVia->
GetWidth( layer ) / 2 );
2724 int64_t maxRadiusSq =
static_cast<int64_t
>( maxRadius ) * maxRadius;
2726 for(
auto& [trkPt, tracks] : trackMap )
2728 if( ( trkPt - viaPos ).SquaredEuclideanNorm() > maxRadiusSq )
2732 bool inside =
false;
2741 int r = hitVia->
GetWidth( trkLayer ) / 2;
2742 int64_t rSq =
static_cast<int64_t
>( r ) * r;
2744 if( ( trkPt - viaPos ).SquaredEuclideanNorm() <= rSq )
2752 activePts.push_back( { trkPt, hitVia->
GetLayerSet() } );
2756 activePts.push_back( { viaPos, hitVia->
GetLayerSet() } );
2763 activePts.erase( activePts.begin() + i );
2767 if( refreshTimer.
msecs() >= refreshIntervalMs )
2771 m_frame->GetCanvas()->ForceRefresh();
2775 refreshTimer.
Start();
2780 std::set<EDA_ITEM*> toDeselect;
2781 std::set<EDA_ITEM*> toSelect;
2787 if( !item->IsBOARD_ITEM() )
2800 toDeselect.insert( item );
2845 std::stack<PCB_SHAPE*> toSearch;
2846 std::set<PCB_SHAPE*> toCleanup;
2848 for(
PCB_SHAPE* startItem : aStartItems )
2849 toSearch.push( startItem );
2862 toSearch.push(
static_cast<PCB_SHAPE*
>( item ) );
2866 while( !toSearch.empty() )
2875 toCleanup.insert( shape );
2884 searchPoint( shape->
GetEnd() );
2895 std::vector<PAD*> pads;
2902 pads.push_back(
pad );
2906 pads.push_back(
static_cast<PAD*
>( item ) );
2915 for(
const CN_EDGE& edge : conn->GetRatsnestForPad(
pad ) )
2917 wxCHECK2( edge.GetSourceNode() && !edge.GetSourceNode()->Dirty(),
continue );
2918 wxCHECK2( edge.GetTargetNode() && !edge.GetTargetNode()->Dirty(),
continue );
2923 if( sourceParent ==
pad )
2926 select(
static_cast<PAD*
>( targetParent )->GetParent() );
2928 else if( targetParent ==
pad )
2931 select(
static_cast<PAD*
>( sourceParent )->GetParent() );
2943 std::vector<BOARD_CONNECTED_ITEM*> sourceItems;
2944 std::vector<FOOTPRINT*> nearestFootprints;
2951 sourceItems.push_back(
pad );
2955 sourceItems.push_back( connItem );
2960 std::shared_ptr<CN_CONNECTIVITY_ALGO> connAlgo = conn->GetConnectivityAlgo();
2964 RN_NET* net = conn->GetRatsnestForNet( sourceItem->GetNetCode() );
2967 if( !net || net->
GetEdges().empty() || !connAlgo->ItemExists( sourceItem ) )
2970 std::vector<std::shared_ptr<CN_CLUSTER>> sourceClusters;
2972 for(
CN_ITEM* cnItem : connAlgo->ItemEntry( sourceItem ).GetItems() )
2974 for(
const std::shared_ptr<CN_ANCHOR>&
anchor : cnItem->Anchors() )
2976 if(
anchor->GetCluster() )
2977 sourceClusters.push_back(
anchor->GetCluster() );
2981 if( sourceClusters.empty() )
2984 auto isSourceAnchor =
2985 [&](
const std::shared_ptr<const CN_ANCHOR>& aAnchor )
2987 if( aAnchor->Parent() == sourceItem )
2990 return std::find( sourceClusters.begin(), sourceClusters.end(),
2991 aAnchor->GetCluster() ) != sourceClusters.end();
2994 double currentDistance = DBL_MAX;
3000 const std::shared_ptr<const CN_ANCHOR>&
source = edge.GetSourceNode();
3001 const std::shared_ptr<const CN_ANCHOR>& target = edge.GetTargetNode();
3003 wxCHECK2(
source && !
source->Dirty() && target && !target->Dirty(),
continue );
3005 if(
source->Parent()->GetParentFootprint() == target->Parent()->GetParentFootprint() )
3010 bool sourceMatches = isSourceAnchor(
source );
3011 bool targetMatches = isSourceAnchor( target );
3013 if( sourceMatches == targetMatches )
3022 if( edge.GetLength() < currentDistance )
3024 currentDistance = edge.GetLength();
3029 if( nearest !=
nullptr )
3030 nearestFootprints.push_back( nearest );
3033 if( nearestFootprints.empty() )
3038 for(
FOOTPRINT* footprint : nearestFootprints )
3051 for(
BOARD_ITEM* item : conn->GetNetItems( aNetCode, { PCB_TRACE_T,
3125 const wxString& chainName = netInfo->
GetNetChain();
3127 if( chainName.IsEmpty() )
3136 if( candidate && candidate->GetNetChain() == chainName )
3152 std::vector<BOARD_ITEM*> footprints;
3157 if( footprint ==
nullptr )
3160 wxString footprint_path = footprint->GetPath().AsString().BeforeLast(
'/' );
3162 if( footprint_path.IsEmpty() )
3163 footprint_path +=
'/';
3165 if( footprint_path == aSheetPath )
3166 footprints.push_back( footprint );
3182 std::list<int> netcodeList;
3183 std::vector<BOARD_CONNECTED_ITEM*> padList;
3187 switch( item->Type() )
3193 if(
pad->IsConnected() )
3195 netcodeList.push_back(
pad->GetNetCode() );
3196 padList.push_back(
pad );
3207 if(
pad->IsConnected() )
3209 netcodeList.push_back(
pad->GetNetCode() );
3210 padList.push_back(
pad );
3222 std::sort( padList.begin(), padList.end() );
3226 netcodeList.unique();
3232 std::vector<int> removeCodeList;
3235 for(
int netCode : netcodeList )
3239 if( !std::binary_search( padList.begin(), padList.end(),
pad ) )
3243 removeCodeList.push_back( netCode );
3249 for(
int removeCode : removeCodeList )
3250 netcodeList.remove( removeCode );
3252 std::unordered_set<BOARD_ITEM*> localConnectionList;
3254 for(
int netCode : netcodeList )
3256 for(
BOARD_ITEM* item : conn->GetNetItems( netCode, { PCB_TRACE_T,
3261 localConnectionList.insert( item );
3265 for(
BOARD_ITEM* item : localConnectionList )
3272 std::vector<BOARD_ITEM*>* items = aEvent.
Parameter<std::vector<BOARD_ITEM*>*>();
3283 std::vector<BOARD_ITEM*>* items = aEvent.
Parameter<std::vector<BOARD_ITEM*>*>();
3301 if( item->IsMoving() )
3318 if(
m_frame->GetPcbNewSettings()->m_CrossProbing.center_on_items )
3320 if(
m_frame->GetPcbNewSettings()->m_CrossProbing.zoom_to_fit )
3327 m_frame->GetCanvas()->ForceRefresh();
3337 wxString sheetPath = *aEvent.
Parameter<wxString*>();
3363 if( !footprint || footprint->
GetPath().empty() )
3369 wxString sheetPath = footprint->
GetPath().
AsString().BeforeLast(
'/' );
3371 if( sheetPath.IsEmpty() )
3392 screenSize.
x = std::max( 10.0, screenSize.
x );
3393 screenSize.
y = std::max( 10.0, screenSize.
y );
3398 double scale =
view->GetScale() / std::max( fabs( vsize.
x / screenSize.
x ),
3399 fabs( vsize.
y / screenSize.
y ) );
3405 m_frame->GetCanvas()->ForceRefresh();
3421#ifdef DEFAULT_PCBNEW_CODE
3423 auto screenSize =
view->ToWorld( GetCanvas()->GetClientSize(),
false );
3426 screenSize.x = std::max( 10.0, fabs( screenSize.x ) );
3427 screenSize.y = std::max( 10.0, screenSize.y );
3428 double ratio = std::max( fabs( bbSize.x / screenSize.x ), fabs( bbSize.y / screenSize.y ) );
3431 if( crossProbingSettings.zoom_to_fit && ( ratio < 0.5 || ratio > 1.0 ) )
3432 view->SetScale(
view->GetScale() / ratio );
3435#ifndef DEFAULT_PCBNEW_CODE
3452 double compRatio = bbSize.y / currTextHeight;
3455 double compRatioBent = 1.0;
3466 screenSize.
x = std::max( 10.0, fabs( screenSize.
x ) );
3467 screenSize.
y = std::max( 10.0, screenSize.
y );
3468 double ratio = std::max( -1.0, fabs( bbSize.y / screenSize.
y ) );
3471 double kicadRatio = std::max( fabs( bbSize.x / screenSize.
x ),
3472 fabs( bbSize.y / screenSize.
y ) );
3480 std::vector<std::pair<double, double>> lut {
3493 std::vector<std::pair<double, double>>::iterator it;
3495 compRatioBent = lut.back().second;
3497 if( compRatio >= lut.front().first )
3503 for( it = lut.begin(); it < lut.end() - 1; it++ )
3505 if( it->first <= compRatio &&
next( it )->first >= compRatio )
3507 double diffx = compRatio - it->first;
3508 double diffn =
next( it )->first - it->first;
3510 compRatioBent = it->second + (
next( it )->second - it->second ) * diffx / diffn;
3517 compRatioBent = lut.front().second;
3525 if( bbSize.x > screenSize.
x * ratio * compRatioBent )
3529 compRatioBent = 1.0;
3530 wxLogTrace(
"CROSS_PROBE_SCALE",
"Part TOO WIDE for screen. Using normal KiCad zoom ratio: %1.5f", ratio );
3535 ratio *= compRatioBent;
3537 bool alwaysZoom =
false;
3540 if( ( ratio < 0.5 || ratio > 1.0 ) || alwaysZoom )
3541 view->SetScale(
view->GetScale() / ratio );
3548 bool cleared =
false;
3560 switch( aItem->
Type() )
3564 int netCode =
static_cast<NETINFO_ITEM*
>( aItem )->GetNetCode();
3583 double marginFactor = 2;
3592 double scaleX = screenSize.
x /
static_cast<double>( aItem->
GetBoundingBox().GetWidth() );
3593 double scaleY = screenSize.
y /
static_cast<double>( aItem->
GetBoundingBox().GetHeight() );
3595 scaleX /= marginFactor;
3596 scaleY /= marginFactor;
3598 double scale = scaleX > scaleY ? scaleY : scaleX;
3617 m_frame->GetCanvas()->ForceRefresh();
3629 switch( aItem.
Type() )
3689 if( cmd != wxID_OK )
3700 if( !i->IsBOARD_ITEM() )
3722 std::set<BOARD_ITEM*> rejected;
3726 if( !i->IsBOARD_ITEM() )
3732 rejected.insert( item );
3736 aCollector.
Remove( item );
3801 aRejected->
pads =
true;
3813 aRejected->
tracks =
true;
3824 aRejected->
vias =
true;
3833 ZONE* zone =
static_cast<ZONE*
>( aItem );
3843 aRejected->
zones =
true;
3852 if( zone ==
m_frame->GetBoard()->m_SolderMaskBridges )
3883 aRejected->
text =
true;
3920 aRejected->
points =
true;
3991 if( cell->HitTest( aPosition, 0 ) )
4007 if( cell->GetRow() == clicked->
GetRow() )
4025 bool enteredGroupFound =
false;
4028 [&](
EDA_ITEM* item,
void* testData )
4046 enteredGroupFound =
true;
4060 if( !enteredGroupFound )
4069 const LSET& aEnabledLayers )
4071 return aVisibleLayers & aEnabledLayers;
4084 return ( aPad.
GetLayerSet() & aVisibleLayers ).any();
4089 bool aBackVisible,
bool aIsFootprintEditor )
4093 if( aIsFootprintEditor || !parentFP )
4097 switch( aItem.
Type() )
4119 if( !onFront && !onBack )
4129 return ( onFront && aFrontVisible ) || ( onBack && aBackVisible );
4138 auto visibleLayers =
4146 set.
set( layer,
view()->IsLayerVisible( layer ) );
4153 board()->GetEnabledLayers() );
4178 bool onActiveLayer =
false;
4180 for(
int layer : activeLayers )
4183 if( layer < PCB_LAYER_ID_COUNT && aItem->IsOnLayer(
ToLAYER_ID( layer ) ) )
4185 onActiveLayer =
true;
4208 && footprint->
Pads().empty()
4209 && footprint->
Zones().empty()
4210 && footprint->
Points().empty() )
4227 for(
const ZONE* zone : footprint->
Zones() )
4264 const ZONE* zone =
nullptr;
4266 const PAD*
pad =
nullptr;
4279 switch( aItem->
Type() )
4285 zone =
static_cast<const ZONE*
>( aItem );
4303 if( !layerVisible( aItem->
GetLayer() ) )
4315 if( !( visibleLayers() &
via->GetLayerSet() ).any() )
4321 field =
static_cast<const PCB_FIELD*
>( aItem );
4337 if( !layerVisible(
text->GetLayer() ) )
4348 if(
text->GetText() == wxT(
"${REFERENCE}" ) )
4350 else if(
text->GetText() == wxT(
"${VALUE}" ) )
4353 if( !
view()->IsLayerVisible( controlLayer ) )
4367 if( !layerVisible( aItem->
GetLayer() ) )
4376 if( !layerVisible( aItem->
GetLayer() ) )
4382 if( !layerVisible( aItem->
GetLayer() ) )
4390 if( !layerVisible( aItem->
GetLayer() ) )
4398 if( !layerVisible( aItem->
GetLayer() ) )
4411 if( !layerVisible( aItem->
GetLayer() ) )
4420 pad =
static_cast<const PAD*
>( aItem );
4428 marker =
static_cast<const PCB_MARKER*
>( aItem );
4436 if( !layerVisible( aItem->
GetLayer() ) )
4497 aGroup->
Add( aItem );
4566 const unsigned GRIP_MARGIN = 20;
4572 if( !item->IsBOARD_ITEM() )
4575 BOX2I itemBox = item->ViewBBox();
4580 if( item->HitTest( aPoint, margin ) )
4587 group->RunOnChildren(
4590 if( aItem->
HitTest( aPoint, margin ) )
4610 SEG loc( aWhere, aWhere );
4612 switch( aItem->
Type() )
4620 if(
text->GetEffectiveTextShape()->Collide( loc, aMaxDistance, &
distance ) )
4642 shape->Collide( loc, aMaxDistance, &
distance );
4663 ZONE* zone =
static_cast<ZONE*
>( aItem );
4685 catch(
const std::exception& e )
4687 wxFAIL_MSG( wxString::Format( wxT(
"Clipper exception occurred: %s" ), e.what() ) );
4717 int actual = aMaxDistance;
4719 if( poly->Outline().Collide( loc, aMaxDistance, &
actual ) )
4735 static_cast<PAD*
>( aItem )->Padstack().ForEachUniqueLayer(
4738 int layerDistance = INT_MAX;
4764 wxCHECK( settings, );
4767 LSET visibleLayers =
m_frame->GetBoard()->GetVisibleLayers();
4768 LSET enabledLayers =
m_frame->GetBoard()->GetEnabledLayers();
4771 wxCHECK( !enabledLayerStack.empty(), );
4773 auto isZoneFillKeepout =
4778 const ZONE* zone =
static_cast<const ZONE*
>( aItem );
4787 std::vector<LAYER_OPACITY_ITEM> opacityStackup;
4789 for(
int i = 0; i < aCollector.
GetCount(); i++ )
4793 LSET itemLayers = item->
GetLayerSet() & enabledLayers & visibleLayers;
4794 LSEQ itemLayerSeq = itemLayers.
Seq( enabledLayerStack );
4807 opacityItem.
m_Item = item;
4809 if( isZoneFillKeepout( item ) )
4812 opacityStackup.emplace_back( opacityItem );
4816 std::sort( opacityStackup.begin(), opacityStackup.end(),
4819 int retv = enabledLayerStack.TestLayers( aLhs.m_Layer, aRhs.m_Layer );
4824 return aLhs.m_Opacity > aRhs.m_Opacity;
4827 std::set<const BOARD_ITEM*> visibleItems;
4828 std::set<const BOARD_ITEM*> itemsToRemove;
4830 double currentStackupOpacity = 0.0;
4837 currentStackupOpacity = opacityItem.m_Opacity;
4838 lastVisibleLayer = opacityItem.m_Layer;
4839 visibleItems.emplace( opacityItem.m_Item );
4849 wxCHECK( item,
false );
4852 if( visibleItems.count( item ) )
4858 && visibleItems.count( item->
GetParent() ) )
4865 if( isZoneFillKeepout( item ) )
4872 if( opacityItem.m_Layer == enabledLayerStack[0] )
4874 visibleItems.emplace( opacityItem.m_Item );
4878 double itemVisibility = opacityItem.m_Opacity * ( 1.0 - currentStackupOpacity );
4880 if( ( itemVisibility <= minAlphaLimit ) && !ignoreItem() )
4881 itemsToRemove.emplace( opacityItem.m_Item );
4883 visibleItems.emplace( opacityItem.m_Item );
4886 if( opacityItem.m_Layer != lastVisibleLayer )
4888 currentStackupOpacity += opacityItem.m_Opacity * ( 1.0 - currentStackupOpacity );
4889 currentStackupOpacity = std::min( currentStackupOpacity, 1.0 );
4890 lastVisibleLayer = opacityItem.m_Layer;
4894 for(
const BOARD_ITEM* itemToRemove : itemsToRemove )
4896 wxCHECK( aCollector.
GetCount() > 1, );
4897 aCollector.
Remove( itemToRemove );
4920 static std::vector<KICAD_T> singleLayerSilkTypes = {
PCB_FIELD_T,
4932 std::set<BOARD_ITEM*> preferred;
4933 std::set<BOARD_ITEM*> rejected;
4940 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
4945 if( aCollector[i]->GetLayer() == activeLayer )
4946 preferred.insert( aCollector[i] );
4947 else if( aCollector.
GetCount() > 1 )
4953 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
4963 if( silkLayers[activeLayer] )
4965 for(
int i = 0; i < aCollector.
GetCount(); ++i )
4969 if( item->
IsType( singleLayerSilkTypes ) && silkLayers[ item->
GetLayer() ] )
4970 preferred.insert( item );
4975 else if( courtyardLayers[activeLayer] && settings->
GetHighContrast() )
4977 for(
int i = 0; i < aCollector.
GetCount(); ++i )
4982 preferred.insert( item );
4986 if( preferred.size() > 0 )
4991 aCollector.
Append( item );
4993 if( preferred.size() == 1 )
4998 constexpr int MAX_SLOP = 5;
5002 int minSlop = INT_MAX;
5004 std::map<BOARD_ITEM*, int> itemsBySloppiness;
5006 for(
int i = 0; i < aCollector.
GetCount(); ++i )
5011 itemsBySloppiness[ item ] = itemSlop;
5013 if( itemSlop < minSlop )
5018 if( minSlop < INT_MAX )
5020 for( std::pair<BOARD_ITEM*, int> pair : itemsBySloppiness )
5022 if( pair.second > minSlop + singlePixel )
5029 constexpr double sizeRatio = 1.5;
5031 std::vector<std::pair<BOARD_ITEM*, double>> itemsByArea;
5033 for(
int i = 0; i < aCollector.
GetCount(); ++i )
5042 area = (double)
SEG::Square( singlePixel ) * MAX_SLOP;
5061 catch(
const std::exception& e )
5063 wxFAIL_MSG( wxString::Format( wxT(
"Clipper exception occurred: %s" ), e.what() ) );
5067 itemsByArea.emplace_back( item, area );
5070 std::sort( itemsByArea.begin(), itemsByArea.end(),
5071 [](
const std::pair<BOARD_ITEM*, double>& lhs,
5072 const std::pair<BOARD_ITEM*, double>& rhs ) ->
bool
5074 return lhs.second < rhs.second;
5077 bool rejecting =
false;
5079 for(
int i = 1; i < (int) itemsByArea.size(); ++i )
5081 if( itemsByArea[i].second > itemsByArea[i-1].second * sizeRatio )
5085 rejected.insert( itemsByArea[i].first );
5090 constexpr double maxCoverRatio = 0.70;
5092 for(
int i = 0; i < aCollector.
GetCount(); ++i )
5096 if( footprint->CoverageRatio( aCollector ) > maxCoverRatio )
5097 rejected.erase( footprint );
5102 if( (
unsigned) aCollector.
GetCount() > rejected.size() )
5114 bool haveItemOnActive =
false;
5117 for(
int i = 0; i < aCollector.
GetCount(); ++i )
5119 if( !aCollector[i]->IsOnLayer( activeLayer ) )
5120 rejected.insert( aCollector[i] );
5122 haveItemOnActive =
true;
5125 if( haveItemOnActive )
5138 m_frame->ShowInfoBarWarning(
_(
"Selection contains locked items. "
5139 "Enable 'Override locks' to operate on them." ),
5149 bool lockedDescendant =
false;
5155 lockedDescendant =
true;
5159 return lockedDescendant;
5164 bool aIsFootprintEditor )
5200 for(
int i = (
int) aCollector.
GetCount() - 1; i >= 0; --i )
5206 aCollector.
Remove( &item );
5216 std::unordered_set<EDA_ITEM*> toAddSet;
5219 std::vector<EDA_ITEM*> toAdd;
5224 if( toAddSet.insert( aGroup ).second )
5225 toAdd.push_back( aGroup );
5230 for(
int j = 0; j < aCollector.
GetCount(); j++ )
5232 if( aCollector[j]->GetParent() )
5233 aCollector[j]->GetParent()->ClearFlags(
CANDIDATE );
5235 if( aCollector[j]->GetParentFootprint() )
5236 aCollector[j]->GetParentFootprint()->ClearFlags(
CANDIDATE );
5241 for(
int j = 0; j < aCollector.
GetCount(); j++ )
5245 for(
int j = 0; j < aCollector.
GetCount(); )
5257 aCollector.
Remove( item );
5274 selectableParent = gen;
5278 if( !selectableParent )
5282 if(
top->AsEdaItem() != item )
5284 queueGroup(
top->AsEdaItem() );
5287 aCollector.
Remove( item );
5294 for(
int k = aCollector.
GetCount() - 1; k >= 0; --k )
5296 if( aCollector[k] == selectableParent )
5312 aCollector.
Remove( item );
5321 if( !aCollector.
HasItem( item ) )
5322 aCollector.
Append( item );
5329 std::set<BOARD_ITEM*> to_add;
5332 for(
int i = (
int) aCollector.
GetCount() - 1; i >= 0; --i )
5341 aCollector.
Remove( item );
5346 aCollector.
Append( item );
5351 bool aForcePromotion )
const
5353 std::set<BOARD_ITEM*> to_add;
5356 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
5361 && ( !
frame()->GetPcbNewSettings()->m_AllowFreePads || aForcePromotion ) )
5366 aCollector.
Remove( item );
5371 aCollector.
Append( item );
5378 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
5383 aCollector.
Remove( item );
5395 bool need_direct_hit =
false;
5403 need_direct_hit =
true;
5411 else if( item->IsBOARD_ITEM() )
5412 fp =
static_cast<BOARD_ITEM*
>( item )->GetParentFootprint();
5418 single_fp =
nullptr;
5421 else if( !single_fp )
5427 else if( single_fp != fp )
5429 single_fp =
nullptr;
5435 auto visibleLayers =
5443 set.
set( layer,
view()->IsLayerVisible( layer ) );
5455 LSET layers = visibleLayers();
5463 for(
int layer : activeLayers )
5466 layers.
set( layer );
5471 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
5487 aCollector.
Remove( item );
5489 bool has_hit =
false;
5503 aCollector.
Remove( item );
5508 else if( single_fp )
5510 if( fp == single_fp )
5513 else if( need_direct_hit )
5527 aCollector.
Remove( item );
5544 std::set<std::pair<PCB_TABLE*, int>> columns;
5552 columns.insert( std::make_pair(
table, cell->GetColumn() ) );
5556 for(
auto& [
table, col ] : columns )
5558 for(
int row = 0; row <
table->GetRowCount(); ++row )
5579 std::set<std::pair<PCB_TABLE*, int>> rows;
5587 rows.insert( std::make_pair(
table, cell->GetRow() ) );
5591 for(
auto& [
table, row ] : rows )
5593 for(
int col = 0; col <
table->GetColCount(); ++col )
5614 std::set<PCB_TABLE*> tables;
5620 tables.insert(
static_cast<PCB_TABLE*
>( cell->GetParent() ) );
5627 if( !
table->IsSelected() )
std::function< void(const VECTOR2I &, GENERAL_COLLECTOR &, PCB_SELECTION_TOOL *)> CLIENT_SELECTION_FILTER
constexpr EDA_IU_SCALE pcbIUScale
constexpr BOX2I BOX2ISafe(const BOX2D &aInput)
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static TOOL_ACTION cancelInteractive
static TOOL_ACTION unselectAll
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
static TOOL_ACTION cursorLeft
static TOOL_ACTION zoomOutCenter
static TOOL_ACTION unselectItem
static TOOL_ACTION zoomIn
static TOOL_ACTION cursorLeftFast
static TOOL_ACTION selectionCursor
Select a single item under the cursor position.
static TOOL_ACTION selectSetLasso
static TOOL_ACTION selectSetRect
Set lasso selection mode.
static TOOL_ACTION groupEnter
static TOOL_ACTION selectColumns
static TOOL_ACTION cursorDown
static TOOL_ACTION zoomOut
static TOOL_ACTION cursorRightFast
static TOOL_ACTION deleteLastPoint
static TOOL_ACTION zoomCenter
static TOOL_ACTION panDown
static TOOL_ACTION cursorDblClick
static TOOL_ACTION selectionActivate
Activation of the selection tool.
static TOOL_ACTION cursorDownFast
static TOOL_ACTION selectionMenu
Run a selection menu to select from a list of items.
static TOOL_ACTION reselectItem
static TOOL_ACTION selectRows
static TOOL_ACTION cursorUpFast
static TOOL_ACTION panLeft
static TOOL_ACTION updateMenu
static TOOL_ACTION doDelete
static TOOL_ACTION selectionTool
static TOOL_ACTION cursorClick
static TOOL_ACTION zoomFitScreen
static TOOL_ACTION increment
static TOOL_ACTION selectionClear
Clear the current selection.
static TOOL_ACTION zoomFitObjects
static TOOL_ACTION zoomInCenter
static TOOL_ACTION panRight
static TOOL_ACTION selectTable
static TOOL_ACTION cursorUp
Cursor control with keyboard.
static TOOL_ACTION groupLeave
static TOOL_ACTION finishInteractive
static TOOL_ACTION cursorRight
static TOOL_ACTION selectAll
static TOOL_ACTION unselectItems
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
BASE_SET & reset(size_t pos)
BASE_SET & set(size_t pos)
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,...
static bool ClassOf(const EDA_ITEM *aItem)
NETINFO_ITEM * GetNet() const
Return NETINFO_ITEM object for a given item.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual bool IsConnected() const
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
bool IsLocked() const override
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
virtual VECTOR2I GetCenter() const
This defaults to the center of the bounding box if not overridden.
virtual double GetCoverageArea(int aTextMargin) const
Return the board area this item covers, used to rank candidates under the cursor so a click on a smal...
FOOTPRINT * GetParentFootprint() const
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
virtual void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const
Invoke a function on all children.
BOARD_ITEM_CONTAINER * GetParent() const
virtual bool IsOnCopperLayer() const
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT, DRC_CONSTRAINT_T aUsage=NULL_CONSTRAINT) const
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Information pertinent to a Pcbnew printed circuit board.
INSPECT_RESULT Visit(INSPECTOR inspector, void *testData, const std::vector< KICAD_T > &scanTypes) override
May be re-implemented for each derived class in order to handle all the types given by its member dat...
bool IsFootprintLayerVisible(PCB_LAYER_ID aLayer) const
Expect either of the two layers on which a footprint can reside, and returns whether that layer is vi...
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Test whether a given element category is visible.
const LSET & GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
bool IsLayerVisible(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
constexpr void SetMaximum()
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
constexpr size_type GetWidth() const
constexpr Vec Centre() const
constexpr size_type GetHeight() const
constexpr bool Contains(const Vec &aPoint) const
constexpr const Vec & GetOrigin() const
constexpr const SizeVec & GetSize() const
CN_ANCHOR represents a physical location that can be connected: a pad or a track/arc/via endpoint.
BOARD_CONNECTED_ITEM * Parent() const
CN_EDGE represents a point-to-point connection, whether realized or unrealized (ie: tracks etc.
CN_ITEM represents a BOARD_CONNECTED_ITEM in the connectivity system (ie: a pad, track/arc/via,...
virtual double OnePixelInIU() const =0
virtual int Accuracy() const =0
void Transfer(int aIndex)
Move the item at aIndex (first position is 0) to the backup list.
void Empty()
Clear the list.
int GetCount() const
Return the number of objects in the list.
bool HasItem(const EDA_ITEM *aItem) const
Tests if aItem has already been collected.
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
void Append(EDA_ITEM *item)
Add an item to the end of the list.
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
A set of EDA_ITEMs (i.e., without duplicates).
std::unordered_set< EDA_ITEM * > & GetItems()
bool HasDesignBlockLink() const
virtual EDA_ITEM * AsEdaItem()=0
A base class for most all the KiCad significant classes used in schematics and boards.
virtual VECTOR2I GetPosition() const
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
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 bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
virtual bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const
Test if aPosition is inside or on the boundary of this item.
EDA_ITEM * GetParent() const
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
EDA_ITEM_FLAGS GetFlags() const
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
virtual std::vector< SHAPE * > MakeEffectiveShapesForHitTesting() const
virtual bool IsVisible() const
std::shared_ptr< SHAPE_COMPOUND > GetEffectiveTextShape(bool aTriangulate=true, const BOX2I &aBBox=BOX2I(), const EDA_ANGLE &aAngle=ANGLE_0) const
Build a list of segments (SHAPE_SEGMENT) to describe a text shape.
static const TOOL_EVENT DisambiguatePoint
Used to inform tool that it should display the disambiguation menu.
static const TOOL_EVENT ClearedEvent
static const TOOL_EVENT InhibitSelectionEditing
Used to inform tools that the selection should temporarily be non-editable.
static const TOOL_EVENT SelectedEvent
static const TOOL_EVENT SelectedItemsModified
Selected item had a property changed (except movement)
static const TOOL_EVENT UninhibitSelectionEditing
static const TOOL_EVENT PointSelectedEvent
static const TOOL_EVENT SelectedItemsMoved
Selected items were moved, this can be very high frequency on the canvas, use with care.
static const TOOL_EVENT UnselectedEvent
A general implementation of a COLLECTORS_GUIDE.
void SetIgnoreBlindBuriedVias(bool ignore)
void SetIgnoreTracks(bool ignore)
void SetIgnoreFootprintsOnFront(bool ignore)
void SetIgnoreFPTextOnFront(bool ignore)
void SetIgnoreMicroVias(bool ignore)
void SetIgnoreZoneFills(bool ignore)
void SetIgnorePadsOnBack(bool ignore)
void SetIgnoreFPTextOnBack(bool ignore)
void SetLayerVisibleBits(const LSET &aLayerBits)
void SetIgnoreThroughVias(bool ignore)
void SetIgnoreThroughHolePads(bool ignore)
void SetIgnoreFPReferences(bool ignore)
void SetIgnoreFPValues(bool ignore)
void SetIgnorePadsOnFront(bool ignore)
void SetIgnoreFootprintsOnBack(bool ignore)
Used when the right click button is pressed, or when the select tool is in effect.
void SetGuide(const COLLECTORS_GUIDE *aGuide)
Record which COLLECTORS_GUIDE to use.
const COLLECTORS_GUIDE * GetGuide() const
static const std::vector< KICAD_T > AllBoardItems
A scan list for all editable board items.
void Collect(BOARD_ITEM *aItem, const std::vector< KICAD_T > &aScanList, const VECTOR2I &aRefPos, const COLLECTORS_GUIDE &aGuide)
Scan a BOARD_ITEM using this class's Inspector method, which does the collection.
static const std::vector< KICAD_T > FootprintItems
A scan list for primary footprint items.
A color representation with 4 components: red, green, blue, alpha.
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const override
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1) override
Add a VIEW_ITEM to the view.
virtual void Remove(VIEW_ITEM *aItem) override
Remove a VIEW_ITEM from the view.
Represent a selection area (currently a rectangle) in a VIEW, drawn corner-to-corner between two poin...
VECTOR2I GetOrigin() const
void SetMode(SELECTION_MODE aMode)
void SetSubtractive(bool aSubtractive)
SELECTION_MODE GetMode() const
void SetAdditive(bool aAdditive)
void SetPoly(SHAPE_LINE_CHAIN &aPoly)
void SetOrigin(const VECTOR2I &aOrigin)
Set the origin of the rectangle (the fixed corner)
const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
SHAPE_LINE_CHAIN & GetPoly()
void SetExclusiveOr(bool aExclusiveOr)
void SetEnd(const VECTOR2I &aEnd)
Set the current end of the rectangle (the corner that moves with the cursor.
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
const std::set< int > & GetHighlightNetCodes() const
Return the netcode of currently highlighted net.
const std::set< int > GetHighContrastLayers() const
Returns the set of currently high-contrast layers.
virtual COLOR4D GetColor(const VIEW_ITEM *aItem, int aLayer) const =0
Returns the color that should be used to draw the specific VIEW_ITEM on the specific layer using curr...
bool GetHighContrast() const
void SetHighlight(bool aEnabled, int aNetcode=-1, bool aMulti=false)
Turns on/off highlighting.
virtual void SetCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true, bool aTriggeredByArrows=false, long aArrowCommand=0)=0
Move cursor to the requested position expressed in world coordinates.
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
An abstract base class for deriving all objects that can be added to a VIEW.
bool IsBOARD_ITEM() const
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
BOX2D GetViewport() const
Return the current viewport visible area rectangle.
virtual void SetScale(double aScale, VECTOR2D aAnchor={ 0, 0 })
Set the scaling factor, zooming around a given anchor point.
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
int Query(const BOX2I &aRect, std::vector< LAYER_ITEM_PAIR > &aResult) const
Find all visible items that touch or are within the rectangle aRect.
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
void Hide(VIEW_ITEM *aItem, bool aHide=true, bool aHideOverlay=false)
Temporarily hide the item in the view (e.g.
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
PAINTER * GetPainter() const
Return the painter object used by the view for drawing VIEW_ITEM objects.
void MarkTargetDirty(int aTarget)
Set or clear target 'dirty' flag.
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Set the item visibility.
wxString AsString() const
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
LSET is a set of PCB_LAYER_IDs.
static const LSET & FrontMask()
Return a mask holding all technical layers and the external CU layer on front side.
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
static const LSET & BackMask()
Return a mask holding all technical layers and the external CU layer on back side.
LSEQ CuStack() const
Return a sequence of copper layers in starting from the front/top and extending to the back/bottom.
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
LSEQ SeqStackupTop2Bottom(PCB_LAYER_ID aSelectedLayer=UNDEFINED_LAYER) const
Generate a sequence of layers that represent a top to bottom stack of this set of layers.
static const LSET & AllLayersMask()
static const LSET & PhysicalLayersMask()
Return a mask holding all layers which are physically realized.
bool Contains(PCB_LAYER_ID aLayer) const
See if the layer set contains a PCB layer.
const VECTOR2I & GetPos() const
void ShapeToPolygon(SHAPE_LINE_CHAIN &aPolygon, int aScale=-1) const
Return the shape polygon in internal units in a SHAPE_LINE_CHAIN the coordinates are relatives to the...
Handle the data for a net.
const wxString & GetNetChain() const
PAD * GetTerminalPad(int aIndex) const
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
PAD_ATTRIB GetAttribute() const
static TOOL_ACTION drag45Degree
static TOOL_ACTION selectNetChain
Select all connections belonging to every net in the current item's net chain.
static TOOL_ACTION unrouteSelected
Removes all tracks from the selected items to the first pad.
static TOOL_ACTION saveToLinkedDesignBlock
static TOOL_ACTION grabUnconnected
Select and move nearest unconnected footprint from ratsnest of selection.
static TOOL_ACTION filterSelection
Filter the items in the current selection (invokes dialog)
static TOOL_ACTION setTerminalPad
static TOOL_ACTION highlightNet
static TOOL_ACTION hideLocalRatsnest
static TOOL_ACTION properties
Activation of the edit tool.
static TOOL_ACTION highlightNetChain
static TOOL_ACTION selectOnSheetFromEeschema
Select all components on sheet from Eeschema crossprobing.
static TOOL_ACTION selectConnection
Select tracks between junctions or expands an existing selection to pads or the entire connection.
static TOOL_ACTION applyDesignBlockLayout
static TOOL_ACTION dragFreeAngle
static TOOL_ACTION clearHighlight
static TOOL_ACTION convertImageToOutlines
static TOOL_ACTION selectUnconnected
Select unconnected footprints from ratsnest of selection.
static TOOL_ACTION unrouteSegment
Removes track segment from the selected item to the next segment.
static TOOL_ACTION moveIndividually
move items one-by-one
static TOOL_ACTION syncSelection
Sets selection to specified items, zooms to fit, if enabled.
static TOOL_ACTION selectSameSheet
Select all components on the same sheet as the selected footprint.
static TOOL_ACTION selectNet
Select all connections belonging to a single net.
static TOOL_ACTION move
move or drag an item
static TOOL_ACTION syncSelectionWithNets
Sets selection to specified items with connected nets, zooms to fit, if enabled.
static TOOL_ACTION deselectNet
Remove all connections belonging to a single net from the active selection.
static TOOL_ACTION placeLinkedDesignBlock
static TOOL_ACTION selectOnSchematic
Select symbols/pins on schematic corresponding to selected footprints/pads.
Common, abstract interface for edit frames.
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
const PCB_DISPLAY_OPTIONS & GetDisplayOptions() const
Display options control the way tracks, vias, outlines and other things are shown (for instance solid...
double m_TrackOpacity
Opacity override for all tracks.
double m_FilledShapeOpacity
Opacity override for graphic shapes.
double m_ZoneOpacity
Opacity override for filled zone areas.
double m_ImageOpacity
Opacity override for user images.
double m_PadOpacity
Opacity override for SMD pads and PTHs.
double m_ViaOpacity
Opacity override for all types of via.
ZONE_DISPLAY_MODE m_ZoneDisplayMode
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the KIGFX::VIEW instance used in the panel.
A drill chart placed on the board, kept in step with the holes.
bool IsDataRow(int aRow) const override
True for a row that reports a drill group, false for the title, heading and totals.
The main frame for Pcbnew.
virtual ACTION_MENU * GetChildContextMenu(TOOL_INTERACTIVE *aTool) const
Get a context menu when interacting with a generator child.
virtual bool IsSelectableAsConnected() const
Indicates whether the generator can be selected as a connected entity.
virtual bool ChildrenAreIndividuallySelectable() const
A set of BOARD_ITEMs (i.e., without duplicates).
static EDA_GROUP * TopLevelGroup(const BOARD_ITEM &aItem, const EDA_GROUP *aScope, bool isFootprintEditor)
Search for highest level group inside of aScope, containing item.
std::unordered_set< BOARD_ITEM * > GetBoardItems() const
static bool WithinScope(const BOARD_ITEM &aItem, const PCB_GROUP *aScope, bool isFootprintEditor)
Tool that displays edit points allowing to modify items by dragging the points.
bool HasPoint()
Indicate the cursor is over an edit point.
A PCB_POINT is a 0-dimensional point that is used to mark a position on a PCB, or more usually a foot...
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
std::vector< VECTOR2I > GetConnectionPoints() const
std::vector< PCB_TABLECELL * > GetCells() const
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
const VECTOR2I & GetStart() const
const VECTOR2I & GetEnd() const
VECTOR2I GetPosition() const override
int GetWidth() const override
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
A small class to help profiling.
void Start()
Start or restart the counter.
double msecs(bool aSinceLast=false)
Describe ratsnest for a single net.
const std::vector< CN_EDGE > & GetEdges() const
static SEG::ecoord Square(int a)
static SELECTION_CONDITION HasType(KICAD_T aType)
Create a functor that tests if among the selected items there is at least one of a given type.
static bool NotEmpty(const SELECTION &aSelection)
Test if there are any items selected.
static SELECTION_CONDITION MoreThan(int aNumber)
Create a functor that tests if the number of selected items is greater than the value given as parame...
static SELECTION_CONDITION Count(int aNumber)
Create a functor that tests if the number of selected items is equal to the value given as parameter.
static SELECTION_CONDITION OnlyTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if the selected items are only of given types.
virtual void Add(EDA_ITEM *aItem)
A null aItem is ignored; the selection never holds null members.
virtual void Remove(EDA_ITEM *aItem)
void ClearReferencePoint()
bool Empty() const
Checks if there is anything selected.
bool Collide(const SEG &aSeg, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the segment aSeg than aClearance,...
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void Move(const VECTOR2I &aVector) override
void GenerateBBoxCache() const
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
int PointCount() const
Return the number of points (vertices) in this line chain.
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if point aP lies closer to us than aClearance.
double Area(bool aAbsolute=true) const
Return the area of this chain.
virtual size_t GetPointCount() const override
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CLastPoint() const
Return the last point in the line chain.
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] from the line chain.
bool Collide(const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the shape aShape than aClearance,...
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
Handle a list of polygons defining a copper zone.
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
bool HitTestForCorner(const VECTOR2I &refPos, int aAccuracy, SHAPE_POLY_SET::VERTEX_INDEX *aCornerHit=nullptr) const
Test if the given VECTOR2I is near a corner.
bool HitTestForEdge(const VECTOR2I &refPos, int aAccuracy, SHAPE_POLY_SET::VERTEX_INDEX *aCornerHit=nullptr) const
Test if the given VECTOR2I is near a segment defined by 2 corners.
bool IsTeardropArea() const
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
bool GetDoNotAllowZoneFills() const
A type-safe container of any type.
#define IGNORE_NETS
Return a list of items connected to a source item aItem.
#define DEFAULT_TEXT_SIZE
The default text size in mils. (can be changed in preference menu)
static bool empty(const wxTextEntryBase *aCtrl)
std::function< INSPECT_RESULT(EDA_ITEM *aItem, void *aTestData) > INSPECTOR_FUNC
Used to inspect and possibly collect the (search) results of iterating over a list or tree of KICAD_T...
#define BRIGHTENED
item is drawn with a bright contour
#define IS_NEW
New item, just created.
#define SELECTED
Item was manually selected by the user.
#define ENTERED
indicates a group has been entered
#define SKIP_STRUCT
flag indicating that the structure should be ignored
#define CANDIDATE
flag indicating that the structure is connected
#define IS_MOVING
Item being moved.
a few functions useful in geometry calculations.
double m_PcbSelectionVisibilityRatio
Board object selection visibility limit.
@ LAYER_POINTS
PCB reference/manual snap points visibility.
@ LAYER_FOOTPRINTS_FR
Show footprints on front.
@ LAYER_DRAW_BITMAPS
Draw images.
@ LAYER_FP_REFERENCES
Show footprints references (when texts are visible).
@ LAYER_DRC_EXCLUSION
Layer for DRC markers which have been individually excluded.
@ LAYER_ZONES
Control for copper zone opacity/visibility (color ignored).
@ LAYER_PADS
Meta control for all pads opacity/visibility (color ignored).
@ LAYER_FOOTPRINTS_BK
Show footprints on back.
@ LAYER_FP_VALUES
Show footprints values (when texts are visible).
@ LAYER_SUBGRIDS
Routing/placement subgrids (PCB_GRID_ITEM) visibility and color.
@ LAYER_VIAS
Meta control for all vias opacity/visibility.
PCB_LAYER_ID
A quick note on layer IDs:
PCB_LAYER_ID ToLAYER_ID(int aLayer)
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
bool BoxHitTest(const VECTOR2I &aHitPoint, const BOX2I &aHittee, int aAccuracy)
Perform a point-to-box hit test.
@ REPAINT
Item needs to be redrawn.
@ TARGET_OVERLAY
Items that may change while the view stays the same (noncached)
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
@ PTH
Plated through hole pad.
Class to handle a set of BOARD_ITEMs.
bool IsGeneratedTableCell(const EDA_ITEM *aItem)
True for a cell whose text is generated from the board, so only its formatting is the user's.
Class that computes missing connections on a PCB.
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
std::function< bool(const SELECTION &)> SELECTION_CONDITION
Functor type that checks a specific condition for selected items.
Increment event parameters.
Struct that will be set with the result of the user choices in the dialog.
bool includeLockedFootprints
bool includeItemsOnTechLayers
bool includeBoardOutlineLayer
const BOARD_ITEM * m_Item
This file contains data structures that are saved in the project file or project local settings file ...
bool otherItems
Anything not fitting one of the above categories.
bool vias
Vias (all types>
bool gridItems
Grid Items.
bool keepouts
Keepout zones.
bool graphics
Graphic lines, shapes, polygons.
bool footprints
Allow selecting entire footprints.
bool text
Text (free or attached to a footprint)
bool lockedItems
Allow selecting locked items.
bool tracks
Copper tracks.
bool dimensions
Dimension items.
KIBIS top(path, &reporter)
static std::vector< int > candidates(const SEGMENT_INDEX &aIndex, const SEG &aQuery, int aPadding)
wxLogTrace helper definitions.
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
@ PCB_CONSTRAINT_T
a geometric constraint between board items
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_DRILL_MAP_T
class PCB_DRILL_MAP, drill symbols drawn at the holes
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
@ PCB_ZONE_T
class ZONE, a copper pour area
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
@ NOT_USED
the 3d code uses this value
@ PCB_MARKER_T
class PCB_MARKER, a marker used to show something
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_GRID_ITEM_T
a subgrid placed on a board
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
@ PCB_NETINFO_T
class NETINFO_ITEM, a description of a net
@ PCB_POINT_T
class PCB_POINT, a 0-dimensional point
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
@ PCB_DRILL_CHART_T
class PCB_DRILL_CHART, a live drill chart derived from PCB_TABLE
Casted dyn_cast(From aObject)
A lightweight dynamic downcast.
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D
VECTOR2D ToVECTOR2D(const wxPoint &aPoint)