67using namespace std::placeholders;
69#include <wx/hyperlink.h>
73#include <dialogs/dialog_tablecell_properties.h>
74#include <dialogs/dialog_table_properties.h>
84 m_selectionTool( nullptr ),
94 m_statusPopup = std::make_unique<STATUS_TEXT_POPUP>( getEditFrame<PCB_BASE_EDIT_FRAME>() );
100 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
103 menu->SetTitle(
_(
"Positioning Tools" ) );
105 auto notMovingCondition = [](
const SELECTION& aSelection )
107 return aSelection.Empty() || !aSelection.Front()->IsMoving();
122 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
124 menu->SetTitle(
_(
"Shape Modification" ) );
139 auto hasCornerCondition =
147 auto hasMidpointCondition =
189 auto positioningToolsCondition =
193 subMenu->Evaluate( aSel );
194 return subMenu->GetMenuItemCount() > 0;
197 auto shapeModificationCondition =
201 subMenu->Evaluate( aSel );
202 return subMenu->GetMenuItemCount() > 0;
205 auto propertiesCondition =
208 if( aSel.GetSize() == 0 )
222 if( aSel.GetSize() == 1 )
234 auto inFootprintEditor =
255 auto multipleFootprintsCondition =
258 bool foundFirst =
false;
274 auto noActiveToolCondition =
280 auto notMovingCondition =
283 return aSelection.Empty() || !aSelection.Front()->IsMoving();
286 auto noItemsCondition =
287 [ this ](
const SELECTION& aSelections ) ->
bool
304 static std::vector<KICAD_T> unroutableTypes = {
PCB_TRACE_T,
310 static std::vector<KICAD_T> trackTypes = {
PCB_TRACE_T,
319 && notMovingCondition );
322 && notMovingCondition
323 && !inFootprintEditor );
325 && notMovingCondition );
347 && !inFootprintEditor );
360 menu.
AddMenu( shapeModificationSubMenu.get(), shapeModificationCondition, 100 );
361 menu.
AddMenu( positioningToolsSubMenu.get(), positioningToolsCondition, 100 );
391 FOOTPRINT* fp = getEditFrame<PCB_BASE_FRAME>()->GetFootprintFromBoardByReference();
482 std::vector<PCB_TRACK*> tracks;
483 std::vector<PCB_TRACK*> vias;
487 if( PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( item ) )
489 if( track->Type() == PCB_VIA_T )
490 vias.push_back( track );
492 tracks.push_back( track );
501 if( tracks.size() == 2 && vias.size() == 0 )
503 if( connected( tracks[0], tracks[1]->GetStart() )
504 || connected( tracks[0], tracks[1]->GetEnd() ) )
506 aCollector.
Remove( tracks[1] );
509 else if( tracks.size() == 2 && vias.size() == 1 )
511 if( connected( tracks[0], vias[0]->GetPosition() )
512 && connected( tracks[1], vias[0]->GetPosition() ) )
514 aCollector.
Remove( tracks[0] );
515 aCollector.
Remove( tracks[1] );
521 if( selection.Empty() )
524 if( selection.Size() == 1 && selection.Front()->Type() ==
PCB_ARC_T )
528 return DragArcTrack( aEvent );
532 invokeInlineRouter( mode );
551 wxString msg = wxString::Format(
_(
"Unable to resize arc tracks of %s or greater." ),
566 bool restore_state =
false;
580 tanStart.
A = *tanIntersect;
582 tanEnd.
A = *tanIntersect;
585 std::set<PCB_TRACK*> addedTracks;
587 auto getUniqueTrackAtAnchorCollinear =
593 int allowedDeviation = theArc->
GetWidth();
595 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
597 for(
int i = 0; i < 3; i++ )
599 itemsOnAnchor = conn->GetConnectedItemsAtAnchor( theArc, aAnchor,
603 allowedDeviation /= 2;
605 if( itemsOnAnchor.size() == 1 )
611 if( itemsOnAnchor.size() == 1 && itemsOnAnchor.front()->Type() ==
PCB_TRACE_T )
613 track =
static_cast<PCB_TRACK*
>( itemsOnAnchor.front() );
619 if( trackSeg.
Angle( aCollinearSeg ) > maxTangentDeviation )
634 addedTracks.insert( track );
640 PCB_TRACK* trackOnStart = getUniqueTrackAtAnchorCollinear( theArc->
GetStart(), tanStart);
641 PCB_TRACK* trackOnEnd = getUniqueTrackAtAnchorCollinear( theArc->
GetEnd(), tanEnd );
646 tanStart.
B = trackOnStart->
GetEnd();
652 tanEnd.
B = trackOnEnd->
GetEnd();
656 if( tanIntersect = tanStart.
IntersectLines( tanEnd ); !tanIntersect )
659 auto isTrackStartClosestToArcStart =
665 return trackStartToArcStart < trackEndToArcStart;
668 bool isStartTrackOnStartPt = isTrackStartClosestToArcStart( trackOnStart );
669 bool isEndTrackOnStartPt = isTrackStartClosestToArcStart( trackOnEnd );
698 auto getFurthestPointToTanInterstect =
701 if( ( aPointA - *tanIntersect ).EuclideanNorm()
713 VECTOR2I tanStartPoint = getFurthestPointToTanInterstect( tanStart.
A, tanStart.
B );
714 VECTOR2I tanEndPoint = getFurthestPointToTanInterstect( tanEnd.
A, tanEnd.
B );
715 VECTOR2I tempTangentPoint = tanEndPoint;
717 if( getFurthestPointToTanInterstect( tanStartPoint, tanEndPoint ) == tanEndPoint )
718 tempTangentPoint = tanStartPoint;
724 SEG cSegTanStart( maxTanPtStart, *tanIntersect );
725 SEG cSegTanEnd( maxTanPtEnd, *tanIntersect );
726 SEG cSegChord( maxTanPtStart, maxTanPtEnd );
728 int cSegTanStartSide = cSegTanStart.
Side( theArc->
GetMid() );
729 int cSegTanEndSide = cSegTanEnd.
Side( theArc->
GetMid() );
730 int cSegChordSide = cSegChord.
Side( theArc->
GetMid() );
732 bool eatFirstMouseUp =
true;
744 std::vector<VECTOR2I> possiblePoints;
751 for(
const VECTOR2I& candidate : possiblePoints )
753 if( ( candidate -
m_cursor ).SquaredEuclideanNorm()
754 < ( closest -
m_cursor ).SquaredEuclideanNorm() )
783 if( isStartTrackOnStartPt )
786 trackOnStart->
SetEnd( newStart );
788 if( isEndTrackOnStartPt )
791 trackOnEnd->
SetEnd( newEnd );
799 if( evt->IsMotion() || evt->IsDrag(
BUT_LEFT ) )
801 eatFirstMouseUp =
false;
803 else if( evt->IsCancelInteractive() || evt->IsActivate() )
805 restore_state =
true;
810 restore_state =
true;
819 eatFirstMouseUp =
false;
831 if( isStartTrackOnStartPt )
832 newStart = trackOnStart->
GetEnd();
834 if( isEndTrackOnStartPt )
835 newEnd = trackOnEnd->
GetEnd();
840 if( trackOnStart->
GetLength() <= maxLengthIU )
842 if( addedTracks.count( trackOnStart ) )
845 addedTracks.erase( trackOnStart );
850 commit.
Remove( trackOnStart );
856 if( trackOnEnd->
GetLength() <= maxLengthIU )
858 if( addedTracks.count( trackOnEnd ) )
861 addedTracks.erase( trackOnEnd );
866 commit.
Remove( trackOnEnd );
885 commit.
Push(
_(
"Drag Arc Track" ) );
897 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
899 BOARD_ITEM* item = aCollector[ i ];
901 if( !dynamic_cast<PCB_TRACK*>( item ) )
902 aCollector.Remove( item );
920 if(
via->GetViaType() == VIATYPE::MICROVIA )
933 via->SetDrill( new_drill );
934 via->SetWidth( new_width );
949 commit.
Push(
_(
"Edit Track Width/Via Size" ) );
966 static int filletRadius = 0;
972 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
974 BOARD_ITEM* item = aCollector[i];
976 if( !dynamic_cast<PCB_TRACK*>( item ) )
977 aCollector.Remove( item );
982 if( selection.
Size() < 2 )
991 if( dlg.ShowModal() == wxID_CANCEL )
996 if( filletRadius == 0 )
999 "The fillet operation was not performed." ) );
1008 bool t1Start =
true;
1009 bool t2Start =
true;
1012 std::vector<FILLET_OP> filletOperations;
1013 bool operationPerformedOnAtLeastOne =
false;
1014 bool didOneAttemptFail =
false;
1015 std::set<PCB_TRACK*> processedTracks;
1017 auto processFilletOp =
1018 [&](
PCB_TRACK* aTrack,
bool aStartPoint )
1022 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
1024 itemsOnAnchor = c->GetConnectedItemsAtAnchor( aTrack,
anchor,
1028 if( itemsOnAnchor.size() > 0
1029 && selection.
Contains( itemsOnAnchor.at( 0 ) )
1035 if( processedTracks.find( trackOther ) == processedTracks.end() )
1037 if( itemsOnAnchor.size() == 1 )
1040 filletOp.t1 = aTrack;
1041 filletOp.t2 = trackOther;
1042 filletOp.t1Start = aStartPoint;
1043 filletOp.t2Start = aTrack->
IsPointOnEnds( filletOp.t2->GetStart() );
1044 filletOperations.push_back( filletOp );
1050 didOneAttemptFail =
true;
1064 processFilletOp( track,
true );
1065 processFilletOp( track,
false );
1067 processedTracks.insert( track );
1073 std::vector<BOARD_ITEM*> itemsToAddToSelection;
1075 for( FILLET_OP filletOp : filletOperations )
1083 if( trackOnStart && trackOnEnd )
1086 if( ( trackOnStart || trackOnEnd ) && track1->
GetLayer() == track2->
GetLayer() )
1094 SHAPE_ARC sArc( t1Seg, t2Seg, filletRadius );
1097 auto setIfPointOnSeg =
1100 VECTOR2I segToVec = aSegment.NearestPoint( aVecToTest ) - aVecToTest;
1105 aPointToSet.
x = aVecToTest.x;
1106 aPointToSet.
y = aVecToTest.y;
1114 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP0() )
1115 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP0() ) )
1117 didOneAttemptFail =
true;
1121 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP1() )
1122 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP1() ) )
1124 didOneAttemptFail =
true;
1134 itemsToAddToSelection.push_back( tArc );
1139 if( filletOp.t1Start )
1142 track1->
SetEnd( t1newPoint );
1144 if( filletOp.t2Start )
1147 track2->
SetEnd( t2newPoint );
1149 operationPerformedOnAtLeastOne =
true;
1153 commit.
Push(
_(
"Fillet Tracks" ) );
1156 for(
BOARD_ITEM* item : itemsToAddToSelection )
1159 if( !operationPerformedOnAtLeastOne )
1161 else if( didOneAttemptFail )
1178 static int filletRadius = 0;
1183 if( dlg.ShowModal() == wxID_CANCEL )
1184 return std::nullopt;
1188 if( filletRadius == 0 )
1190 aErrorMsg =
_(
"A radius of zero was entered.\n"
1191 "The fillet operation was not performed." );
1192 return std::nullopt;
1195 return filletRadius;
1207 wxString& aErrorMsg )
1212 static CHAMFER_PARAMS params{ default_setback, default_setback };
1215 params.m_chamfer_setback_a );
1217 if( dlg.ShowModal() == wxID_CANCEL )
1218 return std::nullopt;
1220 params.m_chamfer_setback_a = dlg.
GetValue();
1223 params.m_chamfer_setback_b = params.m_chamfer_setback_a;
1226 if( params.m_chamfer_setback_a == 0 )
1228 aErrorMsg =
_(
"A setback of zero was entered.\n"
1229 "The chamfer operation was not performed." );
1230 return std::nullopt;
1241 std::vector<VECTOR2I> pts;
1244 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1246 BOARD_ITEM* item = aCollector[i];
1250 if( !item->IsType( { PCB_SHAPE_LOCATE_SEGMENT_T,
1251 PCB_SHAPE_LOCATE_POLY_T,
1252 PCB_SHAPE_LOCATE_RECT_T } ) )
1254 aCollector.
Remove( item );
1260 std::set<PCB_SHAPE*> lines_to_add;
1261 std::vector<PCB_SHAPE*> items_to_remove;
1265 std::vector<VECTOR2I> pts;
1272 items_to_remove.push_back( graphic );
1275 pts.emplace_back( start );
1276 pts.emplace_back(
VECTOR2I( end.x, start.y ) );
1277 pts.emplace_back( end );
1278 pts.emplace_back(
VECTOR2I( start.x, end.y ) );
1283 items_to_remove.push_back( graphic );
1285 for(
int jj = 0; jj < graphic->
GetPolyShape().VertexCount(); ++jj )
1289 for(
size_t jj = 1; jj < pts.size(); ++jj )
1297 lines_to_add.insert( line );
1300 if( pts.size() > 1 )
1305 line->
SetEnd( pts.front() );
1308 lines_to_add.insert( line );
1313 selection.Add( item );
1315 for(
PCB_SHAPE* item : items_to_remove )
1316 selection.Remove( item );
1320 frame()->ShowInfoBarMsg(
_(
"A shape with least two lines must be selected." ) );
1328 std::vector<PCB_SHAPE*> items_to_select_on_success;
1331 std::vector<PCB_SHAPE*> items_to_deselect_on_success;
1336 const auto item_modification_handler = [&](
PCB_SHAPE& aItem )
1342 items_to_select_on_success.push_back( &aItem );
1346 bool any_items_created = !lines_to_add.empty();
1347 const auto item_creation_handler = [&]( std::unique_ptr<PCB_SHAPE> aItem )
1349 any_items_created =
true;
1350 items_to_select_on_success.push_back( aItem.get() );
1351 commit.
Add( aItem.release() );
1354 bool any_items_removed = !items_to_remove.empty();
1355 const auto item_removal_handler = [&](
PCB_SHAPE& aItem )
1357 any_items_removed =
true;
1358 items_to_deselect_on_success.push_back( &aItem );
1364 item_creation_handler, item_modification_handler, item_removal_handler );
1367 std::unique_ptr<PAIRWISE_LINE_ROUTINE> pairwise_line_routine;
1368 wxString error_message;
1372 const std::optional<int> filletRadiusIU =
GetFilletParams( *frame(), error_message );
1374 if( filletRadiusIU.has_value() )
1376 pairwise_line_routine = std::make_unique<LINE_FILLET_ROUTINE>(
1377 frame()->
GetModel(), change_handler, *filletRadiusIU );
1382 const std::optional<CHAMFER_PARAMS> chamfer_params =
1385 if( chamfer_params.has_value() )
1387 pairwise_line_routine = std::make_unique<LINE_CHAMFER_ROUTINE>(
1388 frame()->
GetModel(), change_handler, *chamfer_params );
1395 error_message =
_(
"Exactly two lines must be selected to extend them." );
1399 pairwise_line_routine =
1400 std::make_unique<LINE_EXTENSION_ROUTINE>( frame()->
GetModel(), change_handler );
1404 if( !pairwise_line_routine )
1407 if( !error_message.empty() )
1408 frame()->ShowInfoBarMsg( error_message );
1417 PCB_SHAPE* line_a = static_cast<PCB_SHAPE*>( a );
1418 PCB_SHAPE* line_b = static_cast<PCB_SHAPE*>( b );
1420 pairwise_line_routine->ProcessLinePair( *line_a, *line_b );
1428 m_selectionTool->AddItemToSel( item,
true );
1433 for(
PCB_SHAPE* item : items_to_remove )
1435 commit.Remove( item );
1436 m_selectionTool->RemoveItemFromSel( item,
true );
1440 for(
PCB_SHAPE* item : items_to_select_on_success )
1441 m_selectionTool->AddItemToSel( item,
true );
1444 for(
PCB_SHAPE* item : items_to_deselect_on_success )
1445 m_selectionTool->RemoveItemFromSel( item,
true );
1447 if( any_items_removed )
1450 if( any_items_created )
1456 commit.Push( pairwise_line_routine->GetCommitDescription() );
1458 if (
const std::optional<wxString> msg = pairwise_line_routine->GetStatusMessage()) {
1459 frame()->ShowInfoBarMsg( *msg );
1471 std::vector<VECTOR2I> pts;
1474 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1476 BOARD_ITEM* item = aCollector[i];
1480 if( !item->IsType( { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_ARC_T,
1481 PCB_SHAPE_LOCATE_BEZIER_T } ) )
1483 aCollector.
Remove( item );
1495 if( dlg.ShowModal() == wxID_CANCEL )
1498 s_toleranceValue = dlg.GetValue();
1500 if( s_toleranceValue <= 0 )
1505 std::vector<PCB_SHAPE*> shapeList;
1506 std::vector<std::unique_ptr<PCB_SHAPE>> newShapes;
1512 shapeList.push_back( shape );
1519 std::vector<PCB_SHAPE*> items_to_select;
1521 for( std::unique_ptr<PCB_SHAPE>& ptr : newShapes )
1525 commit.Add( shape );
1526 items_to_select.push_back( shape );
1529 commit.Push(
_(
"Heal Shapes" ) );
1532 for(
PCB_SHAPE* item : items_to_select )
1533 m_selectionTool->AddItemToSel( item,
true );
1535 if( items_to_select.size() > 0 )
1551 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1553 BOARD_ITEM* item = aCollector[i];
1555 if( !item->IsType( {
1556 PCB_SHAPE_LOCATE_POLY_T,
1557 PCB_SHAPE_LOCATE_RECT_T,
1560 aCollector.
Remove( item );
1566 const EDA_ITEM*
const last_item = selection.GetLastAddedItem();
1569 std::vector<PCB_SHAPE*> items_to_process;
1572 items_to_process.push_back(
static_cast<PCB_SHAPE*
>( item ) );
1577 if( item == last_item )
1579 std::swap( items_to_process.back(), items_to_process.front() );
1586 const auto item_modification_handler = [&](
PCB_SHAPE& aItem )
1591 std::vector<PCB_SHAPE*> items_to_select_on_success;
1592 const auto item_creation_handler = [&]( std::unique_ptr<PCB_SHAPE> aItem )
1594 items_to_select_on_success.push_back( aItem.get() );
1595 commit.
Add( aItem.release() );
1598 const auto item_removal_handler = [&](
PCB_SHAPE& aItem )
1605 item_creation_handler, item_modification_handler, item_removal_handler );
1608 std::unique_ptr<POLYGON_BOOLEAN_ROUTINE> boolean_routine;
1612 std::make_unique<POLYGON_MERGE_ROUTINE>( frame()->
GetModel(), change_handler );
1617 std::make_unique<POLYGON_SUBTRACT_ROUTINE>( frame()->
GetModel(), change_handler );
1622 std::make_unique<POLYGON_INTERSECT_ROUTINE>( frame()->
GetModel(), change_handler );
1626 wxASSERT_MSG(
false,
"Could not find a polygon routine for this action" );
1631 for(
PCB_SHAPE* shape : items_to_process )
1633 boolean_routine->ProcessShape( *shape );
1637 for(
PCB_SHAPE* item : items_to_select_on_success )
1639 m_selectionTool->AddItemToSel( item,
true );
1645 commit.Push( boolean_routine->GetCommitDescription() );
1647 if(
const std::optional<wxString> msg = boolean_routine->GetStatusMessage() )
1649 frame()->ShowInfoBarMsg( *msg );
1672 std::vector<PCB_TABLECELL*> cells;
1689 else if( selection.
Size() == 1 )
1723 for(
EDA_ITEM* eda_item : selCopy )
1727 if( !( item->GetLayerSet() & visible ).any() )
1750 commit = &localCommit;
1765 if( selection.
Empty() )
1768 std::optional<VECTOR2I> oldRefPt;
1769 bool is_hover = selection.
IsHover();
1791 if( selection.
Empty() )
1808 if(
frame()->GetCanvas()->GetView()->GetGAL()->IsFlippedX() )
1809 rotateAngle = -rotateAngle;
1815 viewBBox.
Merge( item->ViewBBox() );
1824 typedef std::numeric_limits<int> coord_limits;
1829 bool outOfBounds = rotPos.
x < min || rotPos.
x > max || rotPos.
y < min || rotPos.
y > max
1830 || rotEnd.
x < min || rotEnd.
x > max || rotEnd.
y < min || rotEnd.
y > max;
1836 if( !item->IsNew() && !item->IsMoving() )
1841 board_item->Rotate( refPt, rotateAngle );
1842 board_item->Normalize();
1846 if( !localCommit.
Empty() )
1847 localCommit.
Push(
_(
"Rotate" ) );
1876 mirrored.
x -= aMirrorPoint.
x;
1877 mirrored.
x = -mirrored.
x;
1878 mirrored.
x += aMirrorPoint.
x;
1891 mirrored.
y -= aMirrorPoint.
y;
1892 mirrored.
y = -mirrored.
y;
1893 mirrored.
y += aMirrorPoint.
y;
1969 commit = &localCommit;
1980 if( selection.
Empty() )
1989 bool mirrorLeftRight =
true;
1990 bool mirrorAroundXaxis =
false;
1994 mirrorLeftRight =
false;
1995 mirrorAroundXaxis =
true;
2003 if( !item->IsNew() && !item->IsMoving() )
2007 switch( item->Type() )
2010 static_cast<PCB_SHAPE*
>( item )->
Mirror( mirrorPoint, mirrorAroundXaxis );
2014 static_cast<ZONE*
>( item )->
Mirror( mirrorPoint, mirrorLeftRight );
2019 static_cast<PCB_TEXT*
>( item )->
Mirror( mirrorPoint, mirrorAroundXaxis );
2031 if( mirrorLeftRight )
2041 static_cast<PCB_TRACK*
>( item )->
Mirror( mirrorPoint, mirrorAroundXaxis );
2052 if( !localCommit.
Empty() )
2053 localCommit.
Push(
_(
"Mirror" ) );
2079 commit = &localCommit;
2088 if( selection.
Empty() )
2106 if( !item->IsNew() && !item->IsMoving() )
2109 setJustify(
static_cast<PCB_TEXT*
>( item ) );
2113 if( !item->IsNew() && !item->IsMoving() )
2120 if( !localCommit.
Empty() )
2123 localCommit.
Push(
_(
"Left Justify" ) );
2125 localCommit.
Push(
_(
"Center Justify" ) );
2127 localCommit.
Push(
_(
"Right Justify" ) );
2154 commit = &localCommit;
2166 if( selection.
Empty() )
2169 std::optional<VECTOR2I> oldRefPt;
2181 if( selection.
GetSize() == 1 )
2190 if( !boardItem->IsNew() && !boardItem->IsMoving() )
2191 commit->
Modify( boardItem );
2193 boardItem->Flip( refPt, leftRight );
2194 boardItem->Normalize();
2198 if( !localCommit.
Empty() )
2199 localCommit.
Push(
_(
"Change Side / Flip" ) );
2230 wxCHECK2( board_item,
continue );
2237 switch( item->Type() )
2240 wxASSERT( parentFP );
2241 commit.
Modify( parentFP );
2242 static_cast<PCB_TEXT*
>( board_item )->SetVisible(
false );
2257 commit.
Remove( board_item );
2262 commit.
Modify( board_item );
2263 static_cast<PCB_TABLECELL*
>( board_item )->SetText( wxEmptyString );
2279 commit.
Remove( board_item );
2285 commit.
Modify( parentFP );
2287 parentFP->
Remove( board_item );
2296 if( !aIsCut && aItems.
GetSize() == 1 )
2299 ZONE* zone =
static_cast<ZONE*
>( board_item );
2301 int outlineIdx, holeIdx;
2324 commit.
Remove( board_item );
2328 if( aItems.
Size() == 1 )
2345 commit.
Remove( board_item );
2351 wxASSERT_MSG( parentFP ==
nullptr, wxT(
"Try to delete an item living in a footprint" ) );
2352 commit.
Remove( board_item );
2360 if( enteredGroup && enteredGroup->
GetItems().empty() )
2364 commit.
Push(
_(
"Cut" ) );
2366 commit.
Push(
_(
"Delete" ) );
2376 std::vector<BOARD_ITEM*> lockedItems;
2460 if( selection.
Empty() )
2472 int ret = dialog.ShowModal();
2474 if( ret == wxID_OK )
2482 selCenter += translation;
2484 if( !
frame()->GetPcbNewSettings()->m_Display.m_DisplayInvertYAxis )
2485 rotation = -rotation;
2491 wxCHECK2( boardItem,
continue );
2493 if( !boardItem->
IsNew() )
2494 commit.
Modify( boardItem );
2497 boardItem->
Move( translation );
2499 switch( rotationAnchor )
2505 boardItem->
Rotate( selCenter, angle );
2508 boardItem->
Rotate(
frame()->GetScreen()->m_LocalOrigin, angle );
2511 boardItem->
Rotate(
board()->GetDesignSettings().GetAuxOrigin(), angle );
2519 commit.
Push(
_(
"Move Exactly" ) );
2521 if( selection.IsHover() )
2554 if( selection.
Empty() )
2566 bool is_hover = selection.
IsHover();
2568 std::vector<BOARD_ITEM*> new_items;
2569 new_items.reserve( selection.
Size() );
2578 wxCHECK2( orig_item,
continue );
2601 static_cast<PAD*
>( dupe_item )->SetNumber( padNumber );
2605 new_items.push_back( dupe_item );
2606 commit.
Add( dupe_item );
2615 switch( orig_item->
Type() )
2638 new_items.push_back( dupe_item );
2639 commit.
Add( dupe_item );
2648 dupe_item =
static_cast<PCB_GROUP*
>( orig_item )->DeepDuplicate();
2654 new_items.push_back( aItem );
2655 commit.
Add( aItem );
2659 new_items.push_back( dupe_item );
2660 commit.
Add( dupe_item );
2664 wxASSERT_MSG(
false, wxString::Format( wxT(
"Unhandled item type %d" ),
2665 orig_item->
Type() ) );
2675 EDA_ITEMS nItems( new_items.begin(), new_items.end() );
2679 if( !selection.
Empty() )
2681 editFrame->
DisplayToolMsg( wxString::Format(
_(
"Duplicated %d item(s)" ),
2682 (
int) new_items.size() ) );
2686 commit.
Push(
_(
"Duplicate" ) );
2715 if( selection.
Empty() )
2730 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
2732 if( aCollector[i]->Type() !=
PCB_PAD_T )
2741 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
2752 if( aSelection.
Empty() )
2776 const wxString& aCanceledMessage,
VECTOR2I& aReferencePoint )
2779 std::optional<VECTOR2I> pickedPoint;
2788 [&](
const VECTOR2D& aPoint ) ->
bool
2790 pickedPoint = aPoint;
2792 if( !aSuccessMessage.empty() )
2814 if( !aCanceledMessage.empty() )
2826 [&](
const int& aFinalState )
2841 evt->SetPassEvent();
2851 aReferencePoint = *pickedPoint;
2853 return pickedPoint.has_value();
2861 getEditFrame<PCB_BASE_EDIT_FRAME>()->GetMagneticItemsSettings() );
2863 "pcbnew.InteractiveEdit.selectReferencePoint",
2864 TOOL_ACTION_SCOPE::AS_GLOBAL );
2872 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2874 BOARD_ITEM* item = aCollector[i];
2878 if( ( item->Type() == PCB_FIELD_T || item->Type() == PCB_TEXT_T )
2879 && aCollector.HasItem( item->GetParentFootprint() ) )
2881 aCollector.Remove( item );
2886 aCollector.Remove( item );
2892 aEvent.IsAction( &
ACTIONS::cut ) && !m_isFootprintEditor );
2894 if( !selection.Empty() )
2896 std::vector<BOARD_ITEM*> items;
2901 items.push_back( boardItem );
2908 if( !pickReferencePoint(
_(
"Select reference point for the copy..." ),
2909 _(
"Selection copied" ),
2910 _(
"Copy canceled" ),
2913 frame()->PopTool( selectReferencePoint );
2919 refPoint =
grid.BestDragOrigin( getViewControls()->GetCursorPosition(), items );
2922 selection.SetReferencePoint( refPoint );
2924 io.SetBoard( board() );
2925 io.SaveSelection( selection, m_isFootprintEditor );
2926 frame()->SetStatusText(
_(
"Selection copied" ) );
2929 frame()->PopTool( selectReferencePoint );
2931 if( selection.IsHover() )
2932 m_selectionTool->ClearSelection();
constexpr EDA_IU_SCALE pcbIUScale
static TOOL_ACTION pickerSubTool
static TOOL_ACTION unselectAll
static TOOL_ACTION pasteSpecial
static TOOL_ACTION rightJustify
static TOOL_ACTION pageSettings
static TOOL_ACTION duplicate
static TOOL_ACTION doDelete
static TOOL_ACTION cursorClick
static TOOL_ACTION leftJustify
static TOOL_ACTION selectAll
static TOOL_ACTION centerJustify
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
COMMIT & Stage(EDA_ITEM *aItem, CHANGE_TYPE aChangeType, BASE_SCREEN *aScreen=nullptr) override
virtual void Revert() override
NETINFO_ITEM * GetNet() const
Return #NET_INFO object for a given item.
void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
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...
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
virtual void SetLocked(bool aLocked)
PCB_GROUP * GetParentGroup() const
virtual void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle)
Rotate this object.
virtual BOARD_ITEM * Duplicate() const
Create a copy of this BOARD_ITEM.
virtual void Move(const VECTOR2I &aMoveVector)
Move this object.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
FOOTPRINT * GetParentFootprint() const
virtual bool IsLocked() const
BOARD_ITEM_CONTAINER * GetParent() const
virtual void RunOnDescendants(const std::function< void(BOARD_ITEM *)> &aFunction, int aDepth=0) const
Invoke a function on all descendants.
LSET GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
bool BuildConnectivity(PROGRESS_REPORTER *aReporter=nullptr)
Build or rebuild the board connectivity database for the board, especially the list of connected item...
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
const Vec & GetPosition() const
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Represent basic circle geometry with utility geometry functions.
VECTOR2I Center
Public to make access simpler.
int Radius
Public to make access simpler.
CIRCLE & ConstructFromTanTanPt(const SEG &aLineA, const SEG &aLineB, const VECTOR2I &aP)
Construct this circle such that it is tangent to the given segments and passes through the given poin...
VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute the point on the circumference of the circle that is the closest to aP.
int GetCount() const
Return the number of objects in the list.
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been removed.
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
bool Empty() const
Returns status of an item.
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been added.
@ TABLECELL_PROPS_EDIT_TABLE
enum TABLECELL_PROPS_RETVALUE GetReturnValue()
bool HitTestDrawingSheetItems(KIGFX::VIEW *aView, const VECTOR2I &aPosition)
void ShowInfoBarMsg(const wxString &aMsg, bool aShowCloseButton=false)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an info icon on the left of...
void ShowInfoBarError(const wxString &aErrorMsg, bool aShowCloseButton=false, WX_INFOBAR::MESSAGE_TYPE aType=WX_INFOBAR::MESSAGE_TYPE::GENERIC)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an error icon on the left o...
void DisplayToolMsg(const wxString &msg) override
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
void SetStatusPopup(wxWindow *aPopup)
A base class for most all the KiCad significant classes used in schematics and boards.
virtual VECTOR2I GetPosition() const
void SetFlags(EDA_ITEM_FLAGS aMask)
KICAD_T Type() const
Returns the type of object.
virtual const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
SHAPE_POLY_SET & GetPolyShape()
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
void SetStart(const VECTOR2I &aStart)
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
void SetEnd(const VECTOR2I &aEnd)
void SetWidth(int aWidth)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
static const TOOL_EVENT SelectedEvent
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
static const TOOL_EVENT ConnectivityChangedEvent
Selected item had a property changed (except movement)
static const TOOL_EVENT UnselectedEvent
Used when the right click button is pressed, or when the select tool is in effect.
static const std::vector< KICAD_T > DraggableItems
A scan list for items that can be dragged.
A handler that is based on a set of callbacks provided by the user of the ITEM_MODIFICATION_ROUTINE.
An interface for classes handling user events controlling the view behavior such as zooming,...
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Place the cursor immediately at a given point.
virtual void ShowCursor(bool aEnabled)
Enable or disables display of cursor.
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Return the current mouse pointer position.
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
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.
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...
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
LSET is a set of PCB_LAYER_IDs.
A collection of nets and the parameters used to route or test these nets.
int GetuViaDiameter() const
bool CanHaveNumber() const
Indicates whether or not the pad can have a number.
void FlipPrimitives(bool aFlipLeftRight)
Flip (mirror) the primitives left to right or top to bottom, around the anchor position in custom pad...
VECTOR2I GetPosition() const override
void SetOffset(const VECTOR2I &aOffset)
const VECTOR2I & GetOffset() const
void SetDelta(const VECTOR2I &aSize)
void SetPosition(const VECTOR2I &aPos) override
const VECTOR2I & GetDelta() const
PAD_SHAPE GetShape() const
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
void SetOrientation(const EDA_ANGLE &aAngle)
Set the rotation angle of the pad.
static TOOL_ACTION drag45Degree
static TOOL_ACTION duplicateIncrement
Activation of the duplication tool with incrementing (e.g. pad number)
static TOOL_ACTION changeTrackWidth
Update selected tracks & vias to the current track & via dimensions.
static TOOL_ACTION unrouteSelected
Removes all tracks from the selected items to the first pad.
static TOOL_ACTION mirrorH
Mirroring of selected items.
static TOOL_ACTION updateFootprint
static TOOL_ACTION breakTrack
Break a single track into two segments at the cursor.
static TOOL_ACTION pointEditorMoveMidpoint
static TOOL_ACTION getAndPlace
Find an item and start moving.
static TOOL_ACTION properties
Activation of the edit tool.
static TOOL_ACTION editFpInFpEditor
static TOOL_ACTION selectionClear
Clear the current selection.
static TOOL_ACTION moveWithReference
move with a reference point
static TOOL_ACTION swap
Swapping of selected items.
static TOOL_ACTION moveExact
Activation of the exact move tool.
static TOOL_ACTION intersectPolygons
Intersection of multiple polygons.
static TOOL_ACTION pointEditorMoveCorner
static TOOL_ACTION genRemove
static TOOL_ACTION selectConnection
Select tracks between junctions or expands an existing selection to pads or the entire connection.
static TOOL_ACTION assignNetClass
static TOOL_ACTION packAndMoveFootprints
Pack and start moving selected footprints.
static TOOL_ACTION copyWithReference
copy command with manual reference point selection
static TOOL_ACTION healShapes
Connect selected shapes, possibly extending or cutting them, or adding extra geometry.
static TOOL_ACTION dragFreeAngle
static TOOL_ACTION inspectClearance
static TOOL_ACTION updateLocalRatsnest
static TOOL_ACTION updateFootprints
static TOOL_ACTION deleteFull
static TOOL_ACTION moveIndividually
move items one-by-one
static TOOL_ACTION changeFootprints
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
static TOOL_ACTION chamferLines
Chamfer (i.e. adds a straight line) all selected straight lines by a user defined setback.
static TOOL_ACTION filletTracks
Fillet (i.e. adds an arc tangent to) all selected straight tracks by a user defined radius.
static TOOL_ACTION footprintProperties
static TOOL_ACTION filletLines
Fillet (i.e. adds an arc tangent to) all selected straight lines by a user defined radius.
static TOOL_ACTION changeFootprint
static TOOL_ACTION routerInlineDrag
Activation of the Push and Shove router (inline dragging mode)
static TOOL_ACTION positionRelative
Activation of the position relative tool.
static TOOL_ACTION move
move or drag an item
static TOOL_ACTION mirrorV
static TOOL_ACTION mergePolygons
Merge multiple polygons into a single polygon.
static TOOL_ACTION subtractPolygons
Subtract polygons from other polygons.
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
static TOOL_ACTION flip
Flipping of selected objects.
static TOOL_ACTION createArray
Tool for creating an array of objects.
static TOOL_ACTION extendLines
Extend selected lines to meet at a point.
static TOOL_ACTION rotateCw
Rotation of selected objects.
static TOOL_ACTION rotateCcw
virtual double GetLength() const override
Return the length of the arc track.
void SetMid(const VECTOR2I &aMid)
EDA_ANGLE GetAngle() const
const VECTOR2I & GetMid() const
virtual VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Common, abstract interface for edit frames.
virtual void OnEditItemRequest(BOARD_ITEM *aItem)
Install the corresponding dialog editor for the given item.
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
PCBNEW_SETTINGS * GetPcbNewSettings() const
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
DS_PROXY_VIEW_ITEM * GetDrawingSheet() const
void RedrawRatsnest()
Return the bounding box of the view that should be used if model is not valid.
A set of BOARD_ITEMs (i.e., without duplicates).
std::unordered_set< BOARD_ITEM * > & GetItems()
Tool that displays edit points allowing to modify items by dragging the points.
int GetWidth() const override
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
void SetWidth(int aWidth)
virtual double GetLength() const
Get the length of the track using the hypotenuse calculation.
void SetEnd(const VECTOR2I &aEnd)
void SetStart(const VECTOR2I &aStart)
const VECTOR2I & GetStart() const
const VECTOR2I & GetEnd() const
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...
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
bool ApproxCollinear(const SEG &aSeg, int aDistanceThreshold=1) const
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
SEG PerpendicularSeg(const VECTOR2I &aP) const
Compute a segment perpendicular to this one, passing through point aP.
int Side(const VECTOR2I &aP) const
Determine on which side of directed line passing via segment ends point aP lies.
EDA_ANGLE Angle(const SEG &aOther) const
Determine the smallest angle between two segments.
static SELECTION_CONDITION HasTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if among the selected items there is at least one of a given types.
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.
VECTOR2I GetReferencePoint() const
virtual VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
virtual unsigned int GetSize() const override
Return the number of stored items.
bool HasType(KICAD_T aType) const
Checks if there is at least one item of requested kind.
int Size() const
Returns the number of selected parts.
std::deque< EDA_ITEM * > & Items()
void ClearReferencePoint()
void SetReferencePoint(const VECTOR2I &aP)
bool Empty() const
Checks if there is anything selected.
bool HasReferencePoint() const
size_t CountType(KICAD_T aType) const
bool Contains(EDA_ITEM *aItem) const
virtual BOX2I GetBoundingBox() const
const VECTOR2I & GetP1() const
const VECTOR2I & GetP0() const
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the index-th vertex in a given hole outline within a given outline.
static const int MIN_PRECISION_IU
This is the minimum precision for all the points in a shape.
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
An extension of WX_TEXT_ENTRY_DIALOG that uses UNIT_BINDER to request a dimension (e....
int GetValue()
Returns the value in internal units.
Handle a list of polygons defining a copper zone.
bool UnFill()
Removes the zone filling.
bool HitTestCutout(const VECTOR2I &aRefPos, int *aOutlineIdx=nullptr, int *aHoleIdx=nullptr) const
Test if the given point is contained within a cutout of the zone.
void HatchBorder()
Compute the hatch lines depending on the hatch parameters and stores it in the zone's attribute m_bor...
void RemoveCutout(int aOutlineIdx, int aHoleIdx)
Remove a cutout from the zone.
@ ROTATE_AROUND_USER_ORIGIN
@ ROTATE_AROUND_SEL_CENTER
@ ROTATE_AROUND_AUX_ORIGIN
@ ROTATE_AROUND_ITEM_ANCHOR
static constexpr EDA_ANGLE ANGLE_180
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
#define IS_NEW
New item, just created.
void ConnectBoardShapes(std::vector< PCB_SHAPE * > &aShapeList, std::vector< std::unique_ptr< PCB_SHAPE > > &aNewShapes, int aChainingEpsilon)
Connects shapes to each other, making continious contours (adjacent shapes will have a common vertex)...
@ LAYER_DRAWINGSHEET
drawingsheet frame and titleblock
@ LAYER_SCHEMATIC_DRAWINGSHEET
PCB_LAYER_ID
A quick note on layer IDs:
KICOMMON_API wxString MessageTextFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
A helper to convert the double length aValue to a string in inches, millimeters, or unscaled units.
SGLIB_API S3DMODEL * GetModel(SCENEGRAPH *aNode)
Function GetModel creates an S3DMODEL representation of aNode (raw data, no transforms)
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
void for_all_pairs(_InputIterator __first, _InputIterator __last, _Function __f)
Apply a function to every possible pair of elements of a sequence.
Class to handle a set of BOARD_ITEMs.
std::optional< VECTOR2I > OPT_VECTOR2I
Parameters that define a simple chamfer operation.
constexpr int mmToIU(double mm) const
const VECTOR2I CalcArcMid(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aMinArcAngle=true)
Return the middle point of an arc, half-way between aStart and aEnd.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
double GetLineLength(const VECTOR2I &aPointA, const VECTOR2I &aPointB)
Return the length of a line segment defined by aPointA and aPointB.
double EuclideanNorm(const VECTOR2I &vector)
@ 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_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
@ PCB_MARKER_T
class PCB_MARKER, a marker used to show something
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
@ PCB_SHAPE_LOCATE_SEGMENT_T
@ PCB_SHAPE_LOCATE_RECT_T
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_SHAPE_LOCATE_BEZIER_T
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_SHAPE_LOCATE_POLY_T
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
@ 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
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".