26#include <magic_enum.hpp>
28#include <unordered_set>
69#include <google/protobuf/any.pb.h>
70#include <api/board/board_types.pb.h>
172 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
180 ptrMap[field] = existingField;
181 *existingField = *field;
187 ptrMap[field] = newField;
195 PAD* newPad =
static_cast<PAD*
>(
pad->Clone() );
196 ptrMap[
pad ] = newPad;
203 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
204 ptrMap[ zone ] = newZone;
218 ptrMap[ item ] = newItem;
226 ptrMap[
group ] = newGroup;
233 ptrMap[ point ] = newPoint;
246 if( ptrMap.count( member ) )
247 newGroup->
AddItem( ptrMap[ member ] );
259 *
this = std::move( aFootprint );
299 board->IncrementTimeStamp();
306 types::FootprintInstance footprint;
308 footprint.mutable_id()->set_value(
m_Uuid.AsStdString() );
309 footprint.mutable_position()->set_x_nm(
GetPosition().x );
310 footprint.mutable_position()->set_y_nm(
GetPosition().y );
313 footprint.set_locked(
IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
314 : kiapi::common::types::LockedState::LS_UNLOCKED );
316 google::protobuf::Any buf;
318 buf.UnpackTo( footprint.mutable_reference_field() );
320 buf.UnpackTo( footprint.mutable_value_field() );
322 buf.UnpackTo( footprint.mutable_datasheet_field() );
324 buf.UnpackTo( footprint.mutable_description_field() );
326 types::FootprintAttributes* attrs = footprint.mutable_attributes();
332 attrs->set_do_not_populate(
IsDNP() );
335 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_THROUGH_HOLE );
337 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_SMD );
339 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_UNSPECIFIED );
341 types::Footprint* def = footprint.mutable_definition();
346 def->mutable_attributes()->set_keywords(
GetKeywords().ToStdString() );
350 types::FootprintDesignRuleOverrides* overrides = def->mutable_overrides();
364 overrides->set_zone_connection(
369 types::NetTieDefinition* netTie = def->add_net_ties();
370 wxStringTokenizer tokenizer(
group,
", \t\r\n", wxTOKEN_STRTOK );
372 while( tokenizer.HasMoreTokens() )
373 netTie->add_pad_number( tokenizer.GetNextToken().ToStdString() );
381 if( item->IsMandatory() )
384 google::protobuf::Any* itemMsg = def->add_items();
385 item->Serialize( *itemMsg );
388 for(
const PAD* item :
Pads() )
390 google::protobuf::Any* itemMsg = def->add_items();
391 item->Serialize( *itemMsg );
396 google::protobuf::Any* itemMsg = def->add_items();
397 item->Serialize( *itemMsg );
402 google::protobuf::Any* itemMsg = def->add_items();
403 item->Serialize( *itemMsg );
408 google::protobuf::Any* itemMsg = def->add_items();
409 types::Footprint3DModel modelMsg;
410 modelMsg.set_filename( model.m_Filename.ToUTF8() );
414 modelMsg.set_visible( model.m_Show );
415 modelMsg.set_opacity( model.m_Opacity );
416 itemMsg->PackFrom( modelMsg );
422 aContainer.PackFrom( footprint );
429 types::FootprintInstance footprint;
431 if( !aContainer.UnpackTo( &footprint ) )
438 SetLocked( footprint.locked() == kiapi::common::types::LockedState::LS_LOCKED );
440 google::protobuf::Any buf;
441 types::Field mandatoryField;
443 if( footprint.has_reference_field() )
445 mandatoryField = footprint.reference_field();
447 buf.PackFrom( mandatoryField );
451 if( footprint.has_value_field() )
453 mandatoryField = footprint.value_field();
455 buf.PackFrom( mandatoryField );
459 if( footprint.has_datasheet_field() )
461 mandatoryField = footprint.datasheet_field();
463 buf.PackFrom( mandatoryField );
467 if( footprint.has_description_field() )
469 mandatoryField = footprint.description_field();
471 buf.PackFrom( mandatoryField );
477 switch( footprint.attributes().mounting_style() )
479 case types::FootprintMountingStyle::FMS_THROUGH_HOLE:
483 case types::FootprintMountingStyle::FMS_SMD:
491 SetBoardOnly( footprint.attributes().not_in_schematic() );
495 SetDNP( footprint.attributes().do_not_populate() );
501 SetKeywords( footprint.definition().attributes().keywords() );
503 const types::FootprintDesignRuleOverrides& overrides = footprint.overrides();
505 if( overrides.has_copper_clearance() )
510 if( overrides.has_solder_mask() && overrides.solder_mask().has_solder_mask_margin() )
515 if( overrides.has_solder_paste() )
517 const types::SolderPasteOverrides& pasteSettings = overrides.solder_paste();
519 if( pasteSettings.has_solder_paste_margin() )
524 if( pasteSettings.has_solder_paste_margin_ratio() )
532 for(
const types::NetTieDefinition& netTieMsg : footprint.definition().net_ties() )
536 for(
const std::string&
pad : netTieMsg.pad_number() )
537 group.Append( wxString::Format( wxT(
"%s " ),
pad ) );
545 for(
int layerMsg : footprint.definition().private_layers() )
550 privateLayers.
set( layer );
558 if( !field->IsMandatory() )
569 for(
const google::protobuf::Any& itemMsg : footprint.definition().items() )
577 if( itemMsg.type_url() ==
"type.googleapis.com/kiapi.board.types.Footprint3DModel" )
579 types::Footprint3DModel modelMsg;
581 if( !itemMsg.UnpackTo( &modelMsg ) )
586 model.
m_Filename = wxString::FromUTF8( modelMsg.filename() );
587 model.
m_Show = modelMsg.visible();
593 Models().push_back( std::move( model ) );
597 wxLogTrace(
traceApi, wxString::Format( wxS(
"Attempting to unpack unknown type %s "
598 "from footprint message, skipping" ),
599 itemMsg.type_url() ) );
607 if( item && item->Deserialize( itemMsg ) )
619 if( field->GetId() == aFieldType )
634 if( field->GetId() == aFieldType )
644 return GetField( aFieldName ) !=
nullptr;
652 if( field->GetName() == aFieldName )
668 if( !field->IsVisible() || field->GetText().IsEmpty() )
672 aVector.push_back( field );
675 std::sort( aVector.begin(), aVector.end(),
678 return lhs->GetOrdinal() < rhs->GetOrdinal();
688 ordinal = std::max( ordinal, field->GetOrdinal() + 1 );
695 bool aStyleShapes,
bool aStyleDimensions,
bool aStyleBarcodes )
700 field->StyleFromSettings(
board.GetDesignSettings(),
true );
705 switch( item->Type() )
710 item->StyleFromSettings(
board.GetDesignSettings(),
true );
715 if( aStyleShapes && !item->IsOnCopperLayer() )
716 item->StyleFromSettings(
board.GetDesignSettings(),
true );
725 if( aStyleDimensions )
726 item->StyleFromSettings(
board.GetDesignSettings(),
true );
732 item->StyleFromSettings(
board.GetDesignSettings(),
true );
745 std::vector< BOARD_ITEM* > item_list;
748 item_list.push_back( field );
751 item_list.push_back(
pad );
754 item_list.push_back( gr_item );
759 item_list.push_back(
group );
763 item_list.push_back( zone );
767 item_list.push_back( point );
769 bool changed =
false;
775 const_cast<KIID&
>( item->m_Uuid ) =
KIID();
788 m_pos = aOther.m_pos;
812 std::ranges::copy( aOther.m_jumperPadGroups,
821 for(
PCB_FIELD* field : aOther.m_fields )
824 aOther.m_fields.clear();
832 for(
PAD*
pad : aOther.Pads() )
835 aOther.Pads().clear();
843 for(
ZONE* item : aOther.Zones() )
851 item->SetNetCode( -1 );
854 aOther.Zones().clear();
862 for(
BOARD_ITEM* item : aOther.GraphicalItems() )
865 aOther.GraphicalItems().clear();
876 aOther.Groups().clear();
884 for(
PCB_POINT* point : aOther.Points() )
887 aOther.Points().clear();
900 aOther.m_fields.clear();
901 aOther.Pads().clear();
902 aOther.Zones().clear();
903 aOther.GraphicalItems().clear();
904 aOther.m_initial_comments =
nullptr;
937 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
945 ptrMap[field] = newField;
955 ptrMap[
pad ] = newPad;
964 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
965 ptrMap[ zone ] = newZone;
981 ptrMap[ item ] = newItem;
994 newGroup->
AddItem( ptrMap[ member ] );
1005 ptrMap[ point ] = newItem;
1027 *
this = *
static_cast<const FOOTPRINT*
>( aOther );
1053 aVars->push_back( wxT(
"REFERENCE" ) );
1054 aVars->push_back( wxT(
"VALUE" ) );
1055 aVars->push_back( wxT(
"LAYER" ) );
1056 aVars->push_back( wxT(
"FOOTPRINT_LIBRARY" ) );
1057 aVars->push_back( wxT(
"FOOTPRINT_NAME" ) );
1058 aVars->push_back( wxT(
"SHORT_NET_NAME(<pad_number>)" ) );
1059 aVars->push_back( wxT(
"NET_NAME(<pad_number>)" ) );
1060 aVars->push_back( wxT(
"NET_CLASS(<pad_number>)" ) );
1061 aVars->push_back( wxT(
"PIN_NAME(<pad_number>)" ) );
1070 if( token->IsSameAs( wxT(
"REFERENCE" ) ) )
1075 else if( token->IsSameAs( wxT(
"VALUE" ) ) )
1080 else if( token->IsSameAs( wxT(
"LAYER" ) ) )
1085 else if( token->IsSameAs( wxT(
"FOOTPRINT_LIBRARY" ) ) )
1087 *token =
m_fpid.GetUniStringLibNickname();
1090 else if( token->IsSameAs( wxT(
"FOOTPRINT_NAME" ) ) )
1092 *token =
m_fpid.GetUniStringLibItemName();
1095 else if( token->StartsWith( wxT(
"SHORT_NET_NAME(" ) )
1096 || token->StartsWith( wxT(
"NET_NAME(" ) )
1097 || token->StartsWith( wxT(
"NET_CLASS(" ) )
1098 || token->StartsWith( wxT(
"PIN_NAME(" ) ) )
1100 wxString padNumber = token->AfterFirst(
'(' );
1101 padNumber = padNumber.BeforeLast(
')' );
1105 if(
pad->GetNumber() == padNumber )
1107 if( token->StartsWith( wxT(
"SHORT_NET_NAME" ) ) )
1108 *token =
pad->GetShortNetname();
1109 else if( token->StartsWith( wxT(
"NET_NAME" ) ) )
1110 *token =
pad->GetNetname();
1111 else if( token->StartsWith( wxT(
"NET_CLASS" ) ) )
1112 *token =
pad->GetNetClassName();
1114 *token =
pad->GetPinFunction();
1122 *token = field->GetText();
1144 switch( aBoardItem->
Type() )
1170 m_pads.push_back(
static_cast<PAD*
>( aBoardItem ) );
1172 m_pads.push_front(
static_cast<PAD*
>( aBoardItem ) );
1178 m_zones.push_back(
static_cast<ZONE*
>( aBoardItem ) );
1193 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Markers go at the board level, even in the footprint editor" ) );
1197 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Nested footprints not supported" ) );
1209 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Add(): BOARD_ITEM type (%d) not handled" ),
1210 aBoardItem->
Type() ) );
1222 switch( aBoardItem->
Type() )
1227 if( *it == aBoardItem )
1249 if( *it == aBoardItem )
1259 for(
auto it =
m_pads.begin(); it !=
m_pads.end(); ++it )
1261 if( *it ==
static_cast<PAD*
>( aBoardItem ) )
1273 if( *it ==
static_cast<ZONE*
>( aBoardItem ) )
1285 if( *it ==
static_cast<PCB_GROUP*
>( aBoardItem ) )
1297 if( *it ==
static_cast<PCB_POINT*
>( aBoardItem ) )
1309 msg.Printf( wxT(
"FOOTPRINT::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
1310 aBoardItem->
Type() );
1336 switch(
pad->GetProperty() )
1354 switch(
pad->GetAttribute() )
1361 if(
pad->IsOnCopperLayer() )
1389 return _(
"Through hole" );
1391 return _(
"Other" );
1406 if(
dummy.IsFlipped() )
1410 bbox.
Merge(
pad->GetBoundingBox() );
1455 std::vector<PCB_TEXT*> texts;
1456 bool isFPEdit =
board &&
board->IsFootprintHolder();
1477 texts.push_back(
static_cast<PCB_TEXT*
>( item ) );
1495 bbox.
Merge( item->GetBoundingBox() );
1501 if( field->IsReference() || field->IsValue() )
1504 texts.push_back( field );
1508 bbox.
Merge(
pad->GetBoundingBox() );
1511 bbox.
Merge( zone->GetBoundingBox() );
1514 bbox.
Merge( point->GetBoundingBox() );
1519 if( aIncludeText || noDrawItems )
1536 bool valueLayerIsVisible =
true;
1537 bool refLayerIsVisible =
true;
1555 if( (
Value().IsVisible() && valueLayerIsVisible ) || noDrawItems )
1560 if( (
Reference().IsVisible() && refLayerIsVisible ) || noDrawItems )
1568 if( aIncludeText || noDrawItems )
1586 std::vector<PCB_TEXT*> texts;
1588 bool isFPEdit =
board &&
board->IsFootprintHolder();
1598 if( ( aLayers & item->GetLayerSet() ).none() )
1606 bbox.
Merge( item->GetBoundingBox() );
1611 if( ( aLayers &
pad->GetLayerSet() ).none() )
1614 bbox.
Merge(
pad->GetBoundingBox() );
1619 if( ( aLayers & zone->GetLayerSet() ).none() )
1622 bbox.
Merge( zone->GetBoundingBox() );
1630 if( ( aLayers & point->GetLayerSet() ).none() )
1633 bbox.
Merge( point->GetBoundingBox() );
1643 bool isFPEdit =
board &&
board->IsFootprintHolder();
1669 pad->Padstack().ForEachUniqueLayer(
1683 const SHAPE_POLY_SET& layerPoly = *zone->GetFilledPolysList( layer );
1699 const int halfsize =
pcbIUScale.mmToIU( 1.0 );
1710 std::vector<VECTOR2I> convex_hull;
1716 for(
const VECTOR2I& pt : convex_hull )
1729 bool isFPEdit =
board &&
board->IsFootprintHolder();
1739 if( item->IsOnLayer( aLayer ) )
1753 if(
pad->IsOnLayer( aLayer ) )
1759 if( zone->GetIsRuleArea() )
1762 if( zone->IsOnLayer( aLayer ) )
1764 const std::shared_ptr<SHAPE_POLY_SET>& layerPoly = zone->GetFilledPolysList( aLayer );
1766 for(
int ii = 0; ii < layerPoly->OutlineCount(); ii++ )
1767 rawPolys.
AddOutline( layerPoly->COutline( ii ) );
1771 std::vector<VECTOR2I> convex_hull;
1776 for(
const VECTOR2I& pt : convex_hull )
1797 aList.emplace_back(
_(
"Library" ),
GetFPID().GetLibNickname().wx_str() );
1799 aList.emplace_back(
_(
"Footprint Name" ),
GetFPID().GetLibItemName().wx_str() );
1801 aList.emplace_back(
_(
"Pads" ), wxString::Format( wxT(
"%zu" ), padCount ) );
1804 wxString::Format(
_(
"Keywords: %s" ),
GetKeywords() ) );
1813 case F_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Front" ) );
break;
1814 case B_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Back (Flipped)" ) );
break;
1818 auto addToken = []( wxString* aStr,
const wxString& aAttr )
1820 if( !aStr->IsEmpty() )
1821 *aStr += wxT(
", " );
1830 addToken( &status,
_(
"Locked" ) );
1833 addToken( &status,
_(
"autoplaced" ) );
1836 addToken( &attrs,
_(
"not in schematic" ) );
1839 addToken( &attrs,
_(
"exclude from pos files" ) );
1842 addToken( &attrs,
_(
"exclude from BOM" ) );
1845 addToken( &attrs,
_(
"DNP" ) );
1847 aList.emplace_back(
_(
"Status: " ) + status,
_(
"Attributes:" ) + wxS(
" " ) + attrs );
1849 aList.emplace_back(
_(
"Rotation" ), wxString::Format( wxT(
"%.4g" ),
1855 _(
"Component Class" ),
1859 msg.Printf(
_(
"Footprint: %s" ),
m_fpid.GetUniStringLibId() );
1860 msg2.Printf(
_(
"3D-Shape: %s" ),
m_3D_Drawings.empty() ?
_(
"<none>" )
1862 aList.emplace_back( msg, msg2 );
1866 aList.emplace_back( msg, msg2 );
1874 if(
board->IsFootprintHolder() )
1906 if(
pad->IsOnLayer( aLayer ) )
1912 if( zone->IsOnLayer( aLayer ) )
1918 if( field->IsOnLayer( aLayer ) )
1924 if( item->IsOnLayer( aLayer ) )
1936 if(
pad->IsOnLayer( aLayer ) &&
pad->HitTest( aPosition, aAccuracy ) )
1942 if( zone->IsOnLayer( aLayer ) && zone->HitTest( aPosition, aAccuracy ) )
1948 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer )
1949 && item->HitTest( aPosition, aAccuracy ) )
1961 std::vector<BOARD_ITEM*> items;
1965 if(
pad->IsOnLayer( aLayer ) )
1966 items.push_back(
pad );
1971 if( zone->IsOnLayer( aLayer ) )
1972 items.push_back( zone );
1977 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer ) )
1978 items.push_back( item );
1987 if( !aContained && item->HitTest( aRect, aContained, aAccuracy ) )
1989 else if( aContained && !item->HitTest( aRect, aContained, aAccuracy ) )
1996 return !items.empty() && aContained;
2015 BOX2I arect = aRect;
2035 if(
pad->HitTest( arect,
false, 0 ) )
2041 if( zone->HitTest( arect,
false, 0 ) )
2047 if( point->HitTest( arect,
false, 0 ) )
2058 if( item->Type() !=
PCB_TEXT_T && item->HitTest( arect,
false, 0 ) )
2072 using std::ranges::all_of;
2073 using std::ranges::any_of;
2080 [&](
const auto* aItem )
2082 return aItem && aItem->HitTest( aPoly, aContained );
2088 auto drawings =
m_drawings | std::views::filter( [](
const auto* aItem )
2099 return all_of( drawings, hitTest )
2100 && all_of(
m_pads, hitTest )
2101 && all_of(
m_zones, hitTest );
2106 return any_of( drawings, hitTest )
2107 || any_of(
m_pads, hitTest )
2108 || any_of(
m_zones, hitTest );
2115 bool can_select = aSearchAfterMe ? false :
true;
2119 if( !can_select &&
pad == aSearchAfterMe )
2125 if( can_select &&
pad->GetNumber() == aPadNumber )
2138 if( !(
pad->GetLayerSet() & aLayerMask ).any() )
2141 if(
pad->HitTest( aPosition ) )
2151 std::vector<const PAD*> retv;
2155 if( ( aIgnore && aIgnore ==
pad ) || (
pad->GetNumber() != aPadNumber ) )
2158 retv.push_back(
pad );
2186 std::set<wxString> usedNumbers;
2198 if(
pad->GetNumber().IsEmpty() )
2208 usedNumbers.insert(
pad->GetNumber() );
2223 if(
nullptr == a3DModel )
2251 const std::vector<KICAD_T>& aScanTypes )
2253#if 0 && defined(DEBUG)
2254 std::cout <<
GetClass().mb_str() <<
' ';
2257 bool drawingsScanned =
false;
2259 for(
KICAD_T scanType : aScanTypes )
2307 if( !drawingsScanned )
2315 drawingsScanned =
true;
2351 if( reference.IsEmpty() )
2352 reference =
_(
"<no reference designator>" );
2354 return wxString::Format(
_(
"Footprint %s" ), reference );
2391 aFunction( drawing );
2397 catch( std::bad_function_call& )
2399 wxFAIL_MSG( wxT(
"Error running FOOTPRINT::RunOnChildren" ) );
2406 std::vector<int> layers;
2408 layers.reserve( 6 );
2414 wxASSERT_MSG(
false, wxT(
"Illegal layer" ) );
2432 bool f_silk =
false, b_silk =
false, non_silk =
false;
2436 if( item->GetLayer() ==
F_SilkS )
2438 else if( item->GetLayer() ==
B_SilkS )
2444 if( ( f_silk || b_silk ) && !non_silk &&
m_pads.empty() )
2477 constexpr double MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY = 1.5;
2480 return MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY;
2493 int biggest_clearance =
board->GetMaxClearanceValue();
2494 area.
Inflate( biggest_clearance );
2505 if( aName.find_first_of( invalids ) != std::string::npos )
2519 static const wxChar invalidChars[] = wxT(
"%$<>\t\n\r\"\\/:");
2520 static const wxChar invalidCharsReadable[] = wxT(
"% $ < > 'tab' 'return' 'line feed' \\ \" / :");
2523 return invalidCharsReadable;
2525 return invalidChars;
2531 if( aMoveVector.
x == 0 && aMoveVector.
y == 0 )
2545 EDA_ANGLE newOrientation = orientation + aAngle;
2552 field->KeepUpright();
2557 static_cast<PCB_TEXT*
>( item )->KeepUpright();
2564 wxASSERT( aLayer ==
F_Cu || aLayer ==
B_Cu );
2641 field->EDA_TEXT::Offset(
delta );
2647 zone->Move(
delta );
2650 item->Move(
delta );
2653 point->Move(
delta );
2685 field->Move( moveVector );
2689 pad->Move( moveVector );
2693 item->Move( moveVector );
2697 zone->Move( moveVector );
2702 model.m_Offset.x +=
pcbIUScale.IUTomm( moveVector.
x );
2703 model.m_Offset.y -=
pcbIUScale.IUTomm( moveVector.
y );
2765 const BOARD_ITEM* aItem,
bool addToFootprint )
2769 switch( aItem->
Type() )
2773 PAD* new_pad =
new PAD( *
static_cast<const PAD*
>( aItem ) );
2776 if( addToFootprint )
2777 m_pads.push_back( new_pad );
2785 ZONE* new_zone =
new ZONE( *
static_cast<const ZONE*
>( aItem ) );
2788 if( addToFootprint )
2789 m_zones.push_back( new_zone );
2791 new_item = new_zone;
2800 if( addToFootprint )
2803 new_item = new_point;
2815 switch(
static_cast<const PCB_FIELD*
>( aItem )->GetId() )
2824 if( addToFootprint )
2827 new_item = new_text;
2836 if( addToFootprint )
2839 new_item = new_shape;
2848 if( addToFootprint )
2851 new_item = new_barcode;
2860 if( addToFootprint )
2863 new_item = new_image;
2872 if( addToFootprint )
2875 new_item = new_textbox;
2888 if( addToFootprint )
2891 new_item = dimension;
2899 if( addToFootprint )
2901 group->RunOnChildren(
2921 wxFAIL_MSG( wxT(
"Duplication not supported for items of class " ) + aItem->
GetClass() );
2931 std::set<wxString> usedNumbers;
2935 usedNumbers.insert(
pad->GetNumber() );
2942 while( usedNumbers.count( wxString::Format( wxT(
"%s%d" ), prefix, num ) ) )
2945 return wxString::Format( wxT(
"%s%d" ), prefix, num );
2953 if(
group.contains( aPadNumber ) )
2957 return std::nullopt;
3008 for(
int jj = 0; jj < aPolySet.
HoleCount( ii ); jj++ )
3012 return aPolySet.
Area();
3027 return markerShape.
Area();
3031 double combinedArea = 0.0;
3036 return combinedArea;
3087 double width =
static_cast<const PCB_TRACK*
>( aItem )->GetWidth();
3088 return width * width;
3092 static_cast<const PAD*
>( aItem )->Padstack().ForEachUniqueLayer(
3124 for(
int i = 0; i < aCollector.
GetCount(); ++i )
3128 switch( item->
Type() )
3160 double footprintRegionArea =
polygonArea( footprintRegion );
3161 double uncoveredRegionArea = footprintRegionArea -
polygonArea( coveredRegion );
3162 double coveredArea = footprintRegionArea - uncoveredRegionArea;
3165 if( footprintRegionArea == 0 )
3168 double ratio = coveredArea / footprintRegionArea;
3175 return std::min( ratio, 1.0 );
3181 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
3202 shape->AddShape(
pad->GetEffectiveShape( aLayer, aFlash )->Clone() );
3207 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3209 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3249 std::vector<PCB_SHAPE*> list_front;
3250 std::vector<PCB_SHAPE*> list_back;
3251 std::map<int, int> front_width_histogram;
3252 std::map<int, int> back_width_histogram;
3259 list_back.push_back( shape );
3266 list_front.push_back( shape );
3271 if( !list_front.size() && !list_back.size() )
3275 int chainingEpsilon =
pcbIUScale.mmToIU( 0.02 );
3278 true, aErrorHandler ) )
3288 auto max = std::max_element( front_width_histogram.begin(), front_width_histogram.end(),
3289 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3291 return a.second < b.second;
3294 if( max != front_width_histogram.end() )
3317 auto max = std::max_element( back_width_histogram.begin(), back_width_histogram.end(),
3318 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3320 return a.second < b.second;
3323 if( max != back_width_histogram.end() )
3346 std::map<PCB_LAYER_ID, std::vector<PCB_SHAPE*>> layer_shapes;
3352 if( item->Type() != PCB_SHAPE_T )
3355 for( PCB_LAYER_ID layer : item->GetLayerSet() )
3357 if( !IsCopperLayer( layer ) )
3360 if( board && !board->GetEnabledLayers().Contains( layer ) )
3363 layer_shapes[layer].push_back( static_cast<PCB_SHAPE*>( item ) );
3367 for(
size_t ii = 0; ii < m_pads.size(); ++ii )
3370 bool has_nettie =
false;
3372 auto it = map.find(
pad->GetNumber() );
3374 if( it == map.end() || it->second < 0 )
3377 for(
size_t jj = ii + 1; jj < m_pads.size(); ++jj )
3379 PAD* other = m_pads[ jj ];
3381 auto it2 = map.find( other->
GetNumber() );
3383 if( it2 == map.end() || it2->second < 0 )
3386 if( it2->second == it->second )
3388 m_netTieCache[
pad].insert(
pad->GetNetCode() );
3390 m_netTieCache[other].insert( other->
GetNetCode() );
3391 m_netTieCache[other].insert(
pad->GetNetCode() );
3399 for(
auto& [ layer, shapes ] : layer_shapes )
3401 auto pad_shape =
pad->GetEffectiveShape( layer );
3403 for(
auto other_shape : shapes )
3405 auto shape = other_shape->GetEffectiveShape( layer );
3407 if( pad_shape->Collide( shape.get() ) )
3409 std::set<int>& nettie = m_netTieCache[
pad];
3410 m_netTieCache[other_shape].insert( nettie.begin(), nettie.end() );
3420 std::map<wxString, int> padNumberToGroupIdxMap;
3423 padNumberToGroupIdxMap[
pad->GetNumber() ] = -1;
3426 [&]( wxString aPad,
int aGroup )
3428 aPad.Trim(
true ).Trim(
false );
3430 if( !aPad.IsEmpty() )
3431 padNumberToGroupIdxMap[ aPad ] = aGroup;
3440 for( wxUniCharRef ch :
group )
3449 switch(
static_cast<unsigned char>( ch ) )
3456 processPad(
pad, ii );
3466 processPad(
pad, ii );
3469 return padNumberToGroupIdxMap;
3479 int groupIdx = padToNetTieGroupMap[ aPad->
GetNumber() ];
3480 std::vector<PAD*> otherPads;
3486 if( padToNetTieGroupMap[
pad->GetNumber() ] == groupIdx )
3487 otherPads.push_back(
pad );
3500 if( setAttr && likelyAttr && setAttr != likelyAttr )
3504 switch( likelyAttr )
3507 msg.Printf(
_(
"(expected 'Through hole'; actual '%s')" ),
GetTypeName() );
3510 msg.Printf(
_(
"(expected 'SMD'; actual '%s')" ),
GetTypeName() );
3515 (aErrorHandler)( msg );
3521 const std::function<
void(
const PAD*,
int,
3522 const wxString& )>& aErrorHandler )
3524 if( aErrorHandler ==
nullptr )
3529 pad->CheckPad( aUnitsProvider,
false,
3530 [&](
int errorCode,
const wxString& msg )
3532 aErrorHandler(
pad, errorCode, msg );
3540 const VECTOR2I& )>& aErrorHandler )
3542 std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
3557 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
3560 if( checkedPairs.find( { a, b } ) == checkedPairs.end() )
3562 checkedPairs[ { a, b } ] = 1;
3574 std::shared_ptr<SHAPE_SEGMENT> holeA =
pad->GetEffectiveHoleShape();
3577 if( holeA->Collide( holeB->GetSeg(), 0 ) )
3594 SHAPE* padShape =
pad->GetEffectiveShape( l ).get();
3597 if( padShape->
Collide( otherShape, 0,
nullptr, &pos ) )
3610 const VECTOR2I& )>& aErrorHandler )
3619 std::vector<BOARD_ITEM*> copperItems;
3623 if( item->IsOnCopperLayer() )
3624 copperItems.push_back( item );
3626 item->RunOnChildren(
3630 copperItems.push_back( descendent );
3637 if( !zone->GetIsRuleArea() && zone->IsOnCopperLayer() )
3638 copperItems.push_back( zone );
3643 if( field->IsOnCopperLayer() )
3644 copperItems.push_back( field );
3654 std::map<int, std::vector<const PAD*>> outlineIdxToPadsMap;
3658 if( item->IsOnLayer( layer ) )
3668 for(
int ii = 0; ii < copperOutlines.
OutlineCount(); ++ii )
3670 if(
pad->GetEffectiveShape( layer )->Collide( &copperOutlines.
Outline( ii ), 0 ) )
3671 outlineIdxToPadsMap[ ii ].emplace_back(
pad );
3678 for(
const auto& [ outlineIdx, pads ] : outlineIdxToPadsMap )
3680 if( pads.size() > 1 )
3682 const PAD* firstPad = pads[0];
3683 int firstGroupIdx = padNumberToGroupIdxMap[ firstPad->
GetNumber() ];
3685 for(
size_t ii = 1; ii < pads.size(); ++ii )
3687 const PAD* thisPad = pads[ii];
3688 int thisGroupIdx = padNumberToGroupIdxMap[ thisPad->
GetNumber() ];
3690 if( thisGroupIdx < 0 || thisGroupIdx != firstGroupIdx )
3699 if( item->HitTest( pos, 1 ) )
3701 shortingItem = item;
3707 aErrorHandler( shortingItem, firstPad, thisPad, pos );
3709 aErrorHandler( firstPad, thisPad,
nullptr, pos );
3720 std::set<wxString> padNumbers;
3729 msg.Printf(
_(
"(net-tie pad group contains unknown pad number %s)" ), padNumber );
3730 aErrorHandler( msg );
3732 else if( !padNumbers.insert(
pad->GetNumber() ).second )
3734 msg.Printf(
_(
"(pad %s appears in more than one net-tie pad group)" ), padNumber );
3735 aErrorHandler( msg );
3743 const VECTOR2I& aPt )>& aErrorHandler )
3745 auto checkColliding =
3760 if( itemShape->Collide( otherShape.get(), 0, &
actual, &pos ) )
3761 aErrorHandler( item, other, pos );
3770 checkColliding( item, other );
3774 checkColliding( item,
pad );
3785 std::swap( *
this, *
image );
3794 image->RunOnChildren(
3822 return *
this == other;
3831 for(
size_t ii = 0; ii <
m_pads.size(); ++ii )
3840 for(
size_t ii = 0; ii <
m_drawings.size(); ++ii )
3849 for(
size_t ii = 0; ii <
m_zones.size(); ++ii )
3859 std::vector<PCB_FIELD*> fields, otherFields;
3864 if( fields.size() != otherFields.size() )
3867 for(
size_t ii = 0; ii < fields.size(); ++ii )
3871 if( !( *fields[ii] == *otherFields[ii] ) )
3887 double similarity = 1.0;
3896 similarity *=
pad->Similarity( *otherPad );
3908 if( aPtA.
x != aPtB.
x )
3909 return aPtA.
x < aPtB.
x;
3911 if( aPtA.
y != aPtB.
y )
3912 return aPtA.
y < aPtB.
y;
3914 return std::nullopt;
3920 if( itemA->
Type() != itemB->
Type() )
3921 return itemA->
Type() < itemB->
Type();
3926 switch( itemA->
Type() )
3965 for(
int ii = 0; ii < dwgA->
GetPolyShape().TotalVertices(); ++ii )
3967 if( std::optional<bool> cmp =
4024 return itemA < itemB;
4036 std::optional<bool> padCopperMatches;
4039 const PAD* checkPad = aFirst;
4052 padCopperMatches = aFirst->
GetSize( aLayer ).
x < aSecond->
GetSize( aLayer ).
x;
4054 padCopperMatches = aFirst->
GetSize( aLayer ).
y < aSecond->
GetSize( aLayer ).
y;
4056 padCopperMatches = aFirst->
GetShape( aLayer ) < aSecond->
GetShape( aLayer );
4059 if( padCopperMatches.has_value() )
4060 return *padCopperMatches;
4068 return aFirst < aSecond;
4073bool FOOTPRINT::cmp_padstack::operator()(
const PAD* aFirst,
const PAD* aSecond )
const
4113 if( firstShape->VertexCount() != secondShape->VertexCount() )
4114 return firstShape->VertexCount() < secondShape->VertexCount();
4116 for(
int ii = 0; ii < firstShape->VertexCount(); ++ii )
4118 if( std::optional<bool> cmp =
cmp_points_opt( firstShape->CVertex( ii ), secondShape->CVertex( ii ) ) )
4140 for(
int ii = 0; ii < aFirst->
Outline()->TotalVertices(); ++ii )
4142 if( std::optional<bool> cmp =
4152 return aFirst < aSecond;
4157 int aMaxError,
ERROR_LOC aErrorLoc )
const
4168 clearance.x +=
pad->GetSolderMaskExpansion( padLayer );
4169 clearance.y +=
pad->GetSolderMaskExpansion( padLayer );
4192 if( dummySize.
x <= 0 || dummySize.
y <= 0 )
4196 dummy.SetSize( padLayer, dummySize );
4197 dummy.TransformShapeToPolygon( aBuffer, padLayer, 0, aMaxError, aErrorLoc );
4201 pad->TransformShapeToPolygon( aBuffer, padLayer,
clearance.x, aMaxError, aErrorLoc );
4207 if( !
pad->FlashLayer( aLayer ) )
4212 pad->Padstack().ForEachUniqueLayer(
4215 processPad(
pad, l );
4220 processPad(
pad, aLayer );
4227 int aError,
ERROR_LOC aErrorLoc,
bool aIncludeText,
4228 bool aIncludeShapes,
bool aIncludePrivateItems )
const
4235 if( item->Type() ==
PCB_TEXT_T && aIncludeText )
4240 text->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4251 textbox->PCB_SHAPE::TransformShapeToPolygon( aBuffer, aLayer, 0, aError, aErrorLoc );
4258 if( item->Type() ==
PCB_SHAPE_T && aIncludeShapes )
4279 if( field->GetLayer() == aLayer && field->IsVisible() )
4280 field->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4290 std::set<KIFONT::OUTLINE_FONT*>
fonts;
4304 if( permission == PERMISSION::EDITABLE || permission == PERMISSION::INSTALLABLE )
4305 fonts.insert( outlineFont );
4311 processItem( item );
4314 processItem( field );
4359 return wxEmptyString;
4364 const std::unordered_set<wxString>& aComponentClassNames )
4405 if( zcMap.
Choices().GetCount() == 0 )
4417 if( layerEnum.
Choices().GetCount() == 0 )
4425 wxPGChoices fpLayers;
4436 auto isNotFootprintHolder =
4442 return !
board->IsFootprintHolder();
4449 layer->SetChoices( fpLayers );
4450 layer->SetAvailableFunc( isNotFootprintHolder );
4458 const wxString groupFields =
_HKI(
"Fields" );
4483 const wxString groupAttributes =
_HKI(
"Attributes" );
4497 const wxString groupOverrides =
_HKI(
"Overrides" );
types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
std::unique_ptr< EDA_ITEM > CreateItemForType(KICAD_T aType, EDA_ITEM *aContainer)
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
constexpr EDA_IU_SCALE pcbIUScale
constexpr int ARC_LOW_DEF
BITMAPS
A list of all bitmap identifiers.
#define DEFAULT_COURTYARD_WIDTH
BASE_SET & set(size_t pos)
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
Abstract interface for BOARD_ITEMs capable of storing other items inside.
BOARD_ITEM_CONTAINER(BOARD_ITEM *aParent, KICAD_T aType)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
BOARD_ITEM(BOARD_ITEM *aParent, KICAD_T idtype, PCB_LAYER_ID aLayer=F_Cu)
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
virtual BOARD_ITEM * Duplicate(bool addToParentGroup, BOARD_COMMIT *aCommit=nullptr) const
Create a copy of this BOARD_ITEM.
virtual void TransformShapeToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc) const
Convert the item shape to a polyset.
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 bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
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.
COMPONENT_CLASS_MANAGER & GetComponentClassManager()
Gets the component class manager.
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
constexpr size_type GetWidth() const
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr const Vec GetCenter() const
constexpr size_type GetHeight() const
constexpr bool Contains(const Vec &aPoint) const
constexpr coord_type GetTop() const
constexpr bool Intersects(const BOX2< Vec > &aRect) const
constexpr coord_type GetBottom() const
virtual int Accuracy() const =0
int GetCount() const
Return the number of objects in the list.
COMPONENT_CLASS * GetEffectiveStaticComponentClass(const std::unordered_set< wxString > &classNames)
Gets an effective component class for the given constituent class names.
A lightweight representation of a component class.
bool IsType(FRAME_T aType) const
The base class for create windows for drawing purpose.
std::unordered_set< EDA_ITEM * > & GetItems()
void AddItem(EDA_ITEM *aItem)
Add item to group.
virtual void ClearEditFlags()
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 bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
static INSPECT_RESULT IterateForward(std::deque< T > &aList, INSPECTOR inspector, void *testData, const std::vector< KICAD_T > &scanTypes)
This changes first parameter to avoid the DList and use the main queue instead.
virtual void SetParent(EDA_ITEM *aParent)
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
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
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
const EDA_ANGLE & GetTextAngle() const
virtual const wxString & GetText() const
Return the string associated with the text object.
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
double GetLineSpacing() const
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
int GetTextThickness() const
VECTOR2I GetTextSize() const
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
EMBEDDED_FILES & operator=(EMBEDDED_FILES &&other) noexcept
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Load a file from disk and adds it to the collection.
const std::map< wxString, EMBEDDED_FILE * > & EmbeddedFileMap() const
bool m_embedFonts
If set, fonts will be embedded in the element on save.
ENUM_MAP & Map(T aValue, const wxString &aName)
static ENUM_MAP< T > & Instance()
ENUM_MAP & Undefined(T aValue)
VECTOR3D m_Offset
3D model offset (mm)
VECTOR3D m_Rotation
3D model rotation (degrees)
VECTOR3D m_Scale
3D model scaling factor (dimensionless)
wxString m_Filename
The 3D shape filename in 3D library.
bool m_Show
Include model in rendering.
Used when the right click button is pressed, or when the select tool is in effect.
const COLLECTORS_GUIDE * GetGuide() const
Class that other classes need to inherit from, in order to be inspectable.
FONT is an abstract base class for both outline and stroke fonts.
virtual bool IsOutline() const
Class OUTLINE_FONT implements outline font drawing.
EMBEDDING_PERMISSION GetEmbeddingPermission() const
virtual wxString GetClass() const =0
Return the class name.
static constexpr double LOD_HIDE
Return this constant from ViewGetLOD() to hide the item unconditionally.
static constexpr double LOD_SHOW
Return this constant from ViewGetLOD() to show the item unconditionally.
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.
LSET is a set of PCB_LAYER_IDs.
static const LSET & SideSpecificMask()
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
static const LSET & AllLayersMask()
static wxString 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...
void ForEachUniqueLayer(const std::function< void(PCB_LAYER_ID)> &aMethod) const
Runs the given callable for each active unique copper layer in this padstack, meaning F_Cu for MODE::...
@ NORMAL
Shape is the same on all layers.
@ CUSTOM
Shapes can be defined on arbitrary layers.
@ FRONT_INNER_BACK
Up to three shapes can be defined (F_Cu, inner copper layers, B_Cu)
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer, FLASHING flashPTHPads=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
const BOX2I GetBoundingBox() const override
The bounding box is cached, so this will be efficient most of the time.
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
int GetDrillSizeY() const
PAD_ATTRIB GetAttribute() const
const wxString & GetNumber() const
VECTOR2I GetPosition() const override
int GetDrillSizeX() const
PAD_SHAPE GetShape(PCB_LAYER_ID aLayer) const
int GetSolderMaskExpansion(PCB_LAYER_ID aLayer) const
const PADSTACK & Padstack() const
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
PAD_DRILL_SHAPE GetDrillShape() const
const std::shared_ptr< SHAPE_POLY_SET > & GetEffectivePolygon(PCB_LAYER_ID aLayer, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
std::optional< int > GetLocalSolderMaskMargin() const
VECTOR2I GetSolderPasteMargin(PCB_LAYER_ID aLayer) const
Usually < 0 (mask shape smaller than pad)because the margin can be dependent on the pad size,...
bool HasDrilledHole() const override
std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const override
Return a SHAPE_SEGMENT object representing the pad's hole.
const VECTOR2I & GetSize(PCB_LAYER_ID aLayer) const
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
A set of BOARD_ITEMs (i.e., without duplicates).
A PCB_POINT is a 0-dimensional point that is used to mark a position on a PCB, or more usually a foot...
Object to handle a bitmap image that can be inserted in a PCB.
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
int GetWidth() const override
void TransformShapeToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc) const override
Convert the item shape to a polyset.
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.
STROKE_PARAMS GetStroke() const override
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...
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
virtual VECTOR2I GetPosition() const override
PROPERTY_BASE & SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Set a callback function to determine whether an object provides this property.
PROPERTY_BASE & SetIsHiddenFromLibraryEditors(bool aIsHidden=true)
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 BooleanAdd(const SHAPE_POLY_SET &b)
Perform boolean polyset union.
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 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.
int FullPointCount() const
Return the number of points in the shape poly set.
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()
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
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.
void BooleanIntersection(const SHAPE_POLY_SET &b)
Perform boolean polyset intersection.
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.
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.
bool ConvertOutlineToPolygon(std::vector< PCB_SHAPE * > &aShapeList, SHAPE_POLY_SET &aPolygons, int aErrorMax, int aChainingEpsilon, bool aAllowDisjoint, OUTLINE_ERROR_HANDLER *aErrorHandler, bool aAllowUseArcsInPolygons)
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.
@ CHAMFER_ACUTE_CORNERS
Acute angles are chamfered.
@ DRCE_DRILLED_HOLES_TOO_CLOSE
@ DRCE_DRILLED_HOLES_COLOCATED
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_180
const INSPECTOR_FUNC & INSPECTOR
std::function passed to nested users by ref, avoids copying std::function.
#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
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
@ FRAME_FOOTPRINT_CHOOSER
a few functions useful in geometry calculations.
const wxChar *const traceApi
Flag to enable debug output related to the IPC API and its plugin system.
Some functions to handle hotkeys in KiCad.
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
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_CONFLICTS_SHADOW
Shadow layer for items flagged conflicting.
@ 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:
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 ...
constexpr void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
@ LEFT_RIGHT
Flip left to right (around the Y axis)
@ TOP_BOTTOM
Flip top to bottom (around the X axis)
bool BoxHitTest(const VECTOR2I &aHitPoint, const BOX2I &aHittee, int aAccuracy)
Perform a point-to-box hit test.
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.
KICOMMON_API std::optional< KICAD_T > TypeNameFromAny(const google::protobuf::Any &aMessage)
KICOMMON_API VECTOR3D UnpackVector3D(const types::Vector3D &aInput)
KICOMMON_API void PackSheetPath(types::SheetPath &aOutput, const KIID_PATH &aInput)
KICOMMON_API LIB_ID LibIdFromProto(const types::LibraryIdentifier &aId)
KICOMMON_API types::LibraryIdentifier LibIdToProto(const LIB_ID &aId)
KICOMMON_API void PackVector3D(types::Vector3D &aOutput, const VECTOR3D &aInput)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
@ SMD
Smd pad, appears on the solder paste layer (default)
@ PTH
Plated through hole pad.
@ FIDUCIAL_LOCAL
a fiducial (usually a smd) local to the parent footprint
@ FIDUCIAL_GLBL
a fiducial (usually a smd) for the full board
@ MECHANICAL
a pad used for mechanical support
@ PRESSFIT
a PTH with a hole diameter with tight tolerances for press fit pin
@ HEATSINK
a pad used as heat sink, usually in SMD footprints
@ NONE
no special fabrication property
@ TESTPOINT
a test point pad
@ CASTELLATED
a pad with a castellated through hole
@ BGA
Smd pad, used in BGA footprints.
BARCODE class definition.
Class to handle a set of BOARD_ITEMs.
#define NO_SETTER(owner, type)
@ PT_DEGREE
Angle expressed in degrees.
@ PT_SIZE
Size expressed in distance units (mm/inch)
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)
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ DESCRIPTION
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
@ DATASHEET
name of datasheet
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
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.
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_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_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
@ 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_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_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
@ 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
VECTOR2< int32_t > VECTOR2I
ZONE_CONNECTION
How pads are covered by copper in zone.
@ THERMAL
Use thermal relief for pads.
@ THT_THERMAL
Thermal relief only for THT pads.
@ NONE
Pads are not covered.
@ FULL
pads are covered by copper