26#include <magic_enum.hpp>
29#include <unordered_set>
33#include <wx/tokenzr.h>
71#include <google/protobuf/any.pb.h>
72#include <api/board/board_types.pb.h>
175 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
183 ptrMap[field] = existingField;
184 *existingField = *field;
190 ptrMap[field] = newField;
198 PAD* newPad =
static_cast<PAD*
>(
pad->Clone() );
199 ptrMap[
pad ] = newPad;
206 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
207 ptrMap[ zone ] = newZone;
221 ptrMap[ item ] = newItem;
229 ptrMap[
group ] = newGroup;
236 ptrMap[ point ] = newPoint;
249 if( ptrMap.count( member ) )
250 newGroup->
AddItem( ptrMap[ member ] );
263 *
this = std::move( aFootprint );
303 board->IncrementTimeStamp();
310 types::FootprintInstance footprint;
312 footprint.mutable_id()->set_value(
m_Uuid.AsStdString() );
313 footprint.mutable_position()->set_x_nm(
GetPosition().x );
314 footprint.mutable_position()->set_y_nm(
GetPosition().y );
317 footprint.set_locked(
IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
318 : kiapi::common::types::LockedState::LS_UNLOCKED );
320 google::protobuf::Any buf;
322 buf.UnpackTo( footprint.mutable_reference_field() );
324 buf.UnpackTo( footprint.mutable_value_field() );
326 buf.UnpackTo( footprint.mutable_datasheet_field() );
328 buf.UnpackTo( footprint.mutable_description_field() );
330 types::FootprintAttributes* attrs = footprint.mutable_attributes();
336 attrs->set_do_not_populate(
IsDNP() );
340 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_THROUGH_HOLE );
342 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_SMD );
344 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_UNSPECIFIED );
346 types::Footprint* def = footprint.mutable_definition();
351 def->mutable_attributes()->set_keywords(
GetKeywords().ToStdString() );
355 types::FootprintDesignRuleOverrides* overrides = footprint.mutable_overrides();
369 overrides->set_zone_connection(
374 types::NetTieDefinition* netTie = def->add_net_ties();
375 wxStringTokenizer tokenizer(
group,
", \t\r\n", wxTOKEN_STRTOK );
377 while( tokenizer.HasMoreTokens() )
378 netTie->add_pad_number( tokenizer.GetNextToken().ToStdString() );
386 if( item->IsMandatory() )
389 google::protobuf::Any* itemMsg = def->add_items();
390 item->Serialize( *itemMsg );
393 for(
const PAD* item :
Pads() )
395 google::protobuf::Any* itemMsg = def->add_items();
396 item->Serialize( *itemMsg );
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 types::Footprint3DModel modelMsg;
415 modelMsg.set_filename(
model.m_Filename.ToUTF8() );
419 modelMsg.set_visible(
model.m_Show );
420 modelMsg.set_opacity(
model.m_Opacity );
421 itemMsg->PackFrom( modelMsg );
426 footprint.set_symbol_sheet_name(
m_sheetname.ToUTF8() );
427 footprint.set_symbol_sheet_filename(
m_sheetfile.ToUTF8() );
428 footprint.set_symbol_footprint_filters(
m_filters.ToUTF8() );
430 aContainer.PackFrom( footprint );
437 types::FootprintInstance footprint;
439 if( !aContainer.UnpackTo( &footprint ) )
446 SetLocked( footprint.locked() == kiapi::common::types::LockedState::LS_LOCKED );
448 google::protobuf::Any buf;
449 types::Field mandatoryField;
451 if( footprint.has_reference_field() )
453 mandatoryField = footprint.reference_field();
455 buf.PackFrom( mandatoryField );
459 if( footprint.has_value_field() )
461 mandatoryField = footprint.value_field();
463 buf.PackFrom( mandatoryField );
467 if( footprint.has_datasheet_field() )
469 mandatoryField = footprint.datasheet_field();
471 buf.PackFrom( mandatoryField );
475 if( footprint.has_description_field() )
477 mandatoryField = footprint.description_field();
479 buf.PackFrom( mandatoryField );
485 switch( footprint.attributes().mounting_style() )
487 case types::FootprintMountingStyle::FMS_THROUGH_HOLE:
491 case types::FootprintMountingStyle::FMS_SMD:
499 SetBoardOnly( footprint.attributes().not_in_schematic() );
503 SetDNP( footprint.attributes().do_not_populate() );
510 SetKeywords( footprint.definition().attributes().keywords() );
512 const types::FootprintDesignRuleOverrides& overrides = footprint.overrides();
514 if( overrides.has_copper_clearance() )
519 if( overrides.has_solder_mask() && overrides.solder_mask().has_solder_mask_margin() )
524 if( overrides.has_solder_paste() )
526 const types::SolderPasteOverrides& pasteSettings = overrides.solder_paste();
528 if( pasteSettings.has_solder_paste_margin() )
533 if( pasteSettings.has_solder_paste_margin_ratio() )
541 for(
const types::NetTieDefinition& netTieMsg : footprint.definition().net_ties() )
545 for(
const std::string&
pad : netTieMsg.pad_number() )
546 group.Append( wxString::Format( wxT(
"%s " ),
pad ) );
554 for(
int layerMsg : footprint.definition().private_layers() )
559 privateLayers.
set( layer );
565 m_sheetname = wxString::FromUTF8( footprint.symbol_sheet_name() );
566 m_sheetfile = wxString::FromUTF8( footprint.symbol_sheet_filename() );
567 m_filters = wxString::FromUTF8( footprint.symbol_footprint_filters() );
572 if( !field->IsMandatory() )
580 board->UncacheItemById(
pad->m_Uuid );
583 board->UncacheItemById( item->m_Uuid );
586 board->UncacheItemById( zone->m_Uuid );
592 board->UncacheItemById( point->m_Uuid );
602 for(
const google::protobuf::Any& itemMsg : footprint.definition().items() )
610 if( itemMsg.type_url() ==
"type.googleapis.com/kiapi.board.types.Footprint3DModel" )
612 types::Footprint3DModel modelMsg;
614 if( !itemMsg.UnpackTo( &modelMsg ) )
619 model.m_Filename = wxString::FromUTF8( modelMsg.filename() );
620 model.m_Show = modelMsg.visible();
621 model.m_Opacity = modelMsg.opacity();
630 wxLogTrace(
traceApi, wxString::Format( wxS(
"Attempting to unpack unknown type %s "
631 "from footprint message, skipping" ),
632 itemMsg.type_url() ) );
640 if( item && item->Deserialize( itemMsg ) )
652 if( field->GetId() == aFieldType )
667 if( field->GetId() == aFieldType )
677 return GetField( aFieldName ) !=
nullptr;
685 if( field->GetName() == aFieldName )
701 if( !field->IsVisible() || field->GetText().IsEmpty() )
705 aVector.push_back( field );
708 std::sort( aVector.begin(), aVector.end(),
711 return lhs->GetOrdinal() < rhs->GetOrdinal();
721 ordinal = std::max( ordinal, field->GetOrdinal() + 1 );
728 bool aStyleShapes,
bool aStyleDimensions,
bool aStyleBarcodes )
733 field->StyleFromSettings(
board.GetDesignSettings(),
true );
738 switch( item->Type() )
743 item->StyleFromSettings(
board.GetDesignSettings(),
true );
748 if( aStyleShapes && !item->IsOnCopperLayer() )
749 item->StyleFromSettings(
board.GetDesignSettings(),
true );
758 if( aStyleDimensions )
759 item->StyleFromSettings(
board.GetDesignSettings(),
true );
765 item->StyleFromSettings(
board.GetDesignSettings(),
true );
778 std::vector< BOARD_ITEM* > item_list;
781 item_list.push_back( field );
784 item_list.push_back(
pad );
787 item_list.push_back( gr_item );
792 item_list.push_back(
group );
796 item_list.push_back( zone );
800 item_list.push_back( point );
802 bool changed =
false;
808 const_cast<KIID&
>( item->m_Uuid ) =
KIID();
821 m_pos = aOther.m_pos;
851 board->UncacheItemById( field->m_Uuid );
854 board->UncacheItemById(
pad->m_Uuid );
857 board->UncacheItemById( zone->m_Uuid );
860 board->UncacheItemById( item->m_Uuid );
866 board->UncacheItemById( point->m_Uuid );
875 for(
PCB_FIELD* field : aOther.m_fields )
878 aOther.m_fields.clear();
886 for(
PAD*
pad : aOther.Pads() )
889 aOther.Pads().clear();
897 for(
ZONE* item : aOther.Zones() )
905 item->SetNetCode( -1 );
908 aOther.Zones().clear();
916 for(
BOARD_ITEM* item : aOther.GraphicalItems() )
919 aOther.GraphicalItems().clear();
930 aOther.Groups().clear();
938 for(
PCB_POINT* point : aOther.Points() )
941 aOther.Points().clear();
954 aOther.m_componentClassCacheProxy->GetStaticComponentClass() );
957 aOther.m_fields.clear();
958 aOther.Pads().clear();
959 aOther.Zones().clear();
960 aOther.GraphicalItems().clear();
961 aOther.m_initial_comments =
nullptr;
1001 board->UncacheItemById( field->m_Uuid );
1004 board->UncacheItemById(
pad->m_Uuid );
1007 board->UncacheItemById( zone->m_Uuid );
1010 board->UncacheItemById( item->m_Uuid );
1016 board->UncacheItemById( point->m_Uuid );
1019 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
1030 ptrMap[field] = newField;
1043 ptrMap[
pad ] = newPad;
1055 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
1056 ptrMap[ zone ] = newZone;
1075 ptrMap[ item ] = newItem;
1091 newGroup->
AddItem( ptrMap[ member ] );
1105 ptrMap[ point ] = newItem;
1130 *
this = *
static_cast<const FOOTPRINT*
>( aOther );
1156 aVars->push_back( wxT(
"REFERENCE" ) );
1157 aVars->push_back( wxT(
"VALUE" ) );
1158 aVars->push_back( wxT(
"LAYER" ) );
1159 aVars->push_back( wxT(
"FOOTPRINT_LIBRARY" ) );
1160 aVars->push_back( wxT(
"FOOTPRINT_NAME" ) );
1161 aVars->push_back( wxT(
"SHORT_NET_NAME(<pad_number>)" ) );
1162 aVars->push_back( wxT(
"NET_NAME(<pad_number>)" ) );
1163 aVars->push_back( wxT(
"NET_CLASS(<pad_number>)" ) );
1164 aVars->push_back( wxT(
"PIN_NAME(<pad_number>)" ) );
1173 if( token->IsSameAs( wxT(
"REFERENCE" ) ) )
1178 else if( token->IsSameAs( wxT(
"VALUE" ) ) )
1183 else if( token->IsSameAs( wxT(
"LAYER" ) ) )
1188 else if( token->IsSameAs( wxT(
"FOOTPRINT_LIBRARY" ) ) )
1190 *token =
m_fpid.GetUniStringLibNickname();
1193 else if( token->IsSameAs( wxT(
"FOOTPRINT_NAME" ) ) )
1195 *token =
m_fpid.GetUniStringLibItemName();
1198 else if( token->StartsWith( wxT(
"SHORT_NET_NAME(" ) )
1199 || token->StartsWith( wxT(
"NET_NAME(" ) )
1200 || token->StartsWith( wxT(
"NET_CLASS(" ) )
1201 || token->StartsWith( wxT(
"PIN_NAME(" ) ) )
1203 wxString padNumber = token->AfterFirst(
'(' );
1204 padNumber = padNumber.BeforeLast(
')' );
1208 if(
pad->GetNumber() == padNumber )
1210 if( token->StartsWith( wxT(
"SHORT_NET_NAME" ) ) )
1211 *token =
pad->GetShortNetname();
1212 else if( token->StartsWith( wxT(
"NET_NAME" ) ) )
1213 *token =
pad->GetNetname();
1214 else if( token->StartsWith( wxT(
"NET_CLASS" ) ) )
1215 *token =
pad->GetNetClassName();
1217 *token =
pad->GetPinFunction();
1225 *token = field->GetShownText(
false, aDepth + 1 );
1244 return it !=
m_variants.end() ? &it->second :
nullptr;
1252 return it !=
m_variants.end() ? &it->second :
nullptr;
1258 if( aVariant.
GetName().IsEmpty()
1270 it->second = std::move( updated );
1280 if( aVariantName.IsEmpty()
1283 wxASSERT_MSG(
false, wxT(
"Variant name cannot be empty or default." ) );
1297 auto inserted =
m_variants.emplace( aVariantName, std::move( variant ) );
1298 return &inserted.first->second;
1310 if( aNewName.IsEmpty()
1321 auto existingIt =
m_variants.find( aNewName );
1323 if( existingIt !=
m_variants.end() && existingIt != it )
1326 if( it->first == aNewName )
1332 m_variants.emplace( aNewName, std::move( variant ) );
1345 if( aVariantName.IsEmpty()
1352 return variant->
GetDNP();
1362 if( aVariantName.IsEmpty()
1379 if( aVariantName.IsEmpty()
1394 const wxString& aFieldName )
const
1397 if( !aVariantName.IsEmpty()
1408 return field->GetText();
1425 switch( aBoardItem->
Type() )
1451 m_pads.push_back(
static_cast<PAD*
>( aBoardItem ) );
1453 m_pads.push_front(
static_cast<PAD*
>( aBoardItem ) );
1459 m_zones.push_back(
static_cast<ZONE*
>( aBoardItem ) );
1474 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Markers go at the board level, even in the footprint editor" ) );
1478 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Nested footprints not supported" ) );
1490 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Add(): BOARD_ITEM type (%d) not handled" ),
1491 aBoardItem->
Type() ) );
1501 board->CacheItemById( aBoardItem );
1509 switch( aBoardItem->
Type() )
1514 if( *it == aBoardItem )
1536 if( *it == aBoardItem )
1546 for(
auto it =
m_pads.begin(); it !=
m_pads.end(); ++it )
1548 if( *it ==
static_cast<PAD*
>( aBoardItem ) )
1560 if( *it ==
static_cast<ZONE*
>( aBoardItem ) )
1572 if( *it ==
static_cast<PCB_GROUP*
>( aBoardItem ) )
1584 if( *it ==
static_cast<PCB_POINT*
>( aBoardItem ) )
1596 msg.Printf( wxT(
"FOOTPRINT::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
1597 aBoardItem->
Type() );
1629 switch(
pad->GetProperty() )
1647 switch(
pad->GetAttribute() )
1654 if(
pad->IsOnCopperLayer() )
1682 return _(
"Through hole" );
1684 return _(
"Other" );
1690 std::vector<SEARCH_TERM> terms;
1696 wxStringTokenizer keywordTokenizer(
GetKeywords(), wxS(
" \t\r\n" ), wxTOKEN_STRTOK );
1698 while( keywordTokenizer.HasMoreTokens() )
1699 terms.emplace_back(
SEARCH_TERM( keywordTokenizer.GetNextToken(), 4 ) );
1719 if(
dummy.IsFlipped() )
1723 bbox.
Merge(
pad->GetBoundingBox() );
1772 std::vector<PCB_TEXT*> texts;
1773 bool isFPEdit =
board &&
board->IsFootprintHolder();
1794 texts.push_back(
static_cast<PCB_TEXT*
>( item ) );
1812 bbox.
Merge( item->GetBoundingBox() );
1818 if( field->IsReference() || field->IsValue() )
1821 texts.push_back( field );
1825 bbox.
Merge(
pad->GetBoundingBox() );
1828 bbox.
Merge( zone->GetBoundingBox() );
1831 bbox.
Merge( point->GetBoundingBox() );
1836 if( aIncludeText || noDrawItems )
1853 bool valueLayerIsVisible =
true;
1854 bool refLayerIsVisible =
true;
1872 if( (
Value().IsVisible() && valueLayerIsVisible ) || noDrawItems )
1877 if( (
Reference().IsVisible() && refLayerIsVisible ) || noDrawItems )
1887 if( aIncludeText || noDrawItems )
1905 std::vector<PCB_TEXT*> texts;
1907 bool isFPEdit =
board &&
board->IsFootprintHolder();
1917 if( ( aLayers & item->GetLayerSet() ).none() )
1925 bbox.
Merge( item->GetBoundingBox() );
1930 if( ( aLayers &
pad->GetLayerSet() ).none() )
1933 bbox.
Merge(
pad->GetBoundingBox() );
1938 if( ( aLayers & zone->GetLayerSet() ).none() )
1941 bbox.
Merge( zone->GetBoundingBox() );
1949 if( ( aLayers & point->GetLayerSet() ).none() )
1952 bbox.
Merge( point->GetBoundingBox() );
1962 bool isFPEdit =
board &&
board->IsFootprintHolder();
1988 pad->Padstack().ForEachUniqueLayer(
2002 const SHAPE_POLY_SET& layerPoly = *zone->GetFilledPolysList( layer );
2018 const int halfsize =
pcbIUScale.mmToIU( 1.0 );
2029 std::vector<VECTOR2I> convex_hull;
2035 for(
const VECTOR2I& pt : convex_hull )
2048 bool isFPEdit =
board &&
board->IsFootprintHolder();
2058 if( item->IsOnLayer( aLayer ) )
2072 if(
pad->IsOnLayer( aLayer ) )
2078 if( zone->GetIsRuleArea() )
2081 if( zone->IsOnLayer( aLayer ) )
2083 const std::shared_ptr<SHAPE_POLY_SET>& layerPoly = zone->GetFilledPolysList( aLayer );
2085 for(
int ii = 0; ii < layerPoly->OutlineCount(); ii++ )
2086 rawPolys.
AddOutline( layerPoly->COutline( ii ) );
2090 std::vector<VECTOR2I> convex_hull;
2095 for(
const VECTOR2I& pt : convex_hull )
2118 aList.emplace_back(
_(
"Footprint Name" ),
GetFPID().GetLibItemName().wx_str() );
2120 aList.emplace_back(
_(
"Pads" ), wxString::Format( wxT(
"%zu" ), padCount ) );
2123 wxString::Format(
_(
"Keywords: %s" ),
GetKeywords() ) );
2132 case F_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Front" ) );
break;
2133 case B_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Back (Flipped)" ) );
break;
2137 auto addToken = []( wxString* aStr,
const wxString& aAttr )
2139 if( !aStr->IsEmpty() )
2140 *aStr += wxT(
", " );
2149 addToken( &status,
_(
"Locked" ) );
2152 addToken( &status,
_(
"autoplaced" ) );
2155 addToken( &attrs,
_(
"not in schematic" ) );
2158 addToken( &attrs,
_(
"exclude from pos files" ) );
2161 addToken( &attrs,
_(
"exclude from BOM" ) );
2164 addToken( &attrs,
_(
"DNP" ) );
2166 aList.emplace_back(
_(
"Status: " ) + status,
_(
"Attributes:" ) + wxS(
" " ) + attrs );
2168 aList.emplace_back(
_(
"Rotation" ), wxString::Format( wxT(
"%.4g" ),
2174 _(
"Component Class" ),
2178 msg.Printf(
_(
"Footprint: %s" ),
m_fpid.GetUniStringLibId() );
2179 msg2.Printf(
_(
"3D-Shape: %s" ),
m_3D_Drawings.empty() ?
_(
"<none>" )
2181 aList.emplace_back( msg, msg2 );
2185 aList.emplace_back( msg, msg2 );
2193 if(
board->IsFootprintHolder() )
2225 if(
pad->IsOnLayer( aLayer ) )
2231 if( zone->IsOnLayer( aLayer ) )
2237 if( field->IsOnLayer( aLayer ) )
2243 if( item->IsOnLayer( aLayer ) )
2255 if(
pad->IsOnLayer( aLayer ) &&
pad->HitTest( aPosition, aAccuracy ) )
2261 if( zone->IsOnLayer( aLayer ) && zone->HitTest( aPosition, aAccuracy ) )
2267 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer )
2268 && item->HitTest( aPosition, aAccuracy ) )
2280 std::vector<BOARD_ITEM*> items;
2284 if(
pad->IsOnLayer( aLayer ) )
2285 items.push_back(
pad );
2290 if( zone->IsOnLayer( aLayer ) )
2291 items.push_back( zone );
2296 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer ) )
2297 items.push_back( item );
2306 if( !aContained && item->HitTest( aRect, aContained, aAccuracy ) )
2308 else if( aContained && !item->HitTest( aRect, aContained, aAccuracy ) )
2315 return !items.empty() && aContained;
2334 BOX2I arect = aRect;
2354 if(
pad->HitTest( arect,
false, 0 ) )
2360 if( zone->HitTest( arect,
false, 0 ) )
2366 if( point->HitTest( arect,
false, 0 ) )
2377 if( item->Type() !=
PCB_TEXT_T && item->HitTest( arect,
false, 0 ) )
2391 using std::ranges::all_of;
2392 using std::ranges::any_of;
2399 [&](
const auto* aItem )
2401 return aItem && aItem->HitTest( aPoly, aContained );
2407 auto drawings =
m_drawings | std::views::filter( [](
const auto* aItem )
2418 return all_of( drawings, hitTest )
2419 && all_of(
m_pads, hitTest )
2420 && all_of(
m_zones, hitTest );
2425 return any_of( drawings, hitTest )
2426 || any_of(
m_pads, hitTest )
2427 || any_of(
m_zones, hitTest );
2434 bool can_select = aSearchAfterMe ? false :
true;
2438 if( !can_select &&
pad == aSearchAfterMe )
2444 if( can_select &&
pad->GetNumber() == aPadNumber )
2457 if( !(
pad->GetLayerSet() & aLayerMask ).any() )
2460 if(
pad->HitTest( aPosition ) )
2470 std::vector<const PAD*> retv;
2474 if( ( aIgnore && aIgnore ==
pad ) || (
pad->GetNumber() != aPadNumber ) )
2477 retv.push_back(
pad );
2505 std::set<wxString> usedNumbers;
2517 if(
pad->GetNumber().IsEmpty() )
2527 usedNumbers.insert(
pad->GetNumber() );
2542 if(
nullptr == a3DModel )
2570 const std::vector<KICAD_T>& aScanTypes )
2572#if 0 && defined(DEBUG)
2573 std::cout <<
GetClass().mb_str() <<
' ';
2576 bool drawingsScanned =
false;
2578 for(
KICAD_T scanType : aScanTypes )
2626 if( !drawingsScanned )
2634 drawingsScanned =
true;
2670 if( reference.IsEmpty() )
2671 reference =
_(
"<no reference designator>" );
2673 return wxString::Format(
_(
"Footprint %s" ), reference );
2710 aFunction( drawing );
2716 catch( std::bad_function_call& )
2718 wxFAIL_MSG( wxT(
"Error running FOOTPRINT::RunOnChildren" ) );
2725 std::vector<int> layers;
2727 layers.reserve( 6 );
2733 wxASSERT_MSG(
false, wxT(
"Illegal layer" ) );
2751 bool f_silk =
false, b_silk =
false, non_silk =
false;
2755 if( item->GetLayer() ==
F_SilkS )
2757 else if( item->GetLayer() ==
B_SilkS )
2763 if( ( f_silk || b_silk ) && !non_silk &&
m_pads.empty() )
2800 constexpr double MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY = 1.5;
2803 return MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY;
2816 int biggest_clearance =
board->GetMaxClearanceValue();
2817 area.
Inflate( biggest_clearance );
2828 if( aName.find_first_of( invalids ) != std::string::npos )
2842 static const wxChar invalidChars[] = wxT(
"%$<>\t\n\r\"\\/:");
2843 static const wxChar invalidCharsReadable[] = wxT(
"% $ < > 'tab' 'return' 'line feed' \\ \" / :");
2846 return invalidCharsReadable;
2848 return invalidChars;
2854 if( aMoveVector.
x == 0 && aMoveVector.
y == 0 )
2868 EDA_ANGLE newOrientation = orientation + aAngle;
2875 field->KeepUpright();
2880 static_cast<PCB_TEXT*
>( item )->KeepUpright();
2887 wxASSERT( aLayer ==
F_Cu || aLayer ==
B_Cu );
2964 field->EDA_TEXT::Offset(
delta );
2970 zone->Move(
delta );
2973 item->Move(
delta );
2976 point->Move(
delta );
3008 field->Move( moveVector );
3012 pad->Move( moveVector );
3016 item->Move( moveVector );
3020 zone->Move( moveVector );
3088 const BOARD_ITEM* aItem,
bool addToFootprint )
3092 switch( aItem->
Type() )
3096 PAD* new_pad =
new PAD( *
static_cast<const PAD*
>( aItem ) );
3099 if( addToFootprint )
3100 m_pads.push_back( new_pad );
3108 ZONE* new_zone =
new ZONE( *
static_cast<const ZONE*
>( aItem ) );
3111 if( addToFootprint )
3112 m_zones.push_back( new_zone );
3114 new_item = new_zone;
3123 if( addToFootprint )
3126 new_item = new_point;
3138 switch(
static_cast<const PCB_FIELD*
>( aItem )->GetId() )
3147 if( addToFootprint )
3150 new_item = new_text;
3159 if( addToFootprint )
3162 new_item = new_shape;
3171 if( addToFootprint )
3174 new_item = new_barcode;
3183 if( addToFootprint )
3186 new_item = new_image;
3195 if( addToFootprint )
3198 new_item = new_textbox;
3211 if( addToFootprint )
3214 new_item = dimension;
3222 if( addToFootprint )
3224 group->RunOnChildren(
3244 wxFAIL_MSG( wxT(
"Duplication not supported for items of class " ) + aItem->
GetClass() );
3254 std::set<wxString> usedNumbers;
3258 usedNumbers.insert(
pad->GetNumber() );
3265 while( usedNumbers.count( wxString::Format( wxT(
"%s%d" ), prefix, num ) ) )
3268 return wxString::Format( wxT(
"%s%d" ), prefix, num );
3276 if(
group.contains( aPadNumber ) )
3280 return std::nullopt;
3331 for(
int jj = 0; jj < aPolySet.
HoleCount( ii ); jj++ )
3335 return aPolySet.
Area();
3350 return markerShape.
Area();
3354 double combinedArea = 0.0;
3359 return combinedArea;
3410 double width =
static_cast<const PCB_TRACK*
>( aItem )->GetWidth();
3411 return width * width;
3415 static_cast<const PAD*
>( aItem )->Padstack().ForEachUniqueLayer(
3447 for(
int i = 0; i < aCollector.
GetCount(); ++i )
3451 switch( item->
Type() )
3483 double footprintRegionArea =
polygonArea( footprintRegion );
3484 double uncoveredRegionArea = footprintRegionArea -
polygonArea( coveredRegion );
3485 double coveredArea = footprintRegionArea - uncoveredRegionArea;
3488 if( footprintRegionArea == 0 )
3491 double ratio = coveredArea / footprintRegionArea;
3498 return std::min( ratio, 1.0 );
3504 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
3525 shape->AddShape(
pad->GetEffectiveShape( aLayer, aFlash )->Clone() );
3530 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3532 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3572 std::vector<PCB_SHAPE*> list_front;
3573 std::vector<PCB_SHAPE*> list_back;
3574 std::map<int, int> front_width_histogram;
3575 std::map<int, int> back_width_histogram;
3582 list_back.push_back( shape );
3589 list_front.push_back( shape );
3594 if( !list_front.size() && !list_back.size() )
3598 int chainingEpsilon =
pcbIUScale.mmToIU( 0.02 );
3601 true, aErrorHandler ) )
3611 auto max = std::max_element( front_width_histogram.begin(), front_width_histogram.end(),
3612 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3614 return a.second < b.second;
3617 if( max != front_width_histogram.end() )
3640 auto max = std::max_element( back_width_histogram.begin(), back_width_histogram.end(),
3641 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3643 return a.second < b.second;
3646 if( max != back_width_histogram.end() )
3669 std::map<PCB_LAYER_ID, std::vector<PCB_SHAPE*>> layer_shapes;
3675 if( item->Type() != PCB_SHAPE_T )
3678 for( PCB_LAYER_ID layer : item->GetLayerSet() )
3680 if( !IsCopperLayer( layer ) )
3683 if( board && !board->GetEnabledLayers().Contains( layer ) )
3686 layer_shapes[layer].push_back( static_cast<PCB_SHAPE*>( item ) );
3690 for(
size_t ii = 0; ii < m_pads.size(); ++ii )
3693 bool has_nettie =
false;
3695 auto it = map.find(
pad->GetNumber() );
3697 if( it == map.end() || it->second < 0 )
3700 for(
size_t jj = ii + 1; jj < m_pads.size(); ++jj )
3702 PAD* other = m_pads[ jj ];
3704 auto it2 = map.find( other->
GetNumber() );
3706 if( it2 == map.end() || it2->second < 0 )
3709 if( it2->second == it->second )
3711 m_netTieCache[
pad].insert(
pad->GetNetCode() );
3713 m_netTieCache[other].insert( other->
GetNetCode() );
3714 m_netTieCache[other].insert(
pad->GetNetCode() );
3722 for(
auto& [ layer, shapes ] : layer_shapes )
3724 auto pad_shape =
pad->GetEffectiveShape( layer );
3726 for(
auto other_shape : shapes )
3728 auto shape = other_shape->GetEffectiveShape( layer );
3730 if( pad_shape->Collide( shape.get() ) )
3732 std::set<int>& nettie = m_netTieCache[
pad];
3733 m_netTieCache[other_shape].insert( nettie.begin(), nettie.end() );
3743 std::map<wxString, int> padNumberToGroupIdxMap;
3746 padNumberToGroupIdxMap[
pad->GetNumber() ] = -1;
3749 [&]( wxString aPad,
int aGroup )
3751 aPad.Trim(
true ).Trim(
false );
3753 if( !aPad.IsEmpty() )
3754 padNumberToGroupIdxMap[ aPad ] = aGroup;
3763 for( wxUniCharRef ch :
group )
3772 switch(
static_cast<unsigned char>( ch ) )
3779 processPad(
pad, ii );
3789 processPad(
pad, ii );
3792 return padNumberToGroupIdxMap;
3802 int groupIdx = padToNetTieGroupMap[ aPad->
GetNumber() ];
3803 std::vector<PAD*> otherPads;
3809 if( padToNetTieGroupMap[
pad->GetNumber() ] == groupIdx )
3810 otherPads.push_back(
pad );
3823 if( setAttr && likelyAttr && setAttr != likelyAttr )
3827 switch( likelyAttr )
3830 msg.Printf(
_(
"(expected 'Through hole'; actual '%s')" ),
GetTypeName() );
3833 msg.Printf(
_(
"(expected 'SMD'; actual '%s')" ),
GetTypeName() );
3838 (aErrorHandler)( msg );
3844 const std::function<
void(
const PAD*,
int,
3845 const wxString& )>& aErrorHandler )
3847 if( aErrorHandler ==
nullptr )
3852 pad->CheckPad( aUnitsProvider,
false,
3853 [&](
int errorCode,
const wxString& msg )
3855 aErrorHandler(
pad, errorCode, msg );
3863 const VECTOR2I& )>& aErrorHandler )
3865 std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
3880 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
3883 if( checkedPairs.find( { a, b } ) == checkedPairs.end() )
3885 checkedPairs[ { a, b } ] = 1;
3897 std::shared_ptr<SHAPE_SEGMENT> holeA =
pad->GetEffectiveHoleShape();
3900 if( holeA->Collide( holeB->GetSeg(), 0 ) )
3917 SHAPE* padShape =
pad->GetEffectiveShape( l ).get();
3920 if( padShape->
Collide( otherShape, 0,
nullptr, &pos ) )
3933 const VECTOR2I& )>& aErrorHandler )
3942 std::vector<BOARD_ITEM*> copperItems;
3946 if( item->IsOnCopperLayer() )
3947 copperItems.push_back( item );
3949 item->RunOnChildren(
3953 copperItems.push_back( descendent );
3960 if( !zone->GetIsRuleArea() && zone->IsOnCopperLayer() )
3961 copperItems.push_back( zone );
3966 if( field->IsOnCopperLayer() )
3967 copperItems.push_back( field );
3977 std::map<int, std::vector<const PAD*>> outlineIdxToPadsMap;
3981 if( item->IsOnLayer( layer ) )
3991 for(
int ii = 0; ii < copperOutlines.
OutlineCount(); ++ii )
3993 if(
pad->GetEffectiveShape( layer )->Collide( &copperOutlines.
Outline( ii ), 0 ) )
3994 outlineIdxToPadsMap[ ii ].emplace_back(
pad );
4001 for(
const auto& [ outlineIdx, pads ] : outlineIdxToPadsMap )
4003 if( pads.size() > 1 )
4005 const PAD* firstPad = pads[0];
4006 int firstGroupIdx = padNumberToGroupIdxMap[ firstPad->
GetNumber() ];
4008 for(
size_t ii = 1; ii < pads.size(); ++ii )
4010 const PAD* thisPad = pads[ii];
4011 int thisGroupIdx = padNumberToGroupIdxMap[ thisPad->
GetNumber() ];
4013 if( thisGroupIdx < 0 || thisGroupIdx != firstGroupIdx )
4022 if( item->HitTest( pos, 1 ) )
4024 shortingItem = item;
4030 aErrorHandler( shortingItem, firstPad, thisPad, pos );
4032 aErrorHandler( firstPad, thisPad,
nullptr, pos );
4043 std::set<wxString> padNumbers;
4052 msg.Printf(
_(
"(net-tie pad group contains unknown pad number %s)" ), padNumber );
4053 aErrorHandler( msg );
4055 else if( !padNumbers.insert(
pad->GetNumber() ).second )
4057 msg.Printf(
_(
"(pad %s appears in more than one net-tie pad group)" ), padNumber );
4058 aErrorHandler( msg );
4066 const VECTOR2I& aPt )>& aErrorHandler )
4068 auto checkColliding =
4083 if( itemShape->Collide( otherShape.get(), 0, &
actual, &pos ) )
4084 aErrorHandler( item, other, pos );
4093 checkColliding( item, other );
4097 checkColliding( item,
pad );
4108 std::swap( *
this, *
image );
4117 image->RunOnChildren(
4145 return *
this == other;
4154 for(
size_t ii = 0; ii <
m_pads.size(); ++ii )
4163 for(
size_t ii = 0; ii <
m_drawings.size(); ++ii )
4172 for(
size_t ii = 0; ii <
m_zones.size(); ++ii )
4182 std::vector<PCB_FIELD*> fields, otherFields;
4187 if( fields.size() != otherFields.size() )
4190 for(
size_t ii = 0; ii < fields.size(); ++ii )
4194 if( !( *fields[ii] == *otherFields[ii] ) )
4210 double similarity = 1.0;
4219 similarity *=
pad->Similarity( *otherPad );
4231 if( aPtA.
x != aPtB.
x )
4232 return aPtA.
x < aPtB.
x;
4234 if( aPtA.
y != aPtB.
y )
4235 return aPtA.
y < aPtB.
y;
4237 return std::nullopt;
4243 if( itemA->
Type() != itemB->
Type() )
4244 return itemA->
Type() < itemB->
Type();
4249 switch( itemA->
Type() )
4288 for(
int ii = 0; ii < dwgA->
GetPolyShape().TotalVertices(); ++ii )
4290 if( std::optional<bool> cmp =
4347 return itemA < itemB;
4359 std::optional<bool> padCopperMatches;
4362 const PAD* checkPad = aFirst;
4375 padCopperMatches = aFirst->
GetSize( aLayer ).
x < aSecond->
GetSize( aLayer ).
x;
4377 padCopperMatches = aFirst->
GetSize( aLayer ).
y < aSecond->
GetSize( aLayer ).
y;
4379 padCopperMatches = aFirst->
GetShape( aLayer ) < aSecond->
GetShape( aLayer );
4382 if( padCopperMatches.has_value() )
4383 return *padCopperMatches;
4391 return aFirst < aSecond;
4396bool FOOTPRINT::cmp_padstack::operator()(
const PAD* aFirst,
const PAD* aSecond )
const
4436 if( firstShape->VertexCount() != secondShape->VertexCount() )
4437 return firstShape->VertexCount() < secondShape->VertexCount();
4439 for(
int ii = 0; ii < firstShape->VertexCount(); ++ii )
4441 if( std::optional<bool> cmp =
cmp_points_opt( firstShape->CVertex( ii ), secondShape->CVertex( ii ) ) )
4463 for(
int ii = 0; ii < aFirst->
Outline()->TotalVertices(); ++ii )
4465 if( std::optional<bool> cmp =
4475 return aFirst < aSecond;
4480 int aMaxError,
ERROR_LOC aErrorLoc )
const
4491 clearance.x +=
pad->GetSolderMaskExpansion( padLayer );
4492 clearance.y +=
pad->GetSolderMaskExpansion( padLayer );
4515 if( dummySize.
x <= 0 || dummySize.
y <= 0 )
4519 dummy.SetSize( padLayer, dummySize );
4520 dummy.TransformShapeToPolygon( aBuffer, padLayer, 0, aMaxError, aErrorLoc );
4524 pad->TransformShapeToPolygon( aBuffer, padLayer,
clearance.x, aMaxError, aErrorLoc );
4530 if( !
pad->FlashLayer( aLayer ) )
4535 pad->Padstack().ForEachUniqueLayer(
4538 processPad(
pad, l );
4543 processPad(
pad, aLayer );
4550 int aError,
ERROR_LOC aErrorLoc,
bool aIncludeText,
4551 bool aIncludeShapes,
bool aIncludePrivateItems )
const
4558 if( item->Type() ==
PCB_TEXT_T && aIncludeText )
4563 text->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4574 textbox->PCB_SHAPE::TransformShapeToPolygon( aBuffer, aLayer, 0, aError, aErrorLoc );
4581 if( item->Type() ==
PCB_SHAPE_T && aIncludeShapes )
4602 if( ( aLayer ==
UNDEFINED_LAYER || field->GetLayer() == aLayer ) && field->IsVisible() )
4603 field->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4613 std::set<KIFONT::OUTLINE_FONT*>
fonts;
4627 if( permission == PERMISSION::EDITABLE || permission == PERMISSION::INSTALLABLE )
4628 fonts.insert( outlineFont );
4634 processItem( item );
4637 processItem( field );
4682 return wxEmptyString;
4687 const std::unordered_set<wxString>& aComponentClassNames )
4736 LSET padLayers =
pad->GetLayerSet();
4737 padLayers |= boardCopper;
4738 pad->SetLayerSet( padLayers );
4750 if( zcMap.
Choices().GetCount() == 0 )
4762 if( layerEnum.
Choices().GetCount() == 0 )
4770 wxPGChoices fpLayers;
4781 auto isNotFootprintHolder =
4787 return !
board->IsFootprintHolder();
4794 layer->SetChoices( fpLayers );
4795 layer->SetAvailableFunc( isNotFootprintHolder );
4803 const wxString groupFields =
_HKI(
"Fields" );
4828 const wxString groupAttributes =
_HKI(
"Attributes" );
4842 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.
virtual void SetParent(EDA_ITEM *aParent)
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
const VECTOR2I & GetBezierC2() const
SHAPE_POLY_SET & GetPolyShape()
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
const VECTOR2I & GetBezierC1() const
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
const EDA_ANGLE & GetTextAngle() const
virtual const wxString & GetText() const
Return the string associated with the text object.
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
double GetLineSpacing() const
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
int GetTextThickness() const
VECTOR2I GetTextSize() const
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
EMBEDDED_FILES & operator=(EMBEDDED_FILES &&other) noexcept
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Load a file from disk and adds it to the collection.
const std::map< wxString, EMBEDDED_FILE * > & EmbeddedFileMap() const
bool m_embedFonts
If set, fonts will be embedded in the element on save.
ENUM_MAP & Map(T aValue, const wxString &aName)
static ENUM_MAP< T > & Instance()
ENUM_MAP & Undefined(T aValue)
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 & 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 LSET AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
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:
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".
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