26#include <magic_enum.hpp>
28#include <unordered_set>
63#include <google/protobuf/any.pb.h>
64#include <api/board/board_types.pb.h>
73 m_boundingBoxCacheTimeStamp( 0 ), m_textExcludedBBoxCacheTimeStamp( 0 ),
74 m_hullCacheTimeStamp( 0 ), m_initial_comments( nullptr ),
97 addField( FIELD_T::REFERENCE,
F_SilkS,
true );
98 addField( FIELD_T::VALUE,
F_Fab,
true );
99 addField( FIELD_T::DATASHEET,
F_Fab,
false );
100 addField( FIELD_T::DESCRIPTION,
F_Fab,
false );
139 std::map<BOARD_ITEM*, BOARD_ITEM*> ptrMap;
147 ptrMap[field] = existingField;
148 *existingField = *field;
154 ptrMap[field] = newField;
162 PAD* newPad =
static_cast<PAD*
>(
pad->Clone() );
163 ptrMap[
pad ] = newPad;
164 Add( newPad, ADD_MODE::APPEND );
170 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
171 ptrMap[ zone ] = newZone;
172 Add( newZone, ADD_MODE::APPEND );
185 ptrMap[ item ] = newItem;
186 Add( newItem, ADD_MODE::APPEND );
193 ptrMap[
group ] = newGroup;
194 Add( newGroup, ADD_MODE::APPEND );
206 if( ptrMap.count( member ) )
207 newGroup->
AddItem( ptrMap[ member ] );
230 *
this = std::move( aFootprint );
240 item->SetParentGroup(
nullptr );
272 board->IncrementTimeStamp();
279 types::FootprintInstance footprint;
282 footprint.mutable_position()->set_x_nm(
GetPosition().x );
283 footprint.mutable_position()->set_y_nm(
GetPosition().y );
285 footprint.set_layer( ToProtoEnum<PCB_LAYER_ID, types::BoardLayer>(
GetLayer() ) );
286 footprint.set_locked(
IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
287 : kiapi::common::types::LockedState::LS_UNLOCKED );
289 google::protobuf::Any buf;
291 buf.UnpackTo( footprint.mutable_reference_field() );
293 buf.UnpackTo( footprint.mutable_value_field() );
295 buf.UnpackTo( footprint.mutable_datasheet_field() );
297 buf.UnpackTo( footprint.mutable_description_field() );
299 types::FootprintAttributes* attrs = footprint.mutable_attributes();
305 attrs->set_do_not_populate(
IsDNP() );
308 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_THROUGH_HOLE );
310 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_SMD );
312 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_UNSPECIFIED );
314 types::Footprint* def = footprint.mutable_definition();
319 def->mutable_attributes()->set_keywords(
GetKeywords().ToStdString() );
323 types::FootprintDesignRuleOverrides* overrides = def->mutable_overrides();
337 overrides->set_zone_connection(
342 types::NetTieDefinition* netTie = def->add_net_ties();
343 wxStringTokenizer tokenizer(
group,
" " );
345 while( tokenizer.HasMoreTokens() )
346 netTie->add_pad_number( tokenizer.GetNextToken().ToStdString() );
350 def->add_private_layers( ToProtoEnum<PCB_LAYER_ID, types::BoardLayer>( layer ) );
354 if( item->IsMandatory() )
357 google::protobuf::Any* itemMsg = def->add_items();
358 item->Serialize( *itemMsg );
361 for(
const PAD* item :
Pads() )
363 google::protobuf::Any* itemMsg = def->add_items();
364 item->Serialize( *itemMsg );
369 google::protobuf::Any* itemMsg = def->add_items();
370 item->Serialize( *itemMsg );
375 google::protobuf::Any* itemMsg = def->add_items();
376 item->Serialize( *itemMsg );
381 google::protobuf::Any* itemMsg = def->add_items();
382 types::Footprint3DModel modelMsg;
383 modelMsg.set_filename( model.m_Filename.ToUTF8() );
387 modelMsg.set_visible( model.m_Show );
388 modelMsg.set_opacity( model.m_Opacity );
389 itemMsg->PackFrom( modelMsg );
392 aContainer.PackFrom( footprint );
399 types::FootprintInstance footprint;
401 if( !aContainer.UnpackTo( &footprint ) )
407 SetLayer( FromProtoEnum<PCB_LAYER_ID, types::BoardLayer>( footprint.layer() ) );
408 SetLocked( footprint.locked() == kiapi::common::types::LockedState::LS_LOCKED );
410 google::protobuf::Any buf;
411 types::Field mandatoryField;
413 if( footprint.has_reference_field() )
415 mandatoryField = footprint.reference_field();
416 mandatoryField.mutable_id()->set_id( (
int) FIELD_T::REFERENCE );
417 buf.PackFrom( mandatoryField );
421 if( footprint.has_value_field() )
423 mandatoryField = footprint.value_field();
424 mandatoryField.mutable_id()->set_id( (
int) FIELD_T::VALUE );
425 buf.PackFrom( mandatoryField );
429 if( footprint.has_datasheet_field() )
431 mandatoryField = footprint.datasheet_field();
432 mandatoryField.mutable_id()->set_id( (
int) FIELD_T::DATASHEET );
433 buf.PackFrom( mandatoryField );
437 if( footprint.has_description_field() )
439 mandatoryField = footprint.description_field();
440 mandatoryField.mutable_id()->set_id( (
int) FIELD_T::DESCRIPTION );
441 buf.PackFrom( mandatoryField );
447 switch( footprint.attributes().mounting_style() )
449 case types::FootprintMountingStyle::FMS_THROUGH_HOLE:
453 case types::FootprintMountingStyle::FMS_SMD:
461 SetBoardOnly( footprint.attributes().not_in_schematic() );
465 SetDNP( footprint.attributes().do_not_populate() );
471 SetKeywords( footprint.definition().attributes().keywords() );
473 const types::FootprintDesignRuleOverrides& overrides = footprint.overrides();
475 if( overrides.has_copper_clearance() )
480 if( overrides.has_solder_mask() && overrides.solder_mask().has_solder_mask_margin() )
485 if( overrides.has_solder_paste() )
487 const types::SolderPasteOverrides& pasteSettings = overrides.solder_paste();
489 if( pasteSettings.has_solder_paste_margin() )
494 if( pasteSettings.has_solder_paste_margin_ratio() )
502 for(
const types::NetTieDefinition& netTieMsg : footprint.definition().net_ties() )
506 for(
const std::string&
pad : netTieMsg.pad_number() )
507 group.Append( wxString::Format( wxT(
"%s " ),
pad ) );
515 for(
int layerMsg : footprint.definition().private_layers() )
517 auto layer =
static_cast<types::BoardLayer
>( layerMsg );
518 privateLayers.
set( FromProtoEnum<PCB_LAYER_ID, types::BoardLayer>( layer ) );
526 if( !field->IsMandatory() )
536 for(
const google::protobuf::Any& itemMsg : footprint.definition().items() )
544 if( itemMsg.type_url() ==
"type.googleapis.com/kiapi.board.types.Footprint3DModel" )
546 types::Footprint3DModel modelMsg;
548 if( !itemMsg.UnpackTo( &modelMsg ) )
553 model.
m_Filename = wxString::FromUTF8( modelMsg.filename() );
554 model.
m_Show = modelMsg.visible();
560 Models().push_back( model );
564 wxLogTrace(
traceApi, wxString::Format( wxS(
"Attempting to unpack unknown type %s "
565 "from footprint message, skipping" ),
566 itemMsg.type_url() ) );
574 if( item && item->Deserialize( itemMsg ) )
575 Add( item.release(), ADD_MODE::APPEND );
586 if( field->GetId() == aFieldType )
601 if( field->GetId() == aFieldType )
611 return GetField( aFieldName ) !=
nullptr;
619 if( field->GetName() == aFieldName )
635 if( !field->IsVisible() || field->GetText().IsEmpty() )
639 aVector.push_back( field );
642 std::sort( aVector.begin(), aVector.end(),
645 return lhs->GetOrdinal() < rhs->GetOrdinal();
655 ordinal = std::max( ordinal, field->GetOrdinal() + 1 );
672 switch( item->Type() )
682 if( aStyleShapes && !item->IsOnCopperLayer() )
697 std::vector< BOARD_ITEM* > item_list;
700 item_list.push_back( field );
703 item_list.push_back(
pad );
706 item_list.push_back( gr_item );
711 item_list.push_back(
group );
715 item_list.push_back( zone );
717 bool changed =
false;
723 const_cast<KIID&
>( item->m_Uuid ) =
KIID();
736 m_pos = aOther.m_pos;
760 std::ranges::copy( aOther.m_jumperPadGroups,
769 for(
PCB_FIELD* field : aOther.m_fields )
772 aOther.m_fields.clear();
780 for(
PAD*
pad : aOther.Pads() )
783 aOther.Pads().clear();
791 for(
ZONE* item : aOther.Zones() )
799 item->SetNetCode( -1 );
802 aOther.Zones().clear();
810 for(
BOARD_ITEM* item : aOther.GraphicalItems() )
813 aOther.GraphicalItems().clear();
824 aOther.Groups().clear();
837 aOther.m_fields.clear();
838 aOther.Pads().clear();
839 aOther.Zones().clear();
840 aOther.GraphicalItems().clear();
841 aOther.m_initial_comments =
nullptr;
874 std::map<BOARD_ITEM*, BOARD_ITEM*> ptrMap;
882 ptrMap[field] = newField;
892 ptrMap[
pad ] = newPad;
901 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
902 ptrMap[ zone ] = newZone;
918 ptrMap[ item ] = newItem;
931 newGroup->
AddItem( ptrMap[ member ] );
959 aVars->push_back( wxT(
"REFERENCE" ) );
960 aVars->push_back( wxT(
"VALUE" ) );
961 aVars->push_back( wxT(
"LAYER" ) );
962 aVars->push_back( wxT(
"FOOTPRINT_LIBRARY" ) );
963 aVars->push_back( wxT(
"FOOTPRINT_NAME" ) );
964 aVars->push_back( wxT(
"SHORT_NET_NAME(<pad_number>)" ) );
965 aVars->push_back( wxT(
"NET_NAME(<pad_number>)" ) );
966 aVars->push_back( wxT(
"NET_CLASS(<pad_number>)" ) );
967 aVars->push_back( wxT(
"PIN_NAME(<pad_number>)" ) );
976 if( token->IsSameAs( wxT(
"REFERENCE" ) ) )
981 else if( token->IsSameAs( wxT(
"VALUE" ) ) )
986 else if( token->IsSameAs( wxT(
"LAYER" ) ) )
991 else if( token->IsSameAs( wxT(
"FOOTPRINT_LIBRARY" ) ) )
996 else if( token->IsSameAs( wxT(
"FOOTPRINT_NAME" ) ) )
1001 else if( token->StartsWith( wxT(
"SHORT_NET_NAME(" ) )
1002 || token->StartsWith( wxT(
"NET_NAME(" ) )
1003 || token->StartsWith( wxT(
"NET_CLASS(" ) )
1004 || token->StartsWith( wxT(
"PIN_NAME(" ) ) )
1006 wxString padNumber = token->AfterFirst(
'(' );
1007 padNumber = padNumber.BeforeLast(
')' );
1011 if(
pad->GetNumber() == padNumber )
1013 if( token->StartsWith( wxT(
"SHORT_NET_NAME" ) ) )
1014 *token =
pad->GetShortNetname();
1015 else if( token->StartsWith( wxT(
"NET_NAME" ) ) )
1016 *token =
pad->GetNetname();
1017 else if( token->StartsWith( wxT(
"NET_CLASS" ) ) )
1018 *token =
pad->GetNetClassName();
1020 *token =
pad->GetPinFunction();
1028 *token = field->GetText();
1050 switch( aBoardItem->
Type() )
1066 if( aMode == ADD_MODE::APPEND )
1074 if( aMode == ADD_MODE::APPEND )
1075 m_pads.push_back(
static_cast<PAD*
>( aBoardItem ) );
1077 m_pads.push_front(
static_cast<PAD*
>( aBoardItem ) );
1082 if( aMode == ADD_MODE::APPEND )
1083 m_zones.push_back(
static_cast<ZONE*
>( aBoardItem ) );
1090 if( aMode == ADD_MODE::APPEND )
1098 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Add(): BOARD_ITEM type (%d) not handled" ),
1099 aBoardItem->
Type() ) );
1111 switch( aBoardItem->
Type() )
1116 if( *it == aBoardItem )
1137 if( *it == aBoardItem )
1147 for(
auto it =
m_pads.begin(); it !=
m_pads.end(); ++it )
1149 if( *it ==
static_cast<PAD*
>( aBoardItem ) )
1161 if( *it ==
static_cast<ZONE*
>( aBoardItem ) )
1173 if( *it ==
static_cast<PCB_GROUP*
>( aBoardItem ) )
1185 msg.Printf( wxT(
"FOOTPRINT::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
1186 aBoardItem->
Type() );
1217 switch(
pad->GetProperty() )
1219 case PAD_PROP::FIDUCIAL_GLBL:
1220 case PAD_PROP::FIDUCIAL_LOCAL:
1223 case PAD_PROP::HEATSINK:
1224 case PAD_PROP::CASTELLATED:
1225 case PAD_PROP::MECHANICAL:
1228 case PAD_PROP::NONE:
1230 case PAD_PROP::TESTPOINT:
1234 switch(
pad->GetAttribute() )
1236 case PAD_ATTRIB::PTH:
1240 case PAD_ATTRIB::SMD:
1241 if(
pad->IsOnCopperLayer() )
1269 return _(
"Through hole" );
1271 return _(
"Other" );
1286 if(
dummy.IsFlipped() )
1290 bbox.
Merge(
pad->GetBoundingBox() );
1293 dummy.SetParent(
nullptr );
1294 dummy.SetParentGroup(
nullptr );
1339 std::vector<PCB_TEXT*> texts;
1361 texts.push_back(
static_cast<PCB_TEXT*
>( item ) );
1379 bbox.
Merge( item->GetBoundingBox() );
1385 if( field->IsReference() || field->IsValue() )
1388 texts.push_back( field );
1392 bbox.
Merge(
pad->GetBoundingBox() );
1395 bbox.
Merge( zone->GetBoundingBox() );
1400 if( aIncludeText || noDrawItems )
1417 bool valueLayerIsVisible =
true;
1418 bool refLayerIsVisible =
true;
1436 if( (
Value().IsVisible() && valueLayerIsVisible ) || noDrawItems )
1441 if( (
Reference().IsVisible() && refLayerIsVisible ) || noDrawItems )
1449 if( aIncludeText || noDrawItems )
1467 std::vector<PCB_TEXT*> texts;
1479 if( ( aLayers & item->GetLayerSet() ).none() )
1487 bbox.
Merge( item->GetBoundingBox() );
1492 if( ( aLayers &
pad->GetLayerSet() ).none() )
1495 bbox.
Merge(
pad->GetBoundingBox() );
1500 if( ( aLayers & zone->GetLayerSet() ).none() )
1503 bbox.
Merge( zone->GetBoundingBox() );
1539 pad->Padstack().ForEachUniqueLayer(
1553 const SHAPE_POLY_SET& layerPoly = *zone->GetFilledPolysList( layer );
1580 std::vector<VECTOR2I> convex_hull;
1586 for(
const VECTOR2I& pt : convex_hull )
1609 if( item->IsOnLayer( aLayer ) )
1623 if(
pad->IsOnLayer( aLayer ) )
1629 if( zone->GetIsRuleArea() )
1632 if( zone->IsOnLayer( aLayer ) )
1634 const std::shared_ptr<SHAPE_POLY_SET>& layerPoly = zone->GetFilledPolysList( aLayer );
1636 for(
int ii = 0; ii < layerPoly->OutlineCount(); ii++ )
1637 rawPolys.
AddOutline( layerPoly->COutline( ii ) );
1641 std::vector<VECTOR2I> convex_hull;
1646 for(
const VECTOR2I& pt : convex_hull )
1667 aList.emplace_back(
_(
"Library" ),
GetFPID().GetLibNickname().wx_str() );
1669 aList.emplace_back(
_(
"Footprint Name" ),
GetFPID().GetLibItemName().wx_str() );
1671 aList.emplace_back(
_(
"Pads" ), wxString::Format( wxT(
"%zu" ), padCount ) );
1674 wxString::Format(
_(
"Keywords: %s" ),
GetKeywords() ) );
1683 case F_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Front" ) );
break;
1684 case B_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Back (Flipped)" ) );
break;
1688 auto addToken = []( wxString* aStr,
const wxString& aAttr )
1690 if( !aStr->IsEmpty() )
1691 *aStr += wxT(
", " );
1700 addToken( &status,
_(
"Locked" ) );
1703 addToken( &status,
_(
"autoplaced" ) );
1706 addToken( &attrs,
_(
"not in schematic" ) );
1709 addToken( &attrs,
_(
"exclude from pos files" ) );
1712 addToken( &attrs,
_(
"exclude from BOM" ) );
1715 addToken( &attrs,
_(
"DNP" ) );
1717 aList.emplace_back(
_(
"Status: " ) + status,
_(
"Attributes:" ) + wxS(
" " ) + attrs );
1719 aList.emplace_back(
_(
"Rotation" ), wxString::Format( wxT(
"%.4g" ),
1725 _(
"Component Class" ),
1730 msg2.Printf(
_(
"3D-Shape: %s" ),
m_3D_Drawings.empty() ?
_(
"<none>" )
1732 aList.emplace_back( msg, msg2 );
1736 aList.emplace_back( msg, msg2 );
1744 if( board->IsFootprintHolder() )
1776 if(
pad->IsOnLayer( aLayer ) )
1782 if( zone->IsOnLayer( aLayer ) )
1788 if( field->IsOnLayer( aLayer ) )
1794 if( item->IsOnLayer( aLayer ) )
1806 if(
pad->IsOnLayer( aLayer ) &&
pad->HitTest( aPosition, aAccuracy ) )
1812 if( zone->IsOnLayer( aLayer ) && zone->HitTest( aPosition, aAccuracy ) )
1818 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer )
1819 && item->HitTest( aPosition, aAccuracy ) )
1831 std::vector<BOARD_ITEM*> items;
1835 if(
pad->IsOnLayer( aLayer ) )
1836 items.push_back(
pad );
1841 if( zone->IsOnLayer( aLayer ) )
1842 items.push_back( zone );
1847 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer ) )
1848 items.push_back( item );
1857 if( !aContained && item->HitTest( aRect, aContained, aAccuracy ) )
1859 else if( aContained && !item->HitTest( aRect, aContained, aAccuracy ) )
1866 return !items.empty() && aContained;
1885 BOX2I arect = aRect;
1905 if(
pad->HitTest( arect,
false, 0 ) )
1911 if( zone->HitTest( arect,
false, 0 ) )
1922 if( item->Type() !=
PCB_TEXT_T && item->HitTest( arect,
false, 0 ) )
1936 bool can_select = aSearchAfterMe ? false :
true;
1940 if( !can_select &&
pad == aSearchAfterMe )
1946 if( can_select &&
pad->GetNumber() == aPadNumber )
1959 if( !(
pad->GetLayerSet() & aLayerMask ).any() )
1962 if(
pad->HitTest( aPosition ) )
1972 std::vector<const PAD*> retv;
1976 if( ( aIgnore && aIgnore ==
pad ) || (
pad->GetNumber() != aPadNumber ) )
1979 retv.push_back(
pad );
1995 if(
pad->GetAttribute() == PAD_ATTRIB::NPTH )
2007 std::set<wxString> usedNumbers;
2019 if(
pad->GetNumber().IsEmpty() )
2025 if(
pad->GetAttribute() == PAD_ATTRIB::NPTH )
2029 usedNumbers.insert(
pad->GetNumber() );
2044 if(
nullptr == a3DModel )
2054 const std::vector<KICAD_T>& aScanTypes )
2056#if 0 && defined(DEBUG)
2057 std::cout <<
GetClass().mb_str() <<
' ';
2060 bool drawingsScanned =
false;
2062 for(
KICAD_T scanType : aScanTypes )
2067 if( inspector(
this, testData ) == INSPECT_RESULT::QUIT )
2068 return INSPECT_RESULT::QUIT;
2073 if( IterateForward<PAD*>(
m_pads, inspector, testData, { scanType } )
2074 == INSPECT_RESULT::QUIT )
2076 return INSPECT_RESULT::QUIT;
2082 if( IterateForward<ZONE*>(
m_zones, inspector, testData, { scanType } )
2083 == INSPECT_RESULT::QUIT )
2085 return INSPECT_RESULT::QUIT;
2091 if( IterateForward<PCB_FIELD*>(
m_fields, inspector, testData, { scanType } )
2092 == INSPECT_RESULT::QUIT )
2094 return INSPECT_RESULT::QUIT;
2109 if( !drawingsScanned )
2111 if( IterateForward<BOARD_ITEM*>(
m_drawings, inspector, testData, aScanTypes )
2112 == INSPECT_RESULT::QUIT )
2114 return INSPECT_RESULT::QUIT;
2117 drawingsScanned =
true;
2123 if( IterateForward<PCB_GROUP*>(
m_groups, inspector, testData, { scanType } )
2124 == INSPECT_RESULT::QUIT )
2126 return INSPECT_RESULT::QUIT;
2136 return INSPECT_RESULT::CONTINUE;
2144 if( reference.IsEmpty() )
2145 reference =
_(
"<no reference designator>" );
2147 return wxString::Format(
_(
"Footprint %s" ), reference );
2153 return BITMAPS::module;
2181 aFunction( drawing );
2183 if( aMode == RECURSE_MODE::RECURSE )
2184 drawing->RunOnChildren( aFunction, RECURSE_MODE::RECURSE );
2187 catch( std::bad_function_call& )
2189 wxFAIL_MSG( wxT(
"Error running FOOTPRINT::RunOnChildren" ) );
2196 std::vector<int> layers;
2198 layers.reserve( 6 );
2204 wxASSERT_MSG(
false, wxT(
"Illegal layer" ) );
2225 bool f_silk =
false, b_silk =
false, non_silk =
false;
2229 if( item->GetLayer() ==
F_SilkS )
2231 else if( item->GetLayer() ==
B_SilkS )
2237 if( ( f_silk || b_silk ) && !non_silk &&
m_pads.empty() )
2282 constexpr double MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY = 1.5;
2285 return MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY;
2298 int biggest_clearance = board->GetMaxClearanceValue();
2299 area.
Inflate( biggest_clearance );
2310 if( aName.find_first_of( invalids ) != std::string::npos )
2324 static const wxChar invalidChars[] = wxT(
"%$<>\t\n\r\"\\/:");
2325 static const wxChar invalidCharsReadable[] = wxT(
"% $ < > 'tab' 'return' 'line feed' \\ \" / :");
2328 return invalidCharsReadable;
2330 return invalidChars;
2336 if( aMoveVector.
x == 0 && aMoveVector.
y == 0 )
2350 EDA_ANGLE newOrientation = orientation + aAngle;
2357 field->KeepUpright();
2362 static_cast<PCB_TEXT*
>( item )->KeepUpright();
2369 wxASSERT( aLayer ==
F_Cu || aLayer ==
B_Cu );
2404 field->Flip(
m_pos, FLIP_DIRECTION::TOP_BOTTOM );
2408 pad->Flip(
m_pos, FLIP_DIRECTION::TOP_BOTTOM );
2415 zone->Flip(
m_pos, FLIP_DIRECTION::TOP_BOTTOM );
2419 item->Flip(
m_pos, FLIP_DIRECTION::TOP_BOTTOM );
2422 if( aFlipDirection == FLIP_DIRECTION::LEFT_RIGHT )
2442 field->EDA_TEXT::Offset(
delta );
2448 zone->Move(
delta );
2451 item->Move(
delta );
2483 field->Move( moveVector );
2487 pad->Move( moveVector );
2491 item->Move( moveVector );
2495 zone->Move( moveVector );
2553 RECURSE_MODE::RECURSE );
2563 switch( aItem->
Type() )
2567 PAD* new_pad =
new PAD( *
static_cast<const PAD*
>( aItem ) );
2570 if( aAddToFootprint )
2571 m_pads.push_back( new_pad );
2579 ZONE* new_zone =
new ZONE( *
static_cast<const ZONE*
>( aItem ) );
2582 if( aAddToFootprint )
2583 m_zones.push_back( new_zone );
2585 new_item = new_zone;
2599 case FIELD_T::REFERENCE: new_text->
SetText( wxT(
"${REFERENCE}" ) );
break;
2600 case FIELD_T::VALUE: new_text->
SetText( wxT(
"${VALUE}" ) );
break;
2601 case FIELD_T::DATASHEET: new_text->
SetText( wxT(
"${DATASHEET}" ) );
break;
2606 if( aAddToFootprint )
2609 new_item = new_text;
2618 if( aAddToFootprint )
2621 new_item = new_shape;
2630 if( aAddToFootprint )
2633 new_item = new_textbox;
2645 if( aAddToFootprint )
2648 new_item = dimension;
2656 if( aAddToFootprint )
2658 group->RunOnChildren(
2663 RECURSE_MODE::RECURSE );
2678 wxFAIL_MSG( wxT(
"Duplication not supported for items of class " ) + aItem->
GetClass() );
2688 std::set<wxString> usedNumbers;
2692 usedNumbers.insert(
pad->GetNumber() );
2699 while( usedNumbers.count( wxString::Format( wxT(
"%s%d" ), prefix, num ) ) )
2702 return wxString::Format( wxT(
"%s%d" ), prefix, num );
2710 if(
group.contains( aPadNumber ) )
2714 return std::nullopt;
2765 for(
int jj = 0; jj < aPolySet.
HoleCount( ii ); jj++ )
2769 return aPolySet.
Area();
2784 return markerShape.
Area();
2788 double combinedArea = 0.0;
2793 return combinedArea;
2823 case SHAPE_T::SEGMENT:
2825 case SHAPE_T::BEZIER:
2828 case SHAPE_T::RECTANGLE:
2829 case SHAPE_T::CIRCLE:
2844 double width =
static_cast<const PCB_TRACK*
>( aItem )->GetWidth();
2845 return width * width;
2849 static_cast<const PAD*
>( aItem )->Padstack().ForEachUniqueLayer(
2881 for(
int i = 0; i < aCollector.
GetCount(); ++i )
2885 switch( item->
Type() )
2916 double footprintRegionArea =
polygonArea( footprintRegion );
2917 double uncoveredRegionArea = footprintRegionArea -
polygonArea( coveredRegion );
2918 double coveredArea = footprintRegionArea - uncoveredRegionArea;
2919 double ratio = ( coveredArea / footprintRegionArea );
2926 return std::min( ratio, 1.0 );
2932 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
2953 shape->AddShape(
pad->GetEffectiveShape( aLayer, aFlash )->Clone() );
2958 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
2998 std::vector<PCB_SHAPE*> list_front;
2999 std::vector<PCB_SHAPE*> list_back;
3000 std::map<int, int> front_width_histogram;
3001 std::map<int, int> back_width_histogram;
3008 list_back.push_back( shape );
3015 list_front.push_back( shape );
3020 if( !list_front.size() && !list_back.size() )
3027 true, aErrorHandler ) )
3037 auto max = std::max_element( front_width_histogram.begin(), front_width_histogram.end(),
3038 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3040 return a.second < b.second;
3043 if( max != front_width_histogram.end() )
3066 auto max = std::max_element( back_width_histogram.begin(), back_width_histogram.end(),
3067 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3069 return a.second < b.second;
3072 if( max != back_width_histogram.end() )
3095 std::map<PCB_LAYER_ID, std::vector<PCB_SHAPE*>> layer_shapes;
3100 if( item->Type() != PCB_SHAPE_T )
3103 for( PCB_LAYER_ID layer : item->GetLayerSet() )
3104 layer_shapes[layer].push_back( static_cast<PCB_SHAPE*>( item ) );
3107 for(
size_t ii = 0; ii <
m_pads.size(); ++ii )
3110 bool has_nettie =
false;
3112 auto it = map.find(
pad->GetNumber() );
3114 if( it == map.end() || it->second < 0 )
3117 for(
size_t jj = ii + 1; jj <
m_pads.size(); ++jj )
3121 auto it2 = map.find( other->
GetNumber() );
3123 if( it2 == map.end() || it2->second < 0 )
3126 if( it2->second == it->second )
3139 for(
auto& [ layer, shapes ] : layer_shapes )
3141 auto pad_shape =
pad->GetEffectiveShape( layer );
3143 for(
auto other_shape : shapes )
3145 auto shape = other_shape->GetEffectiveShape( layer );
3147 if( pad_shape->Collide( shape.get() ) )
3150 m_netTieCache[other_shape].insert( nettie.begin(), nettie.end() );
3160 std::map<wxString, int> padNumberToGroupIdxMap;
3163 padNumberToGroupIdxMap[
pad->GetNumber() ] = -1;
3166 [&]( wxString aPad,
int aGroup )
3168 aPad.Trim(
true ).Trim(
false );
3170 if( !aPad.IsEmpty() )
3171 padNumberToGroupIdxMap[ aPad ] = aGroup;
3180 for( wxUniCharRef ch :
group )
3189 switch(
static_cast<unsigned char>( ch ) )
3196 processPad(
pad, ii );
3206 processPad(
pad, ii );
3209 return padNumberToGroupIdxMap;
3219 int groupIdx = padToNetTieGroupMap[ aPad->
GetNumber() ];
3220 std::vector<PAD*> otherPads;
3226 if( padToNetTieGroupMap[
pad->GetNumber() ] == groupIdx )
3227 otherPads.push_back(
pad );
3240 if( setAttr && likelyAttr && setAttr != likelyAttr )
3244 switch( likelyAttr )
3247 msg.Printf(
_(
"(expected 'Through hole'; actual '%s')" ),
GetTypeName() );
3250 msg.Printf(
_(
"(expected 'SMD'; actual '%s')" ),
GetTypeName() );
3255 (aErrorHandler)( msg );
3261 const std::function<
void(
const PAD*,
int,
3262 const wxString& )>& aErrorHandler )
3264 if( aErrorHandler ==
nullptr )
3269 pad->CheckPad( aUnitsProvider,
false,
3270 [&](
int errorCode,
const wxString& msg )
3272 aErrorHandler(
pad, errorCode, msg );
3280 const VECTOR2I& )>& aErrorHandler )
3282 std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
3297 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
3300 if( checkedPairs.find( { a, b } ) == checkedPairs.end() )
3302 checkedPairs[ { a, b } ] = 1;
3304 if(
pad->HasDrilledHole() && other->HasDrilledHole() )
3308 if(
pad->GetPosition() == other->GetPosition() )
3314 std::shared_ptr<SHAPE_SEGMENT> holeA =
pad->GetEffectiveHoleShape();
3315 std::shared_ptr<SHAPE_SEGMENT> holeB = other->GetEffectiveHoleShape();
3317 if( holeA->Collide( holeB->GetSeg(), 0 ) )
3328 if(
pad->GetBoundingBox().Intersects( other->GetBoundingBox() ) )
3332 for(
PCB_LAYER_ID l :
pad->Padstack().RelevantShapeLayers( other->Padstack() ) )
3334 SHAPE* padShape =
pad->GetEffectiveShape( l ).get();
3335 SHAPE* otherShape = other->GetEffectiveShape( l ).get();
3337 if( padShape->
Collide( otherShape, 0,
nullptr, &pos ) )
3350 const VECTOR2I& )>& aErrorHandler )
3359 std::vector<BOARD_ITEM*> copperItems;
3363 if( item->IsOnCopperLayer() )
3364 copperItems.push_back( item );
3366 item->RunOnChildren(
3370 copperItems.push_back( descendent );
3372 RECURSE_MODE::RECURSE );
3377 if( !zone->GetIsRuleArea() && zone->IsOnCopperLayer() )
3378 copperItems.push_back( zone );
3383 if( field->IsOnCopperLayer() )
3384 copperItems.push_back( field );
3394 std::map<int, std::vector<const PAD*>> outlineIdxToPadsMap;
3398 if( item->IsOnLayer( layer ) )
3400 item->TransformShapeToPolygon( copperOutlines, layer, 0,
ARC_HIGH_DEF,
3411 for(
int ii = 0; ii < copperOutlines.
OutlineCount(); ++ii )
3413 if(
pad->GetEffectiveShape( layer )->Collide( &copperOutlines.
Outline( ii ), 0 ) )
3414 outlineIdxToPadsMap[ ii ].emplace_back(
pad );
3421 for(
const auto& [ outlineIdx, pads ] : outlineIdxToPadsMap )
3423 if( pads.size() > 1 )
3425 const PAD* firstPad = pads[0];
3426 int firstGroupIdx = padNumberToGroupIdxMap[ firstPad->
GetNumber() ];
3428 for(
size_t ii = 1; ii < pads.size(); ++ii )
3430 const PAD* thisPad = pads[ii];
3431 int thisGroupIdx = padNumberToGroupIdxMap[ thisPad->
GetNumber() ];
3433 if( thisGroupIdx < 0 || thisGroupIdx != firstGroupIdx )
3442 if( item->HitTest( pos, 1 ) )
3444 shortingItem = item;
3450 aErrorHandler( shortingItem, firstPad, thisPad, pos );
3452 aErrorHandler( firstPad, thisPad,
nullptr, pos );
3463 std::set<wxString> padNumbers;
3472 msg.Printf(
_(
"(net-tie pad group contains unknown pad number %s)" ), padNumber );
3473 aErrorHandler( msg );
3475 else if( !padNumbers.insert(
pad->GetNumber() ).second )
3477 msg.Printf(
_(
"(pad %s appears in more than one net-tie pad group)" ), padNumber );
3478 aErrorHandler( msg );
3486 const VECTOR2I& aPt )>& aErrorHandler )
3488 auto checkColliding =
3495 if( !item->
IsOnLayer( silk ) || !other->IsOnLayer( mask ) )
3499 std::shared_ptr<SHAPE> otherShape = other->GetEffectiveShape( mask );
3503 if( itemShape->Collide( otherShape.get(), 0, &
actual, &pos ) )
3504 aErrorHandler( item, other, pos );
3513 checkColliding( item, other );
3517 checkColliding( item,
pad );
3528 std::swap( *
this, *
image );
3535 RECURSE_MODE::NO_RECURSE );
3537 image->RunOnChildren(
3542 RECURSE_MODE::NO_RECURSE );
3550 if(
pad->GetAttribute() != PAD_ATTRIB::SMD )
3565 return *
this == other;
3574 for(
size_t ii = 0; ii <
m_pads.size(); ++ii )
3583 for(
size_t ii = 0; ii <
m_drawings.size(); ++ii )
3592 for(
size_t ii = 0; ii <
m_zones.size(); ++ii )
3599 std::vector<PCB_FIELD*> fields, otherFields;
3604 if( fields.size() != otherFields.size() )
3607 for(
size_t ii = 0; ii < fields.size(); ++ii )
3611 if( !( *fields[ii] == *otherFields[ii] ) )
3627 double similarity = 1.0;
3636 similarity *=
pad->Similarity( *otherPad );
3645 if( itemA->
Type() != itemB->
Type() )
3646 return itemA->
Type() < itemB->
Type();
3661 if( dwgA->
GetShape() != SHAPE_T::POLY )
3674 if( dwgA->
GetShape() == SHAPE_T::ARC )
3681 else if( dwgA->
GetShape() == SHAPE_T::BEZIER )
3693 else if( dwgA->
GetShape() == SHAPE_T::POLY )
3716 return itemA < itemB;
3730 std::optional<bool> padCopperMatches;
3733 const PAD* checkPad = aFirst;
3746 padCopperMatches = aFirst->
GetSize( aLayer ).
x < aSecond->
GetSize( aLayer ).
x;
3748 padCopperMatches = aFirst->
GetSize( aLayer ).
y < aSecond->
GetSize( aLayer ).
y;
3750 padCopperMatches = aFirst->
GetShape( aLayer ) < aSecond->
GetShape( aLayer );
3753 if( padCopperMatches.has_value() )
3754 return *padCopperMatches;
3762 return aFirst < aSecond;
3767bool FOOTPRINT::cmp_padstack::operator()(
const PAD* aFirst,
const PAD* aSecond )
const
3807 if( firstShape->VertexCount() != secondShape->VertexCount() )
3808 return firstShape->VertexCount() < secondShape->VertexCount();
3810 for(
int ii = 0; ii < firstShape->VertexCount(); ++ii )
3812 if( firstShape->CVertex( ii ).x != secondShape->CVertex( ii ).x )
3813 return firstShape->CVertex( ii ).x < secondShape->CVertex( ii ).x;
3814 if( firstShape->CVertex( ii ).y != secondShape->CVertex( ii ).y )
3815 return firstShape->CVertex( ii ).y < secondShape->CVertex( ii ).y;
3834 for(
int ii = 0; ii < aFirst->
Outline()->TotalVertices(); ++ii )
3845 return aFirst < aSecond;
3850 int aClearance,
int aMaxError,
ERROR_LOC aErrorLoc )
const
3861 clearance.x +=
pad->GetSolderMaskExpansion( padLayer );
3862 clearance.y +=
pad->GetSolderMaskExpansion( padLayer );
3881 &&
pad->GetShape( padLayer ) != PAD_SHAPE::CUSTOM )
3885 if( dummySize.
x <= 0 || dummySize.
y <= 0 )
3889 dummy.SetSize( padLayer, dummySize );
3890 dummy.TransformShapeToPolygon( aBuffer, padLayer, 0, aMaxError, aErrorLoc );
3894 pad->TransformShapeToPolygon( aBuffer, padLayer,
clearance.x, aMaxError,
3901 if( !
pad->FlashLayer( aLayer ) )
3906 pad->Padstack().ForEachUniqueLayer(
3909 processPad(
pad, l );
3914 processPad(
pad, aLayer );
3921 int aClearance,
int aError,
ERROR_LOC aErrorLoc,
3922 bool aIncludeText,
bool aIncludeShapes,
3923 bool aIncludePrivateItems )
const
3930 if( item->Type() ==
PCB_TEXT_T && aIncludeText )
3935 text->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
3947 textbox->PCB_SHAPE::TransformShapeToPolygon( aBuffer, aLayer, 0, aError,
3956 if( item->Type() ==
PCB_SHAPE_T && aIncludeShapes )
3969 if( field->GetLayer() == aLayer && field->IsVisible() )
3970 field->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
3979 using EMBEDDING_PERMISSION = OUTLINE_FONT::EMBEDDING_PERMISSION;
3981 std::set<OUTLINE_FONT*>
fonts;
3987 if(
auto* font =
text->GetFont(); font && !font->IsStroke() )
3989 auto* outline =
static_cast<OUTLINE_FONT*
>( font );
3990 auto permission = outline->GetEmbeddingPermission();
3992 if( permission == EMBEDDING_PERMISSION::EDITABLE
3993 || permission == EMBEDDING_PERMISSION::INSTALLABLE )
3995 fonts.insert( outline );
4009 for(
auto* font :
fonts )
4048 return wxEmptyString;
4053 BOARD* aBoard,
const std::unordered_set<wxString>& aComponentClassNames )
4057 aComponentClassNames );
4074 if( zcMap.
Choices().GetCount() == 0 )
4076 zcMap.
Undefined( ZONE_CONNECTION::INHERITED );
4077 zcMap.
Map( ZONE_CONNECTION::INHERITED,
_HKI(
"Inherited" ) )
4078 .
Map( ZONE_CONNECTION::NONE,
_HKI(
"None" ) )
4079 .
Map( ZONE_CONNECTION::THERMAL,
_HKI(
"Thermal reliefs" ) )
4080 .
Map( ZONE_CONNECTION::FULL,
_HKI(
"Solid" ) )
4081 .
Map( ZONE_CONNECTION::THT_THERMAL,
_HKI(
"Thermal reliefs for PTH" ) );
4086 if( layerEnum.
Choices().GetCount() == 0 )
4094 wxPGChoices fpLayers;
4107 layer->SetChoices( fpLayers );
4112 PROPERTY_DISPLAY::PT_DEGREE ) );
4114 const wxString groupFields =
_HKI(
"Fields" );
4139 const wxString groupAttributes =
_HKI(
"Attributes" );
4153 const wxString groupOverrides =
_HKI(
"Overrides" );
4156 _HKI(
"Exempt From Courtyard Requirement" ),
4160 _HKI(
"Clearance Override" ),
4162 PROPERTY_DISPLAY::PT_SIZE ),
4165 _HKI(
"Solderpaste Margin Override" ),
4167 PROPERTY_DISPLAY::PT_SIZE ),
4170 _HKI(
"Solderpaste Margin Ratio Override" ),
4173 PROPERTY_DISPLAY::PT_RATIO ),
4176 _HKI(
"Zone Connection Style" ),
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 int ARC_HIGH_DEF
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.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
PCB_GROUP * GetParentGroup() const
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 BOARD_ITEM * Duplicate() const
Create a copy of this BOARD_ITEM.
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
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.
bool IsFootprintHolder() const
Find out if the board is being used to hold a single footprint for editing/viewing.
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Test whether a given element category is visible.
bool IsLayerVisible(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
BOARD_DESIGN_SETTINGS & GetDesignSettings() 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 void Move(const Vec &aMoveVector)
Move the rectangle by the aMoveVector.
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.
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.
A base class for most all the KiCad significant classes used in schematics and boards.
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 void SetParent(EDA_ITEM *aParent)
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
virtual wxString GetClass() const =0
Return the class name.
EDA_ITEM_FLAGS GetFlags() const
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,...
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
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)
VECTOR3D m_Offset
3D model offset (mm)
VECTOR3D m_Rotation
3D model rotation (degrees)
VECTOR3D m_Scale
3D model scaling factor (dimensionless)
wxString m_Filename
The 3D shape filename in 3D library.
bool m_Show
Include model in rendering.
Used when the right click button is pressed, or when the select tool is in effect.
const COLLECTORS_GUIDE * GetGuide() const
Class OUTLINE_FONT implements outline font drawing.
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.
std::string AsStdString() const
wxString GetUniStringLibId() const
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
const wxString GetUniStringLibNickname() const
LSET is a set of PCB_LAYER_IDs.
static LSET AllLayersMask()
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
static LSET SideSpecificMask()
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
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.
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,...
const VECTOR2I & GetSize(PCB_LAYER_ID aLayer) const
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).
std::unordered_set< BOARD_ITEM * > & GetItems()
virtual bool RemoveItem(BOARD_ITEM *aItem)
Remove item from group.
virtual bool AddItem(BOARD_ITEM *aItem)
Add item to group.
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) 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...
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
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.
void SetWidth(int aWidth)
Set the width of all segments in the chain.
Represent a set of closed polygons.
void RemoveAllContours()
Remove all outlines & holes (clears) the polygon set.
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.
virtual void CacheTriangulation(bool aPartition=true, bool aSimplify=false)
Build a polygon triangulation, needed to draw a polygon on OpenGL and in some other calculations.
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.
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
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.
void Mirror(const VECTOR2I &aRef, FLIP_DIRECTION aFlipDirection)
Mirror the line points about y or x (or both)
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.
void Move(const VECTOR2I &aVector) override
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.
@ 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
@ FRAME_FOOTPRINT_CHOOSER
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_LOCKED_ITEM_SHADOW
Shadow layer for locked items.
@ 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.
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 std::optional< KICAD_T > TypeNameFromAny(const google::protobuf::Any &aMessage)
KICOMMON_API VECTOR3D UnpackVector3D(const types::Vector3D &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)
Class to handle a set of BOARD_ITEMs.
#define NO_SETTER(owner, type)
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.
int GetTrailingInt(const wxString &aStr)
Gets the trailing int, if any, from a string.
wxString UnescapeString(const wxString &aSource)
constexpr double IUTomm(int iu) const
constexpr int mmToIU(double mm) const
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
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_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_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