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<EDA_ITEM*, EDA_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<EDA_ITEM*, EDA_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 ] );
954 *
this = *
static_cast<const FOOTPRINT*
>( aOther );
980 aVars->push_back( wxT(
"REFERENCE" ) );
981 aVars->push_back( wxT(
"VALUE" ) );
982 aVars->push_back( wxT(
"LAYER" ) );
983 aVars->push_back( wxT(
"FOOTPRINT_LIBRARY" ) );
984 aVars->push_back( wxT(
"FOOTPRINT_NAME" ) );
985 aVars->push_back( wxT(
"SHORT_NET_NAME(<pad_number>)" ) );
986 aVars->push_back( wxT(
"NET_NAME(<pad_number>)" ) );
987 aVars->push_back( wxT(
"NET_CLASS(<pad_number>)" ) );
988 aVars->push_back( wxT(
"PIN_NAME(<pad_number>)" ) );
997 if( token->IsSameAs( wxT(
"REFERENCE" ) ) )
1002 else if( token->IsSameAs( wxT(
"VALUE" ) ) )
1007 else if( token->IsSameAs( wxT(
"LAYER" ) ) )
1012 else if( token->IsSameAs( wxT(
"FOOTPRINT_LIBRARY" ) ) )
1017 else if( token->IsSameAs( wxT(
"FOOTPRINT_NAME" ) ) )
1022 else if( token->StartsWith( wxT(
"SHORT_NET_NAME(" ) )
1023 || token->StartsWith( wxT(
"NET_NAME(" ) )
1024 || token->StartsWith( wxT(
"NET_CLASS(" ) )
1025 || token->StartsWith( wxT(
"PIN_NAME(" ) ) )
1027 wxString padNumber = token->AfterFirst(
'(' );
1028 padNumber = padNumber.BeforeLast(
')' );
1032 if(
pad->GetNumber() == padNumber )
1034 if( token->StartsWith( wxT(
"SHORT_NET_NAME" ) ) )
1035 *token =
pad->GetShortNetname();
1036 else if( token->StartsWith( wxT(
"NET_NAME" ) ) )
1037 *token =
pad->GetNetname();
1038 else if( token->StartsWith( wxT(
"NET_CLASS" ) ) )
1039 *token =
pad->GetNetClassName();
1041 *token =
pad->GetPinFunction();
1049 *token = field->GetText();
1071 switch( aBoardItem->
Type() )
1087 if( aMode == ADD_MODE::APPEND )
1095 if( aMode == ADD_MODE::APPEND )
1096 m_pads.push_back(
static_cast<PAD*
>( aBoardItem ) );
1098 m_pads.push_front(
static_cast<PAD*
>( aBoardItem ) );
1103 if( aMode == ADD_MODE::APPEND )
1104 m_zones.push_back(
static_cast<ZONE*
>( aBoardItem ) );
1111 if( aMode == ADD_MODE::APPEND )
1119 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Add(): BOARD_ITEM type (%d) not handled" ),
1120 aBoardItem->
Type() ) );
1132 switch( aBoardItem->
Type() )
1137 if( *it == aBoardItem )
1158 if( *it == aBoardItem )
1168 for(
auto it =
m_pads.begin(); it !=
m_pads.end(); ++it )
1170 if( *it ==
static_cast<PAD*
>( aBoardItem ) )
1182 if( *it ==
static_cast<ZONE*
>( aBoardItem ) )
1194 if( *it ==
static_cast<PCB_GROUP*
>( aBoardItem ) )
1206 msg.Printf( wxT(
"FOOTPRINT::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
1207 aBoardItem->
Type() );
1238 switch(
pad->GetProperty() )
1240 case PAD_PROP::FIDUCIAL_GLBL:
1241 case PAD_PROP::FIDUCIAL_LOCAL:
1244 case PAD_PROP::HEATSINK:
1245 case PAD_PROP::CASTELLATED:
1246 case PAD_PROP::MECHANICAL:
1249 case PAD_PROP::NONE:
1251 case PAD_PROP::TESTPOINT:
1255 switch(
pad->GetAttribute() )
1257 case PAD_ATTRIB::PTH:
1261 case PAD_ATTRIB::SMD:
1262 if(
pad->IsOnCopperLayer() )
1290 return _(
"Through hole" );
1292 return _(
"Other" );
1307 if(
dummy.IsFlipped() )
1311 bbox.
Merge(
pad->GetBoundingBox() );
1314 dummy.SetParent(
nullptr );
1315 dummy.SetParentGroup(
nullptr );
1360 std::vector<PCB_TEXT*> texts;
1382 texts.push_back(
static_cast<PCB_TEXT*
>( item ) );
1400 bbox.
Merge( item->GetBoundingBox() );
1406 if( field->IsReference() || field->IsValue() )
1409 texts.push_back( field );
1413 bbox.
Merge(
pad->GetBoundingBox() );
1416 bbox.
Merge( zone->GetBoundingBox() );
1421 if( aIncludeText || noDrawItems )
1438 bool valueLayerIsVisible =
true;
1439 bool refLayerIsVisible =
true;
1457 if( (
Value().IsVisible() && valueLayerIsVisible ) || noDrawItems )
1462 if( (
Reference().IsVisible() && refLayerIsVisible ) || noDrawItems )
1470 if( aIncludeText || noDrawItems )
1488 std::vector<PCB_TEXT*> texts;
1500 if( ( aLayers & item->GetLayerSet() ).none() )
1508 bbox.
Merge( item->GetBoundingBox() );
1513 if( ( aLayers &
pad->GetLayerSet() ).none() )
1516 bbox.
Merge(
pad->GetBoundingBox() );
1521 if( ( aLayers & zone->GetLayerSet() ).none() )
1524 bbox.
Merge( zone->GetBoundingBox() );
1560 pad->Padstack().ForEachUniqueLayer(
1574 const SHAPE_POLY_SET& layerPoly = *zone->GetFilledPolysList( layer );
1601 std::vector<VECTOR2I> convex_hull;
1607 for(
const VECTOR2I& pt : convex_hull )
1630 if( item->IsOnLayer( aLayer ) )
1644 if(
pad->IsOnLayer( aLayer ) )
1650 if( zone->GetIsRuleArea() )
1653 if( zone->IsOnLayer( aLayer ) )
1655 const std::shared_ptr<SHAPE_POLY_SET>& layerPoly = zone->GetFilledPolysList( aLayer );
1657 for(
int ii = 0; ii < layerPoly->OutlineCount(); ii++ )
1658 rawPolys.
AddOutline( layerPoly->COutline( ii ) );
1662 std::vector<VECTOR2I> convex_hull;
1667 for(
const VECTOR2I& pt : convex_hull )
1688 aList.emplace_back(
_(
"Library" ),
GetFPID().GetLibNickname().wx_str() );
1690 aList.emplace_back(
_(
"Footprint Name" ),
GetFPID().GetLibItemName().wx_str() );
1692 aList.emplace_back(
_(
"Pads" ), wxString::Format( wxT(
"%zu" ), padCount ) );
1695 wxString::Format(
_(
"Keywords: %s" ),
GetKeywords() ) );
1704 case F_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Front" ) );
break;
1705 case B_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Back (Flipped)" ) );
break;
1709 auto addToken = []( wxString* aStr,
const wxString& aAttr )
1711 if( !aStr->IsEmpty() )
1712 *aStr += wxT(
", " );
1721 addToken( &status,
_(
"Locked" ) );
1724 addToken( &status,
_(
"autoplaced" ) );
1727 addToken( &attrs,
_(
"not in schematic" ) );
1730 addToken( &attrs,
_(
"exclude from pos files" ) );
1733 addToken( &attrs,
_(
"exclude from BOM" ) );
1736 addToken( &attrs,
_(
"DNP" ) );
1738 aList.emplace_back(
_(
"Status: " ) + status,
_(
"Attributes:" ) + wxS(
" " ) + attrs );
1740 aList.emplace_back(
_(
"Rotation" ), wxString::Format( wxT(
"%.4g" ),
1746 _(
"Component Class" ),
1751 msg2.Printf(
_(
"3D-Shape: %s" ),
m_3D_Drawings.empty() ?
_(
"<none>" )
1753 aList.emplace_back( msg, msg2 );
1757 aList.emplace_back( msg, msg2 );
1765 if( board->IsFootprintHolder() )
1797 if(
pad->IsOnLayer( aLayer ) )
1803 if( zone->IsOnLayer( aLayer ) )
1809 if( field->IsOnLayer( aLayer ) )
1815 if( item->IsOnLayer( aLayer ) )
1827 if(
pad->IsOnLayer( aLayer ) &&
pad->HitTest( aPosition, aAccuracy ) )
1833 if( zone->IsOnLayer( aLayer ) && zone->HitTest( aPosition, aAccuracy ) )
1839 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer )
1840 && item->HitTest( aPosition, aAccuracy ) )
1852 std::vector<BOARD_ITEM*> items;
1856 if(
pad->IsOnLayer( aLayer ) )
1857 items.push_back(
pad );
1862 if( zone->IsOnLayer( aLayer ) )
1863 items.push_back( zone );
1868 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer ) )
1869 items.push_back( item );
1878 if( !aContained && item->HitTest( aRect, aContained, aAccuracy ) )
1880 else if( aContained && !item->HitTest( aRect, aContained, aAccuracy ) )
1887 return !items.empty() && aContained;
1906 BOX2I arect = aRect;
1926 if(
pad->HitTest( arect,
false, 0 ) )
1932 if( zone->HitTest( arect,
false, 0 ) )
1943 if( item->Type() !=
PCB_TEXT_T && item->HitTest( arect,
false, 0 ) )
1957 bool can_select = aSearchAfterMe ? false :
true;
1961 if( !can_select &&
pad == aSearchAfterMe )
1967 if( can_select &&
pad->GetNumber() == aPadNumber )
1980 if( !(
pad->GetLayerSet() & aLayerMask ).any() )
1983 if(
pad->HitTest( aPosition ) )
1993 std::vector<const PAD*> retv;
1997 if( ( aIgnore && aIgnore ==
pad ) || (
pad->GetNumber() != aPadNumber ) )
2000 retv.push_back(
pad );
2016 if(
pad->GetAttribute() == PAD_ATTRIB::NPTH )
2028 std::set<wxString> usedNumbers;
2040 if(
pad->GetNumber().IsEmpty() )
2046 if(
pad->GetAttribute() == PAD_ATTRIB::NPTH )
2050 usedNumbers.insert(
pad->GetNumber() );
2065 if(
nullptr == a3DModel )
2093 const std::vector<KICAD_T>& aScanTypes )
2095#if 0 && defined(DEBUG)
2096 std::cout <<
GetClass().mb_str() <<
' ';
2099 bool drawingsScanned =
false;
2101 for(
KICAD_T scanType : aScanTypes )
2106 if( inspector(
this, testData ) == INSPECT_RESULT::QUIT )
2107 return INSPECT_RESULT::QUIT;
2112 if( IterateForward<PAD*>(
m_pads, inspector, testData, { scanType } )
2113 == INSPECT_RESULT::QUIT )
2115 return INSPECT_RESULT::QUIT;
2121 if( IterateForward<ZONE*>(
m_zones, inspector, testData, { scanType } )
2122 == INSPECT_RESULT::QUIT )
2124 return INSPECT_RESULT::QUIT;
2130 if( IterateForward<PCB_FIELD*>(
m_fields, inspector, testData, { scanType } )
2131 == INSPECT_RESULT::QUIT )
2133 return INSPECT_RESULT::QUIT;
2148 if( !drawingsScanned )
2150 if( IterateForward<BOARD_ITEM*>(
m_drawings, inspector, testData, aScanTypes )
2151 == INSPECT_RESULT::QUIT )
2153 return INSPECT_RESULT::QUIT;
2156 drawingsScanned =
true;
2162 if( IterateForward<PCB_GROUP*>(
m_groups, inspector, testData, { scanType } )
2163 == INSPECT_RESULT::QUIT )
2165 return INSPECT_RESULT::QUIT;
2175 return INSPECT_RESULT::CONTINUE;
2183 if( reference.IsEmpty() )
2184 reference =
_(
"<no reference designator>" );
2186 return wxString::Format(
_(
"Footprint %s" ), reference );
2192 return BITMAPS::module;
2220 aFunction( drawing );
2222 if( aMode == RECURSE_MODE::RECURSE )
2223 drawing->RunOnChildren( aFunction, RECURSE_MODE::RECURSE );
2226 catch( std::bad_function_call& )
2228 wxFAIL_MSG( wxT(
"Error running FOOTPRINT::RunOnChildren" ) );
2235 std::vector<int> layers;
2237 layers.reserve( 6 );
2243 wxASSERT_MSG(
false, wxT(
"Illegal layer" ) );
2261 bool f_silk =
false, b_silk =
false, non_silk =
false;
2265 if( item->GetLayer() ==
F_SilkS )
2267 else if( item->GetLayer() ==
B_SilkS )
2273 if( ( f_silk || b_silk ) && !non_silk &&
m_pads.empty() )
2306 constexpr double MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY = 1.5;
2309 return MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY;
2322 int biggest_clearance = board->GetMaxClearanceValue();
2323 area.
Inflate( biggest_clearance );
2334 if( aName.find_first_of( invalids ) != std::string::npos )
2348 static const wxChar invalidChars[] = wxT(
"%$<>\t\n\r\"\\/:");
2349 static const wxChar invalidCharsReadable[] = wxT(
"% $ < > 'tab' 'return' 'line feed' \\ \" / :");
2352 return invalidCharsReadable;
2354 return invalidChars;
2360 if( aMoveVector.
x == 0 && aMoveVector.
y == 0 )
2374 EDA_ANGLE newOrientation = orientation + aAngle;
2381 field->KeepUpright();
2386 static_cast<PCB_TEXT*
>( item )->KeepUpright();
2393 wxASSERT( aLayer ==
F_Cu || aLayer ==
B_Cu );
2428 field->Flip(
m_pos, FLIP_DIRECTION::TOP_BOTTOM );
2432 pad->Flip(
m_pos, FLIP_DIRECTION::TOP_BOTTOM );
2439 zone->Flip(
m_pos, FLIP_DIRECTION::TOP_BOTTOM );
2443 item->Flip(
m_pos, FLIP_DIRECTION::TOP_BOTTOM );
2446 if( aFlipDirection == FLIP_DIRECTION::LEFT_RIGHT )
2466 field->EDA_TEXT::Offset(
delta );
2472 zone->Move(
delta );
2475 item->Move(
delta );
2507 field->Move( moveVector );
2511 pad->Move( moveVector );
2515 item->Move( moveVector );
2519 zone->Move( moveVector );
2577 RECURSE_MODE::RECURSE );
2587 switch( aItem->
Type() )
2591 PAD* new_pad =
new PAD( *
static_cast<const PAD*
>( aItem ) );
2594 if( aAddToFootprint )
2595 m_pads.push_back( new_pad );
2603 ZONE* new_zone =
new ZONE( *
static_cast<const ZONE*
>( aItem ) );
2606 if( aAddToFootprint )
2607 m_zones.push_back( new_zone );
2609 new_item = new_zone;
2623 case FIELD_T::REFERENCE: new_text->
SetText( wxT(
"${REFERENCE}" ) );
break;
2624 case FIELD_T::VALUE: new_text->
SetText( wxT(
"${VALUE}" ) );
break;
2625 case FIELD_T::DATASHEET: new_text->
SetText( wxT(
"${DATASHEET}" ) );
break;
2630 if( aAddToFootprint )
2633 new_item = new_text;
2642 if( aAddToFootprint )
2645 new_item = new_shape;
2654 if( aAddToFootprint )
2657 new_item = new_textbox;
2669 if( aAddToFootprint )
2672 new_item = dimension;
2680 if( aAddToFootprint )
2682 group->RunOnChildren(
2687 RECURSE_MODE::RECURSE );
2702 wxFAIL_MSG( wxT(
"Duplication not supported for items of class " ) + aItem->
GetClass() );
2712 std::set<wxString> usedNumbers;
2716 usedNumbers.insert(
pad->GetNumber() );
2723 while( usedNumbers.count( wxString::Format( wxT(
"%s%d" ), prefix, num ) ) )
2726 return wxString::Format( wxT(
"%s%d" ), prefix, num );
2734 if(
group.contains( aPadNumber ) )
2738 return std::nullopt;
2789 for(
int jj = 0; jj < aPolySet.
HoleCount( ii ); jj++ )
2793 return aPolySet.
Area();
2808 return markerShape.
Area();
2812 double combinedArea = 0.0;
2817 return combinedArea;
2847 case SHAPE_T::SEGMENT:
2849 case SHAPE_T::BEZIER:
2852 case SHAPE_T::RECTANGLE:
2853 case SHAPE_T::CIRCLE:
2868 double width =
static_cast<const PCB_TRACK*
>( aItem )->GetWidth();
2869 return width * width;
2873 static_cast<const PAD*
>( aItem )->Padstack().ForEachUniqueLayer(
2905 for(
int i = 0; i < aCollector.
GetCount(); ++i )
2909 switch( item->
Type() )
2940 double footprintRegionArea =
polygonArea( footprintRegion );
2941 double uncoveredRegionArea = footprintRegionArea -
polygonArea( coveredRegion );
2942 double coveredArea = footprintRegionArea - uncoveredRegionArea;
2943 double ratio = ( coveredArea / footprintRegionArea );
2950 return std::min( ratio, 1.0 );
2956 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
2977 shape->AddShape(
pad->GetEffectiveShape( aLayer, aFlash )->Clone() );
2982 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3022 std::vector<PCB_SHAPE*> list_front;
3023 std::vector<PCB_SHAPE*> list_back;
3024 std::map<int, int> front_width_histogram;
3025 std::map<int, int> back_width_histogram;
3032 list_back.push_back( shape );
3039 list_front.push_back( shape );
3044 if( !list_front.size() && !list_back.size() )
3051 true, aErrorHandler ) )
3061 auto max = std::max_element( front_width_histogram.begin(), front_width_histogram.end(),
3062 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3064 return a.second < b.second;
3067 if( max != front_width_histogram.end() )
3090 auto max = std::max_element( back_width_histogram.begin(), back_width_histogram.end(),
3091 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3093 return a.second < b.second;
3096 if( max != back_width_histogram.end() )
3119 std::map<PCB_LAYER_ID, std::vector<PCB_SHAPE*>> layer_shapes;
3124 if( item->Type() != PCB_SHAPE_T )
3127 for( PCB_LAYER_ID layer : item->GetLayerSet() )
3128 layer_shapes[layer].push_back( static_cast<PCB_SHAPE*>( item ) );
3131 for(
size_t ii = 0; ii <
m_pads.size(); ++ii )
3134 bool has_nettie =
false;
3136 auto it = map.find(
pad->GetNumber() );
3138 if( it == map.end() || it->second < 0 )
3141 for(
size_t jj = ii + 1; jj <
m_pads.size(); ++jj )
3145 auto it2 = map.find( other->
GetNumber() );
3147 if( it2 == map.end() || it2->second < 0 )
3150 if( it2->second == it->second )
3163 for(
auto& [ layer, shapes ] : layer_shapes )
3165 auto pad_shape =
pad->GetEffectiveShape( layer );
3167 for(
auto other_shape : shapes )
3169 auto shape = other_shape->GetEffectiveShape( layer );
3171 if( pad_shape->Collide( shape.get() ) )
3174 m_netTieCache[other_shape].insert( nettie.begin(), nettie.end() );
3184 std::map<wxString, int> padNumberToGroupIdxMap;
3187 padNumberToGroupIdxMap[
pad->GetNumber() ] = -1;
3190 [&]( wxString aPad,
int aGroup )
3192 aPad.Trim(
true ).Trim(
false );
3194 if( !aPad.IsEmpty() )
3195 padNumberToGroupIdxMap[ aPad ] = aGroup;
3204 for( wxUniCharRef ch :
group )
3213 switch(
static_cast<unsigned char>( ch ) )
3220 processPad(
pad, ii );
3230 processPad(
pad, ii );
3233 return padNumberToGroupIdxMap;
3243 int groupIdx = padToNetTieGroupMap[ aPad->
GetNumber() ];
3244 std::vector<PAD*> otherPads;
3250 if( padToNetTieGroupMap[
pad->GetNumber() ] == groupIdx )
3251 otherPads.push_back(
pad );
3264 if( setAttr && likelyAttr && setAttr != likelyAttr )
3268 switch( likelyAttr )
3271 msg.Printf(
_(
"(expected 'Through hole'; actual '%s')" ),
GetTypeName() );
3274 msg.Printf(
_(
"(expected 'SMD'; actual '%s')" ),
GetTypeName() );
3279 (aErrorHandler)( msg );
3285 const std::function<
void(
const PAD*,
int,
3286 const wxString& )>& aErrorHandler )
3288 if( aErrorHandler ==
nullptr )
3293 pad->CheckPad( aUnitsProvider,
false,
3294 [&](
int errorCode,
const wxString& msg )
3296 aErrorHandler(
pad, errorCode, msg );
3304 const VECTOR2I& )>& aErrorHandler )
3306 std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
3321 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
3324 if( checkedPairs.find( { a, b } ) == checkedPairs.end() )
3326 checkedPairs[ { a, b } ] = 1;
3328 if(
pad->HasDrilledHole() && other->HasDrilledHole() )
3332 if(
pad->GetPosition() == other->GetPosition() )
3338 std::shared_ptr<SHAPE_SEGMENT> holeA =
pad->GetEffectiveHoleShape();
3339 std::shared_ptr<SHAPE_SEGMENT> holeB = other->GetEffectiveHoleShape();
3341 if( holeA->Collide( holeB->GetSeg(), 0 ) )
3352 if(
pad->GetBoundingBox().Intersects( other->GetBoundingBox() ) )
3356 for(
PCB_LAYER_ID l :
pad->Padstack().RelevantShapeLayers( other->Padstack() ) )
3358 SHAPE* padShape =
pad->GetEffectiveShape( l ).get();
3359 SHAPE* otherShape = other->GetEffectiveShape( l ).get();
3361 if( padShape->
Collide( otherShape, 0,
nullptr, &pos ) )
3374 const VECTOR2I& )>& aErrorHandler )
3383 std::vector<BOARD_ITEM*> copperItems;
3387 if( item->IsOnCopperLayer() )
3388 copperItems.push_back( item );
3390 item->RunOnChildren(
3394 copperItems.push_back( descendent );
3396 RECURSE_MODE::RECURSE );
3401 if( !zone->GetIsRuleArea() && zone->IsOnCopperLayer() )
3402 copperItems.push_back( zone );
3407 if( field->IsOnCopperLayer() )
3408 copperItems.push_back( field );
3418 std::map<int, std::vector<const PAD*>> outlineIdxToPadsMap;
3422 if( item->IsOnLayer( layer ) )
3424 item->TransformShapeToPolygon( copperOutlines, layer, 0,
ARC_HIGH_DEF,
3435 for(
int ii = 0; ii < copperOutlines.
OutlineCount(); ++ii )
3437 if(
pad->GetEffectiveShape( layer )->Collide( &copperOutlines.
Outline( ii ), 0 ) )
3438 outlineIdxToPadsMap[ ii ].emplace_back(
pad );
3445 for(
const auto& [ outlineIdx, pads ] : outlineIdxToPadsMap )
3447 if( pads.size() > 1 )
3449 const PAD* firstPad = pads[0];
3450 int firstGroupIdx = padNumberToGroupIdxMap[ firstPad->
GetNumber() ];
3452 for(
size_t ii = 1; ii < pads.size(); ++ii )
3454 const PAD* thisPad = pads[ii];
3455 int thisGroupIdx = padNumberToGroupIdxMap[ thisPad->
GetNumber() ];
3457 if( thisGroupIdx < 0 || thisGroupIdx != firstGroupIdx )
3466 if( item->HitTest( pos, 1 ) )
3468 shortingItem = item;
3474 aErrorHandler( shortingItem, firstPad, thisPad, pos );
3476 aErrorHandler( firstPad, thisPad,
nullptr, pos );
3487 std::set<wxString> padNumbers;
3496 msg.Printf(
_(
"(net-tie pad group contains unknown pad number %s)" ), padNumber );
3497 aErrorHandler( msg );
3499 else if( !padNumbers.insert(
pad->GetNumber() ).second )
3501 msg.Printf(
_(
"(pad %s appears in more than one net-tie pad group)" ), padNumber );
3502 aErrorHandler( msg );
3510 const VECTOR2I& aPt )>& aErrorHandler )
3512 auto checkColliding =
3519 if( !item->
IsOnLayer( silk ) || !other->IsOnLayer( mask ) )
3523 std::shared_ptr<SHAPE> otherShape = other->GetEffectiveShape( mask );
3527 if( itemShape->Collide( otherShape.get(), 0, &
actual, &pos ) )
3528 aErrorHandler( item, other, pos );
3537 checkColliding( item, other );
3541 checkColliding( item,
pad );
3552 std::swap( *
this, *
image );
3559 RECURSE_MODE::NO_RECURSE );
3561 image->RunOnChildren(
3566 RECURSE_MODE::NO_RECURSE );
3574 if(
pad->GetAttribute() != PAD_ATTRIB::SMD )
3589 return *
this == other;
3598 for(
size_t ii = 0; ii <
m_pads.size(); ++ii )
3607 for(
size_t ii = 0; ii <
m_drawings.size(); ++ii )
3616 for(
size_t ii = 0; ii <
m_zones.size(); ++ii )
3623 std::vector<PCB_FIELD*> fields, otherFields;
3628 if( fields.size() != otherFields.size() )
3631 for(
size_t ii = 0; ii < fields.size(); ++ii )
3635 if( !( *fields[ii] == *otherFields[ii] ) )
3651 double similarity = 1.0;
3660 similarity *=
pad->Similarity( *otherPad );
3669 if( itemA->
Type() != itemB->
Type() )
3670 return itemA->
Type() < itemB->
Type();
3685 if( dwgA->
GetShape() != SHAPE_T::POLY )
3698 if( dwgA->
GetShape() == SHAPE_T::ARC )
3705 else if( dwgA->
GetShape() == SHAPE_T::BEZIER )
3717 else if( dwgA->
GetShape() == SHAPE_T::POLY )
3740 return itemA < itemB;
3754 std::optional<bool> padCopperMatches;
3757 const PAD* checkPad = aFirst;
3770 padCopperMatches = aFirst->
GetSize( aLayer ).
x < aSecond->
GetSize( aLayer ).
x;
3772 padCopperMatches = aFirst->
GetSize( aLayer ).
y < aSecond->
GetSize( aLayer ).
y;
3774 padCopperMatches = aFirst->
GetShape( aLayer ) < aSecond->
GetShape( aLayer );
3777 if( padCopperMatches.has_value() )
3778 return *padCopperMatches;
3786 return aFirst < aSecond;
3791bool FOOTPRINT::cmp_padstack::operator()(
const PAD* aFirst,
const PAD* aSecond )
const
3831 if( firstShape->VertexCount() != secondShape->VertexCount() )
3832 return firstShape->VertexCount() < secondShape->VertexCount();
3834 for(
int ii = 0; ii < firstShape->VertexCount(); ++ii )
3836 if( firstShape->CVertex( ii ).x != secondShape->CVertex( ii ).x )
3837 return firstShape->CVertex( ii ).x < secondShape->CVertex( ii ).x;
3838 if( firstShape->CVertex( ii ).y != secondShape->CVertex( ii ).y )
3839 return firstShape->CVertex( ii ).y < secondShape->CVertex( ii ).y;
3858 for(
int ii = 0; ii < aFirst->
Outline()->TotalVertices(); ++ii )
3869 return aFirst < aSecond;
3874 int aClearance,
int aMaxError,
ERROR_LOC aErrorLoc )
const
3885 clearance.x +=
pad->GetSolderMaskExpansion( padLayer );
3886 clearance.y +=
pad->GetSolderMaskExpansion( padLayer );
3905 &&
pad->GetShape( padLayer ) != PAD_SHAPE::CUSTOM )
3909 if( dummySize.
x <= 0 || dummySize.
y <= 0 )
3913 dummy.SetSize( padLayer, dummySize );
3914 dummy.TransformShapeToPolygon( aBuffer, padLayer, 0, aMaxError, aErrorLoc );
3918 pad->TransformShapeToPolygon( aBuffer, padLayer,
clearance.x, aMaxError,
3925 if( !
pad->FlashLayer( aLayer ) )
3930 pad->Padstack().ForEachUniqueLayer(
3933 processPad(
pad, l );
3938 processPad(
pad, aLayer );
3945 int aClearance,
int aError,
ERROR_LOC aErrorLoc,
3946 bool aIncludeText,
bool aIncludeShapes,
3947 bool aIncludePrivateItems )
const
3954 if( item->Type() ==
PCB_TEXT_T && aIncludeText )
3959 text->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
3971 textbox->PCB_SHAPE::TransformShapeToPolygon( aBuffer, aLayer, 0, aError,
3980 if( item->Type() ==
PCB_SHAPE_T && aIncludeShapes )
3993 if( field->GetLayer() == aLayer && field->IsVisible() )
3994 field->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4003 using EMBEDDING_PERMISSION = OUTLINE_FONT::EMBEDDING_PERMISSION;
4005 std::set<OUTLINE_FONT*>
fonts;
4011 if(
auto* font =
text->GetFont(); font && !font->IsStroke() )
4013 auto* outline =
static_cast<OUTLINE_FONT*
>( font );
4014 auto permission = outline->GetEmbeddingPermission();
4016 if( permission == EMBEDDING_PERMISSION::EDITABLE
4017 || permission == EMBEDDING_PERMISSION::INSTALLABLE )
4019 fonts.insert( outline );
4033 for(
auto* font :
fonts )
4072 return wxEmptyString;
4077 BOARD* aBoard,
const std::unordered_set<wxString>& aComponentClassNames )
4081 aComponentClassNames );
4098 if( zcMap.
Choices().GetCount() == 0 )
4100 zcMap.
Undefined( ZONE_CONNECTION::INHERITED );
4101 zcMap.
Map( ZONE_CONNECTION::INHERITED,
_HKI(
"Inherited" ) )
4102 .
Map( ZONE_CONNECTION::NONE,
_HKI(
"None" ) )
4103 .
Map( ZONE_CONNECTION::THERMAL,
_HKI(
"Thermal reliefs" ) )
4104 .
Map( ZONE_CONNECTION::FULL,
_HKI(
"Solid" ) )
4105 .
Map( ZONE_CONNECTION::THT_THERMAL,
_HKI(
"Thermal reliefs for PTH" ) );
4110 if( layerEnum.
Choices().GetCount() == 0 )
4118 wxPGChoices fpLayers;
4131 layer->SetChoices( fpLayers );
4136 PROPERTY_DISPLAY::PT_DEGREE ) );
4138 const wxString groupFields =
_HKI(
"Fields" );
4163 const wxString groupAttributes =
_HKI(
"Attributes" );
4177 const wxString groupOverrides =
_HKI(
"Overrides" );
4180 _HKI(
"Exempt From Courtyard Requirement" ),
4184 _HKI(
"Clearance Override" ),
4186 PROPERTY_DISPLAY::PT_SIZE ),
4189 _HKI(
"Solderpaste Margin Override" ),
4191 PROPERTY_DISPLAY::PT_SIZE ),
4194 _HKI(
"Solderpaste Margin Ratio Override" ),
4197 PROPERTY_DISPLAY::PT_RATIO ),
4200 _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.
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 set of EDA_ITEMs (i.e., without duplicates).
std::unordered_set< EDA_ITEM * > & GetItems()
virtual bool RemoveItem(EDA_ITEM *aItem)=0
Remove item from group.
virtual EDA_ITEM * AsEdaItem()=0
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 bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
EDA_GROUP * GetParentGroup() const
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 const LSET & SideSpecificMask()
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
static const LSET & AllLayersMask()
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
void ShapeToPolygon(SHAPE_LINE_CHAIN &aPolygon, int aScale=-1) const
Return the shape polygon in internal units in a SHAPE_LINE_CHAIN the coordinates are relatives to the...
static const int ORPHANED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
void ForEachUniqueLayer(const std::function< void(PCB_LAYER_ID)> &aMethod) const
Runs the given callable for each active unique copper layer in this padstack, meaning F_Cu for MODE::...
@ NORMAL
Shape is the same on all layers.
@ CUSTOM
Shapes can be defined on arbitrary layers.
@ FRONT_INNER_BACK
Up to three shapes can be defined (F_Cu, inner copper layers, B_Cu)
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
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 * > GetBoardItems() const
bool AddItem(EDA_ITEM *aItem) override
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_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