25#include <magic_enum.hpp>
29#include <unordered_set>
34#include <wx/tokenzr.h>
76#include <google/protobuf/any.pb.h>
77#include <api/board/board_types.pb.h>
99 void setter(
void* obj, wxAny& v )
override
103 if( !v.GetAs( &value ) )
109 wxString variantName;
114 if( !variantName.IsEmpty() )
125 footprint->
Add( newField );
133 wxAny
getter(
const void* obj )
const override
141 wxString variantName;
148 if( !variantName.IsEmpty() )
153 return wxAny(
text );
253 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
258 if( field->IsMandatory() )
260 PCB_FIELD* existingField = GetField( field->GetId() );
261 ptrMap[field] = existingField;
262 *existingField = *field;
265 existingField->SetUuidDirect( field->m_Uuid );
266 existingField->SetParent( this );
270 PCB_FIELD* newField = static_cast<PCB_FIELD*>( field->Clone() );
271 ptrMap[field] = newField;
277 for(
PAD*
pad : aFootprint.Pads() )
279 PAD* newPad = static_cast<PAD*>( pad->Clone() );
280 ptrMap[ pad ] = newPad;
281 Add( newPad, ADD_MODE::APPEND );
285 for(
ZONE* zone : aFootprint.Zones() )
287 ZONE* newZone = static_cast<ZONE*>( zone->Clone() );
288 ptrMap[ zone ] = newZone;
289 Add( newZone, ADD_MODE::APPEND );
295 newZone->SetNetCode( -1 );
299 for(
BOARD_ITEM* item : aFootprint.GraphicalItems() )
301 BOARD_ITEM* newItem = static_cast<BOARD_ITEM*>( item->Clone() );
302 ptrMap[ item ] = newItem;
303 Add( newItem, ADD_MODE::APPEND );
309 PCB_GROUP* newGroup = static_cast<PCB_GROUP*>( group->Clone() );
310 ptrMap[ group ] = newGroup;
311 Add( newGroup, ADD_MODE::APPEND );
319 for(
PCB_POINT* point : aFootprint.Points() )
321 PCB_POINT* newPoint = static_cast<PCB_POINT*>( point->Clone() );
322 ptrMap[ point ] = newPoint;
323 Add( newPoint, ADD_MODE::APPEND );
329 PCB_GROUP* newGroup = static_cast<PCB_GROUP*>( ptrMap[ group ] );
331 newGroup->GetItems().clear();
333 for( EDA_ITEM* member : group->GetItems() )
335 if( ptrMap.count( member ) )
336 newGroup->AddItem( ptrMap[ member ] );
350 *
this = std::move( aFootprint );
400 std::vector<PROPERTY_BASE*> props;
405 [&](
const wxString& aName )
411 auto prop = std::make_unique<PCB_FOOTPRINT_FIELD_PROPERTY>( aName );
415 return it->second.get();
420 if( !field->IsMandatory() )
423 if( !isFPedit && field->IsPrivate() )
426 const wxString&
name = field->GetUntranslatedName();
431 props.push_back( getOrCreate(
name ) );
434 std::vector<PCB_FIELD*> userFields;
438 if( field->IsMandatory() || ( !isFPedit && field->IsPrivate() ) )
441 userFields.push_back( field );
444 std::ranges::sort( userFields,
452 const wxString&
name = field->GetUntranslatedName();
453 props.push_back( getOrCreate(
name ) );
457 props.push_back( prop );
466 types::FootprintInstance footprint;
468 footprint.mutable_id()->set_value(
m_Uuid.AsStdString() );
469 footprint.mutable_position()->set_x_nm(
GetPosition().x );
470 footprint.mutable_position()->set_y_nm(
GetPosition().y );
473 footprint.set_locked(
IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
474 : kiapi::common::types::LockedState::LS_UNLOCKED );
477 footprint.mutable_parent()->set_value(
board->m_Uuid.AsStdString() );
484 types::FootprintAttributes* attrs = footprint.mutable_attributes();
491 attrs->set_do_not_populate(
IsDNP() );
495 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_THROUGH_HOLE );
497 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_SMD );
499 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_UNSPECIFIED );
503 types::FootprintDesignRuleOverrides* overrides = footprint.mutable_overrides();
517 overrides->set_zone_connection(
522 footprint.set_symbol_sheet_name(
m_sheetname.ToUTF8() );
523 footprint.set_symbol_sheet_filename(
m_sheetfile.ToUTF8() );
524 footprint.set_symbol_footprint_filters(
m_filters.ToUTF8() );
530 for(
const auto& [variantName, variant] :
m_variants )
532 types::FootprintVariant* variantMsg = footprint.add_variants();
533 variantMsg->set_name( variantName.ToUTF8() );
534 variantMsg->set_do_not_populate( variant.GetDNP() );
535 variantMsg->set_exclude_from_bill_of_materials( variant.GetExcludedFromBOM() );
536 variantMsg->set_exclude_from_position_files( variant.GetExcludedFromPosFiles() );
537 variantMsg->set_exclude_from_simulation( variant.GetExcludedFromSim() );
539 for(
const auto& [fieldName, fieldValue] : variant.GetFields() )
541 variantMsg->mutable_fields()->insert( { std::string( fieldName.ToUTF8() ),
542 std::string( fieldValue.ToUTF8() ) } );
548 types::FootprintUnitInfo* unitMsg = footprint.add_symbol_units();
549 unitMsg->set_name( unit.m_unitName.ToUTF8() );
551 for(
const wxString& pinNumber : unit.m_pins )
552 unitMsg->add_pin_numbers( pinNumber.ToUTF8() );
555 aContainer.PackFrom( footprint );
566 aOutput->mutable_attributes()->set_keywords(
GetKeywords().ToUTF8() );
572 types::NetTieDefinition* netTie = aOutput->add_net_ties();
573 wxStringTokenizer tokenizer(
group,
", \t\r\n", wxTOKEN_STRTOK );
575 while( tokenizer.HasMoreTokens() )
576 netTie->add_pad_number( tokenizer.GetNextToken().ToUTF8() );
582 types::JumperSettings* jumpers = aOutput->mutable_jumpers();
587 types::JumperGroup* jumperGroup = jumpers->add_groups();
589 for(
const wxString& padName :
group.GetNames() )
590 jumperGroup->add_pad_names( padName.ToUTF8() );
598 if( item->IsMandatory() )
601 google::protobuf::Any* itemMsg = aOutput->add_items();
602 item->Serialize( *itemMsg );
605 for(
const PAD* item :
Pads() )
607 google::protobuf::Any* itemMsg = aOutput->add_items();
608 item->Serialize( *itemMsg );
613 google::protobuf::Any* itemMsg = aOutput->add_items();
614 item->Serialize( *itemMsg );
619 google::protobuf::Any* itemMsg = aOutput->add_items();
620 item->Serialize( *itemMsg );
625 google::protobuf::Any* itemMsg = aOutput->add_items();
626 item->Serialize( *itemMsg );
631 if( body->GetExtruded()->m_height > 0 )
633 google::protobuf::Any* itemMsg = aOutput->add_items();
634 body->Serialize( *itemMsg );
640 google::protobuf::Any* itemMsg = aOutput->add_items();
641 types::Footprint3DModel modelMsg;
642 modelMsg.set_filename(
model.m_Filename.ToUTF8() );
646 modelMsg.set_visible(
model.m_Show );
647 modelMsg.set_opacity(
model.m_Opacity );
648 itemMsg->PackFrom( modelMsg );
666 for(
const types::NetTieDefinition& netTieMsg : aInput.net_ties() )
670 for(
const std::string&
pad : netTieMsg.pad_number() )
671 group.Append( wxString::Format( wxT(
"%s, " ),
pad ) );
680 jumperGroups.
Clear();
682 for(
const types::JumperGroup& groupMsg : aInput.jumpers().groups() )
684 std::set<wxString> padNames;
686 for(
const std::string& padName : groupMsg.pad_names() )
687 padNames.insert( wxString::FromUTF8( padName ) );
689 jumperGroups.
Add( std::move( padNames ) );
694 for(
int layerMsg : aInput.private_layers() )
699 privateLayers.
set( layer );
710 if( !field->IsMandatory() )
716 board->UncacheChildrenById( *
this );
729 for(
const google::protobuf::Any& itemMsg : aInput.items() )
737 if( itemMsg.type_url() ==
"type.googleapis.com/kiapi.board.types.Footprint3DModel" )
739 types::Footprint3DModel modelMsg;
741 if( !itemMsg.UnpackTo( &modelMsg ) )
746 model.m_Filename = wxString::FromUTF8( modelMsg.filename() );
747 model.m_Show = modelMsg.visible();
748 model.m_Opacity = modelMsg.opacity();
757 wxLogTrace(
traceApi, wxString::Format( wxS(
"Attempting to unpack unknown type %s "
758 "from footprint message, skipping" ),
759 itemMsg.type_url() ) );
767 if( item && item->Deserialize( itemMsg ) )
778 types::FootprintInstance footprint;
780 if( !aContainer.UnpackTo( &footprint ) )
787 SetLocked( footprint.locked() == kiapi::common::types::LockedState::LS_LOCKED );
789 google::protobuf::Any buf;
790 types::Field mandatoryField;
792 if( footprint.has_reference_field() )
794 mandatoryField = footprint.reference_field();
796 buf.PackFrom( mandatoryField );
800 if( footprint.has_value_field() )
802 mandatoryField = footprint.value_field();
804 buf.PackFrom( mandatoryField );
808 if( footprint.has_datasheet_field() )
810 mandatoryField = footprint.datasheet_field();
812 buf.PackFrom( mandatoryField );
816 if( footprint.has_description_field() )
818 mandatoryField = footprint.description_field();
820 buf.PackFrom( mandatoryField );
826 switch( footprint.attributes().mounting_style() )
828 case types::FootprintMountingStyle::FMS_THROUGH_HOLE:
832 case types::FootprintMountingStyle::FMS_SMD:
840 SetBoardOnly( footprint.attributes().not_in_schematic() );
845 SetDNP( footprint.attributes().do_not_populate() );
851 const types::FootprintDesignRuleOverrides& overrides = footprint.overrides();
853 if( overrides.has_copper_clearance() )
858 if( overrides.has_solder_mask() && overrides.solder_mask().has_solder_mask_margin() )
863 if( overrides.has_solder_paste() )
865 const types::SolderPasteOverrides& pasteSettings = overrides.solder_paste();
867 if( pasteSettings.has_solder_paste_margin() )
872 if( pasteSettings.has_solder_paste_margin_ratio() )
881 m_sheetname = wxString::FromUTF8( footprint.symbol_sheet_name() );
882 m_sheetfile = wxString::FromUTF8( footprint.symbol_sheet_filename() );
883 m_filters = wxString::FromUTF8( footprint.symbol_footprint_filters() );
892 for(
const types::FootprintVariant& variantMsg : footprint.variants() )
894 wxString variantName = wxString::FromUTF8( variantMsg.name() );
900 variant.
SetName( variantName );
901 variant.
SetDNP( variantMsg.do_not_populate() );
906 for(
const auto& [fieldName, fieldValue] : variantMsg.fields() )
907 variant.
SetFieldValue( wxString::FromUTF8( fieldName ), wxString::FromUTF8( fieldValue ) );
912 for(
const types::FootprintUnitInfo& unitMsg : footprint.symbol_units() )
915 unit.
m_unitName = wxString::FromUTF8( unitMsg.name() );
917 for(
const std::string& pinNumber : unitMsg.pin_numbers() )
918 unit.
m_pins.emplace_back( wxString::FromUTF8( pinNumber ) );
931 if( field->GetId() == aFieldType )
946 if( field->GetId() == aFieldType )
956 return GetField( aFieldName ) !=
nullptr;
964 if( field->GetName() == aFieldName )
980 if( !field->IsVisible() || field->GetText().IsEmpty() )
984 aVector.push_back( field );
987 std::sort( aVector.begin(), aVector.end(),
990 return lhs->GetOrdinal() < rhs->GetOrdinal();
996 std::vector<PCB_FIELD*>& aDetached )
998 std::deque<PCB_FIELD*> updatedFieldSet;
999 std::vector<wxString> assignedFields;
1006 *existingField = sourceField;
1009 updatedFieldSet.push_back( existingField );
1010 assignedFields.push_back( sourceField.GetName() );
1015 aAdded.push_back( destField );
1016 updatedFieldSet.push_back( destField );
1023 if( field.IsMandatory() )
1024 assignOrAdd(
const_cast<PCB_FIELD*
>( std::as_const( *this ).GetField( field.GetId() ) ), field );
1026 assignOrAdd(
GetField( field.GetName() ), field );
1031 if( !field->IsMandatory() && !
alg::contains( assignedFields, field->GetName() ) )
1032 aDetached.push_back( field );
1043 m_fields = std::move( updatedFieldSet );
1054 ordinal = std::max( ordinal, field->GetOrdinal() + 1 );
1061 bool aStyleShapes,
bool aStyleDimensions,
bool aStyleBarcodes )
1066 field->StyleFromSettings(
board.GetDesignSettings(),
true );
1071 switch( item->Type() )
1076 item->StyleFromSettings(
board.GetDesignSettings(),
true );
1081 if( aStyleShapes && !item->IsOnCopperLayer() )
1082 item->StyleFromSettings(
board.GetDesignSettings(),
true );
1091 if( aStyleDimensions )
1092 item->StyleFromSettings(
board.GetDesignSettings(),
true );
1097 if( aStyleBarcodes )
1098 item->StyleFromSettings(
board.GetDesignSettings(),
true );
1112 std::vector< BOARD_ITEM* > item_list;
1115 item_list.push_back( field );
1118 item_list.push_back(
pad );
1121 item_list.push_back( gr_item );
1126 item_list.push_back(
group );
1130 item_list.push_back( zone );
1134 item_list.push_back( point );
1136 bool changed =
false;
1142 item->ResetUuidDirect();
1179 board->UncacheChildrenById( *
this );
1187 for(
PCB_FIELD* field : aOther.m_fields )
1190 aOther.m_fields.clear();
1198 for(
PAD*
pad : aOther.Pads() )
1201 aOther.Pads().clear();
1209 for(
ZONE* item : aOther.Zones() )
1217 item->SetNetCode( -1 );
1220 aOther.Zones().clear();
1228 for(
BOARD_ITEM* item : aOther.GraphicalItems() )
1231 aOther.GraphicalItems().clear();
1242 aOther.Groups().clear();
1253 aOther.Constraints().clear();
1261 for(
PCB_POINT* point : aOther.Points() )
1264 aOther.Points().clear();
1278 aOther.m_componentClassCacheProxy->GetStaticComponentClass() );
1290 aOther.m_bodies.clear();
1291 aOther.m_fields.clear();
1292 aOther.Pads().clear();
1293 aOther.Zones().clear();
1294 aOther.GraphicalItems().clear();
1295 aOther.m_initial_comments =
nullptr;
1329 board->UncacheChildrenById( *
this );
1331 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
1342 ptrMap[field] = newField;
1355 ptrMap[
pad ] = newPad;
1367 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
1368 ptrMap[ zone ] = newZone;
1387 ptrMap[ item ] = newItem;
1403 newGroup->
AddItem( ptrMap[ member ] );
1427 ptrMap[ point ] = newItem;
1457 *
this = *
static_cast<const FOOTPRINT*
>( aOther );
1484 if( aSheetPath.empty() )
1488 return m_path.size() >= aSheetPath.size() - 1
1489 && std::equal( aSheetPath.begin() + 1, aSheetPath.end(),
m_path.begin() );
1495 aVars->push_back( wxT(
"REFERENCE" ) );
1496 aVars->push_back( wxT(
"VALUE" ) );
1497 aVars->push_back( wxT(
"LAYER" ) );
1498 aVars->push_back( wxT(
"FOOTPRINT_LIBRARY" ) );
1499 aVars->push_back( wxT(
"FOOTPRINT_NAME" ) );
1500 aVars->push_back( wxT(
"SHORT_NET_NAME(<pad_number>)" ) );
1501 aVars->push_back( wxT(
"NET_NAME(<pad_number>)" ) );
1502 aVars->push_back( wxT(
"NET_CLASS(<pad_number>)" ) );
1503 aVars->push_back( wxT(
"PIN_NAME(<pad_number>)" ) );
1504 aVars->push_back( wxT(
"EXCLUDE_FROM_BOM" ) );
1505 aVars->push_back( wxT(
"EXCLUDE_FROM_BOARD" ) );
1506 aVars->push_back( wxT(
"EXCLUDE_FROM_SIM" ) );
1507 aVars->push_back( wxT(
"EXCLUDE_FROM_POS_FILES" ) );
1508 aVars->push_back( wxT(
"DNP" ) );
1528 wxString variant = aVariantName;
1530 if( token->IsSameAs( wxT(
"REFERENCE" ) ) )
1533 *token = reference->GetShownText( variant,
INTERNAL, aDepth + 1 );
1539 else if( token->IsSameAs( wxT(
"VALUE" ) ) )
1542 *token = value->GetShownText( variant,
INTERNAL, aDepth + 1 );
1548 else if( token->IsSameAs( wxT(
"LAYER" ) ) )
1553 else if( token->IsSameAs( wxT(
"FOOTPRINT_LIBRARY" ) ) )
1555 *token =
m_fpid.GetUniStringLibNickname();
1558 else if( token->IsSameAs( wxT(
"FOOTPRINT_NAME" ) ) )
1560 *token =
m_fpid.GetUniStringLibItemName();
1563 else if( token->StartsWith( wxT(
"SHORT_NET_NAME(" ) )
1564 || token->StartsWith( wxT(
"NET_NAME(" ) )
1565 || token->StartsWith( wxT(
"NET_CLASS(" ) )
1566 || token->StartsWith( wxT(
"PIN_NAME(" ) ) )
1568 wxString padNumber = token->AfterFirst(
'(' );
1569 padNumber = padNumber.BeforeLast(
')' );
1573 if(
pad->GetNumber() == padNumber )
1575 if( token->StartsWith( wxT(
"SHORT_NET_NAME" ) ) )
1576 *token =
pad->GetShortNetname();
1577 else if( token->StartsWith( wxT(
"NET_NAME" ) ) )
1578 *token =
pad->GetNetname();
1579 else if( token->StartsWith( wxT(
"NET_CLASS" ) ) )
1580 *token =
pad->GetNetClassName();
1582 *token =
pad->GetPinFunction();
1588 else if( token->IsSameAs( wxT(
"EXCLUDE_FROM_BOM" ) ) )
1590 *token = wxEmptyString;
1593 *token = wxS(
"Excluded from BOM" );
1597 else if( token->IsSameAs( wxT(
"EXCLUDE_FROM_POS_FILES" ) ) )
1599 *token = wxEmptyString;
1602 *token = wxS(
"Excluded from position files" );
1606 else if( token->IsSameAs( wxT(
"EXCLUDE_FROM_BOARD" ) ) )
1609 *token = wxEmptyString;
1612 else if( token->IsSameAs( wxT(
"EXCLUDE_FROM_SIM" ) ) )
1614 *token = wxEmptyString;
1617 *token = wxS(
"Excluded from simulation" );
1621 else if( token->IsSameAs( wxT(
"DNP" ) ) )
1623 *token = wxEmptyString;
1626 *token = wxS(
"DNP" );
1632 *token = field->GetShownText( variant,
INTERNAL, aDepth + 1 );
1636 else if( token->StartsWith( wxS(
"PROPERTY." ) ) )
1639 wxString propertyName = token->AfterFirst(
'.' );
1640 propertyName.Replace( wxS(
"_" ), wxS(
" " ) );
1646 if( !property || property->IsHiddenFromPropertiesManager() )
1676 return it !=
m_variants.end() ? &it->second :
nullptr;
1684 return it !=
m_variants.end() ? &it->second :
nullptr;
1690 if( aVariant.
GetName().IsEmpty()
1702 it->second = std::move( updated );
1712 if( aVariantName.IsEmpty()
1715 wxASSERT_MSG(
false, wxT(
"Variant name cannot be empty or default." ) );
1730 auto inserted =
m_variants.emplace( aVariantName, std::move( variant ) );
1731 return &inserted.first->second;
1743 if( aNewName.IsEmpty()
1754 auto existingIt =
m_variants.find( aNewName );
1756 if( existingIt !=
m_variants.end() && existingIt != it )
1759 if( it->first == aNewName )
1765 m_variants.emplace( aNewName, std::move( variant ) );
1784 return variant->
GetDNP();
1852 return field->GetText();
1876 switch( aBoardItem->
Type() )
1902 m_pads.push_back(
static_cast<PAD*
>( aBoardItem ) );
1904 m_pads.push_front(
static_cast<PAD*
>( aBoardItem ) );
1910 m_zones.push_back(
static_cast<ZONE*
>( aBoardItem ) );
1933 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Markers go at the board level, even in the footprint editor" ) );
1937 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Nested footprints not supported" ) );
1957 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Add(): BOARD_ITEM type (%d) not handled" ),
1958 aBoardItem->
Type() ) );
1970 board->CacheItemSubtreeById( *aBoardItem );
1974 board->noteDrillModelChange( aBoardItem );
1983 switch( aBoardItem->
Type() )
1988 if( *it == aBoardItem )
1990 const wxString fieldName = ( *it )->GetUntranslatedName();
1994 for(
auto& [variantName, footprintVariant] :
m_variants )
1995 footprintVariant.RemoveFieldValue( fieldName );
2016 if( *it == aBoardItem )
2026 for(
auto it =
m_pads.begin(); it !=
m_pads.end(); ++it )
2028 if( *it ==
static_cast<PAD*
>( aBoardItem ) )
2040 if( *it ==
static_cast<ZONE*
>( aBoardItem ) )
2064 if( *it ==
static_cast<PCB_GROUP*
>( aBoardItem ) )
2074 wxFAIL_MSG( wxT(
"FOOTPRINT::Remove(): Markers go at the board level, even in the footprint editor" ) );
2078 wxFAIL_MSG( wxT(
"FOOTPRINT::Remove(): Nested footprints not supported" ) );
2084 if( *it ==
static_cast<PCB_POINT*
>( aBoardItem ) )
2098 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
2099 aBoardItem->
Type() ) );
2105 if(
board->IsItemIndexedById(
this ) )
2107 board->UncacheItemSubtreeById( *aBoardItem );
2108 board->noteDrillModelChange( aBoardItem );
2111 board->IncrementTimeStamp();
2137 switch(
pad->GetProperty() )
2155 switch(
pad->GetAttribute() )
2162 if(
pad->IsOnCopperLayer() )
2190 return _(
"Through hole" );
2192 return _(
"Unspecified" );
2228 wxStringTokenizer keywordTokenizer(
GetKeywords(), wxS(
" \t\r\n" ), wxTOKEN_STRTOK );
2230 while( keywordTokenizer.HasMoreTokens() )
2251 if(
dummy.IsFlipped() )
2255 bbox.
Merge(
pad->GetBoundingBox() );
2305 std::vector<PCB_TEXT*> texts;
2306 bool isFPEdit =
board &&
board->IsFootprintHolder();
2327 texts.push_back(
static_cast<PCB_TEXT*
>( item ) );
2345 bbox.
Merge( item->GetBoundingBox() );
2351 if( field->IsReference() || field->IsValue() )
2354 texts.push_back( field );
2358 bbox.
Merge(
pad->GetBoundingBox() );
2361 bbox.
Merge( zone->GetBoundingBox() );
2364 bbox.
Merge( point->GetBoundingBox() );
2369 if( aIncludeText || noDrawItems )
2392 bool valueLayerIsVisible =
true;
2393 bool refLayerIsVisible =
true;
2403 valueLayerIsVisible =
board->IsLayerVisible( value->
GetLayer() )
2410 refLayerIsVisible =
board->IsLayerVisible( reference->
GetLayer() )
2417 if( value && ( ( value->
IsVisible() && valueLayerIsVisible ) || noDrawItems ) )
2420 if( reference && ( ( reference->
IsVisible() && refLayerIsVisible ) || noDrawItems ) )
2431 if( aIncludeText || noDrawItems )
2449 std::vector<PCB_TEXT*> texts;
2451 bool isFPEdit =
board &&
board->IsFootprintHolder();
2461 if( ( aLayers & item->GetLayerSet() ).none() )
2469 bbox.
Merge( item->GetBoundingBox() );
2474 if( ( aLayers &
pad->GetLayerSet() ).none() )
2477 bbox.
Merge(
pad->GetBoundingBox() );
2482 if( ( aLayers & zone->GetLayerSet() ).none() )
2485 bbox.
Merge( zone->GetBoundingBox() );
2493 if( ( aLayers & point->GetLayerSet() ).none() )
2496 bbox.
Merge( point->GetBoundingBox() );
2506 bool isFPEdit =
board &&
board->IsFootprintHolder();
2531 pad->Padstack().ForEachUniqueLayer(
2545 const SHAPE_POLY_SET& layerPoly = *zone->GetFilledPolysList( layer );
2561 const int halfsize =
pcbIUScale.mmToIU( 1.0 );
2572 std::vector<VECTOR2I> convex_hull;
2584 for(
const VECTOR2I& pt : convex_hull )
2598 bool isFPEdit =
board &&
board->IsFootprintHolder();
2608 if( item->IsOnLayer( aLayer ) )
2619 if(
pad->IsOnLayer( aLayer ) )
2625 if( zone->GetIsRuleArea() )
2628 if( zone->IsOnLayer( aLayer ) )
2630 const std::shared_ptr<SHAPE_POLY_SET>& layerPoly = zone->GetFilledPolysList( aLayer );
2632 for(
int ii = 0; ii < layerPoly->OutlineCount(); ii++ )
2633 rawPolys.
AddOutline( layerPoly->COutline( ii ) );
2637 std::vector<VECTOR2I> convex_hull;
2642 for(
const VECTOR2I& pt : convex_hull )
2655 variant =
board->GetCurrentVariant();
2668 aList.emplace_back(
_(
"Footprint Name" ),
GetFPID().GetLibItemName().wx_str() );
2673 wxString::Format(
_(
"Keywords: %s" ),
GetKeywords() ) );
2682 case F_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Front" ) );
break;
2683 case B_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Back (Flipped)" ) );
break;
2687 aList.emplace_back(
_(
"Rotation" ), wxString::Format( wxT(
"%.4g" ),
GetOrientation().AsDegrees() ) );
2689 auto addToken = []( wxString* aStr,
const wxString& aAttr )
2691 if( !aStr->IsEmpty() )
2692 *aStr += wxT(
", " );
2701 addToken( &status,
_(
"Locked" ) );
2704 addToken( &status,
_(
"autoplaced" ) );
2707 addToken( &attrs,
_(
"not in schematic" ) );
2710 addToken( &attrs,
_(
"exclude from pos files" ) );
2713 addToken( &attrs,
_(
"exclude from BOM" ) );
2716 addToken( &attrs,
_(
"exclude from simulation" ) );
2719 addToken( &attrs,
_(
"DNP" ) );
2721 aList.emplace_back(
_(
"Status: " ) + status,
_(
"Attributes:" ) + wxS(
" " ) + attrs );
2725 aList.emplace_back(
_(
"Component Class" ),
2729 msg.Printf(
_(
"Footprint: %s" ),
m_fpid.GetUniStringLibId() );
2731 aList.emplace_back( msg, msg2 );
2735 aList.emplace_back( msg, msg2 );
2743 if(
board->IsFootprintHolder() )
2775 return aItem->IsOnLayer( aLayer );
2778 return std::ranges::any_of(
m_pads, isOnLayer )
2779 || std::ranges::any_of(
m_zones, isOnLayer )
2780 || std::ranges::any_of(
m_fields, isOnLayer )
2781 || std::ranges::any_of(
m_drawings, isOnLayer );
2789 if(
pad->IsOnLayer( aLayer ) &&
pad->HitTest( aPosition, aAccuracy ) )
2795 if( zone->IsOnLayer( aLayer ) && zone->HitTest( aPosition, aAccuracy ) )
2801 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer )
2802 && item->HitTest( aPosition, aAccuracy ) )
2814 std::vector<BOARD_ITEM*> items;
2818 if(
pad->IsOnLayer( aLayer ) )
2819 items.push_back(
pad );
2824 if( zone->IsOnLayer( aLayer ) )
2825 items.push_back( zone );
2830 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer ) )
2831 items.push_back( item );
2840 if( !aContained && item->HitTest( aRect, aContained, aAccuracy ) )
2842 else if( aContained && !item->HitTest( aRect, aContained, aAccuracy ) )
2849 return !items.empty() && aContained;
2868 BOX2I arect = aRect;
2888 if(
pad->HitTest( arect,
false, 0 ) )
2894 if( zone->HitTest( arect,
false, 0 ) )
2900 if( point->HitTest( arect,
false, 0 ) )
2911 if( item->Type() !=
PCB_TEXT_T && item->HitTest( arect,
false, 0 ) )
2925 using std::ranges::all_of;
2926 using std::ranges::any_of;
2933 [&](
const auto* aItem )
2935 return aItem && aItem->HitTest( aPoly, aContained );
2941 auto drawings =
m_drawings | std::views::filter( [](
const auto* aItem )
2952 return all_of( drawings, hitTest )
2953 && all_of(
m_pads, hitTest )
2954 && all_of(
m_zones, hitTest );
2959 return any_of( drawings, hitTest )
2960 || any_of(
m_pads, hitTest )
2961 || any_of(
m_zones, hitTest );
2968 bool can_select = aSearchAfterMe ? false :
true;
2972 if( !can_select &&
pad == aSearchAfterMe )
2978 if( can_select &&
pad->GetNumber() == aPadNumber )
2990 if(
pad->m_Uuid == aUuid )
3003 if( !(
pad->GetLayerSet() & aLayerMask ).any() )
3006 if(
pad->HitTest( aPosition ) )
3016 std::vector<const PAD*> retv;
3020 if( ( aIgnore && aIgnore ==
pad ) || (
pad->GetNumber() != aPadNumber ) )
3023 retv.push_back(
pad );
3038 std::set<wxString> usedNumbers;
3050 if(
pad->GetNumber().IsEmpty() )
3053 usedNumbers.insert(
pad->GetNumber() );
3078 auto isElectricalPadNumber =
3079 [](
const wxString& num ) ->
bool
3086 while( i < num.size() && wxIsalpha( num[i] ) )
3094 if( i == num.size() )
3097 for(
size_t j = i; j < num.size(); ++j )
3099 if( !wxIsdigit( num[j] ) )
3106 std::set<wxString> counted;
3118 const wxString& num =
pad->GetNumber();
3120 if( isElectricalPadNumber( num ) )
3122 counted.insert( num );
3124 else if( num.Contains(
'_' ) )
3126 wxString first, second;
3127 first = num.BeforeFirst(
'_', &second );
3129 if( isElectricalPadNumber( first ) && isElectricalPadNumber( second ) )
3131 counted.insert( first );
3132 counted.insert( second );
3137 return static_cast<unsigned>( counted.size() );
3143 if(
nullptr == a3DModel )
3188 const std::vector<KICAD_T>& aScanTypes )
3190#if 0 && defined(DEBUG)
3191 std::cout <<
GetClass().mb_str() <<
' ';
3194 bool drawingsScanned =
false;
3196 for(
KICAD_T scanType : aScanTypes )
3235 if( !drawingsScanned )
3240 drawingsScanned =
true;
3288 if( reference.IsEmpty() )
3289 reference =
_(
"<no reference designator>" );
3291 return wxString::Format(
_(
"Footprint %s" ), reference );
3297 return wxString::Format( wxT(
"%s (%s)" ),
3335 aFunction( constraint );
3342 aFunction( drawing );
3348 catch( std::bad_function_call& )
3350 wxFAIL_MSG( wxT(
"Error running FOOTPRINT::RunOnChildren" ) );
3357 std::vector<int> layers;
3359 layers.reserve( 6 );
3365 wxASSERT_MSG(
false, wxT(
"Illegal layer" ) );
3382 bool f_silk =
false, b_silk =
false, non_silk =
false;
3386 if( item->GetLayer() ==
F_SilkS )
3388 else if( item->GetLayer() ==
B_SilkS )
3394 if( ( f_silk || b_silk ) && !non_silk &&
m_pads.empty() )
3435 constexpr double MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY = 1.5;
3438 return MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY;
3451 int biggest_clearance =
board->GetMaxClearanceValue();
3452 area.
Inflate( biggest_clearance );
3463 if( aName.find_first_of( invalids ) != std::string::npos )
3475 static const wxChar invalidCharsReadable[] = wxT(
"% $ < > 'tab' 'return' 'line feed' \\ \" / :");
3478 return invalidCharsReadable;
3480 return invalidChars.wc_str();
3486 if( aMoveVector.
x == 0 && aMoveVector.
y == 0 )
3500 EDA_ANGLE newOrientation = orientation + aAngle;
3507 field->KeepUpright();
3512 static_cast<PCB_TEXT*
>( item )->KeepUpright();
3519 wxASSERT( aLayer ==
F_Cu || aLayer ==
B_Cu );
3574 field->OnFootprintTransformed();
3577 pad->OnFootprintTransformed();
3580 zone->OnFootprintTransformed();
3588 item->OnFootprintTransformed();
3593 point->OnFootprintTransformed();
3607 body->Flip( pos, aFlipDirection );
3633 if( !std::isfinite( aScaleX ) || !std::isfinite( aScaleY ) || aScaleX <= 0.0 || aScaleY <= 0.0 )
3638 const double ratioX = aScaleX / oldSx;
3639 const double ratioY = aScaleY / oldSy;
3640 const double linearFactor = ( aScaleX + aScaleY ) / ( oldSx + oldSy );
3648 pad->OnFootprintRescaled( ratioX, ratioY, linearFactor,
anchor, parentRotate );
3651 field->OnFootprintRescaled( ratioX, ratioY, linearFactor,
anchor, parentRotate );
3654 item->OnFootprintRescaled( ratioX, ratioY, linearFactor,
anchor, parentRotate );
3657 zone->OnFootprintRescaled( ratioX, ratioY, linearFactor,
anchor, parentRotate );
3660 point->OnFootprintTransformed();
3688 field->OnFootprintTransformed();
3691 pad->OnFootprintTransformed();
3694 zone->OnFootprintTransformed();
3697 point->OnFootprintTransformed();
3705 item->OnFootprintTransformed();
3709 item->Move(
delta );
3749 field->Move( moveVector );
3753 pad->Move( moveVector );
3757 item->Move( moveVector );
3761 zone->Move( moveVector );
3765 point->Move( moveVector );
3804 field->OnFootprintTransformed();
3807 pad->OnFootprintTransformed();
3810 zone->OnFootprintTransformed();
3813 point->OnFootprintTransformed();
3821 item->OnFootprintTransformed();
3825 item->Rotate( rotationCenter, angleChange );
3852 std::map<KIID, KIID> idMap;
3859 idMap[oldId] = child->
m_Uuid;
3864 constraint->RemapKIIDs( idMap );
3871 const BOARD_ITEM* aItem,
bool addToFootprint )
3875 switch( aItem->
Type() )
3879 PAD* new_pad =
new PAD( *
static_cast<const PAD*
>( aItem ) );
3882 if( addToFootprint )
3883 m_pads.push_back( new_pad );
3891 ZONE* new_zone =
new ZONE( *
static_cast<const ZONE*
>( aItem ) );
3894 if( addToFootprint )
3895 m_zones.push_back( new_zone );
3897 new_item = new_zone;
3906 if( addToFootprint )
3909 new_item = new_point;
3918 switch(
static_cast<const PCB_FIELD*
>( aItem )->GetId() )
3926 if( addToFootprint )
3929 new_item = new_field;
3938 if( addToFootprint )
3941 new_item = new_text;
3950 if( addToFootprint )
3953 new_item = new_shape;
3962 if( addToFootprint )
3965 new_item = new_barcode;
3974 if( addToFootprint )
3977 new_item = new_image;
3986 if( addToFootprint )
3989 new_item = new_textbox;
4002 if( addToFootprint )
4005 new_item = dimension;
4011 new_item = aItem->
Duplicate( addToParentGroup, aCommit );
4013 if( addToFootprint )
4023 if( addToFootprint )
4025 group->RunOnChildren(
4045 wxFAIL_MSG( wxT(
"Duplication not supported for items of class " ) + aItem->
GetClass() );
4055 std::set<wxString> usedNumbers;
4059 usedNumbers.insert(
pad->GetNumber() );
4066 while( usedNumbers.count( wxString::Format( wxT(
"%s%d" ), prefix, num ) ) )
4069 return wxString::Format( wxT(
"%s%d" ), prefix, num );
4133 for(
int i = 0; i < aCollector.
GetCount(); ++i )
4137 switch( item->
Type() )
4169 double footprintRegionArea =
polygonArea( footprintRegion );
4170 double uncoveredRegionArea = footprintRegionArea -
polygonArea( coveredRegion );
4171 double coveredArea = footprintRegionArea - uncoveredRegionArea;
4174 if( footprintRegionArea == 0 )
4177 double ratio = coveredArea / footprintRegionArea;
4184 return std::min( ratio, 1.0 );
4191 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
4212 shape->AddShape(
pad->GetEffectiveShape( aLayer, aFlash, aUsage )->Clone() );
4217 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash, aUsage )->Clone() );
4219 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash, aUsage )->Clone() );
4266 std::vector<PCB_SHAPE*> list_front;
4267 std::vector<PCB_SHAPE*> list_back;
4268 std::map<int, int> front_width_histogram;
4269 std::map<int, int> back_width_histogram;
4276 list_back.push_back( shape );
4283 list_front.push_back( shape );
4288 if( !list_front.size() && !list_back.size() )
4292 int chainingEpsilon =
pcbIUScale.mmToIU( 0.02 );
4295 true, aErrorHandler ) )
4305 auto max = std::max_element( front_width_histogram.begin(), front_width_histogram.end(),
4306 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
4308 return a.second < b.second;
4311 if( max != front_width_histogram.end() )
4334 auto max = std::max_element( back_width_histogram.begin(), back_width_histogram.end(),
4335 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
4337 return a.second < b.second;
4340 if( max != back_width_histogram.end() )
4363 std::map<PCB_LAYER_ID, std::vector<PCB_SHAPE*>> layer_shapes;
4369 if( item->Type() != PCB_SHAPE_T )
4372 for( PCB_LAYER_ID layer : item->GetLayerSet() )
4374 if( !IsCopperLayer( layer ) )
4377 if( board && !board->GetEnabledLayers().Contains( layer ) )
4380 layer_shapes[layer].push_back( static_cast<PCB_SHAPE*>( item ) );
4384 for(
size_t ii = 0; ii < m_pads.size(); ++ii )
4387 bool has_nettie =
false;
4389 auto it = map.find(
pad->GetNumber() );
4391 if( it == map.end() || it->second < 0 )
4394 for(
size_t jj = 0; jj < m_pads.size(); ++jj )
4399 PAD* other = m_pads[ jj ];
4401 auto it2 = map.find( other->
GetNumber() );
4403 if( it2 == map.end() || it2->second < 0 )
4406 if( it2->second == it->second )
4408 m_netTieCache[
pad].insert(
pad->GetNetCode() );
4410 m_netTieCache[other].insert( other->
GetNetCode() );
4411 m_netTieCache[other].insert(
pad->GetNetCode() );
4419 for(
auto& [ layer, shapes ] : layer_shapes )
4421 auto pad_shape =
pad->GetEffectiveShape( layer );
4423 for(
auto other_shape : shapes )
4425 auto shape = other_shape->GetEffectiveShape( layer );
4427 if( pad_shape->Collide( shape.get() ) )
4429 std::set<int>& nettie = m_netTieCache[
pad];
4430 m_netTieCache[other_shape].insert( nettie.begin(), nettie.end() );
4440 std::map<wxString, int> padNumberToGroupIdxMap;
4443 padNumberToGroupIdxMap[
pad->GetNumber() ] = -1;
4446 [&]( wxString aPad,
int aGroup )
4448 aPad.Trim(
true ).Trim(
false );
4450 if( !aPad.IsEmpty() )
4451 padNumberToGroupIdxMap[ aPad ] = aGroup;
4460 for( wxUniCharRef ch :
group )
4469 switch(
static_cast<unsigned char>( ch ) )
4476 processPad(
pad, ii );
4486 processPad(
pad, ii );
4489 return padNumberToGroupIdxMap;
4499 int groupIdx = padToNetTieGroupMap[ aPad->
GetNumber() ];
4500 std::vector<PAD*> otherPads;
4506 if( padToNetTieGroupMap[
pad->GetNumber() ] == groupIdx )
4507 otherPads.push_back(
pad );
4521 std::swap( *
this, *
image );
4530 image->RunOnChildren(
4558 return *
this == other;
4565 [](
const auto* aLeft,
const auto* aRight )
4567 return *aLeft == *aRight;
4570 if( !std::ranges::equal(
m_pads, aOther.
m_pads, equalItems ) )
4598 std::vector<PCB_FIELD*> fields, otherFields;
4603 if( fields.size() != otherFields.size() )
4606 for(
size_t ii = 0; ii < fields.size(); ++ii )
4610 if( !( *fields[ii] == *otherFields[ii] ) )
4626 double similarity = 1.0;
4635 similarity *=
pad->Similarity( *otherPad );
4647 if( aPtA.
x != aPtB.
x )
4648 return aPtA.
x < aPtB.
x;
4650 if( aPtA.
y != aPtB.
y )
4651 return aPtA.
y < aPtB.
y;
4653 return std::nullopt;
4659 if( itemA->
Type() != itemB->
Type() )
4660 return itemA->
Type() < itemB->
Type();
4665 switch( itemA->
Type() )
4787 return itemA < itemB;
4799 std::optional<bool> padCopperMatches;
4802 const PAD* checkPad = aFirst;
4815 padCopperMatches = aFirst->
GetSize( aLayer ).
x < aSecond->
GetSize( aLayer ).
x;
4817 padCopperMatches = aFirst->
GetSize( aLayer ).
y < aSecond->
GetSize( aLayer ).
y;
4819 padCopperMatches = aFirst->
GetShape( aLayer ) < aSecond->
GetShape( aLayer );
4822 if( padCopperMatches.has_value() )
4823 return *padCopperMatches;
4831 return aFirst < aSecond;
4836bool FOOTPRINT::cmp_padstack::operator()(
const PAD* aFirst,
const PAD* aSecond )
const
4876 if( firstShape->VertexCount() != secondShape->VertexCount() )
4877 return firstShape->VertexCount() < secondShape->VertexCount();
4879 for(
int ii = 0; ii < firstShape->VertexCount(); ++ii )
4881 if( std::optional<bool> cmp =
cmp_points_opt( firstShape->CVertex( ii ), secondShape->CVertex( ii ) ) )
4915 return aFirst < aSecond;
4920 int aMaxError,
ERROR_LOC aErrorLoc )
const
4931 clearance.x +=
pad->GetSolderMaskExpansion( padLayer );
4932 clearance.y +=
pad->GetSolderMaskExpansion( padLayer );
4955 if( dummySize.
x <= 0 || dummySize.
y <= 0 )
4959 dummy.SetSize( padLayer, dummySize );
4960 dummy.TransformShapeToPolygon( aBuffer, padLayer, 0, aMaxError, aErrorLoc );
4964 pad->TransformShapeToPolygon( aBuffer, padLayer,
clearance.x, aMaxError, aErrorLoc );
4970 if( !
pad->FlashLayer( aLayer ) )
4975 pad->Padstack().ForEachUniqueLayer(
4978 processPad(
pad, l );
4983 processPad(
pad, aLayer );
4990 int aError,
ERROR_LOC aErrorLoc,
bool aIncludeText,
4991 bool aIncludeShapes,
bool aIncludePrivateItems )
const
4998 if( item->Type() ==
PCB_TEXT_T && aIncludeText )
5003 text->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
5014 textbox->PCB_SHAPE::TransformShapeToPolygon( aBuffer, aLayer, 0, aError, aErrorLoc );
5021 if( item->Type() ==
PCB_SHAPE_T && aIncludeShapes )
5042 if( ( aLayer ==
UNDEFINED_LAYER || field->GetLayer() == aLayer ) && field->IsVisible() )
5043 field->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
5053 std::set<KIFONT::OUTLINE_FONT*>
fonts;
5067 if( permission == PERMISSION::EDITABLE || permission == PERMISSION::INSTALLABLE )
5068 fonts.insert( outlineFont );
5074 processItem( item );
5077 processItem( field );
5091 wxLogTrace(
"EMBED",
"Failed to add font file: %s", font->GetFileName() );
5129 return wxEmptyString;
5134 const std::unordered_set<wxString>& aComponentClassNames )
5183 LSET padLayers =
pad->GetLayerSet();
5184 padLayers |= boardCopper;
5185 pad->SetLayerSet( padLayers );
5202 if( zcMap.
Choices().GetCount() == 0 )
5214 if( layerEnum.
Choices().GetCount() == 0 )
5222 wxPGChoices fpLayers;
5233 auto isNotFootprintHolder =
5239 return !
board->IsFootprintHolder();
5263 const wxString groupFields =
_HKI(
"Fields" );
5269 const wxString propertyFields =
_HKI(
"Footprint Properties" );
5291 const wxString groupAttributes =
_HKI(
"Attributes" );
5311 const wxString groupOverrides =
_HKI(
"Overrides" );
KICOMMON_API types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICOMMON_API 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)
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
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)
void SetUuidDirect(const KIID &aUuid)
Raw UUID assignment.
virtual BOARD_ITEM * Duplicate(bool addToParentGroup, BOARD_COMMIT *aCommit=nullptr) const
Create a copy of this BOARD_ITEM.
void SetLocked(bool aLocked) override
PCB_LAYER_ID GetFlippedLayer(PCB_LAYER_ID aLayer) const
Return the layer paired with aLayer on the opposite side of the board.
static double polygonArea(SHAPE_POLY_SET &aPolySet)
Area of aPolySet with every contour closed first, holes subtracted.
bool IsLocked() const override
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
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 void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
VECTOR2I GetFPRelativePosition() const
virtual void TransformShapeToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, KIGFX::RENDER_SETTINGS *aRenderSettings=nullptr) const
Convert the item shape to a polyset.
BOARD_ITEM & operator=(const BOARD_ITEM &aOther)
BOARD_ITEM_CONTAINER * GetParent() const
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Information pertinent to a Pcbnew printed circuit board.
bool IsFootprintHolder() const
Find out if the board is being used to hold a single footprint for editing/viewing.
int GetCopperLayerCount() const
wxString GetCurrentVariant() const
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.
const COMPONENT_CLASS * GetStaticComponentClass() const
Gets the static component class.
COMPONENT_CLASS * GetEffectiveStaticComponentClass(const std::unordered_set< wxString > &classNames)
Computes and returns an effective component class for a (possibly empty) set of constituent class nam...
A lightweight representation of a component class.
int AsTenthsOfADegree() const
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()
void SetFlags(EDA_ITEM_FLAGS aMask)
std::vector< PROPERTY_BASE * > GetCustomPropertiesAsInspectables() const
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.
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
virtual void SetParent(EDA_ITEM *aParent)
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
int GetEllipseMinorRadius() const
const VECTOR2I & GetEllipseCenter() const
EDA_ANGLE GetEllipseEndAngle() const
int GetEllipseMajorRadius() const
EDA_ANGLE GetEllipseRotation() const
EDA_ANGLE GetEllipseStartAngle() const
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual const wxString & GetText() const
Return the string associated with the text object.
virtual bool IsVisible() const
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
double GetLineSpacing() const
virtual void SetText(const wxString &aText)
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.
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)
wxString m_Filename
The 3D shape filename in 3D library.
Used when the right click button is pressed, or when the select tool is in effect.
const COLLECTORS_GUIDE * GetGuide() const
Class that other classes need to inherit from, in order to be inspectable.
wxAny Get(PROPERTY_BASE *aProperty) const
Represents an (ordered) list of JUMPER_GROUP objects.
void Add(JUMPER_GROUP aGroup)
Add a JUMPER_GROUP to the set.
Represents a group of jumper pins or pads, keyed by name.
A typed sum value used to carry the before/after of any single property.
wxString ToDisplayString() const
Human-readable representation with no unit context.
FONT is an abstract base class for both outline and stroke fonts.
virtual bool IsOutline() const
Implement 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 & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
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.
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.
PAD_ATTRIB GetAttribute() const
const wxString & GetNumber() const
VECTOR2I GetDrillSize() const
PAD_SHAPE GetShape(PCB_LAYER_ID aLayer) const
int GetSolderMaskExpansion(PCB_LAYER_ID aLayer) const
VECTOR2I GetSize(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,...
A 3D body attached to a footprint (or, later, placed on a board).
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
A geometric constraint between board items (issue #2329).
wxString GetUntranslatedName() const
Get the untranslated field name for storage, variable look-up, etc.
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.
PCB_FIELD * CloneField() const
Same as Clone, but returns a PCB_FIELD item.
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 GetLibraryBezierC1() const
int GetWidth() const override
void TransformShapeToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, KIGFX::RENDER_SETTINGS *aRenderSettings=nullptr) const override
Convert the item shape to a polyset.
VECTOR2I GetLibraryEnd() const
VECTOR2I GetLibraryStart() const
STROKE_PARAMS GetStroke() const override
SHAPE_POLY_SET GetLibraryPolyShape() const
VECTOR2I GetLibraryBezierC2() const
VECTOR2I GetLibraryArcMid() const
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
bool IsBorderEnabled() const
Tests whether the border is disabled, as configured by the stroke.
void TransformTextToPolySet(SHAPE_POLY_SET &aBuffer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc) const
Convert the text to a polygonSet describing the actual character strokes (one per segment).
EDA_ANGLE GetTextAngle() const override
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
int GetTextThickness() const override
void SetTextAngle(const EDA_ANGLE &aAngle) override
VECTOR2I GetTextSize() const override
PROPERTY_BASE & SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Set a callback function to determine whether an object provides this property.
PROPERTY_BASE(const wxString &aName, PROPERTY_DISPLAY aDisplay=PT_DEFAULT, ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType=ORIGIN_TRANSFORMS::NOT_A_COORD)
Used to generate unique IDs. Must come up front so it's initialized before ctor.
PROPERTY_BASE & SetGroup(const wxString &aGroup)
PROPERTY_BASE & SetIsCopyable(bool aIsCopyable=true)
virtual void SetChoices(const wxPGChoices &aChoices)
Set the possible values for for the property.
PROPERTY_BASE & SetIsHiddenFromLibraryEditors(bool aIsHidden=true)
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 * GetProperty(TYPE_ID aType, const wxString &aProperty) const
Return a property for a specific type.
bool IsAvailableFor(TYPE_ID aItemClass, PROPERTY_BASE *aProp, INSPECTABLE *aItem)
Checks overriden availability and original availability of a property, returns false if the 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...
Represent a set of closed polygons.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
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 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)
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
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.
Handle a list of polygons defining a copper zone.
bool SetNetCode(int aNetCode, bool aNoAssert) override
Override that clamps the netcode to 0 when this zone is in copper-thieving fill mode.
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
SHAPE_POLY_SET GetLibraryOutline() const
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.
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
@ 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.
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:
bool IsValidLayer(int aLayerId)
Test whether a given integer is a valid layer index, i.e.
const wxString & GetLibFilenameForbiddenChars()
Characters illegal in a footprint library filename.
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)
DIFF_VALUE WxAnyToDiffValue(const wxAny &aValue, PROPERTY_BASE *aProperty)
Convert a wxAny value read from a PROPERTY_BASE getter into a DIFF_VALUE that the engine can store,...
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.
void PackEmbeddedFiles(common::types::EmbeddedFiles &aOutput, const EMBEDDED_FILES &aFiles)
bool UnpackEmbeddedFiles(EMBEDDED_FILES &aOutput, const common::types::EmbeddedFiles &aProto)
KICOMMON_API int UnpackDistance(const types::Distance &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API KIID_PATH UnpackSheetPath(const types::SheetPath &aInput)
KICOMMON_API std::optional< KICAD_T > TypeNameFromAny(const google::protobuf::Any &aMessage)
KICOMMON_API VECTOR3D UnpackVector3D(const types::Vector3D &aInput)
KICOMMON_API void PackCustomProperties(google::protobuf::RepeatedPtrField< types::CustomProperty > *aOutput, const EDA_ITEM &aItem)
KICOMMON_API void PackDistance(types::Distance &aOutput, int aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackSheetPath(types::SheetPath &aOutput, const KIID_PATH &aInput)
KICOMMON_API void PackLibId(types::LibraryIdentifier *aOutput, const LIB_ID &aId)
KICOMMON_API LIB_ID UnpackLibId(const types::LibraryIdentifier &aId)
KICOMMON_API void UnpackCustomProperties(const google::protobuf::RepeatedPtrField< types::CustomProperty > &aInput, EDA_ITEM &aItem)
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 TYPE_HASH(x)
Macro to generate unique identifier for a type.
#define NO_SETTER(owner, type)
Macro to define read-only fields (no setter method available)
#define ENUM_TO_WXANY(type)
@ PT_DEGREE
Angle expressed in degrees.
@ PT_SIZE
Size expressed in distance units (mm/inch)
#define REGISTER_TYPE(x)
Helper macro to map type hashes to names.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
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.
wxString GetDefaultVariantName()
int GetTrailingInt(const wxString &aStr)
Gets the trailing int, if any, from a string.
wxString UnescapeString(const wxString &aSource)
A structure for storing weighted search terms.
wxString GetDefaultFieldName(FIELD_T aFieldId, TRANSLATION aTranslation)
Return a default symbol field name for a mandatory field type.
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ USER
The field ID hasn't been set yet; field is invalid.
@ 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_CONSTRAINT_T
a geometric constraint between board items
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
@ PCB_ZONE_T
class ZONE, a copper pour area
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_3D_BODY_T
class PCB_3D_BODY, a 3D body (extruded or model) on a footprint
@ 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