26#include <magic_enum.hpp>
29#include <unordered_set>
33#include <wx/tokenzr.h>
73#include <google/protobuf/any.pb.h>
74#include <api/board/board_types.pb.h>
179 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
187 ptrMap[field] = existingField;
188 *existingField = *field;
194 ptrMap[field] = newField;
202 PAD* newPad =
static_cast<PAD*
>(
pad->Clone() );
203 ptrMap[
pad ] = newPad;
210 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
211 ptrMap[ zone ] = newZone;
225 ptrMap[ item ] = newItem;
233 ptrMap[
group ] = newGroup;
240 ptrMap[ point ] = newPoint;
253 if( ptrMap.count( member ) )
254 newGroup->
AddItem( ptrMap[ member ] );
267 *
this = std::move( aFootprint );
307 board->IncrementTimeStamp();
314 types::FootprintInstance footprint;
316 footprint.mutable_id()->set_value(
m_Uuid.AsStdString() );
317 footprint.mutable_position()->set_x_nm(
GetPosition().x );
318 footprint.mutable_position()->set_y_nm(
GetPosition().y );
321 footprint.set_locked(
IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
322 : kiapi::common::types::LockedState::LS_UNLOCKED );
324 google::protobuf::Any buf;
326 buf.UnpackTo( footprint.mutable_reference_field() );
328 buf.UnpackTo( footprint.mutable_value_field() );
330 buf.UnpackTo( footprint.mutable_datasheet_field() );
332 buf.UnpackTo( footprint.mutable_description_field() );
334 types::FootprintAttributes* attrs = footprint.mutable_attributes();
340 attrs->set_do_not_populate(
IsDNP() );
344 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_THROUGH_HOLE );
346 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_SMD );
348 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_UNSPECIFIED );
350 types::Footprint* def = footprint.mutable_definition();
355 def->mutable_attributes()->set_keywords(
GetKeywords().ToStdString() );
359 types::FootprintDesignRuleOverrides* overrides = footprint.mutable_overrides();
373 overrides->set_zone_connection(
378 types::NetTieDefinition* netTie = def->add_net_ties();
379 wxStringTokenizer tokenizer(
group,
", \t\r\n", wxTOKEN_STRTOK );
381 while( tokenizer.HasMoreTokens() )
382 netTie->add_pad_number( tokenizer.GetNextToken().ToStdString() );
390 if( item->IsMandatory() )
393 google::protobuf::Any* itemMsg = def->add_items();
394 item->Serialize( *itemMsg );
397 for(
const PAD* item :
Pads() )
399 google::protobuf::Any* itemMsg = def->add_items();
400 item->Serialize( *itemMsg );
405 google::protobuf::Any* itemMsg = def->add_items();
406 item->Serialize( *itemMsg );
411 google::protobuf::Any* itemMsg = def->add_items();
412 item->Serialize( *itemMsg );
417 google::protobuf::Any* itemMsg = def->add_items();
418 types::Footprint3DModel modelMsg;
419 modelMsg.set_filename(
model.m_Filename.ToUTF8() );
423 modelMsg.set_visible(
model.m_Show );
424 modelMsg.set_opacity(
model.m_Opacity );
425 itemMsg->PackFrom( modelMsg );
430 footprint.set_symbol_sheet_name(
m_sheetname.ToUTF8() );
431 footprint.set_symbol_sheet_filename(
m_sheetfile.ToUTF8() );
432 footprint.set_symbol_footprint_filters(
m_filters.ToUTF8() );
434 aContainer.PackFrom( footprint );
441 types::FootprintInstance footprint;
443 if( !aContainer.UnpackTo( &footprint ) )
450 SetLocked( footprint.locked() == kiapi::common::types::LockedState::LS_LOCKED );
452 google::protobuf::Any buf;
453 types::Field mandatoryField;
455 if( footprint.has_reference_field() )
457 mandatoryField = footprint.reference_field();
459 buf.PackFrom( mandatoryField );
463 if( footprint.has_value_field() )
465 mandatoryField = footprint.value_field();
467 buf.PackFrom( mandatoryField );
471 if( footprint.has_datasheet_field() )
473 mandatoryField = footprint.datasheet_field();
475 buf.PackFrom( mandatoryField );
479 if( footprint.has_description_field() )
481 mandatoryField = footprint.description_field();
483 buf.PackFrom( mandatoryField );
489 switch( footprint.attributes().mounting_style() )
491 case types::FootprintMountingStyle::FMS_THROUGH_HOLE:
495 case types::FootprintMountingStyle::FMS_SMD:
503 SetBoardOnly( footprint.attributes().not_in_schematic() );
507 SetDNP( footprint.attributes().do_not_populate() );
514 SetKeywords( footprint.definition().attributes().keywords() );
516 const types::FootprintDesignRuleOverrides& overrides = footprint.overrides();
518 if( overrides.has_copper_clearance() )
523 if( overrides.has_solder_mask() && overrides.solder_mask().has_solder_mask_margin() )
528 if( overrides.has_solder_paste() )
530 const types::SolderPasteOverrides& pasteSettings = overrides.solder_paste();
532 if( pasteSettings.has_solder_paste_margin() )
537 if( pasteSettings.has_solder_paste_margin_ratio() )
545 for(
const types::NetTieDefinition& netTieMsg : footprint.definition().net_ties() )
549 for(
const std::string&
pad : netTieMsg.pad_number() )
550 group.Append( wxString::Format( wxT(
"%s " ),
pad ) );
558 for(
int layerMsg : footprint.definition().private_layers() )
563 privateLayers.
set( layer );
569 m_sheetname = wxString::FromUTF8( footprint.symbol_sheet_name() );
570 m_sheetfile = wxString::FromUTF8( footprint.symbol_sheet_filename() );
571 m_filters = wxString::FromUTF8( footprint.symbol_footprint_filters() );
576 if( !field->IsMandatory() )
584 board->UncacheItemById(
pad->m_Uuid );
587 board->UncacheItemById( item->m_Uuid );
590 board->UncacheItemById( zone->m_Uuid );
596 board->UncacheItemById( point->m_Uuid );
606 for(
const google::protobuf::Any& itemMsg : footprint.definition().items() )
614 if( itemMsg.type_url() ==
"type.googleapis.com/kiapi.board.types.Footprint3DModel" )
616 types::Footprint3DModel modelMsg;
618 if( !itemMsg.UnpackTo( &modelMsg ) )
623 model.m_Filename = wxString::FromUTF8( modelMsg.filename() );
624 model.m_Show = modelMsg.visible();
625 model.m_Opacity = modelMsg.opacity();
634 wxLogTrace(
traceApi, wxString::Format( wxS(
"Attempting to unpack unknown type %s "
635 "from footprint message, skipping" ),
636 itemMsg.type_url() ) );
644 if( item && item->Deserialize( itemMsg ) )
656 if( field->GetId() == aFieldType )
671 if( field->GetId() == aFieldType )
681 return GetField( aFieldName ) !=
nullptr;
689 if( field->GetName() == aFieldName )
705 if( !field->IsVisible() || field->GetText().IsEmpty() )
709 aVector.push_back( field );
712 std::sort( aVector.begin(), aVector.end(),
715 return lhs->GetOrdinal() < rhs->GetOrdinal();
725 ordinal = std::max( ordinal, field->GetOrdinal() + 1 );
732 bool aStyleShapes,
bool aStyleDimensions,
bool aStyleBarcodes )
737 field->StyleFromSettings(
board.GetDesignSettings(),
true );
742 switch( item->Type() )
747 item->StyleFromSettings(
board.GetDesignSettings(),
true );
752 if( aStyleShapes && !item->IsOnCopperLayer() )
753 item->StyleFromSettings(
board.GetDesignSettings(),
true );
762 if( aStyleDimensions )
763 item->StyleFromSettings(
board.GetDesignSettings(),
true );
769 item->StyleFromSettings(
board.GetDesignSettings(),
true );
782 std::vector< BOARD_ITEM* > item_list;
785 item_list.push_back( field );
788 item_list.push_back(
pad );
791 item_list.push_back( gr_item );
796 item_list.push_back(
group );
800 item_list.push_back( zone );
804 item_list.push_back( point );
806 bool changed =
false;
812 const_cast<KIID&
>( item->m_Uuid ) =
KIID();
825 m_pos = aOther.m_pos;
855 board->UncacheItemById( field->m_Uuid );
858 board->UncacheItemById(
pad->m_Uuid );
861 board->UncacheItemById( zone->m_Uuid );
864 board->UncacheItemById( item->m_Uuid );
870 board->UncacheItemById( point->m_Uuid );
879 for(
PCB_FIELD* field : aOther.m_fields )
882 aOther.m_fields.clear();
890 for(
PAD*
pad : aOther.Pads() )
893 aOther.Pads().clear();
901 for(
ZONE* item : aOther.Zones() )
909 item->SetNetCode( -1 );
912 aOther.Zones().clear();
920 for(
BOARD_ITEM* item : aOther.GraphicalItems() )
923 aOther.GraphicalItems().clear();
934 aOther.Groups().clear();
942 for(
PCB_POINT* point : aOther.Points() )
945 aOther.Points().clear();
958 aOther.m_componentClassCacheProxy->GetStaticComponentClass() );
961 aOther.m_fields.clear();
962 aOther.Pads().clear();
963 aOther.Zones().clear();
964 aOther.GraphicalItems().clear();
965 aOther.m_initial_comments =
nullptr;
1005 board->UncacheItemById( field->m_Uuid );
1008 board->UncacheItemById(
pad->m_Uuid );
1011 board->UncacheItemById( zone->m_Uuid );
1014 board->UncacheItemById( item->m_Uuid );
1020 board->UncacheItemById( point->m_Uuid );
1023 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
1034 ptrMap[field] = newField;
1047 ptrMap[
pad ] = newPad;
1059 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
1060 ptrMap[ zone ] = newZone;
1079 ptrMap[ item ] = newItem;
1095 newGroup->
AddItem( ptrMap[ member ] );
1109 ptrMap[ point ] = newItem;
1134 *
this = *
static_cast<const FOOTPRINT*
>( aOther );
1160 aVars->push_back( wxT(
"REFERENCE" ) );
1161 aVars->push_back( wxT(
"VALUE" ) );
1162 aVars->push_back( wxT(
"LAYER" ) );
1163 aVars->push_back( wxT(
"FOOTPRINT_LIBRARY" ) );
1164 aVars->push_back( wxT(
"FOOTPRINT_NAME" ) );
1165 aVars->push_back( wxT(
"SHORT_NET_NAME(<pad_number>)" ) );
1166 aVars->push_back( wxT(
"NET_NAME(<pad_number>)" ) );
1167 aVars->push_back( wxT(
"NET_CLASS(<pad_number>)" ) );
1168 aVars->push_back( wxT(
"PIN_NAME(<pad_number>)" ) );
1177 if( token->IsSameAs( wxT(
"REFERENCE" ) ) )
1182 else if( token->IsSameAs( wxT(
"VALUE" ) ) )
1187 else if( token->IsSameAs( wxT(
"LAYER" ) ) )
1192 else if( token->IsSameAs( wxT(
"FOOTPRINT_LIBRARY" ) ) )
1194 *token =
m_fpid.GetUniStringLibNickname();
1197 else if( token->IsSameAs( wxT(
"FOOTPRINT_NAME" ) ) )
1199 *token =
m_fpid.GetUniStringLibItemName();
1202 else if( token->StartsWith( wxT(
"SHORT_NET_NAME(" ) )
1203 || token->StartsWith( wxT(
"NET_NAME(" ) )
1204 || token->StartsWith( wxT(
"NET_CLASS(" ) )
1205 || token->StartsWith( wxT(
"PIN_NAME(" ) ) )
1207 wxString padNumber = token->AfterFirst(
'(' );
1208 padNumber = padNumber.BeforeLast(
')' );
1212 if(
pad->GetNumber() == padNumber )
1214 if( token->StartsWith( wxT(
"SHORT_NET_NAME" ) ) )
1215 *token =
pad->GetShortNetname();
1216 else if( token->StartsWith( wxT(
"NET_NAME" ) ) )
1217 *token =
pad->GetNetname();
1218 else if( token->StartsWith( wxT(
"NET_CLASS" ) ) )
1219 *token =
pad->GetNetClassName();
1221 *token =
pad->GetPinFunction();
1229 *token = field->GetShownText(
false, aDepth + 1 );
1248 return it !=
m_variants.end() ? &it->second :
nullptr;
1256 return it !=
m_variants.end() ? &it->second :
nullptr;
1262 if( aVariant.
GetName().IsEmpty()
1274 it->second = std::move( updated );
1284 if( aVariantName.IsEmpty()
1287 wxASSERT_MSG(
false, wxT(
"Variant name cannot be empty or default." ) );
1301 auto inserted =
m_variants.emplace( aVariantName, std::move( variant ) );
1302 return &inserted.first->second;
1314 if( aNewName.IsEmpty()
1325 auto existingIt =
m_variants.find( aNewName );
1327 if( existingIt !=
m_variants.end() && existingIt != it )
1330 if( it->first == aNewName )
1336 m_variants.emplace( aNewName, std::move( variant ) );
1349 if( aVariantName.IsEmpty()
1356 return variant->
GetDNP();
1366 if( aVariantName.IsEmpty()
1383 if( aVariantName.IsEmpty()
1398 const wxString& aFieldName )
const
1401 if( !aVariantName.IsEmpty()
1412 return field->GetText();
1429 switch( aBoardItem->
Type() )
1455 m_pads.push_back(
static_cast<PAD*
>( aBoardItem ) );
1457 m_pads.push_front(
static_cast<PAD*
>( aBoardItem ) );
1463 m_zones.push_back(
static_cast<ZONE*
>( aBoardItem ) );
1478 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Markers go at the board level, even in the footprint editor" ) );
1482 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Nested footprints not supported" ) );
1494 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Add(): BOARD_ITEM type (%d) not handled" ),
1495 aBoardItem->
Type() ) );
1505 board->CacheItemById( aBoardItem );
1513 switch( aBoardItem->
Type() )
1518 if( *it == aBoardItem )
1540 if( *it == aBoardItem )
1550 for(
auto it =
m_pads.begin(); it !=
m_pads.end(); ++it )
1552 if( *it ==
static_cast<PAD*
>( aBoardItem ) )
1564 if( *it ==
static_cast<ZONE*
>( aBoardItem ) )
1576 if( *it ==
static_cast<PCB_GROUP*
>( aBoardItem ) )
1588 if( *it ==
static_cast<PCB_POINT*
>( aBoardItem ) )
1600 msg.Printf( wxT(
"FOOTPRINT::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
1601 aBoardItem->
Type() );
1633 switch(
pad->GetProperty() )
1651 switch(
pad->GetAttribute() )
1658 if(
pad->IsOnCopperLayer() )
1686 return _(
"Through hole" );
1688 return _(
"Other" );
1694 std::vector<SEARCH_TERM> terms;
1700 wxStringTokenizer keywordTokenizer(
GetKeywords(), wxS(
" \t\r\n" ), wxTOKEN_STRTOK );
1702 while( keywordTokenizer.HasMoreTokens() )
1703 terms.emplace_back(
SEARCH_TERM( keywordTokenizer.GetNextToken(), 4 ) );
1723 if(
dummy.IsFlipped() )
1727 bbox.
Merge(
pad->GetBoundingBox() );
1776 std::vector<PCB_TEXT*> texts;
1777 bool isFPEdit =
board &&
board->IsFootprintHolder();
1798 texts.push_back(
static_cast<PCB_TEXT*
>( item ) );
1816 bbox.
Merge( item->GetBoundingBox() );
1822 if( field->IsReference() || field->IsValue() )
1825 texts.push_back( field );
1829 bbox.
Merge(
pad->GetBoundingBox() );
1832 bbox.
Merge( zone->GetBoundingBox() );
1835 bbox.
Merge( point->GetBoundingBox() );
1840 if( aIncludeText || noDrawItems )
1857 bool valueLayerIsVisible =
true;
1858 bool refLayerIsVisible =
true;
1876 if( (
Value().IsVisible() && valueLayerIsVisible ) || noDrawItems )
1881 if( (
Reference().IsVisible() && refLayerIsVisible ) || noDrawItems )
1891 if( aIncludeText || noDrawItems )
1909 std::vector<PCB_TEXT*> texts;
1911 bool isFPEdit =
board &&
board->IsFootprintHolder();
1921 if( ( aLayers & item->GetLayerSet() ).none() )
1929 bbox.
Merge( item->GetBoundingBox() );
1934 if( ( aLayers &
pad->GetLayerSet() ).none() )
1937 bbox.
Merge(
pad->GetBoundingBox() );
1942 if( ( aLayers & zone->GetLayerSet() ).none() )
1945 bbox.
Merge( zone->GetBoundingBox() );
1953 if( ( aLayers & point->GetLayerSet() ).none() )
1956 bbox.
Merge( point->GetBoundingBox() );
1966 bool isFPEdit =
board &&
board->IsFootprintHolder();
1992 pad->Padstack().ForEachUniqueLayer(
2006 const SHAPE_POLY_SET& layerPoly = *zone->GetFilledPolysList( layer );
2022 const int halfsize =
pcbIUScale.mmToIU( 1.0 );
2033 std::vector<VECTOR2I> convex_hull;
2039 for(
const VECTOR2I& pt : convex_hull )
2052 bool isFPEdit =
board &&
board->IsFootprintHolder();
2062 if( item->IsOnLayer( aLayer ) )
2076 if(
pad->IsOnLayer( aLayer ) )
2082 if( zone->GetIsRuleArea() )
2085 if( zone->IsOnLayer( aLayer ) )
2087 const std::shared_ptr<SHAPE_POLY_SET>& layerPoly = zone->GetFilledPolysList( aLayer );
2089 for(
int ii = 0; ii < layerPoly->OutlineCount(); ii++ )
2090 rawPolys.
AddOutline( layerPoly->COutline( ii ) );
2094 std::vector<VECTOR2I> convex_hull;
2099 for(
const VECTOR2I& pt : convex_hull )
2122 aList.emplace_back(
_(
"Footprint Name" ),
GetFPID().GetLibItemName().wx_str() );
2124 aList.emplace_back(
_(
"Pads" ), wxString::Format( wxT(
"%zu" ), padCount ) );
2127 wxString::Format(
_(
"Keywords: %s" ),
GetKeywords() ) );
2136 case F_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Front" ) );
break;
2137 case B_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Back (Flipped)" ) );
break;
2141 auto addToken = []( wxString* aStr,
const wxString& aAttr )
2143 if( !aStr->IsEmpty() )
2144 *aStr += wxT(
", " );
2153 addToken( &status,
_(
"Locked" ) );
2156 addToken( &status,
_(
"autoplaced" ) );
2159 addToken( &attrs,
_(
"not in schematic" ) );
2162 addToken( &attrs,
_(
"exclude from pos files" ) );
2165 addToken( &attrs,
_(
"exclude from BOM" ) );
2168 addToken( &attrs,
_(
"DNP" ) );
2170 aList.emplace_back(
_(
"Status: " ) + status,
_(
"Attributes:" ) + wxS(
" " ) + attrs );
2172 aList.emplace_back(
_(
"Rotation" ), wxString::Format( wxT(
"%.4g" ),
2178 _(
"Component Class" ),
2182 msg.Printf(
_(
"Footprint: %s" ),
m_fpid.GetUniStringLibId() );
2183 msg2.Printf(
_(
"3D-Shape: %s" ),
m_3D_Drawings.empty() ?
_(
"<none>" )
2185 aList.emplace_back( msg, msg2 );
2189 aList.emplace_back( msg, msg2 );
2197 if(
board->IsFootprintHolder() )
2229 if(
pad->IsOnLayer( aLayer ) )
2235 if( zone->IsOnLayer( aLayer ) )
2241 if( field->IsOnLayer( aLayer ) )
2247 if( item->IsOnLayer( aLayer ) )
2259 if(
pad->IsOnLayer( aLayer ) &&
pad->HitTest( aPosition, aAccuracy ) )
2265 if( zone->IsOnLayer( aLayer ) && zone->HitTest( aPosition, aAccuracy ) )
2271 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer )
2272 && item->HitTest( aPosition, aAccuracy ) )
2284 std::vector<BOARD_ITEM*> items;
2288 if(
pad->IsOnLayer( aLayer ) )
2289 items.push_back(
pad );
2294 if( zone->IsOnLayer( aLayer ) )
2295 items.push_back( zone );
2300 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer ) )
2301 items.push_back( item );
2310 if( !aContained && item->HitTest( aRect, aContained, aAccuracy ) )
2312 else if( aContained && !item->HitTest( aRect, aContained, aAccuracy ) )
2319 return !items.empty() && aContained;
2338 BOX2I arect = aRect;
2358 if(
pad->HitTest( arect,
false, 0 ) )
2364 if( zone->HitTest( arect,
false, 0 ) )
2370 if( point->HitTest( arect,
false, 0 ) )
2381 if( item->Type() !=
PCB_TEXT_T && item->HitTest( arect,
false, 0 ) )
2395 using std::ranges::all_of;
2396 using std::ranges::any_of;
2403 [&](
const auto* aItem )
2405 return aItem && aItem->HitTest( aPoly, aContained );
2411 auto drawings =
m_drawings | std::views::filter( [](
const auto* aItem )
2422 return all_of( drawings, hitTest )
2423 && all_of(
m_pads, hitTest )
2424 && all_of(
m_zones, hitTest );
2429 return any_of( drawings, hitTest )
2430 || any_of(
m_pads, hitTest )
2431 || any_of(
m_zones, hitTest );
2438 bool can_select = aSearchAfterMe ? false :
true;
2442 if( !can_select &&
pad == aSearchAfterMe )
2448 if( can_select &&
pad->GetNumber() == aPadNumber )
2461 if( !(
pad->GetLayerSet() & aLayerMask ).any() )
2464 if(
pad->HitTest( aPosition ) )
2474 std::vector<const PAD*> retv;
2478 if( ( aIgnore && aIgnore ==
pad ) || (
pad->GetNumber() != aPadNumber ) )
2481 retv.push_back(
pad );
2509 std::set<wxString> usedNumbers;
2521 if(
pad->GetNumber().IsEmpty() )
2531 usedNumbers.insert(
pad->GetNumber() );
2546 if(
nullptr == a3DModel )
2574 const std::vector<KICAD_T>& aScanTypes )
2576#if 0 && defined(DEBUG)
2577 std::cout <<
GetClass().mb_str() <<
' ';
2580 bool drawingsScanned =
false;
2582 for(
KICAD_T scanType : aScanTypes )
2630 if( !drawingsScanned )
2638 drawingsScanned =
true;
2674 if( reference.IsEmpty() )
2675 reference =
_(
"<no reference designator>" );
2677 return wxString::Format(
_(
"Footprint %s" ), reference );
2714 aFunction( drawing );
2720 catch( std::bad_function_call& )
2722 wxFAIL_MSG( wxT(
"Error running FOOTPRINT::RunOnChildren" ) );
2729 std::vector<int> layers;
2731 layers.reserve( 6 );
2737 wxASSERT_MSG(
false, wxT(
"Illegal layer" ) );
2755 bool f_silk =
false, b_silk =
false, non_silk =
false;
2759 if( item->GetLayer() ==
F_SilkS )
2761 else if( item->GetLayer() ==
B_SilkS )
2767 if( ( f_silk || b_silk ) && !non_silk &&
m_pads.empty() )
2804 constexpr double MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY = 1.5;
2807 return MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY;
2820 int biggest_clearance =
board->GetMaxClearanceValue();
2821 area.
Inflate( biggest_clearance );
2832 if( aName.find_first_of( invalids ) != std::string::npos )
2846 static const wxChar invalidChars[] = wxT(
"%$<>\t\n\r\"\\/:");
2847 static const wxChar invalidCharsReadable[] = wxT(
"% $ < > 'tab' 'return' 'line feed' \\ \" / :");
2850 return invalidCharsReadable;
2852 return invalidChars;
2858 if( aMoveVector.
x == 0 && aMoveVector.
y == 0 )
2872 EDA_ANGLE newOrientation = orientation + aAngle;
2879 field->KeepUpright();
2884 static_cast<PCB_TEXT*
>( item )->KeepUpright();
2891 wxASSERT( aLayer ==
F_Cu || aLayer ==
B_Cu );
2968 field->EDA_TEXT::Offset(
delta );
2974 zone->Move(
delta );
2977 item->Move(
delta );
2980 point->Move(
delta );
3012 field->Move( moveVector );
3016 pad->Move( moveVector );
3020 item->Move( moveVector );
3024 zone->Move( moveVector );
3092 const BOARD_ITEM* aItem,
bool addToFootprint )
3096 switch( aItem->
Type() )
3100 PAD* new_pad =
new PAD( *
static_cast<const PAD*
>( aItem ) );
3103 if( addToFootprint )
3104 m_pads.push_back( new_pad );
3112 ZONE* new_zone =
new ZONE( *
static_cast<const ZONE*
>( aItem ) );
3115 if( addToFootprint )
3116 m_zones.push_back( new_zone );
3118 new_item = new_zone;
3127 if( addToFootprint )
3130 new_item = new_point;
3142 switch(
static_cast<const PCB_FIELD*
>( aItem )->GetId() )
3151 if( addToFootprint )
3154 new_item = new_text;
3163 if( addToFootprint )
3166 new_item = new_shape;
3175 if( addToFootprint )
3178 new_item = new_barcode;
3187 if( addToFootprint )
3190 new_item = new_image;
3199 if( addToFootprint )
3202 new_item = new_textbox;
3215 if( addToFootprint )
3218 new_item = dimension;
3226 if( addToFootprint )
3228 group->RunOnChildren(
3248 wxFAIL_MSG( wxT(
"Duplication not supported for items of class " ) + aItem->
GetClass() );
3258 std::set<wxString> usedNumbers;
3262 usedNumbers.insert(
pad->GetNumber() );
3269 while( usedNumbers.count( wxString::Format( wxT(
"%s%d" ), prefix, num ) ) )
3272 return wxString::Format( wxT(
"%s%d" ), prefix, num );
3280 if(
group.contains( aPadNumber ) )
3284 return std::nullopt;
3335 for(
int jj = 0; jj < aPolySet.
HoleCount( ii ); jj++ )
3339 return aPolySet.
Area();
3354 return markerShape.
Area();
3358 double combinedArea = 0.0;
3363 return combinedArea;
3414 double width =
static_cast<const PCB_TRACK*
>( aItem )->GetWidth();
3415 return width * width;
3419 static_cast<const PAD*
>( aItem )->Padstack().ForEachUniqueLayer(
3451 for(
int i = 0; i < aCollector.
GetCount(); ++i )
3455 switch( item->
Type() )
3487 double footprintRegionArea =
polygonArea( footprintRegion );
3488 double uncoveredRegionArea = footprintRegionArea -
polygonArea( coveredRegion );
3489 double coveredArea = footprintRegionArea - uncoveredRegionArea;
3492 if( footprintRegionArea == 0 )
3495 double ratio = coveredArea / footprintRegionArea;
3502 return std::min( ratio, 1.0 );
3508 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
3529 shape->AddShape(
pad->GetEffectiveShape( aLayer, aFlash )->Clone() );
3534 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3536 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3576 std::vector<PCB_SHAPE*> list_front;
3577 std::vector<PCB_SHAPE*> list_back;
3578 std::map<int, int> front_width_histogram;
3579 std::map<int, int> back_width_histogram;
3586 list_back.push_back( shape );
3593 list_front.push_back( shape );
3598 if( !list_front.size() && !list_back.size() )
3602 int chainingEpsilon =
pcbIUScale.mmToIU( 0.02 );
3605 true, aErrorHandler ) )
3615 auto max = std::max_element( front_width_histogram.begin(), front_width_histogram.end(),
3616 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3618 return a.second < b.second;
3621 if( max != front_width_histogram.end() )
3644 auto max = std::max_element( back_width_histogram.begin(), back_width_histogram.end(),
3645 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3647 return a.second < b.second;
3650 if( max != back_width_histogram.end() )
3673 std::map<PCB_LAYER_ID, std::vector<PCB_SHAPE*>> layer_shapes;
3679 if( item->Type() != PCB_SHAPE_T )
3682 for( PCB_LAYER_ID layer : item->GetLayerSet() )
3684 if( !IsCopperLayer( layer ) )
3687 if( board && !board->GetEnabledLayers().Contains( layer ) )
3690 layer_shapes[layer].push_back( static_cast<PCB_SHAPE*>( item ) );
3694 for(
size_t ii = 0; ii < m_pads.size(); ++ii )
3697 bool has_nettie =
false;
3699 auto it = map.find(
pad->GetNumber() );
3701 if( it == map.end() || it->second < 0 )
3704 for(
size_t jj = ii + 1; jj < m_pads.size(); ++jj )
3706 PAD* other = m_pads[ jj ];
3708 auto it2 = map.find( other->
GetNumber() );
3710 if( it2 == map.end() || it2->second < 0 )
3713 if( it2->second == it->second )
3715 m_netTieCache[
pad].insert(
pad->GetNetCode() );
3717 m_netTieCache[other].insert( other->
GetNetCode() );
3718 m_netTieCache[other].insert(
pad->GetNetCode() );
3726 for(
auto& [ layer, shapes ] : layer_shapes )
3728 auto pad_shape =
pad->GetEffectiveShape( layer );
3730 for(
auto other_shape : shapes )
3732 auto shape = other_shape->GetEffectiveShape( layer );
3734 if( pad_shape->Collide( shape.get() ) )
3736 std::set<int>& nettie = m_netTieCache[
pad];
3737 m_netTieCache[other_shape].insert( nettie.begin(), nettie.end() );
3747 std::map<wxString, int> padNumberToGroupIdxMap;
3750 padNumberToGroupIdxMap[
pad->GetNumber() ] = -1;
3753 [&]( wxString aPad,
int aGroup )
3755 aPad.Trim(
true ).Trim(
false );
3757 if( !aPad.IsEmpty() )
3758 padNumberToGroupIdxMap[ aPad ] = aGroup;
3767 for( wxUniCharRef ch :
group )
3776 switch(
static_cast<unsigned char>( ch ) )
3783 processPad(
pad, ii );
3793 processPad(
pad, ii );
3796 return padNumberToGroupIdxMap;
3806 int groupIdx = padToNetTieGroupMap[ aPad->
GetNumber() ];
3807 std::vector<PAD*> otherPads;
3813 if( padToNetTieGroupMap[
pad->GetNumber() ] == groupIdx )
3814 otherPads.push_back(
pad );
3827 if( setAttr && likelyAttr && setAttr != likelyAttr )
3831 switch( likelyAttr )
3834 msg.Printf(
_(
"(expected 'Through hole'; actual '%s')" ),
GetTypeName() );
3837 msg.Printf(
_(
"(expected 'SMD'; actual '%s')" ),
GetTypeName() );
3842 (aErrorHandler)( msg );
3848 const std::function<
void(
const PAD*,
int,
3849 const wxString& )>& aErrorHandler )
3851 if( aErrorHandler ==
nullptr )
3856 pad->CheckPad( aUnitsProvider,
false,
3857 [&](
int errorCode,
const wxString& msg )
3859 aErrorHandler(
pad, errorCode, msg );
3867 const VECTOR2I& )>& aErrorHandler )
3869 std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
3884 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
3887 if( checkedPairs.find( { a, b } ) == checkedPairs.end() )
3889 checkedPairs[ { a, b } ] = 1;
3901 std::shared_ptr<SHAPE_SEGMENT> holeA =
pad->GetEffectiveHoleShape();
3904 if( holeA->Collide( holeB->GetSeg(), 0 ) )
3921 SHAPE* padShape =
pad->GetEffectiveShape( l ).get();
3924 if( padShape->
Collide( otherShape, 0,
nullptr, &pos ) )
3937 const VECTOR2I& )>& aErrorHandler )
3946 std::vector<BOARD_ITEM*> copperItems;
3950 if( item->IsOnCopperLayer() )
3951 copperItems.push_back( item );
3953 item->RunOnChildren(
3957 copperItems.push_back( descendent );
3964 if( !zone->GetIsRuleArea() && zone->IsOnCopperLayer() )
3965 copperItems.push_back( zone );
3970 if( field->IsOnCopperLayer() )
3971 copperItems.push_back( field );
3981 std::map<int, std::vector<const PAD*>> outlineIdxToPadsMap;
3985 if( item->IsOnLayer( layer ) )
3995 for(
int ii = 0; ii < copperOutlines.
OutlineCount(); ++ii )
3997 if(
pad->GetEffectiveShape( layer )->Collide( &copperOutlines.
Outline( ii ), 0 ) )
3998 outlineIdxToPadsMap[ ii ].emplace_back(
pad );
4005 for(
const auto& [ outlineIdx, pads ] : outlineIdxToPadsMap )
4007 if( pads.size() > 1 )
4009 const PAD* firstPad = pads[0];
4010 int firstGroupIdx = padNumberToGroupIdxMap[ firstPad->
GetNumber() ];
4012 for(
size_t ii = 1; ii < pads.size(); ++ii )
4014 const PAD* thisPad = pads[ii];
4015 int thisGroupIdx = padNumberToGroupIdxMap[ thisPad->
GetNumber() ];
4017 if( thisGroupIdx < 0 || thisGroupIdx != firstGroupIdx )
4026 if( item->HitTest( pos, 1 ) )
4028 shortingItem = item;
4034 aErrorHandler( shortingItem, firstPad, thisPad, pos );
4036 aErrorHandler( firstPad, thisPad,
nullptr, pos );
4047 std::set<wxString> padNumbers;
4056 msg.Printf(
_(
"(net-tie pad group contains unknown pad number %s)" ), padNumber );
4057 aErrorHandler( msg );
4059 else if( !padNumbers.insert(
pad->GetNumber() ).second )
4061 msg.Printf(
_(
"(pad %s appears in more than one net-tie pad group)" ), padNumber );
4062 aErrorHandler( msg );
4070 const VECTOR2I& aPt )>& aErrorHandler )
4072 auto checkColliding =
4087 if( itemShape->Collide( otherShape.get(), 0, &
actual, &pos ) )
4088 aErrorHandler( item, other, pos );
4097 checkColliding( item, other );
4101 checkColliding( item,
pad );
4112 std::swap( *
this, *
image );
4121 image->RunOnChildren(
4149 return *
this == other;
4158 for(
size_t ii = 0; ii <
m_pads.size(); ++ii )
4167 for(
size_t ii = 0; ii <
m_drawings.size(); ++ii )
4176 for(
size_t ii = 0; ii <
m_zones.size(); ++ii )
4186 std::vector<PCB_FIELD*> fields, otherFields;
4191 if( fields.size() != otherFields.size() )
4194 for(
size_t ii = 0; ii < fields.size(); ++ii )
4198 if( !( *fields[ii] == *otherFields[ii] ) )
4214 double similarity = 1.0;
4223 similarity *=
pad->Similarity( *otherPad );
4235 if( aPtA.
x != aPtB.
x )
4236 return aPtA.
x < aPtB.
x;
4238 if( aPtA.
y != aPtB.
y )
4239 return aPtA.
y < aPtB.
y;
4241 return std::nullopt;
4247 if( itemA->
Type() != itemB->
Type() )
4248 return itemA->
Type() < itemB->
Type();
4253 switch( itemA->
Type() )
4292 for(
int ii = 0; ii < dwgA->
GetPolyShape().TotalVertices(); ++ii )
4294 if( std::optional<bool> cmp =
4351 return itemA < itemB;
4363 std::optional<bool> padCopperMatches;
4366 const PAD* checkPad = aFirst;
4379 padCopperMatches = aFirst->
GetSize( aLayer ).
x < aSecond->
GetSize( aLayer ).
x;
4381 padCopperMatches = aFirst->
GetSize( aLayer ).
y < aSecond->
GetSize( aLayer ).
y;
4383 padCopperMatches = aFirst->
GetShape( aLayer ) < aSecond->
GetShape( aLayer );
4386 if( padCopperMatches.has_value() )
4387 return *padCopperMatches;
4395 return aFirst < aSecond;
4400bool FOOTPRINT::cmp_padstack::operator()(
const PAD* aFirst,
const PAD* aSecond )
const
4440 if( firstShape->VertexCount() != secondShape->VertexCount() )
4441 return firstShape->VertexCount() < secondShape->VertexCount();
4443 for(
int ii = 0; ii < firstShape->VertexCount(); ++ii )
4445 if( std::optional<bool> cmp =
cmp_points_opt( firstShape->CVertex( ii ), secondShape->CVertex( ii ) ) )
4467 for(
int ii = 0; ii < aFirst->
Outline()->TotalVertices(); ++ii )
4469 if( std::optional<bool> cmp =
4479 return aFirst < aSecond;
4484 int aMaxError,
ERROR_LOC aErrorLoc )
const
4495 clearance.x +=
pad->GetSolderMaskExpansion( padLayer );
4496 clearance.y +=
pad->GetSolderMaskExpansion( padLayer );
4519 if( dummySize.
x <= 0 || dummySize.
y <= 0 )
4523 dummy.SetSize( padLayer, dummySize );
4524 dummy.TransformShapeToPolygon( aBuffer, padLayer, 0, aMaxError, aErrorLoc );
4528 pad->TransformShapeToPolygon( aBuffer, padLayer,
clearance.x, aMaxError, aErrorLoc );
4534 if( !
pad->FlashLayer( aLayer ) )
4539 pad->Padstack().ForEachUniqueLayer(
4542 processPad(
pad, l );
4547 processPad(
pad, aLayer );
4554 int aError,
ERROR_LOC aErrorLoc,
bool aIncludeText,
4555 bool aIncludeShapes,
bool aIncludePrivateItems )
const
4562 if( item->Type() ==
PCB_TEXT_T && aIncludeText )
4567 text->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4578 textbox->PCB_SHAPE::TransformShapeToPolygon( aBuffer, aLayer, 0, aError, aErrorLoc );
4585 if( item->Type() ==
PCB_SHAPE_T && aIncludeShapes )
4606 if( ( aLayer ==
UNDEFINED_LAYER || field->GetLayer() == aLayer ) && field->IsVisible() )
4607 field->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4617 std::set<KIFONT::OUTLINE_FONT*>
fonts;
4631 if( permission == PERMISSION::EDITABLE || permission == PERMISSION::INSTALLABLE )
4632 fonts.insert( outlineFont );
4638 processItem( item );
4641 processItem( field );
4686 return wxEmptyString;
4691 const std::unordered_set<wxString>& aComponentClassNames )
4740 LSET padLayers =
pad->GetLayerSet();
4741 padLayers |= boardCopper;
4742 pad->SetLayerSet( padLayers );
4754 if( zcMap.
Choices().GetCount() == 0 )
4766 if( layerEnum.
Choices().GetCount() == 0 )
4774 wxPGChoices fpLayers;
4785 auto isNotFootprintHolder =
4791 return !
board->IsFootprintHolder();
4798 layer->SetChoices( fpLayers );
4799 layer->SetAvailableFunc( isNotFootprintHolder );
4807 const wxString groupFields =
_HKI(
"Fields" );
4815 const wxString groupAttributes =
_HKI(
"Attributes" );
4829 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 & 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.
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:
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.
@ 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