26#include <magic_enum.hpp>
28#include <unordered_set>
68#include <google/protobuf/any.pb.h>
69#include <api/board/board_types.pb.h>
171 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
179 ptrMap[field] = existingField;
180 *existingField = *field;
186 ptrMap[field] = newField;
194 PAD* newPad =
static_cast<PAD*
>(
pad->Clone() );
195 ptrMap[
pad ] = newPad;
202 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
203 ptrMap[ zone ] = newZone;
217 ptrMap[ item ] = newItem;
225 ptrMap[
group ] = newGroup;
232 ptrMap[ point ] = newPoint;
245 if( ptrMap.count( member ) )
246 newGroup->
AddItem( ptrMap[ member ] );
258 *
this = std::move( aFootprint );
298 board->IncrementTimeStamp();
305 types::FootprintInstance footprint;
307 footprint.mutable_id()->set_value(
m_Uuid.AsStdString() );
308 footprint.mutable_position()->set_x_nm(
GetPosition().x );
309 footprint.mutable_position()->set_y_nm(
GetPosition().y );
312 footprint.set_locked(
IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
313 : kiapi::common::types::LockedState::LS_UNLOCKED );
315 google::protobuf::Any buf;
317 buf.UnpackTo( footprint.mutable_reference_field() );
319 buf.UnpackTo( footprint.mutable_value_field() );
321 buf.UnpackTo( footprint.mutable_datasheet_field() );
323 buf.UnpackTo( footprint.mutable_description_field() );
325 types::FootprintAttributes* attrs = footprint.mutable_attributes();
331 attrs->set_do_not_populate(
IsDNP() );
334 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_THROUGH_HOLE );
336 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_SMD );
338 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_UNSPECIFIED );
340 types::Footprint* def = footprint.mutable_definition();
345 def->mutable_attributes()->set_keywords(
GetKeywords().ToStdString() );
349 types::FootprintDesignRuleOverrides* overrides = def->mutable_overrides();
363 overrides->set_zone_connection(
368 types::NetTieDefinition* netTie = def->add_net_ties();
369 wxStringTokenizer tokenizer(
group,
", \t\r\n", wxTOKEN_STRTOK );
371 while( tokenizer.HasMoreTokens() )
372 netTie->add_pad_number( tokenizer.GetNextToken().ToStdString() );
380 if( item->IsMandatory() )
383 google::protobuf::Any* itemMsg = def->add_items();
384 item->Serialize( *itemMsg );
387 for(
const PAD* item :
Pads() )
389 google::protobuf::Any* itemMsg = def->add_items();
390 item->Serialize( *itemMsg );
395 google::protobuf::Any* itemMsg = def->add_items();
396 item->Serialize( *itemMsg );
401 google::protobuf::Any* itemMsg = def->add_items();
402 item->Serialize( *itemMsg );
407 google::protobuf::Any* itemMsg = def->add_items();
408 types::Footprint3DModel modelMsg;
409 modelMsg.set_filename( model.m_Filename.ToUTF8() );
413 modelMsg.set_visible( model.m_Show );
414 modelMsg.set_opacity( model.m_Opacity );
415 itemMsg->PackFrom( modelMsg );
421 aContainer.PackFrom( footprint );
428 types::FootprintInstance footprint;
430 if( !aContainer.UnpackTo( &footprint ) )
437 SetLocked( footprint.locked() == kiapi::common::types::LockedState::LS_LOCKED );
439 google::protobuf::Any buf;
440 types::Field mandatoryField;
442 if( footprint.has_reference_field() )
444 mandatoryField = footprint.reference_field();
446 buf.PackFrom( mandatoryField );
450 if( footprint.has_value_field() )
452 mandatoryField = footprint.value_field();
454 buf.PackFrom( mandatoryField );
458 if( footprint.has_datasheet_field() )
460 mandatoryField = footprint.datasheet_field();
462 buf.PackFrom( mandatoryField );
466 if( footprint.has_description_field() )
468 mandatoryField = footprint.description_field();
470 buf.PackFrom( mandatoryField );
476 switch( footprint.attributes().mounting_style() )
478 case types::FootprintMountingStyle::FMS_THROUGH_HOLE:
482 case types::FootprintMountingStyle::FMS_SMD:
490 SetBoardOnly( footprint.attributes().not_in_schematic() );
494 SetDNP( footprint.attributes().do_not_populate() );
500 SetKeywords( footprint.definition().attributes().keywords() );
502 const types::FootprintDesignRuleOverrides& overrides = footprint.overrides();
504 if( overrides.has_copper_clearance() )
509 if( overrides.has_solder_mask() && overrides.solder_mask().has_solder_mask_margin() )
514 if( overrides.has_solder_paste() )
516 const types::SolderPasteOverrides& pasteSettings = overrides.solder_paste();
518 if( pasteSettings.has_solder_paste_margin() )
523 if( pasteSettings.has_solder_paste_margin_ratio() )
531 for(
const types::NetTieDefinition& netTieMsg : footprint.definition().net_ties() )
535 for(
const std::string&
pad : netTieMsg.pad_number() )
536 group.Append( wxString::Format( wxT(
"%s " ),
pad ) );
544 for(
int layerMsg : footprint.definition().private_layers() )
549 privateLayers.
set( layer );
557 if( !field->IsMandatory() )
568 for(
const google::protobuf::Any& itemMsg : footprint.definition().items() )
576 if( itemMsg.type_url() ==
"type.googleapis.com/kiapi.board.types.Footprint3DModel" )
578 types::Footprint3DModel modelMsg;
580 if( !itemMsg.UnpackTo( &modelMsg ) )
585 model.
m_Filename = wxString::FromUTF8( modelMsg.filename() );
586 model.
m_Show = modelMsg.visible();
592 Models().push_back( std::move( model ) );
596 wxLogTrace(
traceApi, wxString::Format( wxS(
"Attempting to unpack unknown type %s "
597 "from footprint message, skipping" ),
598 itemMsg.type_url() ) );
606 if( item && item->Deserialize( itemMsg ) )
618 if( field->GetId() == aFieldType )
633 if( field->GetId() == aFieldType )
643 return GetField( aFieldName ) !=
nullptr;
651 if( field->GetName() == aFieldName )
667 if( !field->IsVisible() || field->GetText().IsEmpty() )
671 aVector.push_back( field );
674 std::sort( aVector.begin(), aVector.end(),
677 return lhs->GetOrdinal() < rhs->GetOrdinal();
687 ordinal = std::max( ordinal, field->GetOrdinal() + 1 );
699 field->StyleFromSettings(
board.GetDesignSettings() );
704 switch( item->Type() )
709 item->StyleFromSettings(
board.GetDesignSettings() );
714 if( aStyleShapes && !item->IsOnCopperLayer() )
715 item->StyleFromSettings(
board.GetDesignSettings() );
729 std::vector< BOARD_ITEM* > item_list;
732 item_list.push_back( field );
735 item_list.push_back(
pad );
738 item_list.push_back( gr_item );
743 item_list.push_back(
group );
747 item_list.push_back( zone );
751 item_list.push_back( point );
753 bool changed =
false;
759 const_cast<KIID&
>( item->m_Uuid ) =
KIID();
772 m_pos = aOther.m_pos;
796 std::ranges::copy( aOther.m_jumperPadGroups,
805 for(
PCB_FIELD* field : aOther.m_fields )
808 aOther.m_fields.clear();
816 for(
PAD*
pad : aOther.Pads() )
819 aOther.Pads().clear();
827 for(
ZONE* item : aOther.Zones() )
835 item->SetNetCode( -1 );
838 aOther.Zones().clear();
846 for(
BOARD_ITEM* item : aOther.GraphicalItems() )
849 aOther.GraphicalItems().clear();
860 aOther.Groups().clear();
868 for(
PCB_POINT* point : aOther.Points() )
871 aOther.Points().clear();
884 aOther.m_fields.clear();
885 aOther.Pads().clear();
886 aOther.Zones().clear();
887 aOther.GraphicalItems().clear();
888 aOther.m_initial_comments =
nullptr;
921 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
929 ptrMap[field] = newField;
939 ptrMap[
pad ] = newPad;
948 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
949 ptrMap[ zone ] = newZone;
965 ptrMap[ item ] = newItem;
978 newGroup->
AddItem( ptrMap[ member ] );
989 ptrMap[ point ] = newItem;
1011 *
this = *
static_cast<const FOOTPRINT*
>( aOther );
1037 aVars->push_back( wxT(
"REFERENCE" ) );
1038 aVars->push_back( wxT(
"VALUE" ) );
1039 aVars->push_back( wxT(
"LAYER" ) );
1040 aVars->push_back( wxT(
"FOOTPRINT_LIBRARY" ) );
1041 aVars->push_back( wxT(
"FOOTPRINT_NAME" ) );
1042 aVars->push_back( wxT(
"SHORT_NET_NAME(<pad_number>)" ) );
1043 aVars->push_back( wxT(
"NET_NAME(<pad_number>)" ) );
1044 aVars->push_back( wxT(
"NET_CLASS(<pad_number>)" ) );
1045 aVars->push_back( wxT(
"PIN_NAME(<pad_number>)" ) );
1054 if( token->IsSameAs( wxT(
"REFERENCE" ) ) )
1059 else if( token->IsSameAs( wxT(
"VALUE" ) ) )
1064 else if( token->IsSameAs( wxT(
"LAYER" ) ) )
1069 else if( token->IsSameAs( wxT(
"FOOTPRINT_LIBRARY" ) ) )
1071 *token =
m_fpid.GetUniStringLibNickname();
1074 else if( token->IsSameAs( wxT(
"FOOTPRINT_NAME" ) ) )
1076 *token =
m_fpid.GetUniStringLibItemName();
1079 else if( token->StartsWith( wxT(
"SHORT_NET_NAME(" ) )
1080 || token->StartsWith( wxT(
"NET_NAME(" ) )
1081 || token->StartsWith( wxT(
"NET_CLASS(" ) )
1082 || token->StartsWith( wxT(
"PIN_NAME(" ) ) )
1084 wxString padNumber = token->AfterFirst(
'(' );
1085 padNumber = padNumber.BeforeLast(
')' );
1089 if(
pad->GetNumber() == padNumber )
1091 if( token->StartsWith( wxT(
"SHORT_NET_NAME" ) ) )
1092 *token =
pad->GetShortNetname();
1093 else if( token->StartsWith( wxT(
"NET_NAME" ) ) )
1094 *token =
pad->GetNetname();
1095 else if( token->StartsWith( wxT(
"NET_CLASS" ) ) )
1096 *token =
pad->GetNetClassName();
1098 *token =
pad->GetPinFunction();
1106 *token = field->GetText();
1128 switch( aBoardItem->
Type() )
1153 m_pads.push_back(
static_cast<PAD*
>( aBoardItem ) );
1155 m_pads.push_front(
static_cast<PAD*
>( aBoardItem ) );
1161 m_zones.push_back(
static_cast<ZONE*
>( aBoardItem ) );
1176 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Markers go at the board level, even in the footprint editor" ) );
1180 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Nested footprints not supported" ) );
1192 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Add(): BOARD_ITEM type (%d) not handled" ),
1193 aBoardItem->
Type() ) );
1205 switch( aBoardItem->
Type() )
1210 if( *it == aBoardItem )
1231 if( *it == aBoardItem )
1241 for(
auto it =
m_pads.begin(); it !=
m_pads.end(); ++it )
1243 if( *it ==
static_cast<PAD*
>( aBoardItem ) )
1255 if( *it ==
static_cast<ZONE*
>( aBoardItem ) )
1267 if( *it ==
static_cast<PCB_GROUP*
>( aBoardItem ) )
1279 if( *it ==
static_cast<PCB_POINT*
>( aBoardItem ) )
1291 msg.Printf( wxT(
"FOOTPRINT::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
1292 aBoardItem->
Type() );
1318 switch(
pad->GetProperty() )
1336 switch(
pad->GetAttribute() )
1343 if(
pad->IsOnCopperLayer() )
1371 return _(
"Through hole" );
1373 return _(
"Other" );
1388 if(
dummy.IsFlipped() )
1392 bbox.
Merge(
pad->GetBoundingBox() );
1437 std::vector<PCB_TEXT*> texts;
1438 bool isFPEdit =
board &&
board->IsFootprintHolder();
1459 texts.push_back(
static_cast<PCB_TEXT*
>( item ) );
1477 bbox.
Merge( item->GetBoundingBox() );
1483 if( field->IsReference() || field->IsValue() )
1486 texts.push_back( field );
1490 bbox.
Merge(
pad->GetBoundingBox() );
1493 bbox.
Merge( zone->GetBoundingBox() );
1496 bbox.
Merge( point->GetBoundingBox() );
1501 if( aIncludeText || noDrawItems )
1518 bool valueLayerIsVisible =
true;
1519 bool refLayerIsVisible =
true;
1537 if( (
Value().IsVisible() && valueLayerIsVisible ) || noDrawItems )
1542 if( (
Reference().IsVisible() && refLayerIsVisible ) || noDrawItems )
1550 if( aIncludeText || noDrawItems )
1568 std::vector<PCB_TEXT*> texts;
1570 bool isFPEdit =
board &&
board->IsFootprintHolder();
1580 if( ( aLayers & item->GetLayerSet() ).none() )
1588 bbox.
Merge( item->GetBoundingBox() );
1593 if( ( aLayers &
pad->GetLayerSet() ).none() )
1596 bbox.
Merge(
pad->GetBoundingBox() );
1601 if( ( aLayers & zone->GetLayerSet() ).none() )
1604 bbox.
Merge( zone->GetBoundingBox() );
1612 if( ( aLayers & point->GetLayerSet() ).none() )
1615 bbox.
Merge( point->GetBoundingBox() );
1625 bool isFPEdit =
board &&
board->IsFootprintHolder();
1651 pad->Padstack().ForEachUniqueLayer(
1665 const SHAPE_POLY_SET& layerPoly = *zone->GetFilledPolysList( layer );
1681 const int halfsize =
pcbIUScale.mmToIU( 1.0 );
1692 std::vector<VECTOR2I> convex_hull;
1698 for(
const VECTOR2I& pt : convex_hull )
1711 bool isFPEdit =
board &&
board->IsFootprintHolder();
1721 if( item->IsOnLayer( aLayer ) )
1735 if(
pad->IsOnLayer( aLayer ) )
1741 if( zone->GetIsRuleArea() )
1744 if( zone->IsOnLayer( aLayer ) )
1746 const std::shared_ptr<SHAPE_POLY_SET>& layerPoly = zone->GetFilledPolysList( aLayer );
1748 for(
int ii = 0; ii < layerPoly->OutlineCount(); ii++ )
1749 rawPolys.
AddOutline( layerPoly->COutline( ii ) );
1753 std::vector<VECTOR2I> convex_hull;
1758 for(
const VECTOR2I& pt : convex_hull )
1779 aList.emplace_back(
_(
"Library" ),
GetFPID().GetLibNickname().wx_str() );
1781 aList.emplace_back(
_(
"Footprint Name" ),
GetFPID().GetLibItemName().wx_str() );
1783 aList.emplace_back(
_(
"Pads" ), wxString::Format( wxT(
"%zu" ), padCount ) );
1786 wxString::Format(
_(
"Keywords: %s" ),
GetKeywords() ) );
1795 case F_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Front" ) );
break;
1796 case B_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Back (Flipped)" ) );
break;
1800 auto addToken = []( wxString* aStr,
const wxString& aAttr )
1802 if( !aStr->IsEmpty() )
1803 *aStr += wxT(
", " );
1812 addToken( &status,
_(
"Locked" ) );
1815 addToken( &status,
_(
"autoplaced" ) );
1818 addToken( &attrs,
_(
"not in schematic" ) );
1821 addToken( &attrs,
_(
"exclude from pos files" ) );
1824 addToken( &attrs,
_(
"exclude from BOM" ) );
1827 addToken( &attrs,
_(
"DNP" ) );
1829 aList.emplace_back(
_(
"Status: " ) + status,
_(
"Attributes:" ) + wxS(
" " ) + attrs );
1831 aList.emplace_back(
_(
"Rotation" ), wxString::Format( wxT(
"%.4g" ),
1837 _(
"Component Class" ),
1841 msg.Printf(
_(
"Footprint: %s" ),
m_fpid.GetUniStringLibId() );
1842 msg2.Printf(
_(
"3D-Shape: %s" ),
m_3D_Drawings.empty() ?
_(
"<none>" )
1844 aList.emplace_back( msg, msg2 );
1848 aList.emplace_back( msg, msg2 );
1856 if(
board->IsFootprintHolder() )
1888 if(
pad->IsOnLayer( aLayer ) )
1894 if( zone->IsOnLayer( aLayer ) )
1900 if( field->IsOnLayer( aLayer ) )
1906 if( item->IsOnLayer( aLayer ) )
1918 if(
pad->IsOnLayer( aLayer ) &&
pad->HitTest( aPosition, aAccuracy ) )
1924 if( zone->IsOnLayer( aLayer ) && zone->HitTest( aPosition, aAccuracy ) )
1930 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer )
1931 && item->HitTest( aPosition, aAccuracy ) )
1943 std::vector<BOARD_ITEM*> items;
1947 if(
pad->IsOnLayer( aLayer ) )
1948 items.push_back(
pad );
1953 if( zone->IsOnLayer( aLayer ) )
1954 items.push_back( zone );
1959 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer ) )
1960 items.push_back( item );
1969 if( !aContained && item->HitTest( aRect, aContained, aAccuracy ) )
1971 else if( aContained && !item->HitTest( aRect, aContained, aAccuracy ) )
1978 return !items.empty() && aContained;
1997 BOX2I arect = aRect;
2017 if(
pad->HitTest( arect,
false, 0 ) )
2023 if( zone->HitTest( arect,
false, 0 ) )
2029 if( point->HitTest( arect,
false, 0 ) )
2040 if( item->Type() !=
PCB_TEXT_T && item->HitTest( arect,
false, 0 ) )
2054 using std::ranges::all_of;
2055 using std::ranges::any_of;
2062 [&](
const auto* aItem )
2064 return aItem && aItem->HitTest( aPoly, aContained );
2070 auto drawings =
m_drawings | std::views::filter( [](
const auto* aItem )
2081 return all_of( drawings, hitTest )
2082 && all_of(
m_pads, hitTest )
2083 && all_of(
m_zones, hitTest );
2088 return any_of( drawings, hitTest )
2089 || any_of(
m_pads, hitTest )
2090 || any_of(
m_zones, hitTest );
2097 bool can_select = aSearchAfterMe ? false :
true;
2101 if( !can_select &&
pad == aSearchAfterMe )
2107 if( can_select &&
pad->GetNumber() == aPadNumber )
2120 if( !(
pad->GetLayerSet() & aLayerMask ).any() )
2123 if(
pad->HitTest( aPosition ) )
2133 std::vector<const PAD*> retv;
2137 if( ( aIgnore && aIgnore ==
pad ) || (
pad->GetNumber() != aPadNumber ) )
2140 retv.push_back(
pad );
2168 std::set<wxString> usedNumbers;
2180 if(
pad->GetNumber().IsEmpty() )
2190 usedNumbers.insert(
pad->GetNumber() );
2205 if(
nullptr == a3DModel )
2233 const std::vector<KICAD_T>& aScanTypes )
2235#if 0 && defined(DEBUG)
2236 std::cout <<
GetClass().mb_str() <<
' ';
2239 bool drawingsScanned =
false;
2241 for(
KICAD_T scanType : aScanTypes )
2288 if( !drawingsScanned )
2296 drawingsScanned =
true;
2332 if( reference.IsEmpty() )
2333 reference =
_(
"<no reference designator>" );
2335 return wxString::Format(
_(
"Footprint %s" ), reference );
2372 aFunction( drawing );
2378 catch( std::bad_function_call& )
2380 wxFAIL_MSG( wxT(
"Error running FOOTPRINT::RunOnChildren" ) );
2387 std::vector<int> layers;
2389 layers.reserve( 6 );
2395 wxASSERT_MSG(
false, wxT(
"Illegal layer" ) );
2413 bool f_silk =
false, b_silk =
false, non_silk =
false;
2417 if( item->GetLayer() ==
F_SilkS )
2419 else if( item->GetLayer() ==
B_SilkS )
2425 if( ( f_silk || b_silk ) && !non_silk &&
m_pads.empty() )
2458 constexpr double MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY = 1.5;
2461 return MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY;
2474 int biggest_clearance =
board->GetMaxClearanceValue();
2475 area.
Inflate( biggest_clearance );
2486 if( aName.find_first_of( invalids ) != std::string::npos )
2500 static const wxChar invalidChars[] = wxT(
"%$<>\t\n\r\"\\/:");
2501 static const wxChar invalidCharsReadable[] = wxT(
"% $ < > 'tab' 'return' 'line feed' \\ \" / :");
2504 return invalidCharsReadable;
2506 return invalidChars;
2512 if( aMoveVector.
x == 0 && aMoveVector.
y == 0 )
2526 EDA_ANGLE newOrientation = orientation + aAngle;
2533 field->KeepUpright();
2538 static_cast<PCB_TEXT*
>( item )->KeepUpright();
2545 wxASSERT( aLayer ==
F_Cu || aLayer ==
B_Cu );
2622 field->EDA_TEXT::Offset(
delta );
2628 zone->Move(
delta );
2631 item->Move(
delta );
2634 point->Move(
delta );
2666 field->Move( moveVector );
2670 pad->Move( moveVector );
2674 item->Move( moveVector );
2678 zone->Move( moveVector );
2683 model.m_Offset.x +=
pcbIUScale.IUTomm( moveVector.
x );
2684 model.m_Offset.y -=
pcbIUScale.IUTomm( moveVector.
y );
2746 const BOARD_ITEM* aItem,
bool addToFootprint )
2750 switch( aItem->
Type() )
2754 PAD* new_pad =
new PAD( *
static_cast<const PAD*
>( aItem ) );
2757 if( addToFootprint )
2758 m_pads.push_back( new_pad );
2766 ZONE* new_zone =
new ZONE( *
static_cast<const ZONE*
>( aItem ) );
2769 if( addToFootprint )
2770 m_zones.push_back( new_zone );
2772 new_item = new_zone;
2781 if( addToFootprint )
2784 new_item = new_point;
2796 switch(
static_cast<const PCB_FIELD*
>( aItem )->GetId() )
2805 if( addToFootprint )
2808 new_item = new_text;
2817 if( addToFootprint )
2820 new_item = new_shape;
2829 if( addToFootprint )
2832 new_item = new_image;
2841 if( addToFootprint )
2844 new_item = new_textbox;
2857 if( addToFootprint )
2860 new_item = dimension;
2868 if( addToFootprint )
2870 group->RunOnChildren(
2890 wxFAIL_MSG( wxT(
"Duplication not supported for items of class " ) + aItem->
GetClass() );
2900 std::set<wxString> usedNumbers;
2904 usedNumbers.insert(
pad->GetNumber() );
2911 while( usedNumbers.count( wxString::Format( wxT(
"%s%d" ), prefix, num ) ) )
2914 return wxString::Format( wxT(
"%s%d" ), prefix, num );
2922 if(
group.contains( aPadNumber ) )
2926 return std::nullopt;
2977 for(
int jj = 0; jj < aPolySet.
HoleCount( ii ); jj++ )
2981 return aPolySet.
Area();
2996 return markerShape.
Area();
3000 double combinedArea = 0.0;
3005 return combinedArea;
3056 double width =
static_cast<const PCB_TRACK*
>( aItem )->GetWidth();
3057 return width * width;
3061 static_cast<const PAD*
>( aItem )->Padstack().ForEachUniqueLayer(
3093 for(
int i = 0; i < aCollector.
GetCount(); ++i )
3097 switch( item->
Type() )
3128 double footprintRegionArea =
polygonArea( footprintRegion );
3129 double uncoveredRegionArea = footprintRegionArea -
polygonArea( coveredRegion );
3130 double coveredArea = footprintRegionArea - uncoveredRegionArea;
3133 if( footprintRegionArea == 0 )
3136 double ratio = coveredArea / footprintRegionArea;
3143 return std::min( ratio, 1.0 );
3149 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
3170 shape->AddShape(
pad->GetEffectiveShape( aLayer, aFlash )->Clone() );
3175 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3215 std::vector<PCB_SHAPE*> list_front;
3216 std::vector<PCB_SHAPE*> list_back;
3217 std::map<int, int> front_width_histogram;
3218 std::map<int, int> back_width_histogram;
3225 list_back.push_back( shape );
3232 list_front.push_back( shape );
3237 if( !list_front.size() && !list_back.size() )
3241 int chainingEpsilon =
pcbIUScale.mmToIU( 0.02 );
3244 true, aErrorHandler ) )
3254 auto max = std::max_element( front_width_histogram.begin(), front_width_histogram.end(),
3255 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3257 return a.second < b.second;
3260 if( max != front_width_histogram.end() )
3283 auto max = std::max_element( back_width_histogram.begin(), back_width_histogram.end(),
3284 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3286 return a.second < b.second;
3289 if( max != back_width_histogram.end() )
3312 std::map<PCB_LAYER_ID, std::vector<PCB_SHAPE*>> layer_shapes;
3318 if( item->Type() != PCB_SHAPE_T )
3321 for( PCB_LAYER_ID layer : item->GetLayerSet() )
3323 if( !IsCopperLayer( layer ) )
3326 if( board && !board->GetEnabledLayers().Contains( layer ) )
3329 layer_shapes[layer].push_back( static_cast<PCB_SHAPE*>( item ) );
3333 for(
size_t ii = 0; ii < m_pads.size(); ++ii )
3336 bool has_nettie =
false;
3338 auto it = map.find(
pad->GetNumber() );
3340 if( it == map.end() || it->second < 0 )
3343 for(
size_t jj = ii + 1; jj < m_pads.size(); ++jj )
3345 PAD* other = m_pads[ jj ];
3347 auto it2 = map.find( other->
GetNumber() );
3349 if( it2 == map.end() || it2->second < 0 )
3352 if( it2->second == it->second )
3354 m_netTieCache[
pad].insert(
pad->GetNetCode() );
3356 m_netTieCache[other].insert( other->
GetNetCode() );
3357 m_netTieCache[other].insert(
pad->GetNetCode() );
3365 for(
auto& [ layer, shapes ] : layer_shapes )
3367 auto pad_shape =
pad->GetEffectiveShape( layer );
3369 for(
auto other_shape : shapes )
3371 auto shape = other_shape->GetEffectiveShape( layer );
3373 if( pad_shape->Collide( shape.get() ) )
3375 std::set<int>& nettie = m_netTieCache[
pad];
3376 m_netTieCache[other_shape].insert( nettie.begin(), nettie.end() );
3386 std::map<wxString, int> padNumberToGroupIdxMap;
3389 padNumberToGroupIdxMap[
pad->GetNumber() ] = -1;
3392 [&]( wxString aPad,
int aGroup )
3394 aPad.Trim(
true ).Trim(
false );
3396 if( !aPad.IsEmpty() )
3397 padNumberToGroupIdxMap[ aPad ] = aGroup;
3406 for( wxUniCharRef ch :
group )
3415 switch(
static_cast<unsigned char>( ch ) )
3422 processPad(
pad, ii );
3432 processPad(
pad, ii );
3435 return padNumberToGroupIdxMap;
3445 int groupIdx = padToNetTieGroupMap[ aPad->
GetNumber() ];
3446 std::vector<PAD*> otherPads;
3452 if( padToNetTieGroupMap[
pad->GetNumber() ] == groupIdx )
3453 otherPads.push_back(
pad );
3466 if( setAttr && likelyAttr && setAttr != likelyAttr )
3470 switch( likelyAttr )
3473 msg.Printf(
_(
"(expected 'Through hole'; actual '%s')" ),
GetTypeName() );
3476 msg.Printf(
_(
"(expected 'SMD'; actual '%s')" ),
GetTypeName() );
3481 (aErrorHandler)( msg );
3487 const std::function<
void(
const PAD*,
int,
3488 const wxString& )>& aErrorHandler )
3490 if( aErrorHandler ==
nullptr )
3495 pad->CheckPad( aUnitsProvider,
false,
3496 [&](
int errorCode,
const wxString& msg )
3498 aErrorHandler(
pad, errorCode, msg );
3506 const VECTOR2I& )>& aErrorHandler )
3508 std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
3523 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
3526 if( checkedPairs.find( { a, b } ) == checkedPairs.end() )
3528 checkedPairs[ { a, b } ] = 1;
3540 std::shared_ptr<SHAPE_SEGMENT> holeA =
pad->GetEffectiveHoleShape();
3543 if( holeA->Collide( holeB->GetSeg(), 0 ) )
3560 SHAPE* padShape =
pad->GetEffectiveShape( l ).get();
3563 if( padShape->
Collide( otherShape, 0,
nullptr, &pos ) )
3576 const VECTOR2I& )>& aErrorHandler )
3585 std::vector<BOARD_ITEM*> copperItems;
3589 if( item->IsOnCopperLayer() )
3590 copperItems.push_back( item );
3592 item->RunOnChildren(
3596 copperItems.push_back( descendent );
3603 if( !zone->GetIsRuleArea() && zone->IsOnCopperLayer() )
3604 copperItems.push_back( zone );
3609 if( field->IsOnCopperLayer() )
3610 copperItems.push_back( field );
3620 std::map<int, std::vector<const PAD*>> outlineIdxToPadsMap;
3624 if( item->IsOnLayer( layer ) )
3634 for(
int ii = 0; ii < copperOutlines.
OutlineCount(); ++ii )
3636 if(
pad->GetEffectiveShape( layer )->Collide( &copperOutlines.
Outline( ii ), 0 ) )
3637 outlineIdxToPadsMap[ ii ].emplace_back(
pad );
3644 for(
const auto& [ outlineIdx, pads ] : outlineIdxToPadsMap )
3646 if( pads.size() > 1 )
3648 const PAD* firstPad = pads[0];
3649 int firstGroupIdx = padNumberToGroupIdxMap[ firstPad->
GetNumber() ];
3651 for(
size_t ii = 1; ii < pads.size(); ++ii )
3653 const PAD* thisPad = pads[ii];
3654 int thisGroupIdx = padNumberToGroupIdxMap[ thisPad->
GetNumber() ];
3656 if( thisGroupIdx < 0 || thisGroupIdx != firstGroupIdx )
3665 if( item->HitTest( pos, 1 ) )
3667 shortingItem = item;
3673 aErrorHandler( shortingItem, firstPad, thisPad, pos );
3675 aErrorHandler( firstPad, thisPad,
nullptr, pos );
3686 std::set<wxString> padNumbers;
3695 msg.Printf(
_(
"(net-tie pad group contains unknown pad number %s)" ), padNumber );
3696 aErrorHandler( msg );
3698 else if( !padNumbers.insert(
pad->GetNumber() ).second )
3700 msg.Printf(
_(
"(pad %s appears in more than one net-tie pad group)" ), padNumber );
3701 aErrorHandler( msg );
3709 const VECTOR2I& aPt )>& aErrorHandler )
3711 auto checkColliding =
3726 if( itemShape->Collide( otherShape.get(), 0, &
actual, &pos ) )
3727 aErrorHandler( item, other, pos );
3736 checkColliding( item, other );
3740 checkColliding( item,
pad );
3751 std::swap( *
this, *
image );
3760 image->RunOnChildren(
3788 return *
this == other;
3797 for(
size_t ii = 0; ii <
m_pads.size(); ++ii )
3806 for(
size_t ii = 0; ii <
m_drawings.size(); ++ii )
3815 for(
size_t ii = 0; ii <
m_zones.size(); ++ii )
3825 std::vector<PCB_FIELD*> fields, otherFields;
3830 if( fields.size() != otherFields.size() )
3833 for(
size_t ii = 0; ii < fields.size(); ++ii )
3837 if( !( *fields[ii] == *otherFields[ii] ) )
3853 double similarity = 1.0;
3862 similarity *=
pad->Similarity( *otherPad );
3874 if( aPtA.
x != aPtB.
x )
3875 return aPtA.
x < aPtB.
x;
3877 if( aPtA.
y != aPtB.
y )
3878 return aPtA.
y < aPtB.
y;
3880 return std::nullopt;
3886 if( itemA->
Type() != itemB->
Type() )
3887 return itemA->
Type() < itemB->
Type();
3892 switch( itemA->
Type() )
3931 for(
int ii = 0; ii < dwgA->
GetPolyShape().TotalVertices(); ++ii )
3933 if( std::optional<bool> cmp =
3990 return itemA < itemB;
4002 std::optional<bool> padCopperMatches;
4005 const PAD* checkPad = aFirst;
4018 padCopperMatches = aFirst->
GetSize( aLayer ).
x < aSecond->
GetSize( aLayer ).
x;
4020 padCopperMatches = aFirst->
GetSize( aLayer ).
y < aSecond->
GetSize( aLayer ).
y;
4022 padCopperMatches = aFirst->
GetShape( aLayer ) < aSecond->
GetShape( aLayer );
4025 if( padCopperMatches.has_value() )
4026 return *padCopperMatches;
4034 return aFirst < aSecond;
4039bool FOOTPRINT::cmp_padstack::operator()(
const PAD* aFirst,
const PAD* aSecond )
const
4079 if( firstShape->VertexCount() != secondShape->VertexCount() )
4080 return firstShape->VertexCount() < secondShape->VertexCount();
4082 for(
int ii = 0; ii < firstShape->VertexCount(); ++ii )
4084 if( std::optional<bool> cmp =
cmp_points_opt( firstShape->CVertex( ii ), secondShape->CVertex( ii ) ) )
4106 for(
int ii = 0; ii < aFirst->
Outline()->TotalVertices(); ++ii )
4108 if( std::optional<bool> cmp =
4118 return aFirst < aSecond;
4123 int aMaxError,
ERROR_LOC aErrorLoc )
const
4134 clearance.x +=
pad->GetSolderMaskExpansion( padLayer );
4135 clearance.y +=
pad->GetSolderMaskExpansion( padLayer );
4158 if( dummySize.
x <= 0 || dummySize.
y <= 0 )
4162 dummy.SetSize( padLayer, dummySize );
4163 dummy.TransformShapeToPolygon( aBuffer, padLayer, 0, aMaxError, aErrorLoc );
4167 pad->TransformShapeToPolygon( aBuffer, padLayer,
clearance.x, aMaxError, aErrorLoc );
4173 if( !
pad->FlashLayer( aLayer ) )
4178 pad->Padstack().ForEachUniqueLayer(
4181 processPad(
pad, l );
4186 processPad(
pad, aLayer );
4193 int aError,
ERROR_LOC aErrorLoc,
bool aIncludeText,
4194 bool aIncludeShapes,
bool aIncludePrivateItems )
const
4201 if( item->Type() ==
PCB_TEXT_T && aIncludeText )
4206 text->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4217 textbox->PCB_SHAPE::TransformShapeToPolygon( aBuffer, aLayer, 0, aError, aErrorLoc );
4224 if( item->Type() ==
PCB_SHAPE_T && aIncludeShapes )
4237 if( field->GetLayer() == aLayer && field->IsVisible() )
4238 field->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4248 std::set<KIFONT::OUTLINE_FONT*>
fonts;
4262 if( permission == PERMISSION::EDITABLE || permission == PERMISSION::INSTALLABLE )
4263 fonts.insert( outlineFont );
4269 processItem( item );
4272 processItem( field );
4317 return wxEmptyString;
4322 const std::unordered_set<wxString>& aComponentClassNames )
4363 if( zcMap.
Choices().GetCount() == 0 )
4375 if( layerEnum.
Choices().GetCount() == 0 )
4383 wxPGChoices fpLayers;
4396 layer->SetChoices( fpLayers );
4403 const wxString groupFields =
_HKI(
"Fields" );
4428 const wxString groupAttributes =
_HKI(
"Attributes" );
4442 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 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
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 & 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.
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_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