29#include <magic_enum.hpp>
32#include <unordered_set>
36#include <wx/tokenzr.h>
75#include <google/protobuf/any.pb.h>
76#include <api/board/board_types.pb.h>
173 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
181 ptrMap[field] = existingField;
182 *existingField = *field;
188 ptrMap[field] = newField;
196 PAD* newPad =
static_cast<PAD*
>(
pad->Clone() );
197 ptrMap[
pad ] = newPad;
204 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
205 ptrMap[ zone ] = newZone;
219 ptrMap[ item ] = newItem;
227 ptrMap[
group ] = newGroup;
234 ptrMap[ point ] = newPoint;
247 if( ptrMap.count( member ) )
248 newGroup->
AddItem( ptrMap[ member ] );
261 *
this = std::move( aFootprint );
301 board->IncrementTimeStamp();
308 types::FootprintInstance footprint;
310 footprint.mutable_id()->set_value(
m_Uuid.AsStdString() );
311 footprint.mutable_position()->set_x_nm(
GetPosition().x );
312 footprint.mutable_position()->set_y_nm(
GetPosition().y );
315 footprint.set_locked(
IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
316 : kiapi::common::types::LockedState::LS_UNLOCKED );
318 google::protobuf::Any buf;
320 buf.UnpackTo( footprint.mutable_reference_field() );
322 buf.UnpackTo( footprint.mutable_value_field() );
324 buf.UnpackTo( footprint.mutable_datasheet_field() );
326 buf.UnpackTo( footprint.mutable_description_field() );
328 types::FootprintAttributes* attrs = footprint.mutable_attributes();
334 attrs->set_do_not_populate(
IsDNP() );
338 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_THROUGH_HOLE );
340 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_SMD );
342 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_UNSPECIFIED );
344 types::Footprint* def = footprint.mutable_definition();
349 def->mutable_attributes()->set_keywords(
GetKeywords().ToUTF8() );
353 types::FootprintDesignRuleOverrides* overrides = footprint.mutable_overrides();
367 overrides->set_zone_connection(
372 types::NetTieDefinition* netTie = def->add_net_ties();
373 wxStringTokenizer tokenizer(
group,
", \t\r\n", wxTOKEN_STRTOK );
375 while( tokenizer.HasMoreTokens() )
376 netTie->add_pad_number( tokenizer.GetNextToken().ToUTF8() );
382 types::JumperSettings* jumpers = def->mutable_jumpers();
387 types::JumperGroup* jumperGroup = jumpers->add_groups();
389 for(
const wxString& padName :
group )
390 jumperGroup->add_pad_names( padName.ToUTF8() );
395 if( item->IsMandatory() )
398 google::protobuf::Any* itemMsg = def->add_items();
399 item->Serialize( *itemMsg );
402 for(
const PAD* item :
Pads() )
404 google::protobuf::Any* itemMsg = def->add_items();
405 item->Serialize( *itemMsg );
410 google::protobuf::Any* itemMsg = def->add_items();
411 item->Serialize( *itemMsg );
416 google::protobuf::Any* itemMsg = def->add_items();
417 item->Serialize( *itemMsg );
422 google::protobuf::Any* itemMsg = def->add_items();
423 types::Footprint3DModel modelMsg;
424 modelMsg.set_filename(
model.m_Filename.ToUTF8() );
428 modelMsg.set_visible(
model.m_Show );
429 modelMsg.set_opacity(
model.m_Opacity );
430 itemMsg->PackFrom( modelMsg );
435 footprint.set_symbol_sheet_name(
m_sheetname.ToUTF8() );
436 footprint.set_symbol_sheet_filename(
m_sheetfile.ToUTF8() );
437 footprint.set_symbol_footprint_filters(
m_filters.ToUTF8() );
439 aContainer.PackFrom( footprint );
446 types::FootprintInstance footprint;
448 if( !aContainer.UnpackTo( &footprint ) )
455 SetLocked( footprint.locked() == kiapi::common::types::LockedState::LS_LOCKED );
457 google::protobuf::Any buf;
458 types::Field mandatoryField;
460 if( footprint.has_reference_field() )
462 mandatoryField = footprint.reference_field();
464 buf.PackFrom( mandatoryField );
468 if( footprint.has_value_field() )
470 mandatoryField = footprint.value_field();
472 buf.PackFrom( mandatoryField );
476 if( footprint.has_datasheet_field() )
478 mandatoryField = footprint.datasheet_field();
480 buf.PackFrom( mandatoryField );
484 if( footprint.has_description_field() )
486 mandatoryField = footprint.description_field();
488 buf.PackFrom( mandatoryField );
494 switch( footprint.attributes().mounting_style() )
496 case types::FootprintMountingStyle::FMS_THROUGH_HOLE:
500 case types::FootprintMountingStyle::FMS_SMD:
508 SetBoardOnly( footprint.attributes().not_in_schematic() );
512 SetDNP( footprint.attributes().do_not_populate() );
519 SetKeywords( footprint.definition().attributes().keywords() );
521 const types::FootprintDesignRuleOverrides& overrides = footprint.overrides();
523 if( overrides.has_copper_clearance() )
528 if( overrides.has_solder_mask() && overrides.solder_mask().has_solder_mask_margin() )
533 if( overrides.has_solder_paste() )
535 const types::SolderPasteOverrides& pasteSettings = overrides.solder_paste();
537 if( pasteSettings.has_solder_paste_margin() )
542 if( pasteSettings.has_solder_paste_margin_ratio() )
552 for(
const types::NetTieDefinition& netTieMsg : footprint.definition().net_ties() )
556 for(
const std::string&
pad : netTieMsg.pad_number() )
557 group.Append( wxString::Format( wxT(
"%s, " ),
pad ) );
566 for(
const types::JumperGroup& groupMsg : footprint.definition().jumpers().groups() )
568 std::set<wxString>
group;
570 for(
const std::string& padName : groupMsg.pad_names() )
571 group.insert( wxString::FromUTF8( padName ) );
579 for(
int layerMsg : footprint.definition().private_layers() )
584 privateLayers.
set( layer );
590 m_sheetname = wxString::FromUTF8( footprint.symbol_sheet_name() );
591 m_sheetfile = wxString::FromUTF8( footprint.symbol_sheet_filename() );
592 m_filters = wxString::FromUTF8( footprint.symbol_footprint_filters() );
597 if( !field->IsMandatory() )
603 board->UncacheChildrenById(
this );
612 for(
const google::protobuf::Any& itemMsg : footprint.definition().items() )
620 if( itemMsg.type_url() ==
"type.googleapis.com/kiapi.board.types.Footprint3DModel" )
622 types::Footprint3DModel modelMsg;
624 if( !itemMsg.UnpackTo( &modelMsg ) )
629 model.m_Filename = wxString::FromUTF8( modelMsg.filename() );
630 model.m_Show = modelMsg.visible();
631 model.m_Opacity = modelMsg.opacity();
640 wxLogTrace(
traceApi, wxString::Format( wxS(
"Attempting to unpack unknown type %s "
641 "from footprint message, skipping" ),
642 itemMsg.type_url() ) );
650 if( item && item->Deserialize( itemMsg ) )
662 if( field->GetId() == aFieldType )
677 if( field->GetId() == aFieldType )
687 return GetField( aFieldName ) !=
nullptr;
695 if( field->GetName() == aFieldName )
711 if( !field->IsVisible() || field->GetText().IsEmpty() )
715 aVector.push_back( field );
718 std::sort( aVector.begin(), aVector.end(),
721 return lhs->GetOrdinal() < rhs->GetOrdinal();
731 ordinal = std::max( ordinal, field->GetOrdinal() + 1 );
738 bool aStyleShapes,
bool aStyleDimensions,
bool aStyleBarcodes )
743 field->StyleFromSettings(
board.GetDesignSettings(),
true );
748 switch( item->Type() )
753 item->StyleFromSettings(
board.GetDesignSettings(),
true );
758 if( aStyleShapes && !item->IsOnCopperLayer() )
759 item->StyleFromSettings(
board.GetDesignSettings(),
true );
768 if( aStyleDimensions )
769 item->StyleFromSettings(
board.GetDesignSettings(),
true );
775 item->StyleFromSettings(
board.GetDesignSettings(),
true );
788 std::vector< BOARD_ITEM* > item_list;
791 item_list.push_back( field );
794 item_list.push_back(
pad );
797 item_list.push_back( gr_item );
802 item_list.push_back(
group );
806 item_list.push_back( zone );
810 item_list.push_back( point );
812 bool changed =
false;
818 item->ResetUuidDirect();
834 m_pos = aOther.m_pos;
855 board->UncacheChildrenById(
this );
863 for(
PCB_FIELD* field : aOther.m_fields )
866 aOther.m_fields.clear();
874 for(
PAD*
pad : aOther.Pads() )
877 aOther.Pads().clear();
885 for(
ZONE* item : aOther.Zones() )
893 item->SetNetCode( -1 );
896 aOther.Zones().clear();
904 for(
BOARD_ITEM* item : aOther.GraphicalItems() )
907 aOther.GraphicalItems().clear();
918 aOther.Groups().clear();
926 for(
PCB_POINT* point : aOther.Points() )
929 aOther.Points().clear();
942 aOther.m_componentClassCacheProxy->GetStaticComponentClass() );
945 aOther.m_fields.clear();
946 aOther.Pads().clear();
947 aOther.Zones().clear();
948 aOther.GraphicalItems().clear();
949 aOther.m_initial_comments =
nullptr;
983 board->UncacheChildrenById(
this );
985 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
996 ptrMap[field] = newField;
1009 ptrMap[
pad ] = newPad;
1021 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
1022 ptrMap[ zone ] = newZone;
1041 ptrMap[ item ] = newItem;
1057 newGroup->
AddItem( ptrMap[ member ] );
1071 ptrMap[ point ] = newItem;
1096 *
this = *
static_cast<const FOOTPRINT*
>( aOther );
1123 aVars->push_back( wxT(
"REFERENCE" ) );
1124 aVars->push_back( wxT(
"VALUE" ) );
1125 aVars->push_back( wxT(
"LAYER" ) );
1126 aVars->push_back( wxT(
"FOOTPRINT_LIBRARY" ) );
1127 aVars->push_back( wxT(
"FOOTPRINT_NAME" ) );
1128 aVars->push_back( wxT(
"SHORT_NET_NAME(<pad_number>)" ) );
1129 aVars->push_back( wxT(
"NET_NAME(<pad_number>)" ) );
1130 aVars->push_back( wxT(
"NET_CLASS(<pad_number>)" ) );
1131 aVars->push_back( wxT(
"PIN_NAME(<pad_number>)" ) );
1140 if( token->IsSameAs( wxT(
"REFERENCE" ) ) )
1145 else if( token->IsSameAs( wxT(
"VALUE" ) ) )
1150 else if( token->IsSameAs( wxT(
"LAYER" ) ) )
1155 else if( token->IsSameAs( wxT(
"FOOTPRINT_LIBRARY" ) ) )
1157 *token =
m_fpid.GetUniStringLibNickname();
1160 else if( token->IsSameAs( wxT(
"FOOTPRINT_NAME" ) ) )
1162 *token =
m_fpid.GetUniStringLibItemName();
1165 else if( token->StartsWith( wxT(
"SHORT_NET_NAME(" ) )
1166 || token->StartsWith( wxT(
"NET_NAME(" ) )
1167 || token->StartsWith( wxT(
"NET_CLASS(" ) )
1168 || token->StartsWith( wxT(
"PIN_NAME(" ) ) )
1170 wxString padNumber = token->AfterFirst(
'(' );
1171 padNumber = padNumber.BeforeLast(
')' );
1175 if(
pad->GetNumber() == padNumber )
1177 if( token->StartsWith( wxT(
"SHORT_NET_NAME" ) ) )
1178 *token =
pad->GetShortNetname();
1179 else if( token->StartsWith( wxT(
"NET_NAME" ) ) )
1180 *token =
pad->GetNetname();
1181 else if( token->StartsWith( wxT(
"NET_CLASS" ) ) )
1182 *token =
pad->GetNetClassName();
1184 *token =
pad->GetPinFunction();
1192 *token = field->GetShownText(
false, aDepth + 1 );
1211 return it !=
m_variants.end() ? &it->second :
nullptr;
1219 return it !=
m_variants.end() ? &it->second :
nullptr;
1225 if( aVariant.
GetName().IsEmpty()
1237 it->second = std::move( updated );
1247 if( aVariantName.IsEmpty()
1250 wxASSERT_MSG(
false, wxT(
"Variant name cannot be empty or default." ) );
1264 auto inserted =
m_variants.emplace( aVariantName, std::move( variant ) );
1265 return &inserted.first->second;
1277 if( aNewName.IsEmpty()
1288 auto existingIt =
m_variants.find( aNewName );
1290 if( existingIt !=
m_variants.end() && existingIt != it )
1293 if( it->first == aNewName )
1299 m_variants.emplace( aNewName, std::move( variant ) );
1318 return variant->
GetDNP();
1370 return field->GetText();
1387 switch( aBoardItem->
Type() )
1413 m_pads.push_back(
static_cast<PAD*
>( aBoardItem ) );
1415 m_pads.push_front(
static_cast<PAD*
>( aBoardItem ) );
1421 m_zones.push_back(
static_cast<ZONE*
>( aBoardItem ) );
1436 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Markers go at the board level, even in the footprint editor" ) );
1440 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Nested footprints not supported" ) );
1452 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Add(): BOARD_ITEM type (%d) not handled" ),
1453 aBoardItem->
Type() ) );
1463 board->CacheItemSubtreeById( aBoardItem );
1471 switch( aBoardItem->
Type() )
1476 if( *it == aBoardItem )
1498 if( *it == aBoardItem )
1508 for(
auto it =
m_pads.begin(); it !=
m_pads.end(); ++it )
1510 if( *it ==
static_cast<PAD*
>( aBoardItem ) )
1522 if( *it ==
static_cast<ZONE*
>( aBoardItem ) )
1534 if( *it ==
static_cast<PCB_GROUP*
>( aBoardItem ) )
1546 if( *it ==
static_cast<PCB_POINT*
>( aBoardItem ) )
1558 msg.Printf( wxT(
"FOOTPRINT::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
1559 aBoardItem->
Type() );
1566 board->UncacheItemSubtreeById( aBoardItem );
1591 switch(
pad->GetProperty() )
1609 switch(
pad->GetAttribute() )
1616 if(
pad->IsOnCopperLayer() )
1644 return _(
"Through hole" );
1646 return _(
"Other" );
1659 wxStringTokenizer keywordTokenizer(
GetKeywords(), wxS(
" \t\r\n" ), wxTOKEN_STRTOK );
1661 while( keywordTokenizer.HasMoreTokens() )
1682 if(
dummy.IsFlipped() )
1686 bbox.
Merge(
pad->GetBoundingBox() );
1738 std::vector<PCB_TEXT*> texts;
1739 bool isFPEdit =
board &&
board->IsFootprintHolder();
1760 texts.push_back(
static_cast<PCB_TEXT*
>( item ) );
1778 bbox.
Merge( item->GetBoundingBox() );
1784 if( field->IsReference() || field->IsValue() )
1787 texts.push_back( field );
1791 bbox.
Merge(
pad->GetBoundingBox() );
1794 bbox.
Merge( zone->GetBoundingBox() );
1797 bbox.
Merge( point->GetBoundingBox() );
1802 if( aIncludeText || noDrawItems )
1819 bool valueLayerIsVisible =
true;
1820 bool refLayerIsVisible =
true;
1838 if( (
Value().IsVisible() && valueLayerIsVisible ) || noDrawItems )
1843 if( (
Reference().IsVisible() && refLayerIsVisible ) || noDrawItems )
1856 if( aIncludeText || noDrawItems )
1874 std::vector<PCB_TEXT*> texts;
1876 bool isFPEdit =
board &&
board->IsFootprintHolder();
1886 if( ( aLayers & item->GetLayerSet() ).none() )
1894 bbox.
Merge( item->GetBoundingBox() );
1899 if( ( aLayers &
pad->GetLayerSet() ).none() )
1902 bbox.
Merge(
pad->GetBoundingBox() );
1907 if( ( aLayers & zone->GetLayerSet() ).none() )
1910 bbox.
Merge( zone->GetBoundingBox() );
1918 if( ( aLayers & point->GetLayerSet() ).none() )
1921 bbox.
Merge( point->GetBoundingBox() );
1931 bool isFPEdit =
board &&
board->IsFootprintHolder();
1957 pad->Padstack().ForEachUniqueLayer(
1971 const SHAPE_POLY_SET& layerPoly = *zone->GetFilledPolysList( layer );
1987 const int halfsize =
pcbIUScale.mmToIU( 1.0 );
1998 std::vector<VECTOR2I> convex_hull;
2007 for(
const VECTOR2I& pt : convex_hull )
2020 bool isFPEdit =
board &&
board->IsFootprintHolder();
2030 if( item->IsOnLayer( aLayer ) )
2044 if(
pad->IsOnLayer( aLayer ) )
2050 if( zone->GetIsRuleArea() )
2053 if( zone->IsOnLayer( aLayer ) )
2055 const std::shared_ptr<SHAPE_POLY_SET>& layerPoly = zone->GetFilledPolysList( aLayer );
2057 for(
int ii = 0; ii < layerPoly->OutlineCount(); ii++ )
2058 rawPolys.
AddOutline( layerPoly->COutline( ii ) );
2062 std::vector<VECTOR2I> convex_hull;
2067 for(
const VECTOR2I& pt : convex_hull )
2080 variant =
board->GetCurrentVariant();
2094 aList.emplace_back(
_(
"Footprint Name" ),
GetFPID().GetLibItemName().wx_str() );
2096 aList.emplace_back(
_(
"Pads" ), wxString::Format( wxT(
"%zu" ), padCount ) );
2099 wxString::Format(
_(
"Keywords: %s" ),
GetKeywords() ) );
2108 case F_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Front" ) );
break;
2109 case B_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Back (Flipped)" ) );
break;
2113 aList.emplace_back(
_(
"Rotation" ), wxString::Format( wxT(
"%.4g" ),
GetOrientation().AsDegrees() ) );
2115 auto addToken = []( wxString* aStr,
const wxString& aAttr )
2117 if( !aStr->IsEmpty() )
2118 *aStr += wxT(
", " );
2127 addToken( &status,
_(
"Locked" ) );
2130 addToken( &status,
_(
"autoplaced" ) );
2133 addToken( &attrs,
_(
"not in schematic" ) );
2136 addToken( &attrs,
_(
"exclude from pos files" ) );
2139 addToken( &attrs,
_(
"exclude from BOM" ) );
2142 addToken( &attrs,
_(
"DNP" ) );
2144 aList.emplace_back(
_(
"Status: " ) + status,
_(
"Attributes:" ) + wxS(
" " ) + attrs );
2148 aList.emplace_back(
_(
"Component Class" ),
2152 msg.Printf(
_(
"Footprint: %s" ),
m_fpid.GetUniStringLibId() );
2154 aList.emplace_back( msg, msg2 );
2158 aList.emplace_back( msg, msg2 );
2166 if(
board->IsFootprintHolder() )
2198 if(
pad->IsOnLayer( aLayer ) )
2204 if( zone->IsOnLayer( aLayer ) )
2210 if( field->IsOnLayer( aLayer ) )
2216 if( item->IsOnLayer( aLayer ) )
2228 if(
pad->IsOnLayer( aLayer ) &&
pad->HitTest( aPosition, aAccuracy ) )
2234 if( zone->IsOnLayer( aLayer ) && zone->HitTest( aPosition, aAccuracy ) )
2240 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer )
2241 && item->HitTest( aPosition, aAccuracy ) )
2253 std::vector<BOARD_ITEM*> items;
2257 if(
pad->IsOnLayer( aLayer ) )
2258 items.push_back(
pad );
2263 if( zone->IsOnLayer( aLayer ) )
2264 items.push_back( zone );
2269 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer ) )
2270 items.push_back( item );
2279 if( !aContained && item->HitTest( aRect, aContained, aAccuracy ) )
2281 else if( aContained && !item->HitTest( aRect, aContained, aAccuracy ) )
2288 return !items.empty() && aContained;
2307 BOX2I arect = aRect;
2327 if(
pad->HitTest( arect,
false, 0 ) )
2333 if( zone->HitTest( arect,
false, 0 ) )
2339 if( point->HitTest( arect,
false, 0 ) )
2350 if( item->Type() !=
PCB_TEXT_T && item->HitTest( arect,
false, 0 ) )
2364 using std::ranges::all_of;
2365 using std::ranges::any_of;
2372 [&](
const auto* aItem )
2374 return aItem && aItem->HitTest( aPoly, aContained );
2380 auto drawings =
m_drawings | std::views::filter( [](
const auto* aItem )
2391 return all_of( drawings, hitTest )
2392 && all_of(
m_pads, hitTest )
2393 && all_of(
m_zones, hitTest );
2398 return any_of( drawings, hitTest )
2399 || any_of(
m_pads, hitTest )
2400 || any_of(
m_zones, hitTest );
2407 bool can_select = aSearchAfterMe ? false :
true;
2411 if( !can_select &&
pad == aSearchAfterMe )
2417 if( can_select &&
pad->GetNumber() == aPadNumber )
2430 if( !(
pad->GetLayerSet() & aLayerMask ).any() )
2433 if(
pad->HitTest( aPosition ) )
2443 std::vector<const PAD*> retv;
2447 if( ( aIgnore && aIgnore ==
pad ) || (
pad->GetNumber() != aPadNumber ) )
2450 retv.push_back(
pad );
2478 std::set<wxString> usedNumbers;
2490 if(
pad->GetNumber().IsEmpty() )
2500 usedNumbers.insert(
pad->GetNumber() );
2515 if(
nullptr == a3DModel )
2543 const std::vector<KICAD_T>& aScanTypes )
2545#if 0 && defined(DEBUG)
2546 std::cout <<
GetClass().mb_str() <<
' ';
2549 bool drawingsScanned =
false;
2551 for(
KICAD_T scanType : aScanTypes )
2599 if( !drawingsScanned )
2607 drawingsScanned =
true;
2643 if( reference.IsEmpty() )
2644 reference =
_(
"<no reference designator>" );
2646 return wxString::Format(
_(
"Footprint %s" ), reference );
2652 return wxString::Format( wxT(
"%s (%s)" ),
2691 aFunction( drawing );
2697 catch( std::bad_function_call& )
2699 wxFAIL_MSG( wxT(
"Error running FOOTPRINT::RunOnChildren" ) );
2706 std::vector<int> layers;
2708 layers.reserve( 6 );
2714 wxASSERT_MSG(
false, wxT(
"Illegal layer" ) );
2732 bool f_silk =
false, b_silk =
false, non_silk =
false;
2736 if( item->GetLayer() ==
F_SilkS )
2738 else if( item->GetLayer() ==
B_SilkS )
2744 if( ( f_silk || b_silk ) && !non_silk &&
m_pads.empty() )
2781 constexpr double MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY = 1.5;
2784 return MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY;
2797 int biggest_clearance =
board->GetMaxClearanceValue();
2798 area.
Inflate( biggest_clearance );
2809 if( aName.find_first_of( invalids ) != std::string::npos )
2823 static const wxChar invalidChars[] = wxT(
"%$<>\t\n\r\"\\/:");
2824 static const wxChar invalidCharsReadable[] = wxT(
"% $ < > 'tab' 'return' 'line feed' \\ \" / :");
2827 return invalidCharsReadable;
2829 return invalidChars;
2835 if( aMoveVector.
x == 0 && aMoveVector.
y == 0 )
2849 EDA_ANGLE newOrientation = orientation + aAngle;
2856 field->KeepUpright();
2861 static_cast<PCB_TEXT*
>( item )->KeepUpright();
2868 wxASSERT( aLayer ==
F_Cu || aLayer ==
B_Cu );
2954 field->EDA_TEXT::Offset(
delta );
2960 zone->Move(
delta );
2963 item->Move(
delta );
2966 point->Move(
delta );
3004 field->Move( moveVector );
3008 pad->Move( moveVector );
3012 item->Move( moveVector );
3016 zone->Move( moveVector );
3054 field->Rotate( rotationCenter, angleChange );
3057 pad->Rotate( rotationCenter, angleChange );
3060 zone->Rotate( rotationCenter, angleChange );
3063 item->Rotate( rotationCenter, angleChange );
3066 point->Rotate( rotationCenter, angleChange );
3100 const BOARD_ITEM* aItem,
bool addToFootprint )
3104 switch( aItem->
Type() )
3108 PAD* new_pad =
new PAD( *
static_cast<const PAD*
>( aItem ) );
3111 if( addToFootprint )
3112 m_pads.push_back( new_pad );
3120 ZONE* new_zone =
new ZONE( *
static_cast<const ZONE*
>( aItem ) );
3123 if( addToFootprint )
3124 m_zones.push_back( new_zone );
3126 new_item = new_zone;
3135 if( addToFootprint )
3138 new_item = new_point;
3150 switch(
static_cast<const PCB_FIELD*
>( aItem )->GetId() )
3159 if( addToFootprint )
3162 new_item = new_text;
3171 if( addToFootprint )
3174 new_item = new_shape;
3183 if( addToFootprint )
3186 new_item = new_barcode;
3195 if( addToFootprint )
3198 new_item = new_image;
3207 if( addToFootprint )
3210 new_item = new_textbox;
3223 if( addToFootprint )
3226 new_item = dimension;
3234 if( addToFootprint )
3236 group->RunOnChildren(
3256 wxFAIL_MSG( wxT(
"Duplication not supported for items of class " ) + aItem->
GetClass() );
3266 std::set<wxString> usedNumbers;
3270 usedNumbers.insert(
pad->GetNumber() );
3277 while( usedNumbers.count( wxString::Format( wxT(
"%s%d" ), prefix, num ) ) )
3280 return wxString::Format( wxT(
"%s%d" ), prefix, num );
3288 if(
group.contains( aPadNumber ) )
3292 return std::nullopt;
3343 for(
int jj = 0; jj < aPolySet.
HoleCount( ii ); jj++ )
3347 return aPolySet.
Area();
3362 return markerShape.
Area();
3366 double combinedArea = 0.0;
3371 return combinedArea;
3422 double width =
static_cast<const PCB_TRACK*
>( aItem )->GetWidth();
3423 return width * width;
3427 static_cast<const PAD*
>( aItem )->Padstack().ForEachUniqueLayer(
3459 for(
int i = 0; i < aCollector.
GetCount(); ++i )
3463 switch( item->
Type() )
3495 double footprintRegionArea =
polygonArea( footprintRegion );
3496 double uncoveredRegionArea = footprintRegionArea -
polygonArea( coveredRegion );
3497 double coveredArea = footprintRegionArea - uncoveredRegionArea;
3500 if( footprintRegionArea == 0 )
3503 double ratio = coveredArea / footprintRegionArea;
3510 return std::min( ratio, 1.0 );
3516 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
3537 shape->AddShape(
pad->GetEffectiveShape( aLayer, aFlash )->Clone() );
3542 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3544 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3591 std::vector<PCB_SHAPE*> list_front;
3592 std::vector<PCB_SHAPE*> list_back;
3593 std::map<int, int> front_width_histogram;
3594 std::map<int, int> back_width_histogram;
3601 list_back.push_back( shape );
3608 list_front.push_back( shape );
3613 if( !list_front.size() && !list_back.size() )
3617 int chainingEpsilon =
pcbIUScale.mmToIU( 0.02 );
3620 true, aErrorHandler ) )
3630 auto max = std::max_element( front_width_histogram.begin(), front_width_histogram.end(),
3631 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3633 return a.second < b.second;
3636 if( max != front_width_histogram.end() )
3659 auto max = std::max_element( back_width_histogram.begin(), back_width_histogram.end(),
3660 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3662 return a.second < b.second;
3665 if( max != back_width_histogram.end() )
3688 std::map<PCB_LAYER_ID, std::vector<PCB_SHAPE*>> layer_shapes;
3694 if( item->Type() != PCB_SHAPE_T )
3697 for( PCB_LAYER_ID layer : item->GetLayerSet() )
3699 if( !IsCopperLayer( layer ) )
3702 if( board && !board->GetEnabledLayers().Contains( layer ) )
3705 layer_shapes[layer].push_back( static_cast<PCB_SHAPE*>( item ) );
3709 for(
size_t ii = 0; ii < m_pads.size(); ++ii )
3712 bool has_nettie =
false;
3714 auto it = map.find(
pad->GetNumber() );
3716 if( it == map.end() || it->second < 0 )
3719 for(
size_t jj = ii + 1; jj < m_pads.size(); ++jj )
3721 PAD* other = m_pads[ jj ];
3723 auto it2 = map.find( other->
GetNumber() );
3725 if( it2 == map.end() || it2->second < 0 )
3728 if( it2->second == it->second )
3730 m_netTieCache[
pad].insert(
pad->GetNetCode() );
3732 m_netTieCache[other].insert( other->
GetNetCode() );
3733 m_netTieCache[other].insert(
pad->GetNetCode() );
3741 for(
auto& [ layer, shapes ] : layer_shapes )
3743 auto pad_shape =
pad->GetEffectiveShape( layer );
3745 for(
auto other_shape : shapes )
3747 auto shape = other_shape->GetEffectiveShape( layer );
3749 if( pad_shape->Collide( shape.get() ) )
3751 std::set<int>& nettie = m_netTieCache[
pad];
3752 m_netTieCache[other_shape].insert( nettie.begin(), nettie.end() );
3762 std::map<wxString, int> padNumberToGroupIdxMap;
3765 padNumberToGroupIdxMap[
pad->GetNumber() ] = -1;
3768 [&]( wxString aPad,
int aGroup )
3770 aPad.Trim(
true ).Trim(
false );
3772 if( !aPad.IsEmpty() )
3773 padNumberToGroupIdxMap[ aPad ] = aGroup;
3782 for( wxUniCharRef ch :
group )
3791 switch(
static_cast<unsigned char>( ch ) )
3798 processPad(
pad, ii );
3808 processPad(
pad, ii );
3811 return padNumberToGroupIdxMap;
3821 int groupIdx = padToNetTieGroupMap[ aPad->
GetNumber() ];
3822 std::vector<PAD*> otherPads;
3828 if( padToNetTieGroupMap[
pad->GetNumber() ] == groupIdx )
3829 otherPads.push_back(
pad );
3842 if( setAttr && likelyAttr && setAttr != likelyAttr )
3846 switch( likelyAttr )
3849 msg.Printf(
_(
"(expected 'Through hole'; actual '%s')" ),
GetTypeName() );
3852 msg.Printf(
_(
"(expected 'SMD'; actual '%s')" ),
GetTypeName() );
3857 (aErrorHandler)( msg );
3863 const std::function<
void(
const PAD*,
int,
3864 const wxString& )>& aErrorHandler )
3866 if( aErrorHandler ==
nullptr )
3871 pad->CheckPad( aUnitsProvider,
false,
3872 [&](
int errorCode,
const wxString& msg )
3874 aErrorHandler(
pad, errorCode, msg );
3882 const VECTOR2I& )>& aErrorHandler )
3884 std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
3899 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
3902 if( checkedPairs.find( { a, b } ) == checkedPairs.end() )
3904 checkedPairs[ { a, b } ] = 1;
3916 std::shared_ptr<SHAPE_SEGMENT> holeA =
pad->GetEffectiveHoleShape();
3919 if( holeA->Collide( holeB->GetSeg(), 0 ) )
3936 SHAPE* padShape =
pad->GetEffectiveShape( l ).get();
3939 if( padShape->
Collide( otherShape, 0,
nullptr, &pos ) )
3952 const VECTOR2I& )>& aErrorHandler )
3961 std::vector<BOARD_ITEM*> copperItems;
3965 if( item->IsOnCopperLayer() )
3966 copperItems.push_back( item );
3968 item->RunOnChildren(
3972 copperItems.push_back( descendent );
3979 if( !zone->GetIsRuleArea() && zone->IsOnCopperLayer() )
3980 copperItems.push_back( zone );
3985 if( field->IsOnCopperLayer() )
3986 copperItems.push_back( field );
3996 std::map<int, std::vector<const PAD*>> outlineIdxToPadsMap;
4000 if( item->IsOnLayer( layer ) )
4010 for(
int ii = 0; ii < copperOutlines.
OutlineCount(); ++ii )
4012 if(
pad->GetEffectiveShape( layer )->Collide( &copperOutlines.
Outline( ii ), 0 ) )
4013 outlineIdxToPadsMap[ ii ].emplace_back(
pad );
4020 for(
const auto& [ outlineIdx, pads ] : outlineIdxToPadsMap )
4022 if( pads.size() > 1 )
4024 const PAD* firstPad = pads[0];
4025 int firstGroupIdx = padNumberToGroupIdxMap[ firstPad->
GetNumber() ];
4027 for(
size_t ii = 1; ii < pads.size(); ++ii )
4029 const PAD* thisPad = pads[ii];
4030 int thisGroupIdx = padNumberToGroupIdxMap[ thisPad->
GetNumber() ];
4032 if( thisGroupIdx < 0 || thisGroupIdx != firstGroupIdx )
4041 if( item->HitTest( pos, 1 ) )
4043 shortingItem = item;
4049 aErrorHandler( shortingItem, firstPad, thisPad, pos );
4051 aErrorHandler( firstPad, thisPad,
nullptr, pos );
4062 std::set<wxString> padNumbers;
4071 msg.Printf(
_(
"(net-tie pad group contains unknown pad number %s)" ), padNumber );
4072 aErrorHandler( msg );
4074 else if( !padNumbers.insert(
pad->GetNumber() ).second )
4076 msg.Printf(
_(
"(pad %s appears in more than one net-tie pad group)" ), padNumber );
4077 aErrorHandler( msg );
4085 const VECTOR2I& aPt )>& aErrorHandler )
4087 auto checkColliding =
4102 if( itemShape->Collide( otherShape.get(), 0, &
actual, &pos ) )
4103 aErrorHandler( item, other, pos );
4112 checkColliding( item, other );
4116 checkColliding( item,
pad );
4127 std::swap( *
this, *
image );
4136 image->RunOnChildren(
4164 return *
this == other;
4173 for(
size_t ii = 0; ii <
m_pads.size(); ++ii )
4182 for(
size_t ii = 0; ii <
m_drawings.size(); ++ii )
4191 for(
size_t ii = 0; ii <
m_zones.size(); ++ii )
4201 std::vector<PCB_FIELD*> fields, otherFields;
4206 if( fields.size() != otherFields.size() )
4209 for(
size_t ii = 0; ii < fields.size(); ++ii )
4213 if( !( *fields[ii] == *otherFields[ii] ) )
4229 double similarity = 1.0;
4238 similarity *=
pad->Similarity( *otherPad );
4250 if( aPtA.
x != aPtB.
x )
4251 return aPtA.
x < aPtB.
x;
4253 if( aPtA.
y != aPtB.
y )
4254 return aPtA.
y < aPtB.
y;
4256 return std::nullopt;
4262 if( itemA->
Type() != itemB->
Type() )
4263 return itemA->
Type() < itemB->
Type();
4268 switch( itemA->
Type() )
4307 for(
int ii = 0; ii < dwgA->
GetPolyShape().TotalVertices(); ++ii )
4309 if( std::optional<bool> cmp =
4366 return itemA < itemB;
4378 std::optional<bool> padCopperMatches;
4381 const PAD* checkPad = aFirst;
4394 padCopperMatches = aFirst->
GetSize( aLayer ).
x < aSecond->
GetSize( aLayer ).
x;
4396 padCopperMatches = aFirst->
GetSize( aLayer ).
y < aSecond->
GetSize( aLayer ).
y;
4398 padCopperMatches = aFirst->
GetShape( aLayer ) < aSecond->
GetShape( aLayer );
4401 if( padCopperMatches.has_value() )
4402 return *padCopperMatches;
4410 return aFirst < aSecond;
4415bool FOOTPRINT::cmp_padstack::operator()(
const PAD* aFirst,
const PAD* aSecond )
const
4455 if( firstShape->VertexCount() != secondShape->VertexCount() )
4456 return firstShape->VertexCount() < secondShape->VertexCount();
4458 for(
int ii = 0; ii < firstShape->VertexCount(); ++ii )
4460 if( std::optional<bool> cmp =
cmp_points_opt( firstShape->CVertex( ii ), secondShape->CVertex( ii ) ) )
4482 for(
int ii = 0; ii < aFirst->
Outline()->TotalVertices(); ++ii )
4484 if( std::optional<bool> cmp =
4494 return aFirst < aSecond;
4499 int aMaxError,
ERROR_LOC aErrorLoc )
const
4510 clearance.x +=
pad->GetSolderMaskExpansion( padLayer );
4511 clearance.y +=
pad->GetSolderMaskExpansion( padLayer );
4534 if( dummySize.
x <= 0 || dummySize.
y <= 0 )
4538 dummy.SetSize( padLayer, dummySize );
4539 dummy.TransformShapeToPolygon( aBuffer, padLayer, 0, aMaxError, aErrorLoc );
4543 pad->TransformShapeToPolygon( aBuffer, padLayer,
clearance.x, aMaxError, aErrorLoc );
4549 if( !
pad->FlashLayer( aLayer ) )
4554 pad->Padstack().ForEachUniqueLayer(
4557 processPad(
pad, l );
4562 processPad(
pad, aLayer );
4569 int aError,
ERROR_LOC aErrorLoc,
bool aIncludeText,
4570 bool aIncludeShapes,
bool aIncludePrivateItems )
const
4577 if( item->Type() ==
PCB_TEXT_T && aIncludeText )
4582 text->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4593 textbox->PCB_SHAPE::TransformShapeToPolygon( aBuffer, aLayer, 0, aError, aErrorLoc );
4600 if( item->Type() ==
PCB_SHAPE_T && aIncludeShapes )
4621 if( ( aLayer ==
UNDEFINED_LAYER || field->GetLayer() == aLayer ) && field->IsVisible() )
4622 field->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4632 std::set<KIFONT::OUTLINE_FONT*>
fonts;
4646 if( permission == PERMISSION::EDITABLE || permission == PERMISSION::INSTALLABLE )
4647 fonts.insert( outlineFont );
4653 processItem( item );
4656 processItem( field );
4701 return wxEmptyString;
4706 const std::unordered_set<wxString>& aComponentClassNames )
4755 LSET padLayers =
pad->GetLayerSet();
4756 padLayers |= boardCopper;
4757 pad->SetLayerSet( padLayers );
4769 if( zcMap.
Choices().GetCount() == 0 )
4781 if( layerEnum.
Choices().GetCount() == 0 )
4789 wxPGChoices fpLayers;
4800 auto isNotFootprintHolder =
4806 return !
board->IsFootprintHolder();
4813 layer->SetChoices( fpLayers );
4814 layer->SetAvailableFunc( isNotFootprintHolder );
4822 const wxString groupFields =
_HKI(
"Fields" );
4828 const wxString propertyFields =
_HKI(
"Footprint Properties" );
4846 const wxString groupAttributes =
_HKI(
"Attributes" );
4860 const wxString groupOverrides =
_HKI(
"Overrides" );
types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
std::unique_ptr< EDA_ITEM > CreateItemForType(KICAD_T aType, EDA_ITEM *aContainer)
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
constexpr EDA_IU_SCALE pcbIUScale
constexpr int ARC_LOW_DEF
BITMAPS
A list of all bitmap identifiers.
#define DEFAULT_COURTYARD_WIDTH
BASE_SET & set(size_t pos)
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
Abstract interface for BOARD_ITEMs capable of storing other items inside.
BOARD_ITEM_CONTAINER(BOARD_ITEM *aParent, KICAD_T aType)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
BOARD_ITEM(BOARD_ITEM *aParent, KICAD_T idtype, PCB_LAYER_ID aLayer=F_Cu)
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
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.
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.
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)
const VECTOR2I & GetBezierC2() const
SHAPE_POLY_SET & GetPolyShape()
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
const VECTOR2I & GetBezierC1() const
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
const EDA_ANGLE & GetTextAngle() const
virtual const wxString & GetText() const
Return the string associated with the text object.
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
double GetLineSpacing() const
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
int GetTextThickness() const
VECTOR2I GetTextSize() const
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
EMBEDDED_FILES & operator=(EMBEDDED_FILES &&other) noexcept
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Load a file from disk and adds it to the collection.
const std::map< wxString, EMBEDDED_FILE * > & EmbeddedFileMap() const
bool m_embedFonts
If set, fonts will be embedded in the element on save.
ENUM_MAP & Map(T aValue, const wxString &aName)
static ENUM_MAP< T > & Instance()
ENUM_MAP & Undefined(T aValue)
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
const PADSTACK & Padstack() const
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
PAD_DRILL_SHAPE GetDrillShape() const
const std::shared_ptr< SHAPE_POLY_SET > & GetEffectivePolygon(PCB_LAYER_ID aLayer, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
std::optional< int > GetLocalSolderMaskMargin() const
VECTOR2I GetSolderPasteMargin(PCB_LAYER_ID aLayer) const
Usually < 0 (mask shape smaller than pad)because the margin can be dependent on the pad size,...
bool HasDrilledHole() const override
std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const override
Return a SHAPE_SEGMENT object representing the pad's hole.
const VECTOR2I & GetSize(PCB_LAYER_ID aLayer) const
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.
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
A set of BOARD_ITEMs (i.e., without duplicates).
A PCB_POINT is a 0-dimensional point that is used to mark a position on a PCB, or more usually a foot...
Object to handle a bitmap image that can be inserted in a PCB.
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
int GetWidth() const override
void TransformShapeToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, KIGFX::RENDER_SETTINGS *aRenderSettings=nullptr) const override
Convert the item shape to a polyset.
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the shape to a closed polygon.
STROKE_PARAMS GetStroke() const override
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
bool IsBorderEnabled() const
Disables the border, this is done by changing the stroke internally.
void TransformTextToPolySet(SHAPE_POLY_SET &aBuffer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc) const
Function TransformTextToPolySet Convert the text to a polygonSet describing the actual character stro...
virtual VECTOR2I GetPosition() const override
PROPERTY_BASE & SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Set a callback function to determine whether an object provides this property.
PROPERTY_BASE & SetIsHiddenFromLibraryEditors(bool aIsHidden=true)
Provide class metadata.Helper macro to map type hashes to names.
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
PROPERTY_BASE & ReplaceProperty(size_t aBase, const wxString &aName, PROPERTY_BASE *aNew, const wxString &aGroup=wxEmptyString)
Replace an existing property for a specific type.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
double Area(bool aAbsolute=true) const
Return the area of this chain.
const VECTOR2I NearestPoint(const VECTOR2I &aP, bool aAllowInternalShapePoints=true) const
Find a point on the line chain that is closest to point aP.
Represent a set of closed polygons.
void BooleanAdd(const SHAPE_POLY_SET &b)
Perform boolean polyset union.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
double Area()
Return the area of this poly set.
bool Collide(const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the shape aShape than aClearance,...
int TotalVertices() const
Return total number of vertices stored in the set.
int FullPointCount() const
Return the number of points in the shape poly set.
int HoleCount(int aOutline) const
Returns the number of holes in a given outline.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
void Simplify()
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the reference to aHole-th hole in the aIndex-th outline.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
void BooleanIntersection(const SHAPE_POLY_SET &b)
Perform boolean polyset intersection.
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the index-th vertex in a given hole outline within a given outline.
int OutlineCount() const
Return the number of outlines in the set.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
Represent a simple polygon consisting of a zero-thickness closed chain of connected line segments.
An abstract shape on 2D plane.
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
Handle a list of polygons defining a copper zone.
SHAPE_POLY_SET * Outline()
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
unsigned GetAssignedPriority() const
This file is part of the common library.
bool ConvertOutlineToPolygon(std::vector< PCB_SHAPE * > &aShapeList, SHAPE_POLY_SET &aPolygons, int aErrorMax, int aChainingEpsilon, bool aAllowDisjoint, OUTLINE_ERROR_HANDLER *aErrorHandler, bool aAllowUseArcsInPolygons)
Build a polygon set with holes from a PCB_SHAPE list.
const std::function< void(const wxString &msg, BOARD_ITEM *itemA, BOARD_ITEM *itemB, const VECTOR2I &pt)> OUTLINE_ERROR_HANDLER
void BuildConvexHull(std::vector< VECTOR2I > &aResult, const std::vector< VECTOR2I > &aPoly)
Calculate the convex hull of a list of points in counter-clockwise order.
@ CHAMFER_ACUTE_CORNERS
Acute angles are chamfered.
@ DRCE_DRILLED_HOLES_TOO_CLOSE
@ DRCE_DRILLED_HOLES_COLOCATED
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_180
const INSPECTOR_FUNC & INSPECTOR
std::function passed to nested users by ref, avoids copying std::function.
#define COURTYARD_CONFLICT
temporary set when moving footprints having courtyard overlapping
#define MALFORMED_F_COURTYARD
#define MALFORMED_B_COURTYARD
#define STRUCT_DELETED
flag indication structures to be erased
#define MALFORMED_COURTYARDS
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
@ FRAME_FOOTPRINT_CHOOSER
a few functions useful in geometry calculations.
const wxChar *const traceApi
Flag to enable debug output related to the IPC API and its plugin system.
Some functions to handle hotkeys in KiCad.
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
@ LAYER_CONFLICTS_SHADOW
Shadow layer for items flagged conflicting.
@ LAYER_FOOTPRINTS_FR
Show footprints on front.
@ LAYER_FP_REFERENCES
Show footprints references (when texts are visible).
@ LAYER_FOOTPRINTS_BK
Show footprints on back.
@ LAYER_ANCHOR
Anchor of items having an anchor point (texts, footprints).
@ LAYER_FP_VALUES
Show footprints values (when texts are visible).
PCB_LAYER_ID
A quick note on layer IDs:
bool IsValidLayer(int aLayerId)
Test whether a given integer is a valid layer index, i.e.
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 LIB_ID LibIdFromProto(const types::LibraryIdentifier &aId)
KICOMMON_API types::LibraryIdentifier LibIdToProto(const LIB_ID &aId)
KICOMMON_API void PackVector3D(types::Vector3D &aOutput, const VECTOR3D &aInput)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
@ SMD
Smd pad, appears on the solder paste layer (default)
@ PTH
Plated through hole pad.
@ FIDUCIAL_LOCAL
a fiducial (usually a smd) local to the parent footprint
@ FIDUCIAL_GLBL
a fiducial (usually a smd) for the full board
@ MECHANICAL
a pad used for mechanical support
@ PRESSFIT
a PTH with a hole diameter with tight tolerances for press fit pin
@ HEATSINK
a pad used as heat sink, usually in SMD footprints
@ NONE
no special fabrication property
@ TESTPOINT
a test point pad
@ CASTELLATED
a pad with a castellated through hole
@ BGA
Smd pad, used in BGA footprints.
BARCODE class definition.
Class to handle a set of BOARD_ITEMs.
#define NO_SETTER(owner, type)
@ PT_DEGREE
Angle expressed in degrees.
@ PT_SIZE
Size expressed in distance units (mm/inch)
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_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