31#include <unordered_set>
59 m_boundingBoxCacheTimeStamp( 0 ),
60 m_visibleBBoxCacheTimeStamp( 0 ),
61 m_textExcludedBBoxCacheTimeStamp( 0 ),
62 m_hullCacheTimeStamp( 0 ),
63 m_initial_comments( nullptr ),
64 m_courtyard_cache_timestamp( 0 )
136 std::map<BOARD_ITEM*, BOARD_ITEM*> ptrMap;
142 ptrMap[field] = newField;
143 Add( newField, ADD_MODE::APPEND );
149 PAD* newPad =
static_cast<PAD*
>(
pad->Clone() );
150 ptrMap[
pad ] = newPad;
151 Add( newPad, ADD_MODE::APPEND );
157 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
158 ptrMap[ zone ] = newZone;
159 Add( newZone, ADD_MODE::APPEND );
172 ptrMap[ item ] = newItem;
173 Add( newItem, ADD_MODE::APPEND );
180 ptrMap[
group ] = newGroup;
181 Add( newGroup, ADD_MODE::APPEND );
193 if( ptrMap.count( member ) )
194 newGroup->
AddItem( ptrMap[ member ] );
214 *
this = std::move( aFootprint );
224 item->SetParentGroup(
nullptr );
256 board->IncrementTimeStamp();
276 if( field->GetId() == aFieldId )
287 if( field->GetCanonicalName() == aFieldName )
298 if( field->GetName() == aFieldName )
310 if( aFieldName == field->GetName() || aFieldName == field->GetCanonicalName() )
311 return field->GetText();
314 return wxEmptyString;
324 if( !field->IsVisible() || field->GetText().IsEmpty() )
328 aVector.push_back( field );
346 if( aFieldName ==
m_fields[i]->GetName(
false ) )
356 bool aStyleTextAndGraphics )
364 if( aStyleTextAndGraphics )
375 std::vector< BOARD_ITEM* > item_list;
378 item_list.push_back( field );
381 item_list.push_back(
pad );
384 item_list.push_back( gr_item );
389 item_list.push_back(
group );
393 item_list.push_back( zone );
395 bool changed =
false;
401 const_cast<KIID&
>( item->m_Uuid ) =
KIID();
414 m_pos = aOther.m_pos;
442 for(
PCB_FIELD* field : aOther.Fields() )
448 for(
PAD*
pad : aOther.Pads() )
451 aOther.Pads().clear();
456 for(
ZONE* item : aOther.Zones() )
464 item->SetNetCode( -1 );
467 aOther.Zones().clear();
472 for(
BOARD_ITEM* item : aOther.GraphicalItems() )
475 aOther.GraphicalItems().clear();
483 aOther.Groups().clear();
494 aOther.Fields().clear();
495 aOther.Pads().clear();
496 aOther.Zones().clear();
497 aOther.GraphicalItems().clear();
498 aOther.m_initial_comments =
nullptr;
533 std::map<BOARD_ITEM*, BOARD_ITEM*> ptrMap;
541 ptrMap[field] = newField;
551 ptrMap[
pad ] = newPad;
560 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
561 ptrMap[ zone ] = newZone;
577 ptrMap[ item ] = newItem;
590 newGroup->
AddItem( ptrMap[ member ] );
616 aVars->push_back( wxT(
"REFERENCE" ) );
617 aVars->push_back( wxT(
"VALUE" ) );
618 aVars->push_back( wxT(
"LAYER" ) );
619 aVars->push_back( wxT(
"FOOTPRINT_LIBRARY" ) );
620 aVars->push_back( wxT(
"FOOTPRINT_NAME" ) );
621 aVars->push_back( wxT(
"SHORT_NET_NAME(<pad_number>)" ) );
622 aVars->push_back( wxT(
"NET_NAME(<pad_number>)" ) );
623 aVars->push_back( wxT(
"NET_CLASS(<pad_number>)" ) );
624 aVars->push_back( wxT(
"PIN_NAME(<pad_number>)" ) );
633 if( token->IsSameAs( wxT(
"REFERENCE" ) ) )
638 else if( token->IsSameAs( wxT(
"VALUE" ) ) )
643 else if( token->IsSameAs( wxT(
"LAYER" ) ) )
648 else if( token->IsSameAs( wxT(
"FOOTPRINT_LIBRARY" ) ) )
653 else if( token->IsSameAs( wxT(
"FOOTPRINT_NAME" ) ) )
658 else if( token->StartsWith( wxT(
"SHORT_NET_NAME(" ) )
659 || token->StartsWith( wxT(
"NET_NAME(" ) )
660 || token->StartsWith( wxT(
"NET_CLASS(" ) )
661 || token->StartsWith( wxT(
"PIN_NAME(" ) ) )
663 wxString padNumber = token->AfterFirst(
'(' );
664 padNumber = padNumber.BeforeLast(
')' );
668 if(
pad->GetNumber() == padNumber )
670 if( token->StartsWith( wxT(
"SHORT_NET_NAME" ) ) )
671 *token =
pad->GetShortNetname();
672 else if( token->StartsWith( wxT(
"NET_NAME" ) ) )
673 *token =
pad->GetNetname();
674 else if( token->StartsWith( wxT(
"NET_CLASS" ) ) )
675 *token =
pad->GetNetClassName();
677 *token =
pad->GetPinFunction();
707 switch( aBoardItem->
Type() )
724 if( aMode == ADD_MODE::APPEND )
731 if( aMode == ADD_MODE::APPEND )
732 m_pads.push_back(
static_cast<PAD*
>( aBoardItem ) );
734 m_pads.push_front(
static_cast<PAD*
>( aBoardItem ) );
738 if( aMode == ADD_MODE::APPEND )
739 m_zones.push_back(
static_cast<ZONE*
>( aBoardItem ) );
745 if( aMode == ADD_MODE::APPEND )
754 msg.Printf( wxT(
"FOOTPRINT::Add() needs work: BOARD_ITEM type (%d) not handled" ),
755 aBoardItem->
Type() );
769 switch( aBoardItem->
Type() )
777 wxT(
"Please report this bug: Invalid remove operation on required text" ) );
780 if( *it == aBoardItem )
800 if( *it == aBoardItem )
810 for(
auto it =
m_pads.begin(); it !=
m_pads.end(); ++it )
812 if( *it ==
static_cast<PAD*
>( aBoardItem ) )
824 if( *it ==
static_cast<ZONE*
>( aBoardItem ) )
836 if( *it ==
static_cast<PCB_GROUP*
>( aBoardItem ) )
848 msg.Printf( wxT(
"FOOTPRINT::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
849 aBoardItem->
Type() );
880 switch(
pad->GetProperty() )
882 case PAD_PROP::FIDUCIAL_GLBL:
883 case PAD_PROP::FIDUCIAL_LOCAL:
886 case PAD_PROP::HEATSINK:
887 case PAD_PROP::CASTELLATED:
892 case PAD_PROP::TESTPOINT:
896 switch(
pad->GetAttribute() )
898 case PAD_ATTRIB::PTH:
902 case PAD_ATTRIB::SMD:
903 if(
pad->IsOnCopperLayer() )
931 return _(
"Through hole" );
948 if(
dummy.IsFlipped() )
952 bbox.
Merge(
pad->GetBoundingBox() );
955 dummy.SetParent(
nullptr );
956 dummy.SetParentGroup(
nullptr );
970 std::vector<PCB_TEXT*> texts;
976 if( aIncludeText && aIncludeInvisibleText )
981 else if( aIncludeText )
1009 texts.push_back(
static_cast<PCB_TEXT*
>( item ) );
1026 bbox.
Merge( item->GetBoundingBox() );
1030 texts.push_back( field );
1033 bbox.
Merge(
pad->GetBoundingBox() );
1036 bbox.
Merge( zone->GetBoundingBox() );
1041 if( aIncludeText || noDrawItems )
1050 if( aIncludeInvisibleText ||
text->IsVisible() )
1056 bool valueLayerIsVisible =
true;
1057 bool refLayerIsVisible =
true;
1075 if( (
Value().IsVisible() && valueLayerIsVisible )
1076 || aIncludeInvisibleText
1082 if( (
Reference().IsVisible() && refLayerIsVisible )
1083 || aIncludeInvisibleText
1092 if( ( aIncludeText && aIncludeInvisibleText ) || noDrawItems )
1097 else if( aIncludeText )
1115 std::vector<PCB_TEXT*> texts;
1127 if( ( aLayers & item->GetLayerSet() ).none() )
1135 bbox.
Merge( item->GetBoundingBox() );
1140 if( ( aLayers &
pad->GetLayerSet() ).none() )
1143 bbox.
Merge(
pad->GetBoundingBox() );
1148 if( ( aLayers & zone->GetLayerSet() ).none() )
1151 bbox.
Merge( zone->GetBoundingBox() );
1197 const SHAPE_POLY_SET& layerPoly = *zone->GetFilledPolysList( layer );
1224 std::vector<VECTOR2I> convex_hull;
1230 for(
const VECTOR2I& pt : convex_hull )
1254 aList.emplace_back(
_(
"Library" ),
GetFPID().GetLibNickname().wx_str() );
1256 aList.emplace_back(
_(
"Footprint Name" ),
GetFPID().GetLibItemName().wx_str() );
1258 aList.emplace_back(
_(
"Pads" ), wxString::Format( wxT(
"%zu" ), padCount ) );
1261 wxString::Format(
_(
"Keywords: %s" ),
GetKeywords() ) );
1267 aList.emplace_back(
_(
"Board Side" ),
IsFlipped() ?
_(
"Back (Flipped)" ) :
_(
"Front" ) );
1269 auto addToken = []( wxString* aStr,
const wxString& aAttr )
1271 if( !aStr->IsEmpty() )
1272 *aStr += wxT(
", " );
1281 addToken( &status,
_(
"Locked" ) );
1284 addToken( &status,
_(
"autoplaced" ) );
1287 addToken( &attrs,
_(
"not in schematic" ) );
1290 addToken( &attrs,
_(
"exclude from pos files" ) );
1293 addToken( &attrs,
_(
"exclude from BOM" ) );
1296 addToken( &attrs,
_(
"DNP" ) );
1298 aList.emplace_back(
_(
"Status: " ) + status,
_(
"Attributes:" ) + wxS(
" " ) + attrs );
1300 aList.emplace_back(
_(
"Rotation" ), wxString::Format( wxT(
"%.4g" ),
1304 msg2.Printf(
_(
"3D-Shape: %s" ),
m_3D_Drawings.empty() ?
_(
"<none>" )
1306 aList.emplace_back( msg, msg2 );
1310 aList.emplace_back( msg, msg2 );
1319 if(
pad->IsOnLayer( aLayer ) )
1325 if( zone->IsOnLayer( aLayer ) )
1331 if( field->IsOnLayer( aLayer ) )
1337 if( item->IsOnLayer( aLayer ) )
1349 if(
pad->IsOnLayer( aLayer ) &&
pad->HitTest( aPosition, aAccuracy ) )
1355 if( zone->IsOnLayer( aLayer ) && zone->HitTest( aPosition, aAccuracy ) )
1361 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer )
1362 && item->HitTest( aPosition, aAccuracy ) )
1374 std::vector<BOARD_ITEM*> items;
1378 if(
pad->IsOnLayer( aLayer ) )
1379 items.push_back(
pad );
1384 if( zone->IsOnLayer( aLayer ) )
1385 items.push_back( zone );
1390 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer ) )
1391 items.push_back( item );
1400 if( !aContained && item->HitTest( aRect, aContained, aAccuracy ) )
1402 else if( aContained && !item->HitTest( aRect, aContained, aAccuracy ) )
1409 return !items.empty() && aContained;
1428 BOX2I arect = aRect;
1448 if(
pad->HitTest( arect,
false, 0 ) )
1454 if( zone->HitTest( arect,
false, 0 ) )
1465 if( item->Type() !=
PCB_TEXT_T && item->HitTest( arect,
false, 0 ) )
1479 bool can_select = aSearchAfterMe ? false :
true;
1483 if( !can_select &&
pad == aSearchAfterMe )
1489 if( can_select &&
pad->GetNumber() == aPadNumber )
1502 if( !(
pad->GetLayerSet() & aLayerMask ).any() )
1505 if(
pad->HitTest( aPosition ) )
1522 if(
pad->GetAttribute() == PAD_ATTRIB::NPTH )
1534 std::set<wxString> usedNumbers;
1546 if(
pad->GetNumber().IsEmpty() )
1552 if(
pad->GetAttribute() == PAD_ATTRIB::NPTH )
1556 usedNumbers.insert(
pad->GetNumber() );
1559 return usedNumbers.size();
1565 if(
nullptr == a3DModel )
1575 const std::vector<KICAD_T>& aScanTypes )
1577#if 0 && defined(DEBUG)
1578 std::cout <<
GetClass().mb_str() <<
' ';
1581 bool drawingsScanned =
false;
1583 for(
KICAD_T scanType : aScanTypes )
1588 if( inspector(
this, testData ) == INSPECT_RESULT::QUIT )
1589 return INSPECT_RESULT::QUIT;
1594 if( IterateForward<PAD*>(
m_pads, inspector, testData, { scanType } )
1595 == INSPECT_RESULT::QUIT )
1597 return INSPECT_RESULT::QUIT;
1603 if( IterateForward<ZONE*>(
m_zones, inspector, testData, { scanType } )
1604 == INSPECT_RESULT::QUIT )
1606 return INSPECT_RESULT::QUIT;
1612 if( IterateForward<PCB_FIELD*>(
m_fields, inspector, testData, { scanType } )
1613 == INSPECT_RESULT::QUIT )
1615 return INSPECT_RESULT::QUIT;
1628 if( !drawingsScanned )
1630 if( IterateForward<BOARD_ITEM*>(
m_drawings, inspector, testData, aScanTypes )
1631 == INSPECT_RESULT::QUIT )
1633 return INSPECT_RESULT::QUIT;
1636 drawingsScanned =
true;
1642 if( IterateForward<PCB_GROUP*>(
m_groups, inspector, testData, { scanType } )
1643 == INSPECT_RESULT::QUIT )
1645 return INSPECT_RESULT::QUIT;
1655 return INSPECT_RESULT::CONTINUE;
1663 if( reference.IsEmpty() )
1664 reference =
_(
"<no reference designator>" );
1666 return wxString::Format(
_(
"Footprint %s" ), reference );
1672 return BITMAPS::module;
1687 aFunction(
static_cast<PCB_FIELD*
>( field ) );
1693 aFunction(
static_cast<ZONE*
>( zone ) );
1699 aFunction(
static_cast<BOARD_ITEM*
>( drawing ) );
1701 catch( std::bad_function_call& )
1703 wxFAIL_MSG( wxT(
"Error running FOOTPRINT::RunOnChildren" ) );
1716 wxASSERT_MSG(
false, wxT(
"Illegal layer" ) );
1737 bool f_silk =
false, b_silk =
false, non_silk =
false;
1741 if( item->GetLayer() ==
F_SilkS )
1743 else if( item->GetLayer() ==
B_SilkS )
1749 if( ( f_silk || b_silk ) && !non_silk &&
m_pads.empty() )
1752 aLayers[ aCount++ ] =
F_SilkS;
1755 aLayers[ aCount++ ] =
B_SilkS;
1771 return std::numeric_limits<double>::max();
1783 return std::numeric_limits<double>::max();
1792 #define MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY 1.5
1797 return std::numeric_limits<double>::max();
1808 int biggest_clearance = board->GetMaxClearanceValue();
1809 area.
Inflate( biggest_clearance );
1820 if( aName.find_first_of( invalids ) != std::string::npos )
1834 static const wxChar invalidChars[] = wxT(
"%$<>\t\n\r\"\\/:");
1835 static const wxChar invalidCharsReadable[] = wxT(
"% $ < > 'tab' 'return' 'line feed' \\ \" / :");
1838 return invalidCharsReadable;
1840 return invalidChars;
1854 EDA_ANGLE newOrientation = orientation + aAngle;
1861 field->KeepUpright( orientation, newOrientation );
1866 static_cast<PCB_TEXT*
>( item )->KeepUpright( orientation, newOrientation );
1879 wxASSERT( aLayer ==
F_Cu || aLayer ==
B_Cu );
1914 field->Flip(
m_pos,
false );
1925 zone->Flip(
m_pos,
false );
1929 item->Flip(
m_pos,
false );
1932 if( aFlipLeftRight )
1953 field->EDA_TEXT::Offset(
delta );
1959 zone->Move(
delta );
1962 item->Move(
delta );
1990 field->Move( moveVector );
1994 pad->Move( moveVector );
1998 item->Move( moveVector );
2002 zone->Move( moveVector );
2063 switch( aItem->
Type() )
2067 PAD* new_pad =
new PAD( *
static_cast<const PAD*
>( aItem ) );
2070 if( aAddToFootprint )
2071 m_pads.push_back( new_pad );
2079 ZONE* new_zone =
new ZONE( *
static_cast<const ZONE*
>( aItem ) );
2082 if( aAddToFootprint )
2083 m_zones.push_back( new_zone );
2085 new_item = new_zone;
2109 if( aAddToFootprint )
2112 new_item = new_text;
2121 if( aAddToFootprint )
2124 new_item = new_shape;
2133 if( aAddToFootprint )
2136 new_item = new_textbox;
2148 if( aAddToFootprint )
2151 new_item = dimension;
2156 new_item =
static_cast<const PCB_GROUP*
>( aItem )->DeepDuplicate();
2165 wxFAIL_MSG( wxT(
"Duplication not supported for items of class " ) + aItem->
GetClass() );
2175 std::set<wxString> usedNumbers;
2179 usedNumbers.insert(
pad->GetNumber() );
2186 while( usedNumbers.count( wxString::Format( wxT(
"%s%d" ), prefix, num ) ) )
2189 return wxString::Format( wxT(
"%s%d" ), prefix, num );
2240 for(
int jj = 0; jj < aPolySet.
HoleCount( ii ); jj++ )
2244 return aPolySet.
Area();
2259 return markerShape.
Area();
2263 double combinedArea = 0.0;
2268 return combinedArea;
2298 case SHAPE_T::SEGMENT:
2300 case SHAPE_T::BEZIER:
2303 case SHAPE_T::RECTANGLE:
2304 case SHAPE_T::CIRCLE:
2319 double width =
static_cast<const PCB_TRACK*
>( aItem )->GetWidth();
2320 return width * width;
2346 for(
int i = 0; i < aCollector.
GetCount(); ++i )
2350 switch( item->
Type() )
2379 double footprintRegionArea =
polygonArea( footprintRegion );
2380 double uncoveredRegionArea = footprintRegionArea -
polygonArea( coveredRegion );
2381 double coveredArea = footprintRegionArea - uncoveredRegionArea;
2382 double ratio = ( coveredArea / footprintRegionArea );
2389 return std::min( ratio, 1.0 );
2395 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
2416 shape->AddShape(
pad->GetEffectiveShape( aLayer, aFlash )->Clone() );
2421 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
2452 std::vector<PCB_SHAPE*> list_front;
2453 std::vector<PCB_SHAPE*> list_back;
2458 list_back.push_back(
static_cast<PCB_SHAPE*
>( item ) );
2461 list_front.push_back(
static_cast<PCB_SHAPE*
>( item ) );
2464 if( !list_front.size() && !list_back.size() )
2471 true, aErrorHandler ) )
2484 true, aErrorHandler ) )
2500 std::map<wxString, int> padNumberToGroupIdxMap;
2503 padNumberToGroupIdxMap[
pad->GetNumber() ] = -1;
2506 [&]( wxString aPad,
int aGroup )
2508 aPad.Trim(
true ).Trim(
false );
2510 if( !aPad.IsEmpty() )
2511 padNumberToGroupIdxMap[ aPad ] = aGroup;
2520 for( wxUniCharRef ch :
group )
2529 switch(
static_cast<unsigned char>( ch ) )
2536 processPad(
pad, ii );
2546 processPad(
pad, ii );
2549 return padNumberToGroupIdxMap;
2559 int groupIdx = padToNetTieGroupMap[ aPad->
GetNumber() ];
2560 std::vector<PAD*> otherPads;
2566 if( padToNetTieGroupMap[
pad->GetNumber() ] == groupIdx )
2567 otherPads.push_back(
pad );
2580 if( setAttr && likelyAttr && setAttr != likelyAttr )
2584 switch( likelyAttr )
2587 msg.Printf(
_(
"(expected 'Through hole'; actual '%s')" ),
GetTypeName() );
2590 msg.Printf(
_(
"(expected 'SMD'; actual '%s')" ),
GetTypeName() );
2595 (aErrorHandler)( msg );
2601 const wxString& )>& aErrorHandler )
2603 if( aErrorHandler ==
nullptr )
2608 if(
pad->GetAttribute() == PAD_ATTRIB::PTH ||
pad->GetAttribute() == PAD_ATTRIB::NPTH )
2610 if(
pad->GetDrillSizeX() < 1 ||
pad->GetDrillSizeY() < 1 )
2614 if(
pad->GetAttribute() == PAD_ATTRIB::PTH )
2616 if( !
pad->IsOnCopperLayer() )
2628 std::shared_ptr<SHAPE_SEGMENT> hole =
pad->GetEffectiveHoleShape();
2641 if(
pad->GetAttribute() == PAD_ATTRIB::SMD )
2646 _(
"(SMD pad appears on both front and back copper)" ) );
2648 else if(
pad->IsOnLayer(
F_Cu ) )
2653 _(
"(SMD pad copper and mask layers don't match)" ) );
2658 _(
"(SMD pad copper and paste layers don't match)" ) );
2661 else if(
pad->IsOnLayer(
B_Cu ) )
2666 _(
"(SMD pad copper and mask layers don't match)" ) );
2671 _(
"(SMD pad copper and paste layers don't match)" ) );
2680 const VECTOR2I& )>& aErrorHandler )
2682 std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
2690 if( other ==
pad ||
pad->SameLogicalPadAs( other ) )
2703 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
2706 if( checkedPairs.find( { a, b } ) == checkedPairs.end() )
2708 checkedPairs[ { a, b } ] = 1;
2710 if(
pad->GetBoundingBox().Intersects( other->GetBoundingBox() ) )
2713 SHAPE* padShape =
pad->GetEffectiveShape().get();
2714 SHAPE* otherShape = other->GetEffectiveShape().get();
2716 if( padShape->
Collide( otherShape, 0,
nullptr, &pos ) )
2717 aErrorHandler(
pad, other, pos );
2728 const VECTOR2I& )>& aErrorHandler )
2737 std::vector<BOARD_ITEM*> copperItems;
2741 if( item->IsOnCopperLayer() )
2743 copperItems.push_back( item );
2750 copperItems.push_back( descendent );
2757 if( !zone->GetIsRuleArea() && zone->IsOnCopperLayer() )
2758 copperItems.push_back( zone );
2763 if( field->IsOnCopperLayer() )
2764 copperItems.push_back( field );
2774 std::map<int, std::vector<const PAD*>> outlineIdxToPadsMap;
2778 if( item->IsOnLayer( layer ) )
2780 item->TransformShapeToPolygon( copperOutlines, layer, 0,
ARC_HIGH_DEF,
2791 for(
int ii = 0; ii < copperOutlines.
OutlineCount(); ++ii )
2793 if(
pad->GetEffectiveShape( layer )->Collide( &copperOutlines.
Outline( ii ), 0 ) )
2794 outlineIdxToPadsMap[ ii ].emplace_back(
pad );
2801 for(
const auto& [ outlineIdx, pads ] : outlineIdxToPadsMap )
2803 if( pads.size() > 1 )
2805 const PAD* firstPad = pads[0];
2806 int firstGroupIdx = padNumberToGroupIdxMap[ firstPad->
GetNumber() ];
2808 for(
size_t ii = 1; ii < pads.size(); ++ii )
2810 const PAD* thisPad = pads[ii];
2811 int thisGroupIdx = padNumberToGroupIdxMap[ thisPad->
GetNumber() ];
2813 if( thisGroupIdx < 0 || thisGroupIdx != firstGroupIdx )
2822 if( item->HitTest( pos, 1 ) )
2824 shortingItem = item;
2830 aErrorHandler( shortingItem, firstPad, thisPad, pos );
2832 aErrorHandler( firstPad, thisPad,
nullptr, pos );
2843 std::set<wxString> padNumbers;
2848 for(
auto [ padNumber,
_ ] : ret )
2854 msg.Printf(
_(
"(net-tie pad group contains unknown pad number %s)" ), padNumber );
2855 aErrorHandler( msg );
2857 else if( !padNumbers.insert(
pad->GetNumber() ).second )
2859 msg.Printf(
_(
"(pad %s appears in more than one net-tie pad group)" ), padNumber );
2860 aErrorHandler( msg );
2870 std::swap( *
this, *
static_cast<FOOTPRINT*
>( aImage ) );
2878 if(
pad->GetAttribute() != PAD_ATTRIB::SMD )
2886#define TEST( a, b ) { if( a != b ) return a < b; }
2887#define TEST_PT( a, b ) { if( a.x != b.x ) return a.x < b.x; if( a.y != b.y ) return a.y < b.y; }
2905 if( dwgA->
GetShape() == SHAPE_T::ARC )
2909 else if( dwgA->
GetShape() == SHAPE_T::BEZIER )
2914 else if( dwgA->
GetShape() == SHAPE_T::POLY )
2918 for(
int ii = 0; ii < dwgA->
GetPolyShape().TotalVertices(); ++ii )
2927 return itemA < itemB;
2943 return aFirst < aSecond;
2954 for(
int ii = 0; ii < aFirst->
Outline()->TotalVertices(); ++ii )
2959 return aFirst < aSecond;
2967 int aClearance,
int aMaxError,
ERROR_LOC aErrorLoc,
2968 bool aSkipNPTHPadsWihNoCopper,
bool aSkipPlatedPads,
2969 bool aSkipNonPlatedPads )
const
2973 if( !
pad->FlashLayer( aLayer ) )
2976 VECTOR2I clearance( aClearance, aClearance );
2981 if( aSkipPlatedPads &&
pad->FlashLayer(
F_Mask ) )
2984 if( aSkipNonPlatedPads && !
pad->FlashLayer(
F_Mask ) )
2990 if( aSkipPlatedPads &&
pad->FlashLayer(
B_Mask ) )
2993 if( aSkipNonPlatedPads && !
pad->FlashLayer(
B_Mask ) )
3000 clearance.
x +=
pad->GetSolderMaskExpansion();
3001 clearance.
y +=
pad->GetSolderMaskExpansion();
3006 clearance +=
pad->GetSolderPasteMargin();
3019 if( ( clearance.
x < 0 || clearance.
x != clearance.
y )
3020 &&
pad->GetShape() != PAD_SHAPE::CUSTOM )
3022 VECTOR2I dummySize =
pad->GetSize() + clearance + clearance;
3024 if( dummySize.
x <= 0 || dummySize.
y <= 0 )
3028 dummy.SetSize( dummySize );
3029 dummy.TransformShapeToPolygon( aBuffer, aLayer, 0, aMaxError, aErrorLoc );
3033 pad->TransformShapeToPolygon( aBuffer, aLayer, clearance.
x, aMaxError, aErrorLoc );
3040 int aClearance,
int aError,
ERROR_LOC aErrorLoc,
3041 bool aIncludeText,
bool aIncludeShapes,
3042 bool aIncludePrivateItems )
const
3044 std::vector<const PCB_TEXT*> texts;
3051 if( item->Type() ==
PCB_TEXT_T && aIncludeText )
3056 texts.push_back(
text );
3067 textbox->PCB_SHAPE::TransformShapeToPolygon( aBuffer, aLayer, 0, aError, aErrorLoc );
3073 if( item->Type() ==
PCB_SHAPE_T && aIncludeShapes )
3086 if( field->GetLayer() == aLayer && field->IsVisible() )
3087 texts.push_back( field );
3092 text->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
3102 if( zcMap.
Choices().GetCount() == 0 )
3104 zcMap.
Undefined( ZONE_CONNECTION::INHERITED );
3105 zcMap.
Map( ZONE_CONNECTION::INHERITED,
_HKI(
"Inherited" ) )
3106 .
Map( ZONE_CONNECTION::NONE,
_HKI(
"None" ) )
3107 .
Map( ZONE_CONNECTION::THERMAL,
_HKI(
"Thermal reliefs" ) )
3108 .
Map( ZONE_CONNECTION::FULL,
_HKI(
"Solid" ) )
3109 .
Map( ZONE_CONNECTION::THT_THERMAL,
_HKI(
"Thermal reliefs for PTH" ) );
3114 if( layerEnum.
Choices().GetCount() == 0 )
3122 wxPGChoices fpLayers;
3135 layer->SetChoices( fpLayers );
3140 PROPERTY_DISPLAY::PT_DEGREE ) );
3142 const wxString groupFootprint =
_HKI(
"Fields" );
3161 const wxString groupAttributes =
_HKI(
"Attributes" );
3175 const wxString groupOverrides =
_HKI(
"Overrides" );
3178 _HKI(
"Exempt from courtyard requirement" ),
3183 PROPERTY_DISPLAY::PT_SIZE ),
3187 PROPERTY_DISPLAY::PT_SIZE ),
3190 _HKI(
"Solderpaste Margin Ratio Override" ),
3195 _HKI(
"Zone Connection Style" ),
constexpr int ARC_HIGH_DEF
constexpr EDA_IU_SCALE pcbIUScale
constexpr int ARC_LOW_DEF
BITMAPS
A list of all bitmap identifiers.
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
Abstract interface for BOARD_ITEMs capable of storing other items inside.
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.
PCB_GROUP * GetParentGroup() const
virtual void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const
Convert the item shape to a closed polygon.
virtual BOARD_ITEM * Duplicate() const
Create a copy of this BOARD_ITEM.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
VECTOR2I GetFPRelativePosition() const
BOARD_ITEM_CONTAINER * GetParent() const
virtual bool IsOnCopperLayer() const
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Information pertinent to a Pcbnew printed circuit board.
bool IsFootprintHolder() const
Find out if the board is being used to hold a single footprint for editing/viewing.
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Test whether a given element category is visible.
bool IsLayerVisible(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
const Vec GetCenter() const
bool Intersects(const BOX2< Vec > &aRect) const
coord_type GetTop() const
coord_type GetHeight() const
coord_type GetWidth() const
void Move(const Vec &aMoveVector)
Move the rectangle by the aMoveVector.
bool Contains(const Vec &aPoint) const
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
coord_type GetBottom() const
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
virtual double OnePixelInIU() const =0
int GetCount() const
Return the number of objects in the list.
bool IsType(FRAME_T aType) const
The base class for create windows for drawing purpose.
A base class for most all the KiCad significant classes used in schematics and boards.
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Assign the members of aItem to another object.
void SetFlags(EDA_ITEM_FLAGS aMask)
KICAD_T Type() const
Returns the type of object.
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
virtual void SetParent(EDA_ITEM *aParent)
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
virtual wxString GetClass() const =0
Return the class name.
EDA_ITEM_FLAGS GetFlags() const
const VECTOR2I & GetBezierC2() const
SHAPE_POLY_SET & GetPolyShape()
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
const VECTOR2I & GetBezierC1() const
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
ENUM_MAP & Map(T aValue, const wxString &aName)
static ENUM_MAP< T > & Instance()
ENUM_MAP & Undefined(T aValue)
wxString m_Filename
The 3D shape filename in 3D library.
Used when the right click button is pressed, or when the select tool is in effect.
const COLLECTORS_GUIDE * GetGuide() const
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
wxString GetUniStringLibId() const
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
const wxString GetUniStringLibNickname() const
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
LSET is a set of PCB_LAYER_IDs.
static LSET AllLayersMask()
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
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...
static const int ORPHANED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
const wxString & GetNumber() const
VECTOR2I GetPosition() const override
PAD_SHAPE GetShape() const
const VECTOR2I & GetSize() const
bool IsMandatoryField() const
A set of BOARD_ITEMs (i.e., without duplicates).
std::unordered_set< BOARD_ITEM * > & GetItems()
bool RemoveItem(BOARD_ITEM *aItem)
Remove item from group.
bool AddItem(BOARD_ITEM *aItem)
Add item to group.
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
int GetWidth() const override
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the shape to a closed polygon.
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
bool IsBorderEnabled() const
Disables the border, this is done by changing the stroke internally.
void TransformTextToPolySet(SHAPE_POLY_SET &aBuffer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc) const
Function TransformTextToPolySet Convert the text to a polygonSet describing the actual character stro...
bool IsVisible() const override
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Provide class metadata.Helper macro to map type hashes to names.
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
PROPERTY_BASE & ReplaceProperty(size_t aBase, const wxString &aName, PROPERTY_BASE *aNew, const wxString &aGroup=wxEmptyString)
Replace an existing property for a specific type.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
double Area(bool aAbsolute=true) const
Return the area of this chain.
const VECTOR2I NearestPoint(const VECTOR2I &aP, bool aAllowInternalShapePoints=true) const
Find a point on the line chain that is closest to point aP.
Represent a set of closed polygons.
void Rotate(const EDA_ANGLE &aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
void RemoveAllContours()
Remove all outlines & holes (clears) the polygon set.
void BooleanSubtract(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset difference For aFastMode meaning, see function booleanOp.
@ CHAMFER_ACUTE_CORNERS
Acute angles are chamfered.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
double Area()
Return the area of this poly set.
bool IsEmpty() const
Return true if the set is empty (no polygons at all)
void CacheTriangulation(bool aPartition=true, bool aSimplify=false)
Build a polygon triangulation, needed to draw a polygon on OpenGL and in some other calculations.
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,...
int TotalVertices() const
Return total number of vertices stored in the set.
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
int HoleCount(int aOutline) const
Returns the number of holes in a given outline.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
void Simplify(POLYGON_MODE aFastMode)
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFastMo...
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirror the line points about y or x (or both)
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the reference to aHole-th hole in the aIndex-th outline.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the index-th vertex in a given hole outline within a given outline.
int OutlineCount() const
Return the number of outlines in the set.
void Move(const VECTOR2I &aVector) override
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
Represent a simple polygon consisting of a zero-thickness closed chain of connected line segments.
An abstract shape on 2D plane.
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.
SHAPE_POLY_SET * Outline()
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
unsigned GetAssignedPriority() const
This file is part of the common library.
void TransformOvalToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a oblong shape to a polygon, using multiple segments.
bool ConvertOutlineToPolygon(std::vector< PCB_SHAPE * > &aShapeList, SHAPE_POLY_SET &aPolygons, int aErrorMax, int aChainingEpsilon, bool aAllowDisjoint, OUTLINE_ERROR_HANDLER *aErrorHandler, bool aAllowUseArcsInPolygons)
Function ConvertOutlineToPolygon build a polygon set (with holes) from a PCB_SHAPE list,...
const std::function< void(const wxString &msg, BOARD_ITEM *itemA, BOARD_ITEM *itemB, const VECTOR2I &pt)> OUTLINE_ERROR_HANDLER
void BuildConvexHull(std::vector< VECTOR2I > &aResult, const std::vector< VECTOR2I > &aPoly)
Calculate the convex hull of a list of points in counter-clockwise order.
@ DRCE_PAD_TH_WITH_NO_HOLE
static constexpr EDA_ANGLE & ANGLE_180
static constexpr EDA_ANGLE & ANGLE_0
const INSPECTOR_FUNC & INSPECTOR
#define COURTYARD_CONFLICT
temporary set when moving footprints having courtyard overlapping
#define MALFORMED_F_COURTYARD
#define MALFORMED_B_COURTYARD
#define STRUCT_DELETED
flag indication structures to be erased
#define MALFORMED_COURTYARDS
@ FRAME_FOOTPRINT_CHOOSER
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
Some functions to handle hotkeys in KiCad.
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
@ LAYER_LOCKED_ITEM_SHADOW
shadow layer for locked items
@ LAYER_CONFLICTS_SHADOW
shadow layer for items flagged conficting
@ LAYER_FOOTPRINTS_FR
show footprints on front
@ LAYER_FP_REFERENCES
show footprints references (when texts are visible)
@ LAYER_FOOTPRINTS_BK
show footprints on back
@ LAYER_ANCHOR
anchor of items having an anchor point (texts, footprints)
@ LAYER_FP_VALUES
show footprints values (when texts are visible)
PCB_LAYER_ID
A quick note on layer IDs:
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
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 ...
void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
wxString GetRefDesPrefix(const wxString &aRefDes)
Get the (non-numeric) prefix from a refdes - e.g.
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Class to handle a set of BOARD_ITEMs.
#define NO_SETTER(owner, type)
Collection of utility functions for component reference designators (refdes)
std::vector< FAB_LAYER_COLOR > dummy
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
int GetTrailingInt(const wxString &aStr)
Gets the trailing int, if any, from a string.
wxString UnescapeString(const wxString &aSource)
constexpr double IUTomm(int iu) const
constexpr int mmToIU(double mm) const
MANDATORY_FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ DATASHEET_FIELD
name of datasheet
@ FOOTPRINT_FIELD
Field Name Module PCB, i.e. "16DIP300".
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ MANDATORY_FIELDS
The first 5 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
@ 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_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_FIELD_T
class PCB_FIELD, text associated with a footprint property
@ PCB_MARKER_T
class PCB_MARKER, a marker used to show something
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_BITMAP_T
class PCB_BITMAP, bitmap on a layer
@ 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_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
@ 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".