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>
181 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
189 ptrMap[field] = existingField;
190 *existingField = *field;
196 ptrMap[field] = newField;
204 PAD* newPad =
static_cast<PAD*
>(
pad->Clone() );
205 ptrMap[
pad ] = newPad;
212 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
213 ptrMap[ zone ] = newZone;
227 ptrMap[ item ] = newItem;
235 ptrMap[
group ] = newGroup;
242 ptrMap[ point ] = newPoint;
255 if( ptrMap.count( member ) )
256 newGroup->
AddItem( ptrMap[ member ] );
269 *
this = std::move( aFootprint );
309 board->IncrementTimeStamp();
316 types::FootprintInstance footprint;
318 footprint.mutable_id()->set_value(
m_Uuid.AsStdString() );
319 footprint.mutable_position()->set_x_nm(
GetPosition().x );
320 footprint.mutable_position()->set_y_nm(
GetPosition().y );
323 footprint.set_locked(
IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
324 : kiapi::common::types::LockedState::LS_UNLOCKED );
326 google::protobuf::Any buf;
328 buf.UnpackTo( footprint.mutable_reference_field() );
330 buf.UnpackTo( footprint.mutable_value_field() );
332 buf.UnpackTo( footprint.mutable_datasheet_field() );
334 buf.UnpackTo( footprint.mutable_description_field() );
336 types::FootprintAttributes* attrs = footprint.mutable_attributes();
342 attrs->set_do_not_populate(
IsDNP() );
346 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_THROUGH_HOLE );
348 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_SMD );
350 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_UNSPECIFIED );
352 types::Footprint* def = footprint.mutable_definition();
357 def->mutable_attributes()->set_keywords(
GetKeywords().ToStdString() );
361 types::FootprintDesignRuleOverrides* overrides = footprint.mutable_overrides();
375 overrides->set_zone_connection(
380 types::NetTieDefinition* netTie = def->add_net_ties();
381 wxStringTokenizer tokenizer(
group,
", \t\r\n", wxTOKEN_STRTOK );
383 while( tokenizer.HasMoreTokens() )
384 netTie->add_pad_number( tokenizer.GetNextToken().ToStdString() );
392 if( item->IsMandatory() )
395 google::protobuf::Any* itemMsg = def->add_items();
396 item->Serialize( *itemMsg );
399 for(
const PAD* item :
Pads() )
401 google::protobuf::Any* itemMsg = def->add_items();
402 item->Serialize( *itemMsg );
407 google::protobuf::Any* itemMsg = def->add_items();
408 item->Serialize( *itemMsg );
413 google::protobuf::Any* itemMsg = def->add_items();
414 item->Serialize( *itemMsg );
419 google::protobuf::Any* itemMsg = def->add_items();
420 types::Footprint3DModel modelMsg;
421 modelMsg.set_filename(
model.m_Filename.ToUTF8() );
425 modelMsg.set_visible(
model.m_Show );
426 modelMsg.set_opacity(
model.m_Opacity );
427 itemMsg->PackFrom( modelMsg );
432 footprint.set_symbol_sheet_name(
m_sheetname.ToUTF8() );
433 footprint.set_symbol_sheet_filename(
m_sheetfile.ToUTF8() );
434 footprint.set_symbol_footprint_filters(
m_filters.ToUTF8() );
436 aContainer.PackFrom( footprint );
443 types::FootprintInstance footprint;
445 if( !aContainer.UnpackTo( &footprint ) )
452 SetLocked( footprint.locked() == kiapi::common::types::LockedState::LS_LOCKED );
454 google::protobuf::Any buf;
455 types::Field mandatoryField;
457 if( footprint.has_reference_field() )
459 mandatoryField = footprint.reference_field();
461 buf.PackFrom( mandatoryField );
465 if( footprint.has_value_field() )
467 mandatoryField = footprint.value_field();
469 buf.PackFrom( mandatoryField );
473 if( footprint.has_datasheet_field() )
475 mandatoryField = footprint.datasheet_field();
477 buf.PackFrom( mandatoryField );
481 if( footprint.has_description_field() )
483 mandatoryField = footprint.description_field();
485 buf.PackFrom( mandatoryField );
491 switch( footprint.attributes().mounting_style() )
493 case types::FootprintMountingStyle::FMS_THROUGH_HOLE:
497 case types::FootprintMountingStyle::FMS_SMD:
505 SetBoardOnly( footprint.attributes().not_in_schematic() );
509 SetDNP( footprint.attributes().do_not_populate() );
516 SetKeywords( footprint.definition().attributes().keywords() );
518 const types::FootprintDesignRuleOverrides& overrides = footprint.overrides();
520 if( overrides.has_copper_clearance() )
525 if( overrides.has_solder_mask() && overrides.solder_mask().has_solder_mask_margin() )
530 if( overrides.has_solder_paste() )
532 const types::SolderPasteOverrides& pasteSettings = overrides.solder_paste();
534 if( pasteSettings.has_solder_paste_margin() )
539 if( pasteSettings.has_solder_paste_margin_ratio() )
547 for(
const types::NetTieDefinition& netTieMsg : footprint.definition().net_ties() )
551 for(
const std::string&
pad : netTieMsg.pad_number() )
552 group.Append( wxString::Format( wxT(
"%s " ),
pad ) );
560 for(
int layerMsg : footprint.definition().private_layers() )
565 privateLayers.
set( layer );
571 m_sheetname = wxString::FromUTF8( footprint.symbol_sheet_name() );
572 m_sheetfile = wxString::FromUTF8( footprint.symbol_sheet_filename() );
573 m_filters = wxString::FromUTF8( footprint.symbol_footprint_filters() );
578 if( !field->IsMandatory() )
586 board->UncacheItemById(
pad->m_Uuid );
589 board->UncacheItemById( item->m_Uuid );
592 board->UncacheItemById( zone->m_Uuid );
598 board->UncacheItemById( point->m_Uuid );
608 for(
const google::protobuf::Any& itemMsg : footprint.definition().items() )
616 if( itemMsg.type_url() ==
"type.googleapis.com/kiapi.board.types.Footprint3DModel" )
618 types::Footprint3DModel modelMsg;
620 if( !itemMsg.UnpackTo( &modelMsg ) )
625 model.m_Filename = wxString::FromUTF8( modelMsg.filename() );
626 model.m_Show = modelMsg.visible();
627 model.m_Opacity = modelMsg.opacity();
636 wxLogTrace(
traceApi, wxString::Format( wxS(
"Attempting to unpack unknown type %s "
637 "from footprint message, skipping" ),
638 itemMsg.type_url() ) );
646 if( item && item->Deserialize( itemMsg ) )
658 if( field->GetId() == aFieldType )
673 if( field->GetId() == aFieldType )
683 return GetField( aFieldName ) !=
nullptr;
691 if( field->GetName() == aFieldName )
707 if( !field->IsVisible() || field->GetText().IsEmpty() )
711 aVector.push_back( field );
714 std::sort( aVector.begin(), aVector.end(),
717 return lhs->GetOrdinal() < rhs->GetOrdinal();
727 ordinal = std::max( ordinal, field->GetOrdinal() + 1 );
734 bool aStyleShapes,
bool aStyleDimensions,
bool aStyleBarcodes )
739 field->StyleFromSettings(
board.GetDesignSettings(),
true );
744 switch( item->Type() )
749 item->StyleFromSettings(
board.GetDesignSettings(),
true );
754 if( aStyleShapes && !item->IsOnCopperLayer() )
755 item->StyleFromSettings(
board.GetDesignSettings(),
true );
764 if( aStyleDimensions )
765 item->StyleFromSettings(
board.GetDesignSettings(),
true );
771 item->StyleFromSettings(
board.GetDesignSettings(),
true );
784 std::vector< BOARD_ITEM* > item_list;
787 item_list.push_back( field );
790 item_list.push_back(
pad );
793 item_list.push_back( gr_item );
798 item_list.push_back(
group );
802 item_list.push_back( zone );
806 item_list.push_back( point );
808 bool changed =
false;
814 const_cast<KIID&
>( item->m_Uuid ) =
KIID();
827 m_pos = aOther.m_pos;
857 board->UncacheItemById( field->m_Uuid );
860 board->UncacheItemById(
pad->m_Uuid );
863 board->UncacheItemById( zone->m_Uuid );
866 board->UncacheItemById( item->m_Uuid );
872 board->UncacheItemById( point->m_Uuid );
881 for(
PCB_FIELD* field : aOther.m_fields )
884 aOther.m_fields.clear();
892 for(
PAD*
pad : aOther.Pads() )
895 aOther.Pads().clear();
903 for(
ZONE* item : aOther.Zones() )
911 item->SetNetCode( -1 );
914 aOther.Zones().clear();
922 for(
BOARD_ITEM* item : aOther.GraphicalItems() )
925 aOther.GraphicalItems().clear();
936 aOther.Groups().clear();
944 for(
PCB_POINT* point : aOther.Points() )
947 aOther.Points().clear();
960 aOther.m_componentClassCacheProxy->GetStaticComponentClass() );
963 aOther.m_fields.clear();
964 aOther.Pads().clear();
965 aOther.Zones().clear();
966 aOther.GraphicalItems().clear();
967 aOther.m_initial_comments =
nullptr;
1007 board->UncacheItemById( field->m_Uuid );
1010 board->UncacheItemById(
pad->m_Uuid );
1013 board->UncacheItemById( zone->m_Uuid );
1016 board->UncacheItemById( item->m_Uuid );
1022 board->UncacheItemById( point->m_Uuid );
1025 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
1036 ptrMap[field] = newField;
1049 ptrMap[
pad ] = newPad;
1061 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
1062 ptrMap[ zone ] = newZone;
1081 ptrMap[ item ] = newItem;
1097 newGroup->
AddItem( ptrMap[ member ] );
1111 ptrMap[ point ] = newItem;
1136 *
this = *
static_cast<const FOOTPRINT*
>( aOther );
1162 aVars->push_back( wxT(
"REFERENCE" ) );
1163 aVars->push_back( wxT(
"VALUE" ) );
1164 aVars->push_back( wxT(
"LAYER" ) );
1165 aVars->push_back( wxT(
"FOOTPRINT_LIBRARY" ) );
1166 aVars->push_back( wxT(
"FOOTPRINT_NAME" ) );
1167 aVars->push_back( wxT(
"SHORT_NET_NAME(<pad_number>)" ) );
1168 aVars->push_back( wxT(
"NET_NAME(<pad_number>)" ) );
1169 aVars->push_back( wxT(
"NET_CLASS(<pad_number>)" ) );
1170 aVars->push_back( wxT(
"PIN_NAME(<pad_number>)" ) );
1179 if( token->IsSameAs( wxT(
"REFERENCE" ) ) )
1184 else if( token->IsSameAs( wxT(
"VALUE" ) ) )
1189 else if( token->IsSameAs( wxT(
"LAYER" ) ) )
1194 else if( token->IsSameAs( wxT(
"FOOTPRINT_LIBRARY" ) ) )
1196 *token =
m_fpid.GetUniStringLibNickname();
1199 else if( token->IsSameAs( wxT(
"FOOTPRINT_NAME" ) ) )
1201 *token =
m_fpid.GetUniStringLibItemName();
1204 else if( token->StartsWith( wxT(
"SHORT_NET_NAME(" ) )
1205 || token->StartsWith( wxT(
"NET_NAME(" ) )
1206 || token->StartsWith( wxT(
"NET_CLASS(" ) )
1207 || token->StartsWith( wxT(
"PIN_NAME(" ) ) )
1209 wxString padNumber = token->AfterFirst(
'(' );
1210 padNumber = padNumber.BeforeLast(
')' );
1214 if(
pad->GetNumber() == padNumber )
1216 if( token->StartsWith( wxT(
"SHORT_NET_NAME" ) ) )
1217 *token =
pad->GetShortNetname();
1218 else if( token->StartsWith( wxT(
"NET_NAME" ) ) )
1219 *token =
pad->GetNetname();
1220 else if( token->StartsWith( wxT(
"NET_CLASS" ) ) )
1221 *token =
pad->GetNetClassName();
1223 *token =
pad->GetPinFunction();
1231 *token = field->GetShownText(
false, aDepth + 1 );
1250 return it !=
m_variants.end() ? &it->second :
nullptr;
1258 return it !=
m_variants.end() ? &it->second :
nullptr;
1264 if( aVariant.
GetName().IsEmpty()
1276 it->second = std::move( updated );
1286 if( aVariantName.IsEmpty()
1289 wxASSERT_MSG(
false, wxT(
"Variant name cannot be empty or default." ) );
1303 auto inserted =
m_variants.emplace( aVariantName, std::move( variant ) );
1304 return &inserted.first->second;
1316 if( aNewName.IsEmpty()
1327 auto existingIt =
m_variants.find( aNewName );
1329 if( existingIt !=
m_variants.end() && existingIt != it )
1332 if( it->first == aNewName )
1338 m_variants.emplace( aNewName, std::move( variant ) );
1357 return variant->
GetDNP();
1409 return field->GetText();
1426 switch( aBoardItem->
Type() )
1452 m_pads.push_back(
static_cast<PAD*
>( aBoardItem ) );
1454 m_pads.push_front(
static_cast<PAD*
>( aBoardItem ) );
1460 m_zones.push_back(
static_cast<ZONE*
>( aBoardItem ) );
1475 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Markers go at the board level, even in the footprint editor" ) );
1479 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Nested footprints not supported" ) );
1491 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Add(): BOARD_ITEM type (%d) not handled" ),
1492 aBoardItem->
Type() ) );
1502 board->CacheItemById( aBoardItem );
1510 switch( aBoardItem->
Type() )
1515 if( *it == aBoardItem )
1537 if( *it == aBoardItem )
1547 for(
auto it =
m_pads.begin(); it !=
m_pads.end(); ++it )
1549 if( *it ==
static_cast<PAD*
>( aBoardItem ) )
1561 if( *it ==
static_cast<ZONE*
>( aBoardItem ) )
1573 if( *it ==
static_cast<PCB_GROUP*
>( aBoardItem ) )
1585 if( *it ==
static_cast<PCB_POINT*
>( aBoardItem ) )
1597 msg.Printf( wxT(
"FOOTPRINT::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
1598 aBoardItem->
Type() );
1630 switch(
pad->GetProperty() )
1648 switch(
pad->GetAttribute() )
1655 if(
pad->IsOnCopperLayer() )
1683 return _(
"Through hole" );
1685 return _(
"Other" );
1698 wxStringTokenizer keywordTokenizer(
GetKeywords(), wxS(
" \t\r\n" ), wxTOKEN_STRTOK );
1700 while( keywordTokenizer.HasMoreTokens() )
1721 if(
dummy.IsFlipped() )
1725 bbox.
Merge(
pad->GetBoundingBox() );
1774 std::vector<PCB_TEXT*> texts;
1775 bool isFPEdit =
board &&
board->IsFootprintHolder();
1796 texts.push_back(
static_cast<PCB_TEXT*
>( item ) );
1814 bbox.
Merge( item->GetBoundingBox() );
1820 if( field->IsReference() || field->IsValue() )
1823 texts.push_back( field );
1827 bbox.
Merge(
pad->GetBoundingBox() );
1830 bbox.
Merge( zone->GetBoundingBox() );
1833 bbox.
Merge( point->GetBoundingBox() );
1838 if( aIncludeText || noDrawItems )
1855 bool valueLayerIsVisible =
true;
1856 bool refLayerIsVisible =
true;
1874 if( (
Value().IsVisible() && valueLayerIsVisible ) || noDrawItems )
1879 if( (
Reference().IsVisible() && refLayerIsVisible ) || noDrawItems )
1889 if( aIncludeText || noDrawItems )
1907 std::vector<PCB_TEXT*> texts;
1909 bool isFPEdit =
board &&
board->IsFootprintHolder();
1919 if( ( aLayers & item->GetLayerSet() ).none() )
1927 bbox.
Merge( item->GetBoundingBox() );
1932 if( ( aLayers &
pad->GetLayerSet() ).none() )
1935 bbox.
Merge(
pad->GetBoundingBox() );
1940 if( ( aLayers & zone->GetLayerSet() ).none() )
1943 bbox.
Merge( zone->GetBoundingBox() );
1951 if( ( aLayers & point->GetLayerSet() ).none() )
1954 bbox.
Merge( point->GetBoundingBox() );
1964 bool isFPEdit =
board &&
board->IsFootprintHolder();
1990 pad->Padstack().ForEachUniqueLayer(
2004 const SHAPE_POLY_SET& layerPoly = *zone->GetFilledPolysList( layer );
2020 const int halfsize =
pcbIUScale.mmToIU( 1.0 );
2031 std::vector<VECTOR2I> convex_hull;
2037 for(
const VECTOR2I& pt : convex_hull )
2050 bool isFPEdit =
board &&
board->IsFootprintHolder();
2060 if( item->IsOnLayer( aLayer ) )
2074 if(
pad->IsOnLayer( aLayer ) )
2080 if( zone->GetIsRuleArea() )
2083 if( zone->IsOnLayer( aLayer ) )
2085 const std::shared_ptr<SHAPE_POLY_SET>& layerPoly = zone->GetFilledPolysList( aLayer );
2087 for(
int ii = 0; ii < layerPoly->OutlineCount(); ii++ )
2088 rawPolys.
AddOutline( layerPoly->COutline( ii ) );
2092 std::vector<VECTOR2I> convex_hull;
2097 for(
const VECTOR2I& pt : convex_hull )
2110 variant =
board->GetCurrentVariant();
2124 aList.emplace_back(
_(
"Footprint Name" ),
GetFPID().GetLibItemName().wx_str() );
2126 aList.emplace_back(
_(
"Pads" ), wxString::Format( wxT(
"%zu" ), padCount ) );
2129 wxString::Format(
_(
"Keywords: %s" ),
GetKeywords() ) );
2138 case F_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Front" ) );
break;
2139 case B_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Back (Flipped)" ) );
break;
2143 aList.emplace_back(
_(
"Rotation" ), wxString::Format( wxT(
"%.4g" ),
GetOrientation().AsDegrees() ) );
2145 auto addToken = []( wxString* aStr,
const wxString& aAttr )
2147 if( !aStr->IsEmpty() )
2148 *aStr += wxT(
", " );
2157 addToken( &status,
_(
"Locked" ) );
2160 addToken( &status,
_(
"autoplaced" ) );
2163 addToken( &attrs,
_(
"not in schematic" ) );
2166 addToken( &attrs,
_(
"exclude from pos files" ) );
2169 addToken( &attrs,
_(
"exclude from BOM" ) );
2172 addToken( &attrs,
_(
"DNP" ) );
2174 aList.emplace_back(
_(
"Status: " ) + status,
_(
"Attributes:" ) + wxS(
" " ) + attrs );
2178 aList.emplace_back(
_(
"Component Class" ),
2182 msg.Printf(
_(
"Footprint: %s" ),
m_fpid.GetUniStringLibId() );
2184 aList.emplace_back( msg, msg2 );
2188 aList.emplace_back( msg, msg2 );
2196 if(
board->IsFootprintHolder() )
2228 if(
pad->IsOnLayer( aLayer ) )
2234 if( zone->IsOnLayer( aLayer ) )
2240 if( field->IsOnLayer( aLayer ) )
2246 if( item->IsOnLayer( aLayer ) )
2258 if(
pad->IsOnLayer( aLayer ) &&
pad->HitTest( aPosition, aAccuracy ) )
2264 if( zone->IsOnLayer( aLayer ) && zone->HitTest( aPosition, aAccuracy ) )
2270 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer )
2271 && item->HitTest( aPosition, aAccuracy ) )
2283 std::vector<BOARD_ITEM*> items;
2287 if(
pad->IsOnLayer( aLayer ) )
2288 items.push_back(
pad );
2293 if( zone->IsOnLayer( aLayer ) )
2294 items.push_back( zone );
2299 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer ) )
2300 items.push_back( item );
2309 if( !aContained && item->HitTest( aRect, aContained, aAccuracy ) )
2311 else if( aContained && !item->HitTest( aRect, aContained, aAccuracy ) )
2318 return !items.empty() && aContained;
2337 BOX2I arect = aRect;
2357 if(
pad->HitTest( arect,
false, 0 ) )
2363 if( zone->HitTest( arect,
false, 0 ) )
2369 if( point->HitTest( arect,
false, 0 ) )
2380 if( item->Type() !=
PCB_TEXT_T && item->HitTest( arect,
false, 0 ) )
2394 using std::ranges::all_of;
2395 using std::ranges::any_of;
2402 [&](
const auto* aItem )
2404 return aItem && aItem->HitTest( aPoly, aContained );
2410 auto drawings =
m_drawings | std::views::filter( [](
const auto* aItem )
2421 return all_of( drawings, hitTest )
2422 && all_of(
m_pads, hitTest )
2423 && all_of(
m_zones, hitTest );
2428 return any_of( drawings, hitTest )
2429 || any_of(
m_pads, hitTest )
2430 || any_of(
m_zones, hitTest );
2437 bool can_select = aSearchAfterMe ? false :
true;
2441 if( !can_select &&
pad == aSearchAfterMe )
2447 if( can_select &&
pad->GetNumber() == aPadNumber )
2460 if( !(
pad->GetLayerSet() & aLayerMask ).any() )
2463 if(
pad->HitTest( aPosition ) )
2473 std::vector<const PAD*> retv;
2477 if( ( aIgnore && aIgnore ==
pad ) || (
pad->GetNumber() != aPadNumber ) )
2480 retv.push_back(
pad );
2508 std::set<wxString> usedNumbers;
2520 if(
pad->GetNumber().IsEmpty() )
2530 usedNumbers.insert(
pad->GetNumber() );
2545 if(
nullptr == a3DModel )
2573 const std::vector<KICAD_T>& aScanTypes )
2575#if 0 && defined(DEBUG)
2576 std::cout <<
GetClass().mb_str() <<
' ';
2579 bool drawingsScanned =
false;
2581 for(
KICAD_T scanType : aScanTypes )
2629 if( !drawingsScanned )
2637 drawingsScanned =
true;
2673 if( reference.IsEmpty() )
2674 reference =
_(
"<no reference designator>" );
2676 return wxString::Format(
_(
"Footprint %s" ), reference );
2682 return wxString::Format( wxT(
"%s (%s)" ),
2721 aFunction( drawing );
2727 catch( std::bad_function_call& )
2729 wxFAIL_MSG( wxT(
"Error running FOOTPRINT::RunOnChildren" ) );
2736 std::vector<int> layers;
2738 layers.reserve( 6 );
2744 wxASSERT_MSG(
false, wxT(
"Illegal layer" ) );
2762 bool f_silk =
false, b_silk =
false, non_silk =
false;
2766 if( item->GetLayer() ==
F_SilkS )
2768 else if( item->GetLayer() ==
B_SilkS )
2774 if( ( f_silk || b_silk ) && !non_silk &&
m_pads.empty() )
2811 constexpr double MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY = 1.5;
2814 return MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY;
2827 int biggest_clearance =
board->GetMaxClearanceValue();
2828 area.
Inflate( biggest_clearance );
2839 if( aName.find_first_of( invalids ) != std::string::npos )
2853 static const wxChar invalidChars[] = wxT(
"%$<>\t\n\r\"\\/:");
2854 static const wxChar invalidCharsReadable[] = wxT(
"% $ < > 'tab' 'return' 'line feed' \\ \" / :");
2857 return invalidCharsReadable;
2859 return invalidChars;
2865 if( aMoveVector.
x == 0 && aMoveVector.
y == 0 )
2879 EDA_ANGLE newOrientation = orientation + aAngle;
2886 field->KeepUpright();
2891 static_cast<PCB_TEXT*
>( item )->KeepUpright();
2898 wxASSERT( aLayer ==
F_Cu || aLayer ==
B_Cu );
2979 field->EDA_TEXT::Offset(
delta );
2985 zone->Move(
delta );
2988 item->Move(
delta );
2991 point->Move(
delta );
3023 field->Move( moveVector );
3027 pad->Move( moveVector );
3031 item->Move( moveVector );
3035 zone->Move( moveVector );
3067 field->Rotate( rotationCenter, angleChange );
3070 pad->Rotate( rotationCenter, angleChange );
3073 zone->Rotate( rotationCenter, angleChange );
3076 item->Rotate( rotationCenter, angleChange );
3079 point->Rotate( rotationCenter, angleChange );
3108 const BOARD_ITEM* aItem,
bool addToFootprint )
3112 switch( aItem->
Type() )
3116 PAD* new_pad =
new PAD( *
static_cast<const PAD*
>( aItem ) );
3119 if( addToFootprint )
3120 m_pads.push_back( new_pad );
3128 ZONE* new_zone =
new ZONE( *
static_cast<const ZONE*
>( aItem ) );
3131 if( addToFootprint )
3132 m_zones.push_back( new_zone );
3134 new_item = new_zone;
3143 if( addToFootprint )
3146 new_item = new_point;
3158 switch(
static_cast<const PCB_FIELD*
>( aItem )->GetId() )
3167 if( addToFootprint )
3170 new_item = new_text;
3179 if( addToFootprint )
3182 new_item = new_shape;
3191 if( addToFootprint )
3194 new_item = new_barcode;
3203 if( addToFootprint )
3206 new_item = new_image;
3215 if( addToFootprint )
3218 new_item = new_textbox;
3231 if( addToFootprint )
3234 new_item = dimension;
3242 if( addToFootprint )
3244 group->RunOnChildren(
3264 wxFAIL_MSG( wxT(
"Duplication not supported for items of class " ) + aItem->
GetClass() );
3274 std::set<wxString> usedNumbers;
3278 usedNumbers.insert(
pad->GetNumber() );
3285 while( usedNumbers.count( wxString::Format( wxT(
"%s%d" ), prefix, num ) ) )
3288 return wxString::Format( wxT(
"%s%d" ), prefix, num );
3296 if(
group.contains( aPadNumber ) )
3300 return std::nullopt;
3351 for(
int jj = 0; jj < aPolySet.
HoleCount( ii ); jj++ )
3355 return aPolySet.
Area();
3370 return markerShape.
Area();
3374 double combinedArea = 0.0;
3379 return combinedArea;
3430 double width =
static_cast<const PCB_TRACK*
>( aItem )->GetWidth();
3431 return width * width;
3435 static_cast<const PAD*
>( aItem )->Padstack().ForEachUniqueLayer(
3467 for(
int i = 0; i < aCollector.
GetCount(); ++i )
3471 switch( item->
Type() )
3503 double footprintRegionArea =
polygonArea( footprintRegion );
3504 double uncoveredRegionArea = footprintRegionArea -
polygonArea( coveredRegion );
3505 double coveredArea = footprintRegionArea - uncoveredRegionArea;
3508 if( footprintRegionArea == 0 )
3511 double ratio = coveredArea / footprintRegionArea;
3518 return std::min( ratio, 1.0 );
3524 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
3545 shape->AddShape(
pad->GetEffectiveShape( aLayer, aFlash )->Clone() );
3550 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3552 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3592 std::vector<PCB_SHAPE*> list_front;
3593 std::vector<PCB_SHAPE*> list_back;
3594 std::map<int, int> front_width_histogram;
3595 std::map<int, int> back_width_histogram;
3602 list_back.push_back( shape );
3609 list_front.push_back( shape );
3614 if( !list_front.size() && !list_back.size() )
3618 int chainingEpsilon =
pcbIUScale.mmToIU( 0.02 );
3621 true, aErrorHandler ) )
3631 auto max = std::max_element( front_width_histogram.begin(), front_width_histogram.end(),
3632 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3634 return a.second < b.second;
3637 if( max != front_width_histogram.end() )
3660 auto max = std::max_element( back_width_histogram.begin(), back_width_histogram.end(),
3661 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3663 return a.second < b.second;
3666 if( max != back_width_histogram.end() )
3689 std::map<PCB_LAYER_ID, std::vector<PCB_SHAPE*>> layer_shapes;
3695 if( item->Type() != PCB_SHAPE_T )
3698 for( PCB_LAYER_ID layer : item->GetLayerSet() )
3700 if( !IsCopperLayer( layer ) )
3703 if( board && !board->GetEnabledLayers().Contains( layer ) )
3706 layer_shapes[layer].push_back( static_cast<PCB_SHAPE*>( item ) );
3710 for(
size_t ii = 0; ii < m_pads.size(); ++ii )
3713 bool has_nettie =
false;
3715 auto it = map.find(
pad->GetNumber() );
3717 if( it == map.end() || it->second < 0 )
3720 for(
size_t jj = ii + 1; jj < m_pads.size(); ++jj )
3722 PAD* other = m_pads[ jj ];
3724 auto it2 = map.find( other->
GetNumber() );
3726 if( it2 == map.end() || it2->second < 0 )
3729 if( it2->second == it->second )
3731 m_netTieCache[
pad].insert(
pad->GetNetCode() );
3733 m_netTieCache[other].insert( other->
GetNetCode() );
3734 m_netTieCache[other].insert(
pad->GetNetCode() );
3742 for(
auto& [ layer, shapes ] : layer_shapes )
3744 auto pad_shape =
pad->GetEffectiveShape( layer );
3746 for(
auto other_shape : shapes )
3748 auto shape = other_shape->GetEffectiveShape( layer );
3750 if( pad_shape->Collide( shape.get() ) )
3752 std::set<int>& nettie = m_netTieCache[
pad];
3753 m_netTieCache[other_shape].insert( nettie.begin(), nettie.end() );
3763 std::map<wxString, int> padNumberToGroupIdxMap;
3766 padNumberToGroupIdxMap[
pad->GetNumber() ] = -1;
3769 [&]( wxString aPad,
int aGroup )
3771 aPad.Trim(
true ).Trim(
false );
3773 if( !aPad.IsEmpty() )
3774 padNumberToGroupIdxMap[ aPad ] = aGroup;
3783 for( wxUniCharRef ch :
group )
3792 switch(
static_cast<unsigned char>( ch ) )
3799 processPad(
pad, ii );
3809 processPad(
pad, ii );
3812 return padNumberToGroupIdxMap;
3822 int groupIdx = padToNetTieGroupMap[ aPad->
GetNumber() ];
3823 std::vector<PAD*> otherPads;
3829 if( padToNetTieGroupMap[
pad->GetNumber() ] == groupIdx )
3830 otherPads.push_back(
pad );
3843 if( setAttr && likelyAttr && setAttr != likelyAttr )
3847 switch( likelyAttr )
3850 msg.Printf(
_(
"(expected 'Through hole'; actual '%s')" ),
GetTypeName() );
3853 msg.Printf(
_(
"(expected 'SMD'; actual '%s')" ),
GetTypeName() );
3858 (aErrorHandler)( msg );
3864 const std::function<
void(
const PAD*,
int,
3865 const wxString& )>& aErrorHandler )
3867 if( aErrorHandler ==
nullptr )
3872 pad->CheckPad( aUnitsProvider,
false,
3873 [&](
int errorCode,
const wxString& msg )
3875 aErrorHandler(
pad, errorCode, msg );
3883 const VECTOR2I& )>& aErrorHandler )
3885 std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
3900 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
3903 if( checkedPairs.find( { a, b } ) == checkedPairs.end() )
3905 checkedPairs[ { a, b } ] = 1;
3917 std::shared_ptr<SHAPE_SEGMENT> holeA =
pad->GetEffectiveHoleShape();
3920 if( holeA->Collide( holeB->GetSeg(), 0 ) )
3937 SHAPE* padShape =
pad->GetEffectiveShape( l ).get();
3940 if( padShape->
Collide( otherShape, 0,
nullptr, &pos ) )
3953 const VECTOR2I& )>& aErrorHandler )
3962 std::vector<BOARD_ITEM*> copperItems;
3966 if( item->IsOnCopperLayer() )
3967 copperItems.push_back( item );
3969 item->RunOnChildren(
3973 copperItems.push_back( descendent );
3980 if( !zone->GetIsRuleArea() && zone->IsOnCopperLayer() )
3981 copperItems.push_back( zone );
3986 if( field->IsOnCopperLayer() )
3987 copperItems.push_back( field );
3997 std::map<int, std::vector<const PAD*>> outlineIdxToPadsMap;
4001 if( item->IsOnLayer( layer ) )
4011 for(
int ii = 0; ii < copperOutlines.
OutlineCount(); ++ii )
4013 if(
pad->GetEffectiveShape( layer )->Collide( &copperOutlines.
Outline( ii ), 0 ) )
4014 outlineIdxToPadsMap[ ii ].emplace_back(
pad );
4021 for(
const auto& [ outlineIdx, pads ] : outlineIdxToPadsMap )
4023 if( pads.size() > 1 )
4025 const PAD* firstPad = pads[0];
4026 int firstGroupIdx = padNumberToGroupIdxMap[ firstPad->
GetNumber() ];
4028 for(
size_t ii = 1; ii < pads.size(); ++ii )
4030 const PAD* thisPad = pads[ii];
4031 int thisGroupIdx = padNumberToGroupIdxMap[ thisPad->
GetNumber() ];
4033 if( thisGroupIdx < 0 || thisGroupIdx != firstGroupIdx )
4042 if( item->HitTest( pos, 1 ) )
4044 shortingItem = item;
4050 aErrorHandler( shortingItem, firstPad, thisPad, pos );
4052 aErrorHandler( firstPad, thisPad,
nullptr, pos );
4063 std::set<wxString> padNumbers;
4072 msg.Printf(
_(
"(net-tie pad group contains unknown pad number %s)" ), padNumber );
4073 aErrorHandler( msg );
4075 else if( !padNumbers.insert(
pad->GetNumber() ).second )
4077 msg.Printf(
_(
"(pad %s appears in more than one net-tie pad group)" ), padNumber );
4078 aErrorHandler( msg );
4086 const VECTOR2I& aPt )>& aErrorHandler )
4088 auto checkColliding =
4103 if( itemShape->Collide( otherShape.get(), 0, &
actual, &pos ) )
4104 aErrorHandler( item, other, pos );
4113 checkColliding( item, other );
4117 checkColliding( item,
pad );
4128 std::swap( *
this, *
image );
4137 image->RunOnChildren(
4165 return *
this == other;
4174 for(
size_t ii = 0; ii <
m_pads.size(); ++ii )
4183 for(
size_t ii = 0; ii <
m_drawings.size(); ++ii )
4192 for(
size_t ii = 0; ii <
m_zones.size(); ++ii )
4202 std::vector<PCB_FIELD*> fields, otherFields;
4207 if( fields.size() != otherFields.size() )
4210 for(
size_t ii = 0; ii < fields.size(); ++ii )
4214 if( !( *fields[ii] == *otherFields[ii] ) )
4230 double similarity = 1.0;
4239 similarity *=
pad->Similarity( *otherPad );
4251 if( aPtA.
x != aPtB.
x )
4252 return aPtA.
x < aPtB.
x;
4254 if( aPtA.
y != aPtB.
y )
4255 return aPtA.
y < aPtB.
y;
4257 return std::nullopt;
4263 if( itemA->
Type() != itemB->
Type() )
4264 return itemA->
Type() < itemB->
Type();
4269 switch( itemA->
Type() )
4308 for(
int ii = 0; ii < dwgA->
GetPolyShape().TotalVertices(); ++ii )
4310 if( std::optional<bool> cmp =
4367 return itemA < itemB;
4379 std::optional<bool> padCopperMatches;
4382 const PAD* checkPad = aFirst;
4395 padCopperMatches = aFirst->
GetSize( aLayer ).
x < aSecond->
GetSize( aLayer ).
x;
4397 padCopperMatches = aFirst->
GetSize( aLayer ).
y < aSecond->
GetSize( aLayer ).
y;
4399 padCopperMatches = aFirst->
GetShape( aLayer ) < aSecond->
GetShape( aLayer );
4402 if( padCopperMatches.has_value() )
4403 return *padCopperMatches;
4411 return aFirst < aSecond;
4416bool FOOTPRINT::cmp_padstack::operator()(
const PAD* aFirst,
const PAD* aSecond )
const
4456 if( firstShape->VertexCount() != secondShape->VertexCount() )
4457 return firstShape->VertexCount() < secondShape->VertexCount();
4459 for(
int ii = 0; ii < firstShape->VertexCount(); ++ii )
4461 if( std::optional<bool> cmp =
cmp_points_opt( firstShape->CVertex( ii ), secondShape->CVertex( ii ) ) )
4483 for(
int ii = 0; ii < aFirst->
Outline()->TotalVertices(); ++ii )
4485 if( std::optional<bool> cmp =
4495 return aFirst < aSecond;
4500 int aMaxError,
ERROR_LOC aErrorLoc )
const
4511 clearance.x +=
pad->GetSolderMaskExpansion( padLayer );
4512 clearance.y +=
pad->GetSolderMaskExpansion( padLayer );
4535 if( dummySize.
x <= 0 || dummySize.
y <= 0 )
4539 dummy.SetSize( padLayer, dummySize );
4540 dummy.TransformShapeToPolygon( aBuffer, padLayer, 0, aMaxError, aErrorLoc );
4544 pad->TransformShapeToPolygon( aBuffer, padLayer,
clearance.x, aMaxError, aErrorLoc );
4550 if( !
pad->FlashLayer( aLayer ) )
4555 pad->Padstack().ForEachUniqueLayer(
4558 processPad(
pad, l );
4563 processPad(
pad, aLayer );
4570 int aError,
ERROR_LOC aErrorLoc,
bool aIncludeText,
4571 bool aIncludeShapes,
bool aIncludePrivateItems )
const
4578 if( item->Type() ==
PCB_TEXT_T && aIncludeText )
4583 text->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4594 textbox->PCB_SHAPE::TransformShapeToPolygon( aBuffer, aLayer, 0, aError, aErrorLoc );
4601 if( item->Type() ==
PCB_SHAPE_T && aIncludeShapes )
4622 if( ( aLayer ==
UNDEFINED_LAYER || field->GetLayer() == aLayer ) && field->IsVisible() )
4623 field->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4633 std::set<KIFONT::OUTLINE_FONT*>
fonts;
4647 if( permission == PERMISSION::EDITABLE || permission == PERMISSION::INSTALLABLE )
4648 fonts.insert( outlineFont );
4654 processItem( item );
4657 processItem( field );
4702 return wxEmptyString;
4707 const std::unordered_set<wxString>& aComponentClassNames )
4756 LSET padLayers =
pad->GetLayerSet();
4757 padLayers |= boardCopper;
4758 pad->SetLayerSet( padLayers );
4770 if( zcMap.
Choices().GetCount() == 0 )
4782 if( layerEnum.
Choices().GetCount() == 0 )
4790 wxPGChoices fpLayers;
4801 auto isNotFootprintHolder =
4807 return !
board->IsFootprintHolder();
4814 layer->SetChoices( fpLayers );
4815 layer->SetAvailableFunc( isNotFootprintHolder );
4823 const wxString groupFields =
_HKI(
"Fields" );
4829 const wxString propertyFields =
_HKI(
"Footprint Properties" );
4847 const wxString groupAttributes =
_HKI(
"Attributes" );
4861 const wxString groupOverrides =
_HKI(
"Overrides" );
types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
std::unique_ptr< EDA_ITEM > CreateItemForType(KICAD_T aType, EDA_ITEM *aContainer)
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
constexpr EDA_IU_SCALE pcbIUScale
constexpr int ARC_LOW_DEF
BITMAPS
A list of all bitmap identifiers.
#define DEFAULT_COURTYARD_WIDTH
BASE_SET & set(size_t pos)
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
Abstract interface for BOARD_ITEMs capable of storing other items inside.
BOARD_ITEM_CONTAINER(BOARD_ITEM *aParent, KICAD_T aType)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
BOARD_ITEM(BOARD_ITEM *aParent, KICAD_T idtype, PCB_LAYER_ID aLayer=F_Cu)
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
virtual BOARD_ITEM * Duplicate(bool addToParentGroup, BOARD_COMMIT *aCommit=nullptr) const
Create a copy of this BOARD_ITEM.
virtual void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const
Convert the item shape to a closed polygon.
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
VECTOR2I GetFPRelativePosition() const
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_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()
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Assign the members of aItem to another object.
void SetFlags(EDA_ITEM_FLAGS aMask)
KICAD_T Type() const
Returns the type of object.
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
static INSPECT_RESULT IterateForward(std::deque< T > &aList, INSPECTOR inspector, void *testData, const std::vector< KICAD_T > &scanTypes)
This changes first parameter to avoid the DList and use the main queue instead.
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(PROPERTY_BASE *aProperty, const wxString &aGroup)
Replace an existing property.
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