26#include <magic_enum.hpp>
28#include <unordered_set>
69#include <google/protobuf/any.pb.h>
70#include <api/board/board_types.pb.h>
169 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
177 ptrMap[field] = existingField;
178 *existingField = *field;
184 ptrMap[field] = newField;
192 PAD* newPad =
static_cast<PAD*
>(
pad->Clone() );
193 ptrMap[
pad ] = newPad;
200 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
201 ptrMap[ zone ] = newZone;
215 ptrMap[ item ] = newItem;
223 ptrMap[
group ] = newGroup;
230 ptrMap[ point ] = newPoint;
243 if( ptrMap.count( member ) )
244 newGroup->
AddItem( ptrMap[ member ] );
256 *
this = std::move( aFootprint );
296 board->IncrementTimeStamp();
303 types::FootprintInstance footprint;
305 footprint.mutable_id()->set_value(
m_Uuid.AsStdString() );
306 footprint.mutable_position()->set_x_nm(
GetPosition().x );
307 footprint.mutable_position()->set_y_nm(
GetPosition().y );
310 footprint.set_locked(
IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
311 : kiapi::common::types::LockedState::LS_UNLOCKED );
313 google::protobuf::Any buf;
315 buf.UnpackTo( footprint.mutable_reference_field() );
317 buf.UnpackTo( footprint.mutable_value_field() );
319 buf.UnpackTo( footprint.mutable_datasheet_field() );
321 buf.UnpackTo( footprint.mutable_description_field() );
323 types::FootprintAttributes* attrs = footprint.mutable_attributes();
329 attrs->set_do_not_populate(
IsDNP() );
332 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_THROUGH_HOLE );
334 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_SMD );
336 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_UNSPECIFIED );
338 types::Footprint* def = footprint.mutable_definition();
343 def->mutable_attributes()->set_keywords(
GetKeywords().ToStdString() );
347 types::FootprintDesignRuleOverrides* overrides = def->mutable_overrides();
361 overrides->set_zone_connection(
366 types::NetTieDefinition* netTie = def->add_net_ties();
367 wxStringTokenizer tokenizer(
group,
", \t\r\n", wxTOKEN_STRTOK );
369 while( tokenizer.HasMoreTokens() )
370 netTie->add_pad_number( tokenizer.GetNextToken().ToStdString() );
378 if( item->IsMandatory() )
381 google::protobuf::Any* itemMsg = def->add_items();
382 item->Serialize( *itemMsg );
385 for(
const PAD* item :
Pads() )
387 google::protobuf::Any* itemMsg = def->add_items();
388 item->Serialize( *itemMsg );
393 google::protobuf::Any* itemMsg = def->add_items();
394 item->Serialize( *itemMsg );
399 google::protobuf::Any* itemMsg = def->add_items();
400 item->Serialize( *itemMsg );
405 google::protobuf::Any* itemMsg = def->add_items();
406 types::Footprint3DModel modelMsg;
407 modelMsg.set_filename( model.m_Filename.ToUTF8() );
411 modelMsg.set_visible( model.m_Show );
412 modelMsg.set_opacity( model.m_Opacity );
413 itemMsg->PackFrom( modelMsg );
419 aContainer.PackFrom( footprint );
426 types::FootprintInstance footprint;
428 if( !aContainer.UnpackTo( &footprint ) )
435 SetLocked( footprint.locked() == kiapi::common::types::LockedState::LS_LOCKED );
437 google::protobuf::Any buf;
438 types::Field mandatoryField;
440 if( footprint.has_reference_field() )
442 mandatoryField = footprint.reference_field();
444 buf.PackFrom( mandatoryField );
448 if( footprint.has_value_field() )
450 mandatoryField = footprint.value_field();
452 buf.PackFrom( mandatoryField );
456 if( footprint.has_datasheet_field() )
458 mandatoryField = footprint.datasheet_field();
460 buf.PackFrom( mandatoryField );
464 if( footprint.has_description_field() )
466 mandatoryField = footprint.description_field();
468 buf.PackFrom( mandatoryField );
474 switch( footprint.attributes().mounting_style() )
476 case types::FootprintMountingStyle::FMS_THROUGH_HOLE:
480 case types::FootprintMountingStyle::FMS_SMD:
488 SetBoardOnly( footprint.attributes().not_in_schematic() );
492 SetDNP( footprint.attributes().do_not_populate() );
498 SetKeywords( footprint.definition().attributes().keywords() );
500 const types::FootprintDesignRuleOverrides& overrides = footprint.overrides();
502 if( overrides.has_copper_clearance() )
507 if( overrides.has_solder_mask() && overrides.solder_mask().has_solder_mask_margin() )
512 if( overrides.has_solder_paste() )
514 const types::SolderPasteOverrides& pasteSettings = overrides.solder_paste();
516 if( pasteSettings.has_solder_paste_margin() )
521 if( pasteSettings.has_solder_paste_margin_ratio() )
529 for(
const types::NetTieDefinition& netTieMsg : footprint.definition().net_ties() )
533 for(
const std::string&
pad : netTieMsg.pad_number() )
534 group.Append( wxString::Format( wxT(
"%s " ),
pad ) );
542 for(
int layerMsg : footprint.definition().private_layers() )
547 privateLayers.
set( layer );
555 if( !field->IsMandatory() )
566 for(
const google::protobuf::Any& itemMsg : footprint.definition().items() )
574 if( itemMsg.type_url() ==
"type.googleapis.com/kiapi.board.types.Footprint3DModel" )
576 types::Footprint3DModel modelMsg;
578 if( !itemMsg.UnpackTo( &modelMsg ) )
583 model.
m_Filename = wxString::FromUTF8( modelMsg.filename() );
584 model.
m_Show = modelMsg.visible();
590 Models().push_back( std::move( model ) );
594 wxLogTrace(
traceApi, wxString::Format( wxS(
"Attempting to unpack unknown type %s "
595 "from footprint message, skipping" ),
596 itemMsg.type_url() ) );
604 if( item && item->Deserialize( itemMsg ) )
616 if( field->GetId() == aFieldType )
631 if( field->GetId() == aFieldType )
641 return GetField( aFieldName ) !=
nullptr;
649 if( field->GetName() == aFieldName )
665 if( !field->IsVisible() || field->GetText().IsEmpty() )
669 aVector.push_back( field );
672 std::sort( aVector.begin(), aVector.end(),
675 return lhs->GetOrdinal() < rhs->GetOrdinal();
685 ordinal = std::max( ordinal, field->GetOrdinal() + 1 );
692 bool aStyleShapes,
bool aStyleDimensions,
bool aStyleBarcodes )
697 field->StyleFromSettings(
board.GetDesignSettings(),
true );
702 switch( item->Type() )
707 item->StyleFromSettings(
board.GetDesignSettings(),
true );
712 if( aStyleShapes && !item->IsOnCopperLayer() )
713 item->StyleFromSettings(
board.GetDesignSettings(),
true );
722 if( aStyleDimensions )
723 item->StyleFromSettings(
board.GetDesignSettings(),
true );
729 item->StyleFromSettings(
board.GetDesignSettings(),
true );
742 std::vector< BOARD_ITEM* > item_list;
745 item_list.push_back( field );
748 item_list.push_back(
pad );
751 item_list.push_back( gr_item );
756 item_list.push_back(
group );
760 item_list.push_back( zone );
764 item_list.push_back( point );
766 bool changed =
false;
772 const_cast<KIID&
>( item->m_Uuid ) =
KIID();
785 m_pos = aOther.m_pos;
816 for(
PCB_FIELD* field : aOther.m_fields )
819 aOther.m_fields.clear();
827 for(
PAD*
pad : aOther.Pads() )
830 aOther.Pads().clear();
838 for(
ZONE* item : aOther.Zones() )
846 item->SetNetCode( -1 );
849 aOther.Zones().clear();
857 for(
BOARD_ITEM* item : aOther.GraphicalItems() )
860 aOther.GraphicalItems().clear();
871 aOther.Groups().clear();
879 for(
PCB_POINT* point : aOther.Points() )
882 aOther.Points().clear();
895 aOther.m_fields.clear();
896 aOther.Pads().clear();
897 aOther.Zones().clear();
898 aOther.GraphicalItems().clear();
899 aOther.m_initial_comments =
nullptr;
932 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
940 ptrMap[field] = newField;
950 ptrMap[
pad ] = newPad;
959 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
960 ptrMap[ zone ] = newZone;
976 ptrMap[ item ] = newItem;
989 newGroup->
AddItem( ptrMap[ member ] );
1000 ptrMap[ point ] = newItem;
1022 *
this = *
static_cast<const FOOTPRINT*
>( aOther );
1048 aVars->push_back( wxT(
"REFERENCE" ) );
1049 aVars->push_back( wxT(
"VALUE" ) );
1050 aVars->push_back( wxT(
"LAYER" ) );
1051 aVars->push_back( wxT(
"FOOTPRINT_LIBRARY" ) );
1052 aVars->push_back( wxT(
"FOOTPRINT_NAME" ) );
1053 aVars->push_back( wxT(
"SHORT_NET_NAME(<pad_number>)" ) );
1054 aVars->push_back( wxT(
"NET_NAME(<pad_number>)" ) );
1055 aVars->push_back( wxT(
"NET_CLASS(<pad_number>)" ) );
1056 aVars->push_back( wxT(
"PIN_NAME(<pad_number>)" ) );
1065 if( token->IsSameAs( wxT(
"REFERENCE" ) ) )
1070 else if( token->IsSameAs( wxT(
"VALUE" ) ) )
1075 else if( token->IsSameAs( wxT(
"LAYER" ) ) )
1080 else if( token->IsSameAs( wxT(
"FOOTPRINT_LIBRARY" ) ) )
1082 *token =
m_fpid.GetUniStringLibNickname();
1085 else if( token->IsSameAs( wxT(
"FOOTPRINT_NAME" ) ) )
1087 *token =
m_fpid.GetUniStringLibItemName();
1090 else if( token->StartsWith( wxT(
"SHORT_NET_NAME(" ) )
1091 || token->StartsWith( wxT(
"NET_NAME(" ) )
1092 || token->StartsWith( wxT(
"NET_CLASS(" ) )
1093 || token->StartsWith( wxT(
"PIN_NAME(" ) ) )
1095 wxString padNumber = token->AfterFirst(
'(' );
1096 padNumber = padNumber.BeforeLast(
')' );
1100 if(
pad->GetNumber() == padNumber )
1102 if( token->StartsWith( wxT(
"SHORT_NET_NAME" ) ) )
1103 *token =
pad->GetShortNetname();
1104 else if( token->StartsWith( wxT(
"NET_NAME" ) ) )
1105 *token =
pad->GetNetname();
1106 else if( token->StartsWith( wxT(
"NET_CLASS" ) ) )
1107 *token =
pad->GetNetClassName();
1109 *token =
pad->GetPinFunction();
1117 *token = field->GetText();
1139 switch( aBoardItem->
Type() )
1165 m_pads.push_back(
static_cast<PAD*
>( aBoardItem ) );
1167 m_pads.push_front(
static_cast<PAD*
>( aBoardItem ) );
1173 m_zones.push_back(
static_cast<ZONE*
>( aBoardItem ) );
1188 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Markers go at the board level, even in the footprint editor" ) );
1192 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Nested footprints not supported" ) );
1204 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Add(): BOARD_ITEM type (%d) not handled" ),
1205 aBoardItem->
Type() ) );
1219 switch( aBoardItem->
Type() )
1224 if( *it == aBoardItem )
1246 if( *it == aBoardItem )
1256 for(
auto it =
m_pads.begin(); it !=
m_pads.end(); ++it )
1258 if( *it ==
static_cast<PAD*
>( aBoardItem ) )
1270 if( *it ==
static_cast<ZONE*
>( aBoardItem ) )
1282 if( *it ==
static_cast<PCB_GROUP*
>( aBoardItem ) )
1294 if( *it ==
static_cast<PCB_POINT*
>( aBoardItem ) )
1306 msg.Printf( wxT(
"FOOTPRINT::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
1307 aBoardItem->
Type() );
1335 switch(
pad->GetProperty() )
1353 switch(
pad->GetAttribute() )
1360 if(
pad->IsOnCopperLayer() )
1388 return _(
"Through hole" );
1390 return _(
"Other" );
1405 if(
dummy.IsFlipped() )
1409 bbox.
Merge(
pad->GetBoundingBox() );
1454 std::vector<PCB_TEXT*> texts;
1455 bool isFPEdit =
board &&
board->IsFootprintHolder();
1476 texts.push_back(
static_cast<PCB_TEXT*
>( item ) );
1494 bbox.
Merge( item->GetBoundingBox() );
1500 if( field->IsReference() || field->IsValue() )
1503 texts.push_back( field );
1507 bbox.
Merge(
pad->GetBoundingBox() );
1510 bbox.
Merge( zone->GetBoundingBox() );
1513 bbox.
Merge( point->GetBoundingBox() );
1518 if( aIncludeText || noDrawItems )
1535 bool valueLayerIsVisible =
true;
1536 bool refLayerIsVisible =
true;
1554 if( (
Value().IsVisible() && valueLayerIsVisible ) || noDrawItems )
1559 if( (
Reference().IsVisible() && refLayerIsVisible ) || noDrawItems )
1567 if( aIncludeText || noDrawItems )
1585 std::vector<PCB_TEXT*> texts;
1587 bool isFPEdit =
board &&
board->IsFootprintHolder();
1597 if( ( aLayers & item->GetLayerSet() ).none() )
1605 bbox.
Merge( item->GetBoundingBox() );
1610 if( ( aLayers &
pad->GetLayerSet() ).none() )
1613 bbox.
Merge(
pad->GetBoundingBox() );
1618 if( ( aLayers & zone->GetLayerSet() ).none() )
1621 bbox.
Merge( zone->GetBoundingBox() );
1629 if( ( aLayers & point->GetLayerSet() ).none() )
1632 bbox.
Merge( point->GetBoundingBox() );
1642 bool isFPEdit =
board &&
board->IsFootprintHolder();
1668 pad->Padstack().ForEachUniqueLayer(
1682 const SHAPE_POLY_SET& layerPoly = *zone->GetFilledPolysList( layer );
1698 const int halfsize =
pcbIUScale.mmToIU( 1.0 );
1709 std::vector<VECTOR2I> convex_hull;
1715 for(
const VECTOR2I& pt : convex_hull )
1728 bool isFPEdit =
board &&
board->IsFootprintHolder();
1738 if( item->IsOnLayer( aLayer ) )
1752 if(
pad->IsOnLayer( aLayer ) )
1758 if( zone->GetIsRuleArea() )
1761 if( zone->IsOnLayer( aLayer ) )
1763 const std::shared_ptr<SHAPE_POLY_SET>& layerPoly = zone->GetFilledPolysList( aLayer );
1765 for(
int ii = 0; ii < layerPoly->OutlineCount(); ii++ )
1766 rawPolys.
AddOutline( layerPoly->COutline( ii ) );
1770 std::vector<VECTOR2I> convex_hull;
1775 for(
const VECTOR2I& pt : convex_hull )
1796 aList.emplace_back(
_(
"Library" ),
GetFPID().GetLibNickname().wx_str() );
1798 aList.emplace_back(
_(
"Footprint Name" ),
GetFPID().GetLibItemName().wx_str() );
1800 aList.emplace_back(
_(
"Pads" ), wxString::Format( wxT(
"%zu" ), padCount ) );
1803 wxString::Format(
_(
"Keywords: %s" ),
GetKeywords() ) );
1812 case F_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Front" ) );
break;
1813 case B_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Back (Flipped)" ) );
break;
1817 auto addToken = []( wxString* aStr,
const wxString& aAttr )
1819 if( !aStr->IsEmpty() )
1820 *aStr += wxT(
", " );
1829 addToken( &status,
_(
"Locked" ) );
1832 addToken( &status,
_(
"autoplaced" ) );
1835 addToken( &attrs,
_(
"not in schematic" ) );
1838 addToken( &attrs,
_(
"exclude from pos files" ) );
1841 addToken( &attrs,
_(
"exclude from BOM" ) );
1844 addToken( &attrs,
_(
"DNP" ) );
1846 aList.emplace_back(
_(
"Status: " ) + status,
_(
"Attributes:" ) + wxS(
" " ) + attrs );
1848 aList.emplace_back(
_(
"Rotation" ), wxString::Format( wxT(
"%.4g" ),
1854 _(
"Component Class" ),
1858 msg.Printf(
_(
"Footprint: %s" ),
m_fpid.GetUniStringLibId() );
1859 msg2.Printf(
_(
"3D-Shape: %s" ),
m_3D_Drawings.empty() ?
_(
"<none>" )
1861 aList.emplace_back( msg, msg2 );
1865 aList.emplace_back( msg, msg2 );
1873 if(
board->IsFootprintHolder() )
1905 if(
pad->IsOnLayer( aLayer ) )
1911 if( zone->IsOnLayer( aLayer ) )
1917 if( field->IsOnLayer( aLayer ) )
1923 if( item->IsOnLayer( aLayer ) )
1935 if(
pad->IsOnLayer( aLayer ) &&
pad->HitTest( aPosition, aAccuracy ) )
1941 if( zone->IsOnLayer( aLayer ) && zone->HitTest( aPosition, aAccuracy ) )
1947 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer )
1948 && item->HitTest( aPosition, aAccuracy ) )
1960 std::vector<BOARD_ITEM*> items;
1964 if(
pad->IsOnLayer( aLayer ) )
1965 items.push_back(
pad );
1970 if( zone->IsOnLayer( aLayer ) )
1971 items.push_back( zone );
1976 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer ) )
1977 items.push_back( item );
1986 if( !aContained && item->HitTest( aRect, aContained, aAccuracy ) )
1988 else if( aContained && !item->HitTest( aRect, aContained, aAccuracy ) )
1995 return !items.empty() && aContained;
2014 BOX2I arect = aRect;
2034 if(
pad->HitTest( arect,
false, 0 ) )
2040 if( zone->HitTest( arect,
false, 0 ) )
2046 if( point->HitTest( arect,
false, 0 ) )
2057 if( item->Type() !=
PCB_TEXT_T && item->HitTest( arect,
false, 0 ) )
2071 using std::ranges::all_of;
2072 using std::ranges::any_of;
2079 [&](
const auto* aItem )
2081 return aItem && aItem->HitTest( aPoly, aContained );
2087 auto drawings =
m_drawings | std::views::filter( [](
const auto* aItem )
2098 return all_of( drawings, hitTest )
2099 && all_of(
m_pads, hitTest )
2100 && all_of(
m_zones, hitTest );
2105 return any_of( drawings, hitTest )
2106 || any_of(
m_pads, hitTest )
2107 || any_of(
m_zones, hitTest );
2114 bool can_select = aSearchAfterMe ? false :
true;
2118 if( !can_select &&
pad == aSearchAfterMe )
2124 if( can_select &&
pad->GetNumber() == aPadNumber )
2137 if( !(
pad->GetLayerSet() & aLayerMask ).any() )
2140 if(
pad->HitTest( aPosition ) )
2150 std::vector<const PAD*> retv;
2154 if( ( aIgnore && aIgnore ==
pad ) || (
pad->GetNumber() != aPadNumber ) )
2157 retv.push_back(
pad );
2185 std::set<wxString> usedNumbers;
2197 if(
pad->GetNumber().IsEmpty() )
2207 usedNumbers.insert(
pad->GetNumber() );
2222 if(
nullptr == a3DModel )
2250 const std::vector<KICAD_T>& aScanTypes )
2252#if 0 && defined(DEBUG)
2253 std::cout <<
GetClass().mb_str() <<
' ';
2256 bool drawingsScanned =
false;
2258 for(
KICAD_T scanType : aScanTypes )
2306 if( !drawingsScanned )
2314 drawingsScanned =
true;
2350 if( reference.IsEmpty() )
2351 reference =
_(
"<no reference designator>" );
2353 return wxString::Format(
_(
"Footprint %s" ), reference );
2390 aFunction( drawing );
2396 catch( std::bad_function_call& )
2398 wxFAIL_MSG( wxT(
"Error running FOOTPRINT::RunOnChildren" ) );
2405 std::vector<int> layers;
2407 layers.reserve( 6 );
2413 wxASSERT_MSG(
false, wxT(
"Illegal layer" ) );
2431 bool f_silk =
false, b_silk =
false, non_silk =
false;
2435 if( item->GetLayer() ==
F_SilkS )
2437 else if( item->GetLayer() ==
B_SilkS )
2443 if( ( f_silk || b_silk ) && !non_silk &&
m_pads.empty() )
2476 constexpr double MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY = 1.5;
2479 return MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY;
2492 int biggest_clearance =
board->GetMaxClearanceValue();
2493 area.
Inflate( biggest_clearance );
2504 if( aName.find_first_of( invalids ) != std::string::npos )
2518 static const wxChar invalidChars[] = wxT(
"%$<>\t\n\r\"\\/:");
2519 static const wxChar invalidCharsReadable[] = wxT(
"% $ < > 'tab' 'return' 'line feed' \\ \" / :");
2522 return invalidCharsReadable;
2524 return invalidChars;
2530 if( aMoveVector.
x == 0 && aMoveVector.
y == 0 )
2544 EDA_ANGLE newOrientation = orientation + aAngle;
2551 field->KeepUpright();
2556 static_cast<PCB_TEXT*
>( item )->KeepUpright();
2563 wxASSERT( aLayer ==
F_Cu || aLayer ==
B_Cu );
2640 field->EDA_TEXT::Offset(
delta );
2646 zone->Move(
delta );
2649 item->Move(
delta );
2652 point->Move(
delta );
2684 field->Move( moveVector );
2688 pad->Move( moveVector );
2692 item->Move( moveVector );
2696 zone->Move( moveVector );
2701 model.m_Offset.x +=
pcbIUScale.IUTomm( moveVector.
x );
2702 model.m_Offset.y -=
pcbIUScale.IUTomm( moveVector.
y );
2764 const BOARD_ITEM* aItem,
bool addToFootprint )
2768 switch( aItem->
Type() )
2772 PAD* new_pad =
new PAD( *
static_cast<const PAD*
>( aItem ) );
2775 if( addToFootprint )
2776 m_pads.push_back( new_pad );
2784 ZONE* new_zone =
new ZONE( *
static_cast<const ZONE*
>( aItem ) );
2787 if( addToFootprint )
2788 m_zones.push_back( new_zone );
2790 new_item = new_zone;
2799 if( addToFootprint )
2802 new_item = new_point;
2814 switch(
static_cast<const PCB_FIELD*
>( aItem )->GetId() )
2823 if( addToFootprint )
2826 new_item = new_text;
2835 if( addToFootprint )
2838 new_item = new_shape;
2847 if( addToFootprint )
2850 new_item = new_barcode;
2859 if( addToFootprint )
2862 new_item = new_image;
2871 if( addToFootprint )
2874 new_item = new_textbox;
2887 if( addToFootprint )
2890 new_item = dimension;
2898 if( addToFootprint )
2900 group->RunOnChildren(
2920 wxFAIL_MSG( wxT(
"Duplication not supported for items of class " ) + aItem->
GetClass() );
2930 std::set<wxString> usedNumbers;
2934 usedNumbers.insert(
pad->GetNumber() );
2941 while( usedNumbers.count( wxString::Format( wxT(
"%s%d" ), prefix, num ) ) )
2944 return wxString::Format( wxT(
"%s%d" ), prefix, num );
2952 if(
group.contains( aPadNumber ) )
2956 return std::nullopt;
3007 for(
int jj = 0; jj < aPolySet.
HoleCount( ii ); jj++ )
3011 return aPolySet.
Area();
3026 return markerShape.
Area();
3030 double combinedArea = 0.0;
3035 return combinedArea;
3086 double width =
static_cast<const PCB_TRACK*
>( aItem )->GetWidth();
3087 return width * width;
3091 static_cast<const PAD*
>( aItem )->Padstack().ForEachUniqueLayer(
3123 for(
int i = 0; i < aCollector.
GetCount(); ++i )
3127 switch( item->
Type() )
3159 double footprintRegionArea =
polygonArea( footprintRegion );
3160 double uncoveredRegionArea = footprintRegionArea -
polygonArea( coveredRegion );
3161 double coveredArea = footprintRegionArea - uncoveredRegionArea;
3164 if( footprintRegionArea == 0 )
3167 double ratio = coveredArea / footprintRegionArea;
3174 return std::min( ratio, 1.0 );
3180 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
3201 shape->AddShape(
pad->GetEffectiveShape( aLayer, aFlash )->Clone() );
3206 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3208 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3248 std::vector<PCB_SHAPE*> list_front;
3249 std::vector<PCB_SHAPE*> list_back;
3250 std::map<int, int> front_width_histogram;
3251 std::map<int, int> back_width_histogram;
3258 list_back.push_back( shape );
3265 list_front.push_back( shape );
3270 if( !list_front.size() && !list_back.size() )
3274 int chainingEpsilon =
pcbIUScale.mmToIU( 0.02 );
3277 true, aErrorHandler ) )
3287 auto max = std::max_element( front_width_histogram.begin(), front_width_histogram.end(),
3288 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3290 return a.second < b.second;
3293 if( max != front_width_histogram.end() )
3316 auto max = std::max_element( back_width_histogram.begin(), back_width_histogram.end(),
3317 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3319 return a.second < b.second;
3322 if( max != back_width_histogram.end() )
3345 std::map<PCB_LAYER_ID, std::vector<PCB_SHAPE*>> layer_shapes;
3351 if( item->Type() != PCB_SHAPE_T )
3354 for( PCB_LAYER_ID layer : item->GetLayerSet() )
3356 if( !IsCopperLayer( layer ) )
3359 if( board && !board->GetEnabledLayers().Contains( layer ) )
3362 layer_shapes[layer].push_back( static_cast<PCB_SHAPE*>( item ) );
3366 for(
size_t ii = 0; ii < m_pads.size(); ++ii )
3369 bool has_nettie =
false;
3371 auto it = map.find(
pad->GetNumber() );
3373 if( it == map.end() || it->second < 0 )
3376 for(
size_t jj = ii + 1; jj < m_pads.size(); ++jj )
3378 PAD* other = m_pads[ jj ];
3380 auto it2 = map.find( other->
GetNumber() );
3382 if( it2 == map.end() || it2->second < 0 )
3385 if( it2->second == it->second )
3387 m_netTieCache[
pad].insert(
pad->GetNetCode() );
3389 m_netTieCache[other].insert( other->
GetNetCode() );
3390 m_netTieCache[other].insert(
pad->GetNetCode() );
3398 for(
auto& [ layer, shapes ] : layer_shapes )
3400 auto pad_shape =
pad->GetEffectiveShape( layer );
3402 for(
auto other_shape : shapes )
3404 auto shape = other_shape->GetEffectiveShape( layer );
3406 if( pad_shape->Collide( shape.get() ) )
3408 std::set<int>& nettie = m_netTieCache[
pad];
3409 m_netTieCache[other_shape].insert( nettie.begin(), nettie.end() );
3419 std::map<wxString, int> padNumberToGroupIdxMap;
3422 padNumberToGroupIdxMap[
pad->GetNumber() ] = -1;
3425 [&]( wxString aPad,
int aGroup )
3427 aPad.Trim(
true ).Trim(
false );
3429 if( !aPad.IsEmpty() )
3430 padNumberToGroupIdxMap[ aPad ] = aGroup;
3439 for( wxUniCharRef ch :
group )
3448 switch(
static_cast<unsigned char>( ch ) )
3455 processPad(
pad, ii );
3465 processPad(
pad, ii );
3468 return padNumberToGroupIdxMap;
3478 int groupIdx = padToNetTieGroupMap[ aPad->
GetNumber() ];
3479 std::vector<PAD*> otherPads;
3485 if( padToNetTieGroupMap[
pad->GetNumber() ] == groupIdx )
3486 otherPads.push_back(
pad );
3499 if( setAttr && likelyAttr && setAttr != likelyAttr )
3503 switch( likelyAttr )
3506 msg.Printf(
_(
"(expected 'Through hole'; actual '%s')" ),
GetTypeName() );
3509 msg.Printf(
_(
"(expected 'SMD'; actual '%s')" ),
GetTypeName() );
3514 (aErrorHandler)( msg );
3520 const std::function<
void(
const PAD*,
int,
3521 const wxString& )>& aErrorHandler )
3523 if( aErrorHandler ==
nullptr )
3528 pad->CheckPad( aUnitsProvider,
false,
3529 [&](
int errorCode,
const wxString& msg )
3531 aErrorHandler(
pad, errorCode, msg );
3539 const VECTOR2I& )>& aErrorHandler )
3541 std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
3556 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
3559 if( checkedPairs.find( { a, b } ) == checkedPairs.end() )
3561 checkedPairs[ { a, b } ] = 1;
3573 std::shared_ptr<SHAPE_SEGMENT> holeA =
pad->GetEffectiveHoleShape();
3576 if( holeA->Collide( holeB->GetSeg(), 0 ) )
3593 SHAPE* padShape =
pad->GetEffectiveShape( l ).get();
3596 if( padShape->
Collide( otherShape, 0,
nullptr, &pos ) )
3609 const VECTOR2I& )>& aErrorHandler )
3618 std::vector<BOARD_ITEM*> copperItems;
3622 if( item->IsOnCopperLayer() )
3623 copperItems.push_back( item );
3625 item->RunOnChildren(
3629 copperItems.push_back( descendent );
3636 if( !zone->GetIsRuleArea() && zone->IsOnCopperLayer() )
3637 copperItems.push_back( zone );
3642 if( field->IsOnCopperLayer() )
3643 copperItems.push_back( field );
3653 std::map<int, std::vector<const PAD*>> outlineIdxToPadsMap;
3657 if( item->IsOnLayer( layer ) )
3667 for(
int ii = 0; ii < copperOutlines.
OutlineCount(); ++ii )
3669 if(
pad->GetEffectiveShape( layer )->Collide( &copperOutlines.
Outline( ii ), 0 ) )
3670 outlineIdxToPadsMap[ ii ].emplace_back(
pad );
3677 for(
const auto& [ outlineIdx, pads ] : outlineIdxToPadsMap )
3679 if( pads.size() > 1 )
3681 const PAD* firstPad = pads[0];
3682 int firstGroupIdx = padNumberToGroupIdxMap[ firstPad->
GetNumber() ];
3684 for(
size_t ii = 1; ii < pads.size(); ++ii )
3686 const PAD* thisPad = pads[ii];
3687 int thisGroupIdx = padNumberToGroupIdxMap[ thisPad->
GetNumber() ];
3689 if( thisGroupIdx < 0 || thisGroupIdx != firstGroupIdx )
3698 if( item->HitTest( pos, 1 ) )
3700 shortingItem = item;
3706 aErrorHandler( shortingItem, firstPad, thisPad, pos );
3708 aErrorHandler( firstPad, thisPad,
nullptr, pos );
3719 std::set<wxString> padNumbers;
3728 msg.Printf(
_(
"(net-tie pad group contains unknown pad number %s)" ), padNumber );
3729 aErrorHandler( msg );
3731 else if( !padNumbers.insert(
pad->GetNumber() ).second )
3733 msg.Printf(
_(
"(pad %s appears in more than one net-tie pad group)" ), padNumber );
3734 aErrorHandler( msg );
3742 const VECTOR2I& aPt )>& aErrorHandler )
3744 auto checkColliding =
3759 if( itemShape->Collide( otherShape.get(), 0, &
actual, &pos ) )
3760 aErrorHandler( item, other, pos );
3769 checkColliding( item, other );
3773 checkColliding( item,
pad );
3784 std::swap( *
this, *
image );
3793 image->RunOnChildren(
3821 return *
this == other;
3830 for(
size_t ii = 0; ii <
m_pads.size(); ++ii )
3839 for(
size_t ii = 0; ii <
m_drawings.size(); ++ii )
3848 for(
size_t ii = 0; ii <
m_zones.size(); ++ii )
3858 std::vector<PCB_FIELD*> fields, otherFields;
3863 if( fields.size() != otherFields.size() )
3866 for(
size_t ii = 0; ii < fields.size(); ++ii )
3870 if( !( *fields[ii] == *otherFields[ii] ) )
3886 double similarity = 1.0;
3895 similarity *=
pad->Similarity( *otherPad );
3907 if( aPtA.
x != aPtB.
x )
3908 return aPtA.
x < aPtB.
x;
3910 if( aPtA.
y != aPtB.
y )
3911 return aPtA.
y < aPtB.
y;
3913 return std::nullopt;
3919 if( itemA->
Type() != itemB->
Type() )
3920 return itemA->
Type() < itemB->
Type();
3925 switch( itemA->
Type() )
3964 for(
int ii = 0; ii < dwgA->
GetPolyShape().TotalVertices(); ++ii )
3966 if( std::optional<bool> cmp =
4023 return itemA < itemB;
4035 std::optional<bool> padCopperMatches;
4038 const PAD* checkPad = aFirst;
4051 padCopperMatches = aFirst->
GetSize( aLayer ).
x < aSecond->
GetSize( aLayer ).
x;
4053 padCopperMatches = aFirst->
GetSize( aLayer ).
y < aSecond->
GetSize( aLayer ).
y;
4055 padCopperMatches = aFirst->
GetShape( aLayer ) < aSecond->
GetShape( aLayer );
4058 if( padCopperMatches.has_value() )
4059 return *padCopperMatches;
4067 return aFirst < aSecond;
4072bool FOOTPRINT::cmp_padstack::operator()(
const PAD* aFirst,
const PAD* aSecond )
const
4112 if( firstShape->VertexCount() != secondShape->VertexCount() )
4113 return firstShape->VertexCount() < secondShape->VertexCount();
4115 for(
int ii = 0; ii < firstShape->VertexCount(); ++ii )
4117 if( std::optional<bool> cmp =
cmp_points_opt( firstShape->CVertex( ii ), secondShape->CVertex( ii ) ) )
4139 for(
int ii = 0; ii < aFirst->
Outline()->TotalVertices(); ++ii )
4141 if( std::optional<bool> cmp =
4151 return aFirst < aSecond;
4156 int aMaxError,
ERROR_LOC aErrorLoc )
const
4167 clearance.x +=
pad->GetSolderMaskExpansion( padLayer );
4168 clearance.y +=
pad->GetSolderMaskExpansion( padLayer );
4191 if( dummySize.
x <= 0 || dummySize.
y <= 0 )
4195 dummy.SetSize( padLayer, dummySize );
4196 dummy.TransformShapeToPolygon( aBuffer, padLayer, 0, aMaxError, aErrorLoc );
4200 pad->TransformShapeToPolygon( aBuffer, padLayer,
clearance.x, aMaxError, aErrorLoc );
4206 if( !
pad->FlashLayer( aLayer ) )
4211 pad->Padstack().ForEachUniqueLayer(
4214 processPad(
pad, l );
4219 processPad(
pad, aLayer );
4226 int aError,
ERROR_LOC aErrorLoc,
bool aIncludeText,
4227 bool aIncludeShapes,
bool aIncludePrivateItems )
const
4234 if( item->Type() ==
PCB_TEXT_T && aIncludeText )
4239 text->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4250 textbox->PCB_SHAPE::TransformShapeToPolygon( aBuffer, aLayer, 0, aError, aErrorLoc );
4257 if( item->Type() ==
PCB_SHAPE_T && aIncludeShapes )
4278 if( field->GetLayer() == aLayer && field->IsVisible() )
4279 field->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4289 std::set<KIFONT::OUTLINE_FONT*>
fonts;
4303 if( permission == PERMISSION::EDITABLE || permission == PERMISSION::INSTALLABLE )
4304 fonts.insert( outlineFont );
4310 processItem( item );
4313 processItem( field );
4358 return wxEmptyString;
4363 const std::unordered_set<wxString>& aComponentClassNames )
4404 if( zcMap.
Choices().GetCount() == 0 )
4416 if( layerEnum.
Choices().GetCount() == 0 )
4424 wxPGChoices fpLayers;
4435 auto isNotFootprintHolder =
4441 return !
board->IsFootprintHolder();
4448 layer->SetChoices( fpLayers );
4449 layer->SetAvailableFunc( isNotFootprintHolder );
4457 const wxString groupFields =
_HKI(
"Fields" );
4482 const wxString groupAttributes =
_HKI(
"Attributes" );
4496 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