25#include <magic_enum.hpp>
29#include <unordered_set>
33#include <wx/tokenzr.h>
74#include <google/protobuf/any.pb.h>
75#include <api/board/board_types.pb.h>
175 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
180 if( field->IsMandatory() )
182 PCB_FIELD* existingField = GetField( field->GetId() );
183 ptrMap[field] = existingField;
184 *existingField = *field;
185 existingField->SetParent( this );
189 PCB_FIELD* newField = static_cast<PCB_FIELD*>( field->Clone() );
190 ptrMap[field] = newField;
196 for(
PAD*
pad : aFootprint.Pads() )
198 PAD* newPad = static_cast<PAD*>( pad->Clone() );
199 ptrMap[ pad ] = newPad;
200 Add( newPad, ADD_MODE::APPEND );
204 for(
ZONE* zone : aFootprint.Zones() )
206 ZONE* newZone = static_cast<ZONE*>( zone->Clone() );
207 ptrMap[ zone ] = newZone;
208 Add( newZone, ADD_MODE::APPEND );
214 newZone->SetNetCode( -1 );
218 for(
BOARD_ITEM* item : aFootprint.GraphicalItems() )
220 BOARD_ITEM* newItem = static_cast<BOARD_ITEM*>( item->Clone() );
221 ptrMap[ item ] = newItem;
222 Add( newItem, ADD_MODE::APPEND );
228 PCB_GROUP* newGroup = static_cast<PCB_GROUP*>( group->Clone() );
229 ptrMap[ group ] = newGroup;
230 Add( newGroup, ADD_MODE::APPEND );
238 for(
PCB_POINT* point : aFootprint.Points() )
240 PCB_POINT* newPoint = static_cast<PCB_POINT*>( point->Clone() );
241 ptrMap[ point ] = newPoint;
242 Add( newPoint, ADD_MODE::APPEND );
248 PCB_GROUP* newGroup = static_cast<PCB_GROUP*>( ptrMap[ group ] );
250 newGroup->GetItems().clear();
252 for( EDA_ITEM* member : group->GetItems() )
254 if( ptrMap.count( member ) )
255 newGroup->AddItem( ptrMap[ member ] );
269 *
this = std::move( aFootprint );
314 board->IncrementTimeStamp();
321 types::FootprintInstance footprint;
323 footprint.mutable_id()->set_value(
m_Uuid.AsStdString() );
324 footprint.mutable_position()->set_x_nm(
GetPosition().x );
325 footprint.mutable_position()->set_y_nm(
GetPosition().y );
328 footprint.set_locked(
IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
329 : kiapi::common::types::LockedState::LS_UNLOCKED );
331 google::protobuf::Any buf;
333 buf.UnpackTo( footprint.mutable_reference_field() );
335 buf.UnpackTo( footprint.mutable_value_field() );
337 buf.UnpackTo( footprint.mutable_datasheet_field() );
339 buf.UnpackTo( footprint.mutable_description_field() );
341 types::FootprintAttributes* attrs = footprint.mutable_attributes();
347 attrs->set_do_not_populate(
IsDNP() );
351 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_THROUGH_HOLE );
353 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_SMD );
355 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_UNSPECIFIED );
357 types::Footprint* def = footprint.mutable_definition();
362 def->mutable_attributes()->set_keywords(
GetKeywords().ToUTF8() );
366 types::FootprintDesignRuleOverrides* overrides = footprint.mutable_overrides();
380 overrides->set_zone_connection(
385 types::NetTieDefinition* netTie = def->add_net_ties();
386 wxStringTokenizer tokenizer(
group,
", \t\r\n", wxTOKEN_STRTOK );
388 while( tokenizer.HasMoreTokens() )
389 netTie->add_pad_number( tokenizer.GetNextToken().ToUTF8() );
395 types::JumperSettings* jumpers = def->mutable_jumpers();
400 types::JumperGroup* jumperGroup = jumpers->add_groups();
402 for(
const wxString& padName :
group )
403 jumperGroup->add_pad_names( padName.ToUTF8() );
408 if( item->IsMandatory() )
411 google::protobuf::Any* itemMsg = def->add_items();
412 item->Serialize( *itemMsg );
415 for(
const PAD* item :
Pads() )
417 google::protobuf::Any* itemMsg = def->add_items();
418 item->Serialize( *itemMsg );
423 google::protobuf::Any* itemMsg = def->add_items();
424 item->Serialize( *itemMsg );
429 google::protobuf::Any* itemMsg = def->add_items();
430 item->Serialize( *itemMsg );
435 google::protobuf::Any* itemMsg = def->add_items();
436 types::Footprint3DModel modelMsg;
437 modelMsg.set_filename(
model.m_Filename.ToUTF8() );
441 modelMsg.set_visible(
model.m_Show );
442 modelMsg.set_opacity(
model.m_Opacity );
443 itemMsg->PackFrom( modelMsg );
448 footprint.set_symbol_sheet_name(
m_sheetname.ToUTF8() );
449 footprint.set_symbol_sheet_filename(
m_sheetfile.ToUTF8() );
450 footprint.set_symbol_footprint_filters(
m_filters.ToUTF8() );
452 aContainer.PackFrom( footprint );
459 types::FootprintInstance footprint;
461 if( !aContainer.UnpackTo( &footprint ) )
468 SetLocked( footprint.locked() == kiapi::common::types::LockedState::LS_LOCKED );
470 google::protobuf::Any buf;
471 types::Field mandatoryField;
473 if( footprint.has_reference_field() )
475 mandatoryField = footprint.reference_field();
477 buf.PackFrom( mandatoryField );
481 if( footprint.has_value_field() )
483 mandatoryField = footprint.value_field();
485 buf.PackFrom( mandatoryField );
489 if( footprint.has_datasheet_field() )
491 mandatoryField = footprint.datasheet_field();
493 buf.PackFrom( mandatoryField );
497 if( footprint.has_description_field() )
499 mandatoryField = footprint.description_field();
501 buf.PackFrom( mandatoryField );
507 switch( footprint.attributes().mounting_style() )
509 case types::FootprintMountingStyle::FMS_THROUGH_HOLE:
513 case types::FootprintMountingStyle::FMS_SMD:
521 SetBoardOnly( footprint.attributes().not_in_schematic() );
525 SetDNP( footprint.attributes().do_not_populate() );
532 SetKeywords( footprint.definition().attributes().keywords() );
534 const types::FootprintDesignRuleOverrides& overrides = footprint.overrides();
536 if( overrides.has_copper_clearance() )
541 if( overrides.has_solder_mask() && overrides.solder_mask().has_solder_mask_margin() )
546 if( overrides.has_solder_paste() )
548 const types::SolderPasteOverrides& pasteSettings = overrides.solder_paste();
550 if( pasteSettings.has_solder_paste_margin() )
555 if( pasteSettings.has_solder_paste_margin_ratio() )
565 for(
const types::NetTieDefinition& netTieMsg : footprint.definition().net_ties() )
569 for(
const std::string&
pad : netTieMsg.pad_number() )
570 group.Append( wxString::Format( wxT(
"%s, " ),
pad ) );
579 for(
const types::JumperGroup& groupMsg : footprint.definition().jumpers().groups() )
581 std::set<wxString>
group;
583 for(
const std::string& padName : groupMsg.pad_names() )
584 group.insert( wxString::FromUTF8( padName ) );
592 for(
int layerMsg : footprint.definition().private_layers() )
597 privateLayers.
set( layer );
603 m_sheetname = wxString::FromUTF8( footprint.symbol_sheet_name() );
604 m_sheetfile = wxString::FromUTF8( footprint.symbol_sheet_filename() );
605 m_filters = wxString::FromUTF8( footprint.symbol_footprint_filters() );
610 if( !field->IsMandatory() )
616 board->UncacheChildrenById(
this );
626 for(
const google::protobuf::Any& itemMsg : footprint.definition().items() )
634 if( itemMsg.type_url() ==
"type.googleapis.com/kiapi.board.types.Footprint3DModel" )
636 types::Footprint3DModel modelMsg;
638 if( !itemMsg.UnpackTo( &modelMsg ) )
643 model.m_Filename = wxString::FromUTF8( modelMsg.filename() );
644 model.m_Show = modelMsg.visible();
645 model.m_Opacity = modelMsg.opacity();
654 wxLogTrace(
traceApi, wxString::Format( wxS(
"Attempting to unpack unknown type %s "
655 "from footprint message, skipping" ),
656 itemMsg.type_url() ) );
664 if( item && item->Deserialize( itemMsg ) )
676 if( field->GetId() == aFieldType )
691 if( field->GetId() == aFieldType )
701 return GetField( aFieldName ) !=
nullptr;
709 if( field->GetName() == aFieldName )
725 if( !field->IsVisible() || field->GetText().IsEmpty() )
729 aVector.push_back( field );
732 std::sort( aVector.begin(), aVector.end(),
735 return lhs->GetOrdinal() < rhs->GetOrdinal();
745 ordinal = std::max( ordinal, field->GetOrdinal() + 1 );
752 bool aStyleShapes,
bool aStyleDimensions,
bool aStyleBarcodes )
757 field->StyleFromSettings(
board.GetDesignSettings(),
true );
762 switch( item->Type() )
767 item->StyleFromSettings(
board.GetDesignSettings(),
true );
772 if( aStyleShapes && !item->IsOnCopperLayer() )
773 item->StyleFromSettings(
board.GetDesignSettings(),
true );
782 if( aStyleDimensions )
783 item->StyleFromSettings(
board.GetDesignSettings(),
true );
789 item->StyleFromSettings(
board.GetDesignSettings(),
true );
802 std::vector< BOARD_ITEM* > item_list;
805 item_list.push_back( field );
808 item_list.push_back(
pad );
811 item_list.push_back( gr_item );
816 item_list.push_back(
group );
820 item_list.push_back( zone );
824 item_list.push_back( point );
826 bool changed =
false;
832 item->ResetUuidDirect();
869 board->UncacheChildrenById(
this );
877 for(
PCB_FIELD* field : aOther.m_fields )
880 aOther.m_fields.clear();
888 for(
PAD*
pad : aOther.Pads() )
891 aOther.Pads().clear();
899 for(
ZONE* item : aOther.Zones() )
907 item->SetNetCode( -1 );
910 aOther.Zones().clear();
918 for(
BOARD_ITEM* item : aOther.GraphicalItems() )
921 aOther.GraphicalItems().clear();
932 aOther.Groups().clear();
943 aOther.Constraints().clear();
951 for(
PCB_POINT* point : aOther.Points() )
954 aOther.Points().clear();
968 aOther.m_componentClassCacheProxy->GetStaticComponentClass() );
971 aOther.m_fields.clear();
972 aOther.Pads().clear();
973 aOther.Zones().clear();
974 aOther.GraphicalItems().clear();
975 aOther.m_initial_comments =
nullptr;
1009 board->UncacheChildrenById(
this );
1011 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
1022 ptrMap[field] = newField;
1035 ptrMap[
pad ] = newPad;
1047 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
1048 ptrMap[ zone ] = newZone;
1067 ptrMap[ item ] = newItem;
1083 newGroup->
AddItem( ptrMap[ member ] );
1107 ptrMap[ point ] = newItem;
1138 *
this = *
static_cast<const FOOTPRINT*
>( aOther );
1165 aVars->push_back( wxT(
"REFERENCE" ) );
1166 aVars->push_back( wxT(
"VALUE" ) );
1167 aVars->push_back( wxT(
"LAYER" ) );
1168 aVars->push_back( wxT(
"FOOTPRINT_LIBRARY" ) );
1169 aVars->push_back( wxT(
"FOOTPRINT_NAME" ) );
1170 aVars->push_back( wxT(
"SHORT_NET_NAME(<pad_number>)" ) );
1171 aVars->push_back( wxT(
"NET_NAME(<pad_number>)" ) );
1172 aVars->push_back( wxT(
"NET_CLASS(<pad_number>)" ) );
1173 aVars->push_back( wxT(
"PIN_NAME(<pad_number>)" ) );
1182 if( token->IsSameAs( wxT(
"REFERENCE" ) ) )
1187 else if( token->IsSameAs( wxT(
"VALUE" ) ) )
1192 else if( token->IsSameAs( wxT(
"LAYER" ) ) )
1197 else if( token->IsSameAs( wxT(
"FOOTPRINT_LIBRARY" ) ) )
1199 *token =
m_fpid.GetUniStringLibNickname();
1202 else if( token->IsSameAs( wxT(
"FOOTPRINT_NAME" ) ) )
1204 *token =
m_fpid.GetUniStringLibItemName();
1207 else if( token->StartsWith( wxT(
"SHORT_NET_NAME(" ) )
1208 || token->StartsWith( wxT(
"NET_NAME(" ) )
1209 || token->StartsWith( wxT(
"NET_CLASS(" ) )
1210 || token->StartsWith( wxT(
"PIN_NAME(" ) ) )
1212 wxString padNumber = token->AfterFirst(
'(' );
1213 padNumber = padNumber.BeforeLast(
')' );
1217 if(
pad->GetNumber() == padNumber )
1219 if( token->StartsWith( wxT(
"SHORT_NET_NAME" ) ) )
1220 *token =
pad->GetShortNetname();
1221 else if( token->StartsWith( wxT(
"NET_NAME" ) ) )
1222 *token =
pad->GetNetname();
1223 else if( token->StartsWith( wxT(
"NET_CLASS" ) ) )
1224 *token =
pad->GetNetClassName();
1226 *token =
pad->GetPinFunction();
1234 *token = field->GetShownText(
false, aDepth + 1 );
1253 return it !=
m_variants.end() ? &it->second :
nullptr;
1261 return it !=
m_variants.end() ? &it->second :
nullptr;
1267 if( aVariant.
GetName().IsEmpty()
1279 it->second = std::move( updated );
1289 if( aVariantName.IsEmpty()
1292 wxASSERT_MSG(
false, wxT(
"Variant name cannot be empty or default." ) );
1306 auto inserted =
m_variants.emplace( aVariantName, std::move( variant ) );
1307 return &inserted.first->second;
1319 if( aNewName.IsEmpty()
1330 auto existingIt =
m_variants.find( aNewName );
1332 if( existingIt !=
m_variants.end() && existingIt != it )
1335 if( it->first == aNewName )
1341 m_variants.emplace( aNewName, std::move( variant ) );
1360 return variant->
GetDNP();
1412 return field->GetText();
1436 switch( aBoardItem->
Type() )
1462 m_pads.push_back(
static_cast<PAD*
>( aBoardItem ) );
1464 m_pads.push_front(
static_cast<PAD*
>( aBoardItem ) );
1470 m_zones.push_back(
static_cast<ZONE*
>( aBoardItem ) );
1493 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Markers go at the board level, even in the footprint editor" ) );
1497 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Nested footprints not supported" ) );
1509 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Add(): BOARD_ITEM type (%d) not handled" ),
1510 aBoardItem->
Type() ) );
1521 board->CacheItemSubtreeById( aBoardItem );
1529 switch( aBoardItem->
Type() )
1534 if( *it == aBoardItem )
1556 if( *it == aBoardItem )
1566 for(
auto it =
m_pads.begin(); it !=
m_pads.end(); ++it )
1568 if( *it ==
static_cast<PAD*
>( aBoardItem ) )
1580 if( *it ==
static_cast<ZONE*
>( aBoardItem ) )
1604 if( *it ==
static_cast<PCB_GROUP*
>( aBoardItem ) )
1614 wxFAIL_MSG( wxT(
"FOOTPRINT::Remove(): Markers go at the board level, even in the footprint editor" ) );
1618 wxFAIL_MSG( wxT(
"FOOTPRINT::Remove(): Nested footprints not supported" ) );
1624 if( *it ==
static_cast<PCB_POINT*
>( aBoardItem ) )
1634 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
1635 aBoardItem->
Type() ) );
1640 board->UncacheItemSubtreeById( aBoardItem );
1665 switch(
pad->GetProperty() )
1683 switch(
pad->GetAttribute() )
1690 if(
pad->IsOnCopperLayer() )
1718 return _(
"Through hole" );
1720 return _(
"Other" );
1733 wxStringTokenizer keywordTokenizer(
GetKeywords(), wxS(
" \t\r\n" ), wxTOKEN_STRTOK );
1735 while( keywordTokenizer.HasMoreTokens() )
1756 if(
dummy.IsFlipped() )
1760 bbox.
Merge(
pad->GetBoundingBox() );
1812 std::vector<PCB_TEXT*> texts;
1813 bool isFPEdit =
board &&
board->IsFootprintHolder();
1834 texts.push_back(
static_cast<PCB_TEXT*
>( item ) );
1852 bbox.
Merge( item->GetBoundingBox() );
1858 if( field->IsReference() || field->IsValue() )
1861 texts.push_back( field );
1865 bbox.
Merge(
pad->GetBoundingBox() );
1868 bbox.
Merge( zone->GetBoundingBox() );
1871 bbox.
Merge( point->GetBoundingBox() );
1876 if( aIncludeText || noDrawItems )
1893 bool valueLayerIsVisible =
true;
1894 bool refLayerIsVisible =
true;
1912 if( (
Value().IsVisible() && valueLayerIsVisible ) || noDrawItems )
1917 if( (
Reference().IsVisible() && refLayerIsVisible ) || noDrawItems )
1930 if( aIncludeText || noDrawItems )
1948 std::vector<PCB_TEXT*> texts;
1950 bool isFPEdit =
board &&
board->IsFootprintHolder();
1960 if( ( aLayers & item->GetLayerSet() ).none() )
1968 bbox.
Merge( item->GetBoundingBox() );
1973 if( ( aLayers &
pad->GetLayerSet() ).none() )
1976 bbox.
Merge(
pad->GetBoundingBox() );
1981 if( ( aLayers & zone->GetLayerSet() ).none() )
1984 bbox.
Merge( zone->GetBoundingBox() );
1992 if( ( aLayers & point->GetLayerSet() ).none() )
1995 bbox.
Merge( point->GetBoundingBox() );
2005 bool isFPEdit =
board &&
board->IsFootprintHolder();
2031 pad->Padstack().ForEachUniqueLayer(
2045 const SHAPE_POLY_SET& layerPoly = *zone->GetFilledPolysList( layer );
2061 const int halfsize =
pcbIUScale.mmToIU( 1.0 );
2072 std::vector<VECTOR2I> convex_hull;
2081 for(
const VECTOR2I& pt : convex_hull )
2094 bool isFPEdit =
board &&
board->IsFootprintHolder();
2104 if( item->IsOnLayer( aLayer ) )
2118 if(
pad->IsOnLayer( aLayer ) )
2124 if( zone->GetIsRuleArea() )
2127 if( zone->IsOnLayer( aLayer ) )
2129 const std::shared_ptr<SHAPE_POLY_SET>& layerPoly = zone->GetFilledPolysList( aLayer );
2131 for(
int ii = 0; ii < layerPoly->OutlineCount(); ii++ )
2132 rawPolys.
AddOutline( layerPoly->COutline( ii ) );
2136 std::vector<VECTOR2I> convex_hull;
2141 for(
const VECTOR2I& pt : convex_hull )
2154 variant =
board->GetCurrentVariant();
2168 aList.emplace_back(
_(
"Footprint Name" ),
GetFPID().GetLibItemName().wx_str() );
2170 aList.emplace_back(
_(
"Pads" ), wxString::Format( wxT(
"%zu" ), padCount ) );
2173 wxString::Format(
_(
"Keywords: %s" ),
GetKeywords() ) );
2182 case F_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Front" ) );
break;
2183 case B_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Back (Flipped)" ) );
break;
2187 aList.emplace_back(
_(
"Rotation" ), wxString::Format( wxT(
"%.4g" ),
GetOrientation().AsDegrees() ) );
2189 auto addToken = []( wxString* aStr,
const wxString& aAttr )
2191 if( !aStr->IsEmpty() )
2192 *aStr += wxT(
", " );
2201 addToken( &status,
_(
"Locked" ) );
2204 addToken( &status,
_(
"autoplaced" ) );
2207 addToken( &attrs,
_(
"not in schematic" ) );
2210 addToken( &attrs,
_(
"exclude from pos files" ) );
2213 addToken( &attrs,
_(
"exclude from BOM" ) );
2216 addToken( &attrs,
_(
"DNP" ) );
2218 aList.emplace_back(
_(
"Status: " ) + status,
_(
"Attributes:" ) + wxS(
" " ) + attrs );
2222 aList.emplace_back(
_(
"Component Class" ),
2226 msg.Printf(
_(
"Footprint: %s" ),
m_fpid.GetUniStringLibId() );
2228 aList.emplace_back( msg, msg2 );
2232 aList.emplace_back( msg, msg2 );
2240 if(
board->IsFootprintHolder() )
2272 if(
pad->IsOnLayer( aLayer ) )
2278 if( zone->IsOnLayer( aLayer ) )
2284 if( field->IsOnLayer( aLayer ) )
2290 if( item->IsOnLayer( aLayer ) )
2302 if(
pad->IsOnLayer( aLayer ) &&
pad->HitTest( aPosition, aAccuracy ) )
2308 if( zone->IsOnLayer( aLayer ) && zone->HitTest( aPosition, aAccuracy ) )
2314 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer )
2315 && item->HitTest( aPosition, aAccuracy ) )
2327 std::vector<BOARD_ITEM*> items;
2331 if(
pad->IsOnLayer( aLayer ) )
2332 items.push_back(
pad );
2337 if( zone->IsOnLayer( aLayer ) )
2338 items.push_back( zone );
2343 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer ) )
2344 items.push_back( item );
2353 if( !aContained && item->HitTest( aRect, aContained, aAccuracy ) )
2355 else if( aContained && !item->HitTest( aRect, aContained, aAccuracy ) )
2362 return !items.empty() && aContained;
2381 BOX2I arect = aRect;
2401 if(
pad->HitTest( arect,
false, 0 ) )
2407 if( zone->HitTest( arect,
false, 0 ) )
2413 if( point->HitTest( arect,
false, 0 ) )
2424 if( item->Type() !=
PCB_TEXT_T && item->HitTest( arect,
false, 0 ) )
2438 using std::ranges::all_of;
2439 using std::ranges::any_of;
2446 [&](
const auto* aItem )
2448 return aItem && aItem->HitTest( aPoly, aContained );
2454 auto drawings =
m_drawings | std::views::filter( [](
const auto* aItem )
2465 return all_of( drawings, hitTest )
2466 && all_of(
m_pads, hitTest )
2467 && all_of(
m_zones, hitTest );
2472 return any_of( drawings, hitTest )
2473 || any_of(
m_pads, hitTest )
2474 || any_of(
m_zones, hitTest );
2481 bool can_select = aSearchAfterMe ? false :
true;
2485 if( !can_select &&
pad == aSearchAfterMe )
2491 if( can_select &&
pad->GetNumber() == aPadNumber )
2503 if(
pad->m_Uuid == aUuid )
2516 if( !(
pad->GetLayerSet() & aLayerMask ).any() )
2519 if(
pad->HitTest( aPosition ) )
2529 std::vector<const PAD*> retv;
2533 if( ( aIgnore && aIgnore ==
pad ) || (
pad->GetNumber() != aPadNumber ) )
2536 retv.push_back(
pad );
2564 std::set<wxString> usedNumbers;
2576 if(
pad->GetNumber().IsEmpty() )
2586 usedNumbers.insert(
pad->GetNumber() );
2607 auto isElectricalPadNumber = [](
const wxString& num ) ->
bool
2614 while( i < num.size() && wxIsalpha( num[i] ) )
2622 if( i == num.size() )
2625 for(
size_t j = i; j < num.size(); ++j )
2627 if( !wxIsdigit( num[j] ) )
2634 std::set<wxString> counted;
2646 const wxString& num =
pad->GetNumber();
2648 if( isElectricalPadNumber( num ) )
2649 counted.insert( num );
2652 return static_cast<unsigned>( counted.size() );
2658 if(
nullptr == a3DModel )
2701 const std::vector<KICAD_T>& aScanTypes )
2703#if 0 && defined(DEBUG)
2704 std::cout <<
GetClass().mb_str() <<
' ';
2707 bool drawingsScanned =
false;
2709 for(
KICAD_T scanType : aScanTypes )
2757 if( !drawingsScanned )
2765 drawingsScanned =
true;
2810 if( reference.IsEmpty() )
2811 reference =
_(
"<no reference designator>" );
2813 return wxString::Format(
_(
"Footprint %s" ), reference );
2819 return wxString::Format( wxT(
"%s (%s)" ),
2854 aFunction( constraint );
2861 aFunction( drawing );
2867 catch( std::bad_function_call& )
2869 wxFAIL_MSG( wxT(
"Error running FOOTPRINT::RunOnChildren" ) );
2876 std::vector<int> layers;
2878 layers.reserve( 6 );
2884 wxASSERT_MSG(
false, wxT(
"Illegal layer" ) );
2901 bool f_silk =
false, b_silk =
false, non_silk =
false;
2905 if( item->GetLayer() ==
F_SilkS )
2907 else if( item->GetLayer() ==
B_SilkS )
2913 if( ( f_silk || b_silk ) && !non_silk &&
m_pads.empty() )
2950 constexpr double MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY = 1.5;
2953 return MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY;
2966 int biggest_clearance =
board->GetMaxClearanceValue();
2967 area.
Inflate( biggest_clearance );
2978 if( aName.find_first_of( invalids ) != std::string::npos )
2990 static const wxChar invalidCharsReadable[] = wxT(
"% $ < > 'tab' 'return' 'line feed' \\ \" / :");
2993 return invalidCharsReadable;
2995 return invalidChars.wc_str();
3001 if( aMoveVector.
x == 0 && aMoveVector.
y == 0 )
3015 EDA_ANGLE newOrientation = orientation + aAngle;
3022 field->KeepUpright();
3027 static_cast<PCB_TEXT*
>( item )->KeepUpright();
3034 wxASSERT( aLayer ==
F_Cu || aLayer ==
B_Cu );
3089 field->OnFootprintTransformed();
3092 pad->OnFootprintTransformed();
3095 zone->OnFootprintTransformed();
3103 item->OnFootprintTransformed();
3108 point->OnFootprintTransformed();
3149 if( !std::isfinite( aScaleX ) || !std::isfinite( aScaleY ) || aScaleX <= 0.0 || aScaleY <= 0.0 )
3154 const double ratioX = aScaleX / oldSx;
3155 const double ratioY = aScaleY / oldSy;
3156 const double linearFactor = ( aScaleX + aScaleY ) / ( oldSx + oldSy );
3164 pad->OnFootprintRescaled( ratioX, ratioY, linearFactor,
anchor, parentRotate );
3167 field->OnFootprintRescaled( ratioX, ratioY, linearFactor,
anchor, parentRotate );
3170 item->OnFootprintRescaled( ratioX, ratioY, linearFactor,
anchor, parentRotate );
3173 zone->OnFootprintRescaled( ratioX, ratioY, linearFactor,
anchor, parentRotate );
3176 point->OnFootprintTransformed();
3204 field->OnFootprintTransformed();
3207 pad->OnFootprintTransformed();
3210 zone->OnFootprintTransformed();
3213 point->OnFootprintTransformed();
3221 item->OnFootprintTransformed();
3225 item->Move(
delta );
3265 field->Move( moveVector );
3269 pad->Move( moveVector );
3273 item->Move( moveVector );
3277 zone->Move( moveVector );
3281 point->Move( moveVector );
3320 field->OnFootprintTransformed();
3323 pad->OnFootprintTransformed();
3326 zone->OnFootprintTransformed();
3329 point->OnFootprintTransformed();
3337 item->OnFootprintTransformed();
3341 item->Rotate( rotationCenter, angleChange );
3368 std::map<KIID, KIID> idMap;
3375 idMap[oldId] = child->
m_Uuid;
3380 constraint->RemapKIIDs( idMap );
3387 const BOARD_ITEM* aItem,
bool addToFootprint )
3391 switch( aItem->
Type() )
3395 PAD* new_pad =
new PAD( *
static_cast<const PAD*
>( aItem ) );
3398 if( addToFootprint )
3399 m_pads.push_back( new_pad );
3407 ZONE* new_zone =
new ZONE( *
static_cast<const ZONE*
>( aItem ) );
3410 if( addToFootprint )
3411 m_zones.push_back( new_zone );
3413 new_item = new_zone;
3422 if( addToFootprint )
3425 new_item = new_point;
3437 switch(
static_cast<const PCB_FIELD*
>( aItem )->GetId() )
3446 if( addToFootprint )
3449 new_item = new_text;
3458 if( addToFootprint )
3461 new_item = new_shape;
3470 if( addToFootprint )
3473 new_item = new_barcode;
3482 if( addToFootprint )
3485 new_item = new_image;
3494 if( addToFootprint )
3497 new_item = new_textbox;
3510 if( addToFootprint )
3513 new_item = dimension;
3521 if( addToFootprint )
3523 group->RunOnChildren(
3543 wxFAIL_MSG( wxT(
"Duplication not supported for items of class " ) + aItem->
GetClass() );
3553 std::set<wxString> usedNumbers;
3557 usedNumbers.insert(
pad->GetNumber() );
3564 while( usedNumbers.count( wxString::Format( wxT(
"%s%d" ), prefix, num ) ) )
3567 return wxString::Format( wxT(
"%s%d" ), prefix, num );
3575 if(
group.contains( aPadNumber ) )
3579 return std::nullopt;
3630 for(
int jj = 0; jj < aPolySet.
HoleCount( ii ); jj++ )
3634 return aPolySet.
Area();
3649 return markerShape.
Area();
3653 double combinedArea = 0.0;
3658 return combinedArea;
3709 double width =
static_cast<const PCB_TRACK*
>( aItem )->GetWidth();
3710 return width * width;
3714 static_cast<const PAD*
>( aItem )->Padstack().ForEachUniqueLayer(
3724 const ZONE* zone =
static_cast<const ZONE*
>( aItem );
3774 for(
int i = 0; i < aCollector.
GetCount(); ++i )
3778 switch( item->
Type() )
3810 double footprintRegionArea =
polygonArea( footprintRegion );
3811 double uncoveredRegionArea = footprintRegionArea -
polygonArea( coveredRegion );
3812 double coveredArea = footprintRegionArea - uncoveredRegionArea;
3815 if( footprintRegionArea == 0 )
3818 double ratio = coveredArea / footprintRegionArea;
3825 return std::min( ratio, 1.0 );
3831 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
3852 shape->AddShape(
pad->GetEffectiveShape( aLayer, aFlash )->Clone() );
3857 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3859 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3906 std::vector<PCB_SHAPE*> list_front;
3907 std::vector<PCB_SHAPE*> list_back;
3908 std::map<int, int> front_width_histogram;
3909 std::map<int, int> back_width_histogram;
3916 list_back.push_back( shape );
3923 list_front.push_back( shape );
3928 if( !list_front.size() && !list_back.size() )
3932 int chainingEpsilon =
pcbIUScale.mmToIU( 0.02 );
3935 true, aErrorHandler ) )
3945 auto max = std::max_element( front_width_histogram.begin(), front_width_histogram.end(),
3946 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3948 return a.second < b.second;
3951 if( max != front_width_histogram.end() )
3974 auto max = std::max_element( back_width_histogram.begin(), back_width_histogram.end(),
3975 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3977 return a.second < b.second;
3980 if( max != back_width_histogram.end() )
4003 std::map<PCB_LAYER_ID, std::vector<PCB_SHAPE*>> layer_shapes;
4009 if( item->Type() != PCB_SHAPE_T )
4012 for( PCB_LAYER_ID layer : item->GetLayerSet() )
4014 if( !IsCopperLayer( layer ) )
4017 if( board && !board->GetEnabledLayers().Contains( layer ) )
4020 layer_shapes[layer].push_back( static_cast<PCB_SHAPE*>( item ) );
4024 for(
size_t ii = 0; ii < m_pads.size(); ++ii )
4027 bool has_nettie =
false;
4029 auto it = map.find(
pad->GetNumber() );
4031 if( it == map.end() || it->second < 0 )
4034 for(
size_t jj = 0; jj < m_pads.size(); ++jj )
4039 PAD* other = m_pads[ jj ];
4041 auto it2 = map.find( other->
GetNumber() );
4043 if( it2 == map.end() || it2->second < 0 )
4046 if( it2->second == it->second )
4048 m_netTieCache[
pad].insert(
pad->GetNetCode() );
4050 m_netTieCache[other].insert( other->
GetNetCode() );
4051 m_netTieCache[other].insert(
pad->GetNetCode() );
4059 for(
auto& [ layer, shapes ] : layer_shapes )
4061 auto pad_shape =
pad->GetEffectiveShape( layer );
4063 for(
auto other_shape : shapes )
4065 auto shape = other_shape->GetEffectiveShape( layer );
4067 if( pad_shape->Collide( shape.get() ) )
4069 std::set<int>& nettie = m_netTieCache[
pad];
4070 m_netTieCache[other_shape].insert( nettie.begin(), nettie.end() );
4080 std::map<wxString, int> padNumberToGroupIdxMap;
4083 padNumberToGroupIdxMap[
pad->GetNumber() ] = -1;
4086 [&]( wxString aPad,
int aGroup )
4088 aPad.Trim(
true ).Trim(
false );
4090 if( !aPad.IsEmpty() )
4091 padNumberToGroupIdxMap[ aPad ] = aGroup;
4100 for( wxUniCharRef ch :
group )
4109 switch(
static_cast<unsigned char>( ch ) )
4116 processPad(
pad, ii );
4126 processPad(
pad, ii );
4129 return padNumberToGroupIdxMap;
4139 int groupIdx = padToNetTieGroupMap[ aPad->
GetNumber() ];
4140 std::vector<PAD*> otherPads;
4146 if( padToNetTieGroupMap[
pad->GetNumber() ] == groupIdx )
4147 otherPads.push_back(
pad );
4160 if( setAttr && likelyAttr && setAttr != likelyAttr )
4164 switch( likelyAttr )
4167 msg.Printf(
_(
"(expected 'Through hole'; actual '%s')" ),
GetTypeName() );
4170 msg.Printf(
_(
"(expected 'SMD'; actual '%s')" ),
GetTypeName() );
4175 (aErrorHandler)( msg );
4181 const std::function<
void(
const PAD*,
int,
4182 const wxString& )>& aErrorHandler )
4184 if( aErrorHandler ==
nullptr )
4189 pad->CheckPad( aUnitsProvider,
false,
4190 [&](
int errorCode,
const wxString& msg )
4192 aErrorHandler(
pad, errorCode, msg );
4200 const VECTOR2I& )>& aErrorHandler )
4202 std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
4217 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
4220 if( checkedPairs.find( { a, b } ) == checkedPairs.end() )
4222 checkedPairs[ { a, b } ] = 1;
4234 std::shared_ptr<SHAPE_SEGMENT> holeA =
pad->GetEffectiveHoleShape();
4237 if( holeA->Collide( holeB->GetSeg(), 0 ) )
4254 SHAPE* padShape =
pad->GetEffectiveShape( l ).get();
4257 if( padShape->
Collide( otherShape, 0,
nullptr, &pos ) )
4270 const VECTOR2I& )>& aErrorHandler )
4279 std::vector<BOARD_ITEM*> copperItems;
4283 if( item->IsOnCopperLayer() )
4284 copperItems.push_back( item );
4286 item->RunOnChildren(
4290 copperItems.push_back( descendent );
4297 if( !zone->GetIsRuleArea() && zone->IsOnCopperLayer() )
4298 copperItems.push_back( zone );
4303 if( field->IsOnCopperLayer() )
4304 copperItems.push_back( field );
4314 std::map<int, std::vector<const PAD*>> outlineIdxToPadsMap;
4318 if( item->IsOnLayer( layer ) )
4328 for(
int ii = 0; ii < copperOutlines.
OutlineCount(); ++ii )
4330 if(
pad->GetEffectiveShape( layer )->Collide( &copperOutlines.
Outline( ii ), 0 ) )
4331 outlineIdxToPadsMap[ ii ].emplace_back(
pad );
4338 for(
const auto& [ outlineIdx, pads ] : outlineIdxToPadsMap )
4340 if( pads.size() > 1 )
4342 const PAD* firstPad = pads[0];
4343 int firstGroupIdx = padNumberToGroupIdxMap[ firstPad->
GetNumber() ];
4345 for(
size_t ii = 1; ii < pads.size(); ++ii )
4347 const PAD* thisPad = pads[ii];
4348 int thisGroupIdx = padNumberToGroupIdxMap[ thisPad->
GetNumber() ];
4350 if( thisGroupIdx < 0 || thisGroupIdx != firstGroupIdx )
4359 if( item->HitTest( pos, 1 ) )
4361 shortingItem = item;
4367 aErrorHandler( shortingItem, firstPad, thisPad, pos );
4369 aErrorHandler( firstPad, thisPad,
nullptr, pos );
4380 std::set<wxString> padNumbers;
4389 msg.Printf(
_(
"(net-tie pad group contains unknown pad number %s)" ), padNumber );
4390 aErrorHandler( msg );
4392 else if( !padNumbers.insert(
pad->GetNumber() ).second )
4394 msg.Printf(
_(
"(pad %s appears in more than one net-tie pad group)" ), padNumber );
4395 aErrorHandler( msg );
4403 const VECTOR2I& aPt )>& aErrorHandler )
4405 auto checkColliding =
4420 if( itemShape->Collide( otherShape.get(), 0, &
actual, &pos ) )
4421 aErrorHandler( item, other, pos );
4430 checkColliding( item, other );
4434 checkColliding( item,
pad );
4445 std::swap( *
this, *
image );
4454 image->RunOnChildren(
4482 return *
this == other;
4491 for(
size_t ii = 0; ii <
m_pads.size(); ++ii )
4500 for(
size_t ii = 0; ii <
m_drawings.size(); ++ii )
4509 for(
size_t ii = 0; ii <
m_zones.size(); ++ii )
4519 std::vector<PCB_FIELD*> fields, otherFields;
4524 if( fields.size() != otherFields.size() )
4527 for(
size_t ii = 0; ii < fields.size(); ++ii )
4531 if( !( *fields[ii] == *otherFields[ii] ) )
4547 double similarity = 1.0;
4556 similarity *=
pad->Similarity( *otherPad );
4568 if( aPtA.
x != aPtB.
x )
4569 return aPtA.
x < aPtB.
x;
4571 if( aPtA.
y != aPtB.
y )
4572 return aPtA.
y < aPtB.
y;
4574 return std::nullopt;
4580 if( itemA->
Type() != itemB->
Type() )
4581 return itemA->
Type() < itemB->
Type();
4586 switch( itemA->
Type() )
4708 return itemA < itemB;
4720 std::optional<bool> padCopperMatches;
4723 const PAD* checkPad = aFirst;
4736 padCopperMatches = aFirst->
GetSize( aLayer ).
x < aSecond->
GetSize( aLayer ).
x;
4738 padCopperMatches = aFirst->
GetSize( aLayer ).
y < aSecond->
GetSize( aLayer ).
y;
4740 padCopperMatches = aFirst->
GetShape( aLayer ) < aSecond->
GetShape( aLayer );
4743 if( padCopperMatches.has_value() )
4744 return *padCopperMatches;
4752 return aFirst < aSecond;
4757bool FOOTPRINT::cmp_padstack::operator()(
const PAD* aFirst,
const PAD* aSecond )
const
4797 if( firstShape->VertexCount() != secondShape->VertexCount() )
4798 return firstShape->VertexCount() < secondShape->VertexCount();
4800 for(
int ii = 0; ii < firstShape->VertexCount(); ++ii )
4802 if( std::optional<bool> cmp =
cmp_points_opt( firstShape->CVertex( ii ), secondShape->CVertex( ii ) ) )
4836 return aFirst < aSecond;
4841 int aMaxError,
ERROR_LOC aErrorLoc )
const
4852 clearance.x +=
pad->GetSolderMaskExpansion( padLayer );
4853 clearance.y +=
pad->GetSolderMaskExpansion( padLayer );
4876 if( dummySize.
x <= 0 || dummySize.
y <= 0 )
4880 dummy.SetSize( padLayer, dummySize );
4881 dummy.TransformShapeToPolygon( aBuffer, padLayer, 0, aMaxError, aErrorLoc );
4885 pad->TransformShapeToPolygon( aBuffer, padLayer,
clearance.x, aMaxError, aErrorLoc );
4891 if( !
pad->FlashLayer( aLayer ) )
4896 pad->Padstack().ForEachUniqueLayer(
4899 processPad(
pad, l );
4904 processPad(
pad, aLayer );
4911 int aError,
ERROR_LOC aErrorLoc,
bool aIncludeText,
4912 bool aIncludeShapes,
bool aIncludePrivateItems )
const
4919 if( item->Type() ==
PCB_TEXT_T && aIncludeText )
4924 text->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4935 textbox->PCB_SHAPE::TransformShapeToPolygon( aBuffer, aLayer, 0, aError, aErrorLoc );
4942 if( item->Type() ==
PCB_SHAPE_T && aIncludeShapes )
4963 if( ( aLayer ==
UNDEFINED_LAYER || field->GetLayer() == aLayer ) && field->IsVisible() )
4964 field->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4974 std::set<KIFONT::OUTLINE_FONT*>
fonts;
4988 if( permission == PERMISSION::EDITABLE || permission == PERMISSION::INSTALLABLE )
4989 fonts.insert( outlineFont );
4995 processItem( item );
4998 processItem( field );
5043 return wxEmptyString;
5048 const std::unordered_set<wxString>& aComponentClassNames )
5097 LSET padLayers =
pad->GetLayerSet();
5098 padLayers |= boardCopper;
5099 pad->SetLayerSet( padLayers );
5111 if( zcMap.
Choices().GetCount() == 0 )
5123 if( layerEnum.
Choices().GetCount() == 0 )
5131 wxPGChoices fpLayers;
5142 auto isNotFootprintHolder =
5148 return !
board->IsFootprintHolder();
5155 layer->SetChoices( fpLayers );
5156 layer->SetAvailableFunc( isNotFootprintHolder );
5172 const wxString groupFields =
_HKI(
"Fields" );
5178 const wxString propertyFields =
_HKI(
"Footprint Properties" );
5196 const wxString groupAttributes =
_HKI(
"Attributes" );
5210 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)
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)
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
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.
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
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
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.
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayer) const
int GetCopperLayerCount() 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)
Gets an effective component class for the given constituent class names.
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)
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.
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.
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 & 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.
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
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,...
bool HasDrilledHole() const override
std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const override
Return a SHAPE_SEGMENT object representing the pad's hole.
A geometric constraint between board items (issue #2329).
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
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.
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
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
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
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...
EDA_ANGLE GetTextAngle() const override
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 & 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.
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
SHAPE_POLY_SET * Outline()
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
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the zone shape to a closed polygon Used in filling zones calculations Circles and arcs are ap...
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:
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)
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 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 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 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)
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.
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".
wxString GetCanonicalFieldName(FIELD_T aFieldType)
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
class PCB_CONSTRAINT, 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_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