26#include <magic_enum.hpp>
28#include <unordered_set>
64#include <google/protobuf/any.pb.h>
65#include <api/board/board_types.pb.h>
77 m_fileFormatVersionAtLoad( 0 ),
78 m_boundingBoxCacheTimeStamp( 0 ),
79 m_textExcludedBBoxCacheTimeStamp( 0 ),
80 m_hullCacheTimeStamp( 0 ),
81 m_duplicatePadNumbersAreJumpers( false ),
82 m_allowMissingCourtyard( false ),
83 m_allowSolderMaskBridges( false ),
88 m_initial_comments( nullptr ),
103 addField( FIELD_T::REFERENCE,
F_SilkS,
true );
104 addField( FIELD_T::VALUE,
F_Fab,
true );
105 addField( FIELD_T::DATASHEET,
F_Fab,
false );
106 addField( FIELD_T::DESCRIPTION,
F_Fab,
false );
163 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
171 ptrMap[field] = existingField;
172 *existingField = *field;
178 ptrMap[field] = newField;
186 PAD* newPad =
static_cast<PAD*
>(
pad->Clone() );
187 ptrMap[
pad ] = newPad;
188 Add( newPad, ADD_MODE::APPEND );
194 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
195 ptrMap[ zone ] = newZone;
196 Add( newZone, ADD_MODE::APPEND );
209 ptrMap[ item ] = newItem;
210 Add( newItem, ADD_MODE::APPEND );
217 ptrMap[
group ] = newGroup;
218 Add( newGroup, ADD_MODE::APPEND );
230 if( ptrMap.count( member ) )
231 newGroup->
AddItem( ptrMap[ member ] );
243 *
this = std::move( aFootprint );
278 board->IncrementTimeStamp();
285 types::FootprintInstance footprint;
288 footprint.mutable_position()->set_x_nm(
GetPosition().x );
289 footprint.mutable_position()->set_y_nm(
GetPosition().y );
291 footprint.set_layer( ToProtoEnum<PCB_LAYER_ID, types::BoardLayer>(
GetLayer() ) );
292 footprint.set_locked(
IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
293 : kiapi::common::types::LockedState::LS_UNLOCKED );
295 google::protobuf::Any buf;
297 buf.UnpackTo( footprint.mutable_reference_field() );
299 buf.UnpackTo( footprint.mutable_value_field() );
301 buf.UnpackTo( footprint.mutable_datasheet_field() );
303 buf.UnpackTo( footprint.mutable_description_field() );
305 types::FootprintAttributes* attrs = footprint.mutable_attributes();
311 attrs->set_do_not_populate(
IsDNP() );
314 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_THROUGH_HOLE );
316 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_SMD );
318 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_UNSPECIFIED );
320 types::Footprint* def = footprint.mutable_definition();
325 def->mutable_attributes()->set_keywords(
GetKeywords().ToStdString() );
329 types::FootprintDesignRuleOverrides* overrides = def->mutable_overrides();
343 overrides->set_zone_connection(
348 types::NetTieDefinition* netTie = def->add_net_ties();
349 wxStringTokenizer tokenizer(
group,
" " );
351 while( tokenizer.HasMoreTokens() )
352 netTie->add_pad_number( tokenizer.GetNextToken().ToStdString() );
356 def->add_private_layers( ToProtoEnum<PCB_LAYER_ID, types::BoardLayer>( layer ) );
360 if( item->IsMandatory() )
363 google::protobuf::Any* itemMsg = def->add_items();
364 item->Serialize( *itemMsg );
367 for(
const PAD* item :
Pads() )
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 item->Serialize( *itemMsg );
387 google::protobuf::Any* itemMsg = def->add_items();
388 types::Footprint3DModel modelMsg;
389 modelMsg.set_filename( model.m_Filename.ToUTF8() );
393 modelMsg.set_visible( model.m_Show );
394 modelMsg.set_opacity( model.m_Opacity );
395 itemMsg->PackFrom( modelMsg );
401 aContainer.PackFrom( footprint );
408 types::FootprintInstance footprint;
410 if( !aContainer.UnpackTo( &footprint ) )
416 SetLayer( FromProtoEnum<PCB_LAYER_ID, types::BoardLayer>( footprint.layer() ) );
417 SetLocked( footprint.locked() == kiapi::common::types::LockedState::LS_LOCKED );
419 google::protobuf::Any buf;
420 types::Field mandatoryField;
422 if( footprint.has_reference_field() )
424 mandatoryField = footprint.reference_field();
425 mandatoryField.mutable_id()->set_id( (
int) FIELD_T::REFERENCE );
426 buf.PackFrom( mandatoryField );
430 if( footprint.has_value_field() )
432 mandatoryField = footprint.value_field();
433 mandatoryField.mutable_id()->set_id( (
int) FIELD_T::VALUE );
434 buf.PackFrom( mandatoryField );
438 if( footprint.has_datasheet_field() )
440 mandatoryField = footprint.datasheet_field();
441 mandatoryField.mutable_id()->set_id( (
int) FIELD_T::DATASHEET );
442 buf.PackFrom( mandatoryField );
446 if( footprint.has_description_field() )
448 mandatoryField = footprint.description_field();
449 mandatoryField.mutable_id()->set_id( (
int) FIELD_T::DESCRIPTION );
450 buf.PackFrom( mandatoryField );
456 switch( footprint.attributes().mounting_style() )
458 case types::FootprintMountingStyle::FMS_THROUGH_HOLE:
462 case types::FootprintMountingStyle::FMS_SMD:
470 SetBoardOnly( footprint.attributes().not_in_schematic() );
474 SetDNP( footprint.attributes().do_not_populate() );
480 SetKeywords( footprint.definition().attributes().keywords() );
482 const types::FootprintDesignRuleOverrides& overrides = footprint.overrides();
484 if( overrides.has_copper_clearance() )
489 if( overrides.has_solder_mask() && overrides.solder_mask().has_solder_mask_margin() )
494 if( overrides.has_solder_paste() )
496 const types::SolderPasteOverrides& pasteSettings = overrides.solder_paste();
498 if( pasteSettings.has_solder_paste_margin() )
503 if( pasteSettings.has_solder_paste_margin_ratio() )
511 for(
const types::NetTieDefinition& netTieMsg : footprint.definition().net_ties() )
515 for(
const std::string&
pad : netTieMsg.pad_number() )
516 group.Append( wxString::Format( wxT(
"%s " ),
pad ) );
524 for(
int layerMsg : footprint.definition().private_layers() )
526 auto layer = FromProtoEnum<PCB_LAYER_ID, types::BoardLayer>(
static_cast<types::BoardLayer
>( layerMsg ) );
529 privateLayers.
set( layer );
537 if( !field->IsMandatory() )
547 for(
const google::protobuf::Any& itemMsg : footprint.definition().items() )
555 if( itemMsg.type_url() ==
"type.googleapis.com/kiapi.board.types.Footprint3DModel" )
557 types::Footprint3DModel modelMsg;
559 if( !itemMsg.UnpackTo( &modelMsg ) )
564 model.
m_Filename = wxString::FromUTF8( modelMsg.filename() );
565 model.
m_Show = modelMsg.visible();
571 Models().push_back( std::move( model ) );
575 wxLogTrace(
traceApi, wxString::Format( wxS(
"Attempting to unpack unknown type %s "
576 "from footprint message, skipping" ),
577 itemMsg.type_url() ) );
585 if( item && item->Deserialize( itemMsg ) )
586 Add( item.release(), ADD_MODE::APPEND );
597 if( field->GetId() == aFieldType )
612 if( field->GetId() == aFieldType )
622 return GetField( aFieldName ) !=
nullptr;
630 if( field->GetName() == aFieldName )
646 if( !field->IsVisible() || field->GetText().IsEmpty() )
650 aVector.push_back( field );
653 std::sort( aVector.begin(), aVector.end(),
656 return lhs->GetOrdinal() < rhs->GetOrdinal();
666 ordinal = std::max( ordinal, field->GetOrdinal() + 1 );
683 switch( item->Type() )
693 if( aStyleShapes && !item->IsOnCopperLayer() )
708 std::vector< BOARD_ITEM* > item_list;
711 item_list.push_back( field );
714 item_list.push_back(
pad );
717 item_list.push_back( gr_item );
722 item_list.push_back(
group );
726 item_list.push_back( zone );
728 bool changed =
false;
734 const_cast<KIID&
>( item->m_Uuid ) =
KIID();
747 m_pos = aOther.m_pos;
771 std::ranges::copy( aOther.m_jumperPadGroups,
780 for(
PCB_FIELD* field : aOther.m_fields )
783 aOther.m_fields.clear();
791 for(
PAD*
pad : aOther.Pads() )
794 aOther.Pads().clear();
802 for(
ZONE* item : aOther.Zones() )
810 item->SetNetCode( -1 );
813 aOther.Zones().clear();
821 for(
BOARD_ITEM* item : aOther.GraphicalItems() )
824 aOther.GraphicalItems().clear();
835 aOther.Groups().clear();
848 aOther.m_fields.clear();
849 aOther.Pads().clear();
850 aOther.Zones().clear();
851 aOther.GraphicalItems().clear();
852 aOther.m_initial_comments =
nullptr;
885 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
893 ptrMap[field] = newField;
903 ptrMap[
pad ] = newPad;
912 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
913 ptrMap[ zone ] = newZone;
929 ptrMap[ item ] = newItem;
942 newGroup->
AddItem( ptrMap[ member ] );
965 *
this = *
static_cast<const FOOTPRINT*
>( aOther );
991 aVars->push_back( wxT(
"REFERENCE" ) );
992 aVars->push_back( wxT(
"VALUE" ) );
993 aVars->push_back( wxT(
"LAYER" ) );
994 aVars->push_back( wxT(
"FOOTPRINT_LIBRARY" ) );
995 aVars->push_back( wxT(
"FOOTPRINT_NAME" ) );
996 aVars->push_back( wxT(
"SHORT_NET_NAME(<pad_number>)" ) );
997 aVars->push_back( wxT(
"NET_NAME(<pad_number>)" ) );
998 aVars->push_back( wxT(
"NET_CLASS(<pad_number>)" ) );
999 aVars->push_back( wxT(
"PIN_NAME(<pad_number>)" ) );
1008 if( token->IsSameAs( wxT(
"REFERENCE" ) ) )
1013 else if( token->IsSameAs( wxT(
"VALUE" ) ) )
1018 else if( token->IsSameAs( wxT(
"LAYER" ) ) )
1023 else if( token->IsSameAs( wxT(
"FOOTPRINT_LIBRARY" ) ) )
1028 else if( token->IsSameAs( wxT(
"FOOTPRINT_NAME" ) ) )
1033 else if( token->StartsWith( wxT(
"SHORT_NET_NAME(" ) )
1034 || token->StartsWith( wxT(
"NET_NAME(" ) )
1035 || token->StartsWith( wxT(
"NET_CLASS(" ) )
1036 || token->StartsWith( wxT(
"PIN_NAME(" ) ) )
1038 wxString padNumber = token->AfterFirst(
'(' );
1039 padNumber = padNumber.BeforeLast(
')' );
1043 if(
pad->GetNumber() == padNumber )
1045 if( token->StartsWith( wxT(
"SHORT_NET_NAME" ) ) )
1046 *token =
pad->GetShortNetname();
1047 else if( token->StartsWith( wxT(
"NET_NAME" ) ) )
1048 *token =
pad->GetNetname();
1049 else if( token->StartsWith( wxT(
"NET_CLASS" ) ) )
1050 *token =
pad->GetNetClassName();
1052 *token =
pad->GetPinFunction();
1060 *token = field->GetText();
1082 switch( aBoardItem->
Type() )
1098 if( aMode == ADD_MODE::APPEND )
1106 if( aMode == ADD_MODE::APPEND )
1107 m_pads.push_back(
static_cast<PAD*
>( aBoardItem ) );
1109 m_pads.push_front(
static_cast<PAD*
>( aBoardItem ) );
1114 if( aMode == ADD_MODE::APPEND )
1115 m_zones.push_back(
static_cast<ZONE*
>( aBoardItem ) );
1122 if( aMode == ADD_MODE::APPEND )
1130 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Markers go at the board level, even in the footprint editor" ) );
1134 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Nested footprints not supported" ) );
1138 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Add(): BOARD_ITEM type (%d) not handled" ),
1139 aBoardItem->
Type() ) );
1151 switch( aBoardItem->
Type() )
1156 if( *it == aBoardItem )
1177 if( *it == aBoardItem )
1187 for(
auto it =
m_pads.begin(); it !=
m_pads.end(); ++it )
1189 if( *it ==
static_cast<PAD*
>( aBoardItem ) )
1201 if( *it ==
static_cast<ZONE*
>( aBoardItem ) )
1213 if( *it ==
static_cast<PCB_GROUP*
>( aBoardItem ) )
1225 msg.Printf( wxT(
"FOOTPRINT::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
1226 aBoardItem->
Type() );
1252 switch(
pad->GetProperty() )
1254 case PAD_PROP::FIDUCIAL_GLBL:
1255 case PAD_PROP::FIDUCIAL_LOCAL:
1258 case PAD_PROP::HEATSINK:
1259 case PAD_PROP::CASTELLATED:
1260 case PAD_PROP::MECHANICAL:
1263 case PAD_PROP::NONE:
1265 case PAD_PROP::TESTPOINT:
1266 case PAD_PROP::PRESSFIT:
1270 switch(
pad->GetAttribute() )
1272 case PAD_ATTRIB::PTH:
1276 case PAD_ATTRIB::SMD:
1277 if(
pad->IsOnCopperLayer() )
1305 return _(
"Through hole" );
1307 return _(
"Other" );
1322 if(
dummy.IsFlipped() )
1326 bbox.
Merge(
pad->GetBoundingBox() );
1371 std::vector<PCB_TEXT*> texts;
1393 texts.push_back(
static_cast<PCB_TEXT*
>( item ) );
1411 bbox.
Merge( item->GetBoundingBox() );
1417 if( field->IsReference() || field->IsValue() )
1420 texts.push_back( field );
1424 bbox.
Merge(
pad->GetBoundingBox() );
1427 bbox.
Merge( zone->GetBoundingBox() );
1432 if( aIncludeText || noDrawItems )
1449 bool valueLayerIsVisible =
true;
1450 bool refLayerIsVisible =
true;
1468 if( (
Value().IsVisible() && valueLayerIsVisible ) || noDrawItems )
1473 if( (
Reference().IsVisible() && refLayerIsVisible ) || noDrawItems )
1481 if( aIncludeText || noDrawItems )
1499 std::vector<PCB_TEXT*> texts;
1511 if( ( aLayers & item->GetLayerSet() ).none() )
1519 bbox.
Merge( item->GetBoundingBox() );
1524 if( ( aLayers &
pad->GetLayerSet() ).none() )
1527 bbox.
Merge(
pad->GetBoundingBox() );
1532 if( ( aLayers & zone->GetLayerSet() ).none() )
1535 bbox.
Merge( zone->GetBoundingBox() );
1571 pad->Padstack().ForEachUniqueLayer(
1585 const SHAPE_POLY_SET& layerPoly = *zone->GetFilledPolysList( layer );
1612 std::vector<VECTOR2I> convex_hull;
1618 for(
const VECTOR2I& pt : convex_hull )
1641 if( item->IsOnLayer( aLayer ) )
1655 if(
pad->IsOnLayer( aLayer ) )
1661 if( zone->GetIsRuleArea() )
1664 if( zone->IsOnLayer( aLayer ) )
1666 const std::shared_ptr<SHAPE_POLY_SET>& layerPoly = zone->GetFilledPolysList( aLayer );
1668 for(
int ii = 0; ii < layerPoly->OutlineCount(); ii++ )
1669 rawPolys.
AddOutline( layerPoly->COutline( ii ) );
1673 std::vector<VECTOR2I> convex_hull;
1678 for(
const VECTOR2I& pt : convex_hull )
1699 aList.emplace_back(
_(
"Library" ),
GetFPID().GetLibNickname().wx_str() );
1701 aList.emplace_back(
_(
"Footprint Name" ),
GetFPID().GetLibItemName().wx_str() );
1703 aList.emplace_back(
_(
"Pads" ), wxString::Format( wxT(
"%zu" ), padCount ) );
1706 wxString::Format(
_(
"Keywords: %s" ),
GetKeywords() ) );
1715 case F_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Front" ) );
break;
1716 case B_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Back (Flipped)" ) );
break;
1720 auto addToken = []( wxString* aStr,
const wxString& aAttr )
1722 if( !aStr->IsEmpty() )
1723 *aStr += wxT(
", " );
1732 addToken( &status,
_(
"Locked" ) );
1735 addToken( &status,
_(
"autoplaced" ) );
1738 addToken( &attrs,
_(
"not in schematic" ) );
1741 addToken( &attrs,
_(
"exclude from pos files" ) );
1744 addToken( &attrs,
_(
"exclude from BOM" ) );
1747 addToken( &attrs,
_(
"DNP" ) );
1749 aList.emplace_back(
_(
"Status: " ) + status,
_(
"Attributes:" ) + wxS(
" " ) + attrs );
1751 aList.emplace_back(
_(
"Rotation" ), wxString::Format( wxT(
"%.4g" ),
1757 _(
"Component Class" ),
1762 msg2.Printf(
_(
"3D-Shape: %s" ),
m_3D_Drawings.empty() ?
_(
"<none>" )
1764 aList.emplace_back( msg, msg2 );
1768 aList.emplace_back( msg, msg2 );
1776 if( board->IsFootprintHolder() )
1808 if(
pad->IsOnLayer( aLayer ) )
1814 if( zone->IsOnLayer( aLayer ) )
1820 if( field->IsOnLayer( aLayer ) )
1826 if( item->IsOnLayer( aLayer ) )
1838 if(
pad->IsOnLayer( aLayer ) &&
pad->HitTest( aPosition, aAccuracy ) )
1844 if( zone->IsOnLayer( aLayer ) && zone->HitTest( aPosition, aAccuracy ) )
1850 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer )
1851 && item->HitTest( aPosition, aAccuracy ) )
1863 std::vector<BOARD_ITEM*> items;
1867 if(
pad->IsOnLayer( aLayer ) )
1868 items.push_back(
pad );
1873 if( zone->IsOnLayer( aLayer ) )
1874 items.push_back( zone );
1879 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer ) )
1880 items.push_back( item );
1889 if( !aContained && item->HitTest( aRect, aContained, aAccuracy ) )
1891 else if( aContained && !item->HitTest( aRect, aContained, aAccuracy ) )
1898 return !items.empty() && aContained;
1917 BOX2I arect = aRect;
1937 if(
pad->HitTest( arect,
false, 0 ) )
1943 if( zone->HitTest( arect,
false, 0 ) )
1954 if( item->Type() !=
PCB_TEXT_T && item->HitTest( arect,
false, 0 ) )
1968 using std::ranges::all_of;
1969 using std::ranges::any_of;
1976 [&](
const auto* aItem )
1978 return aItem && aItem->HitTest( aPoly, aContained );
1984 auto drawings =
m_drawings | std::views::filter( [](
const auto* aItem )
1995 return all_of( drawings, hitTest )
1996 && all_of(
m_pads, hitTest )
1997 && all_of(
m_zones, hitTest );
2002 return any_of( drawings, hitTest )
2003 || any_of(
m_pads, hitTest )
2004 || any_of(
m_zones, hitTest );
2011 bool can_select = aSearchAfterMe ? false :
true;
2015 if( !can_select &&
pad == aSearchAfterMe )
2021 if( can_select &&
pad->GetNumber() == aPadNumber )
2034 if( !(
pad->GetLayerSet() & aLayerMask ).any() )
2037 if(
pad->HitTest( aPosition ) )
2047 std::vector<const PAD*> retv;
2051 if( ( aIgnore && aIgnore ==
pad ) || (
pad->GetNumber() != aPadNumber ) )
2054 retv.push_back(
pad );
2070 if(
pad->GetAttribute() == PAD_ATTRIB::NPTH )
2082 std::set<wxString> usedNumbers;
2094 if(
pad->GetNumber().IsEmpty() )
2100 if(
pad->GetAttribute() == PAD_ATTRIB::NPTH )
2104 usedNumbers.insert(
pad->GetNumber() );
2119 if(
nullptr == a3DModel )
2147 const std::vector<KICAD_T>& aScanTypes )
2149#if 0 && defined(DEBUG)
2150 std::cout <<
GetClass().mb_str() <<
' ';
2153 bool drawingsScanned =
false;
2155 for(
KICAD_T scanType : aScanTypes )
2160 if( inspector(
this, testData ) == INSPECT_RESULT::QUIT )
2161 return INSPECT_RESULT::QUIT;
2166 if( IterateForward<PAD*>(
m_pads, inspector, testData, { scanType } )
2167 == INSPECT_RESULT::QUIT )
2169 return INSPECT_RESULT::QUIT;
2175 if( IterateForward<ZONE*>(
m_zones, inspector, testData, { scanType } )
2176 == INSPECT_RESULT::QUIT )
2178 return INSPECT_RESULT::QUIT;
2184 if( IterateForward<PCB_FIELD*>(
m_fields, inspector, testData, { scanType } )
2185 == INSPECT_RESULT::QUIT )
2187 return INSPECT_RESULT::QUIT;
2202 if( !drawingsScanned )
2204 if( IterateForward<BOARD_ITEM*>(
m_drawings, inspector, testData, aScanTypes )
2205 == INSPECT_RESULT::QUIT )
2207 return INSPECT_RESULT::QUIT;
2210 drawingsScanned =
true;
2216 if( IterateForward<PCB_GROUP*>(
m_groups, inspector, testData, { scanType } )
2217 == INSPECT_RESULT::QUIT )
2219 return INSPECT_RESULT::QUIT;
2229 return INSPECT_RESULT::CONTINUE;
2237 if( reference.IsEmpty() )
2238 reference =
_(
"<no reference designator>" );
2240 return wxString::Format(
_(
"Footprint %s" ), reference );
2246 return BITMAPS::module;
2274 aFunction( drawing );
2276 if( aMode == RECURSE_MODE::RECURSE )
2277 drawing->RunOnChildren( aFunction, RECURSE_MODE::RECURSE );
2280 catch( std::bad_function_call& )
2282 wxFAIL_MSG( wxT(
"Error running FOOTPRINT::RunOnChildren" ) );
2289 std::vector<int> layers;
2291 layers.reserve( 6 );
2297 wxASSERT_MSG(
false, wxT(
"Illegal layer" ) );
2315 bool f_silk =
false, b_silk =
false, non_silk =
false;
2319 if( item->GetLayer() ==
F_SilkS )
2321 else if( item->GetLayer() ==
B_SilkS )
2327 if( ( f_silk || b_silk ) && !non_silk &&
m_pads.empty() )
2360 constexpr double MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY = 1.5;
2363 return MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY;
2376 int biggest_clearance = board->GetMaxClearanceValue();
2377 area.
Inflate( biggest_clearance );
2388 if( aName.find_first_of( invalids ) != std::string::npos )
2402 static const wxChar invalidChars[] = wxT(
"%$<>\t\n\r\"\\/:");
2403 static const wxChar invalidCharsReadable[] = wxT(
"% $ < > 'tab' 'return' 'line feed' \\ \" / :");
2406 return invalidCharsReadable;
2408 return invalidChars;
2414 if( aMoveVector.
x == 0 && aMoveVector.
y == 0 )
2428 EDA_ANGLE newOrientation = orientation + aAngle;
2435 field->KeepUpright();
2440 static_cast<PCB_TEXT*
>( item )->KeepUpright();
2447 wxASSERT( aLayer ==
F_Cu || aLayer ==
B_Cu );
2482 field->Flip(
m_pos, FLIP_DIRECTION::TOP_BOTTOM );
2486 pad->Flip(
m_pos, FLIP_DIRECTION::TOP_BOTTOM );
2493 zone->Flip(
m_pos, FLIP_DIRECTION::TOP_BOTTOM );
2497 item->Flip(
m_pos, FLIP_DIRECTION::TOP_BOTTOM );
2500 if( aFlipDirection == FLIP_DIRECTION::LEFT_RIGHT )
2520 field->EDA_TEXT::Offset(
delta );
2526 zone->Move(
delta );
2529 item->Move(
delta );
2561 field->Move( moveVector );
2565 pad->Move( moveVector );
2569 item->Move( moveVector );
2573 zone->Move( moveVector );
2631 RECURSE_MODE::RECURSE );
2638 const BOARD_ITEM* aItem,
bool addToFootprint )
2642 switch( aItem->
Type() )
2646 PAD* new_pad =
new PAD( *
static_cast<const PAD*
>( aItem ) );
2649 if( addToFootprint )
2650 m_pads.push_back( new_pad );
2658 ZONE* new_zone =
new ZONE( *
static_cast<const ZONE*
>( aItem ) );
2661 if( addToFootprint )
2662 m_zones.push_back( new_zone );
2664 new_item = new_zone;
2678 case FIELD_T::REFERENCE: new_text->
SetText( wxT(
"${REFERENCE}" ) );
break;
2679 case FIELD_T::VALUE: new_text->
SetText( wxT(
"${VALUE}" ) );
break;
2680 case FIELD_T::DATASHEET: new_text->
SetText( wxT(
"${DATASHEET}" ) );
break;
2685 if( addToFootprint )
2688 new_item = new_text;
2697 if( addToFootprint )
2700 new_item = new_shape;
2709 if( addToFootprint )
2712 new_item = new_image;
2721 if( addToFootprint )
2724 new_item = new_textbox;
2737 if( addToFootprint )
2740 new_item = dimension;
2748 if( addToFootprint )
2750 group->RunOnChildren(
2755 RECURSE_MODE::RECURSE );
2770 wxFAIL_MSG( wxT(
"Duplication not supported for items of class " ) + aItem->
GetClass() );
2780 std::set<wxString> usedNumbers;
2784 usedNumbers.insert(
pad->GetNumber() );
2791 while( usedNumbers.count( wxString::Format( wxT(
"%s%d" ), prefix, num ) ) )
2794 return wxString::Format( wxT(
"%s%d" ), prefix, num );
2802 if(
group.contains( aPadNumber ) )
2806 return std::nullopt;
2857 for(
int jj = 0; jj < aPolySet.
HoleCount( ii ); jj++ )
2861 return aPolySet.
Area();
2876 return markerShape.
Area();
2880 double combinedArea = 0.0;
2885 return combinedArea;
2915 case SHAPE_T::SEGMENT:
2917 case SHAPE_T::BEZIER:
2920 case SHAPE_T::RECTANGLE:
2921 case SHAPE_T::CIRCLE:
2936 double width =
static_cast<const PCB_TRACK*
>( aItem )->GetWidth();
2937 return width * width;
2941 static_cast<const PAD*
>( aItem )->Padstack().ForEachUniqueLayer(
2973 for(
int i = 0; i < aCollector.
GetCount(); ++i )
2977 switch( item->
Type() )
3008 double footprintRegionArea =
polygonArea( footprintRegion );
3009 double uncoveredRegionArea = footprintRegionArea -
polygonArea( coveredRegion );
3010 double coveredArea = footprintRegionArea - uncoveredRegionArea;
3011 double ratio = ( coveredArea / footprintRegionArea );
3018 return std::min( ratio, 1.0 );
3024 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
3045 shape->AddShape(
pad->GetEffectiveShape( aLayer, aFlash )->Clone() );
3050 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3090 std::vector<PCB_SHAPE*> list_front;
3091 std::vector<PCB_SHAPE*> list_back;
3092 std::map<int, int> front_width_histogram;
3093 std::map<int, int> back_width_histogram;
3100 list_back.push_back( shape );
3107 list_front.push_back( shape );
3112 if( !list_front.size() && !list_back.size() )
3119 true, aErrorHandler ) )
3129 auto max = std::max_element( front_width_histogram.begin(), front_width_histogram.end(),
3130 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3132 return a.second < b.second;
3135 if( max != front_width_histogram.end() )
3158 auto max = std::max_element( back_width_histogram.begin(), back_width_histogram.end(),
3159 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3161 return a.second < b.second;
3164 if( max != back_width_histogram.end() )
3187 std::map<PCB_LAYER_ID, std::vector<PCB_SHAPE*>> layer_shapes;
3192 if( item->Type() != PCB_SHAPE_T )
3195 for( PCB_LAYER_ID layer : item->GetLayerSet() )
3196 layer_shapes[layer].push_back( static_cast<PCB_SHAPE*>( item ) );
3199 for(
size_t ii = 0; ii <
m_pads.size(); ++ii )
3202 bool has_nettie =
false;
3204 auto it = map.find(
pad->GetNumber() );
3206 if( it == map.end() || it->second < 0 )
3209 for(
size_t jj = ii + 1; jj <
m_pads.size(); ++jj )
3213 auto it2 = map.find( other->
GetNumber() );
3215 if( it2 == map.end() || it2->second < 0 )
3218 if( it2->second == it->second )
3231 for(
auto& [ layer, shapes ] : layer_shapes )
3233 auto pad_shape =
pad->GetEffectiveShape( layer );
3235 for(
auto other_shape : shapes )
3237 auto shape = other_shape->GetEffectiveShape( layer );
3239 if( pad_shape->Collide( shape.get() ) )
3242 m_netTieCache[other_shape].insert( nettie.begin(), nettie.end() );
3252 std::map<wxString, int> padNumberToGroupIdxMap;
3255 padNumberToGroupIdxMap[
pad->GetNumber() ] = -1;
3258 [&]( wxString aPad,
int aGroup )
3260 aPad.Trim(
true ).Trim(
false );
3262 if( !aPad.IsEmpty() )
3263 padNumberToGroupIdxMap[ aPad ] = aGroup;
3272 for( wxUniCharRef ch :
group )
3281 switch(
static_cast<unsigned char>( ch ) )
3288 processPad(
pad, ii );
3298 processPad(
pad, ii );
3301 return padNumberToGroupIdxMap;
3311 int groupIdx = padToNetTieGroupMap[ aPad->
GetNumber() ];
3312 std::vector<PAD*> otherPads;
3318 if( padToNetTieGroupMap[
pad->GetNumber() ] == groupIdx )
3319 otherPads.push_back(
pad );
3332 if( setAttr && likelyAttr && setAttr != likelyAttr )
3336 switch( likelyAttr )
3339 msg.Printf(
_(
"(expected 'Through hole'; actual '%s')" ),
GetTypeName() );
3342 msg.Printf(
_(
"(expected 'SMD'; actual '%s')" ),
GetTypeName() );
3347 (aErrorHandler)( msg );
3353 const std::function<
void(
const PAD*,
int,
3354 const wxString& )>& aErrorHandler )
3356 if( aErrorHandler ==
nullptr )
3361 pad->CheckPad( aUnitsProvider,
false,
3362 [&](
int errorCode,
const wxString& msg )
3364 aErrorHandler(
pad, errorCode, msg );
3372 const VECTOR2I& )>& aErrorHandler )
3374 std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
3389 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
3392 if( checkedPairs.find( { a, b } ) == checkedPairs.end() )
3394 checkedPairs[ { a, b } ] = 1;
3396 if(
pad->HasDrilledHole() && other->HasDrilledHole() )
3400 if(
pad->GetPosition() == other->GetPosition() )
3406 std::shared_ptr<SHAPE_SEGMENT> holeA =
pad->GetEffectiveHoleShape();
3407 std::shared_ptr<SHAPE_SEGMENT> holeB = other->GetEffectiveHoleShape();
3409 if( holeA->Collide( holeB->GetSeg(), 0 ) )
3420 if(
pad->GetBoundingBox().Intersects( other->GetBoundingBox() ) )
3424 for(
PCB_LAYER_ID l :
pad->Padstack().RelevantShapeLayers( other->Padstack() ) )
3426 SHAPE* padShape =
pad->GetEffectiveShape( l ).get();
3427 SHAPE* otherShape = other->GetEffectiveShape( l ).get();
3429 if( padShape->
Collide( otherShape, 0,
nullptr, &pos ) )
3442 const VECTOR2I& )>& aErrorHandler )
3451 std::vector<BOARD_ITEM*> copperItems;
3455 if( item->IsOnCopperLayer() )
3456 copperItems.push_back( item );
3458 item->RunOnChildren(
3462 copperItems.push_back( descendent );
3464 RECURSE_MODE::RECURSE );
3469 if( !zone->GetIsRuleArea() && zone->IsOnCopperLayer() )
3470 copperItems.push_back( zone );
3475 if( field->IsOnCopperLayer() )
3476 copperItems.push_back( field );
3486 std::map<int, std::vector<const PAD*>> outlineIdxToPadsMap;
3490 if( item->IsOnLayer( layer ) )
3500 for(
int ii = 0; ii < copperOutlines.
OutlineCount(); ++ii )
3502 if(
pad->GetEffectiveShape( layer )->Collide( &copperOutlines.
Outline( ii ), 0 ) )
3503 outlineIdxToPadsMap[ ii ].emplace_back(
pad );
3510 for(
const auto& [ outlineIdx, pads ] : outlineIdxToPadsMap )
3512 if( pads.size() > 1 )
3514 const PAD* firstPad = pads[0];
3515 int firstGroupIdx = padNumberToGroupIdxMap[ firstPad->
GetNumber() ];
3517 for(
size_t ii = 1; ii < pads.size(); ++ii )
3519 const PAD* thisPad = pads[ii];
3520 int thisGroupIdx = padNumberToGroupIdxMap[ thisPad->
GetNumber() ];
3522 if( thisGroupIdx < 0 || thisGroupIdx != firstGroupIdx )
3531 if( item->HitTest( pos, 1 ) )
3533 shortingItem = item;
3539 aErrorHandler( shortingItem, firstPad, thisPad, pos );
3541 aErrorHandler( firstPad, thisPad,
nullptr, pos );
3552 std::set<wxString> padNumbers;
3561 msg.Printf(
_(
"(net-tie pad group contains unknown pad number %s)" ), padNumber );
3562 aErrorHandler( msg );
3564 else if( !padNumbers.insert(
pad->GetNumber() ).second )
3566 msg.Printf(
_(
"(pad %s appears in more than one net-tie pad group)" ), padNumber );
3567 aErrorHandler( msg );
3575 const VECTOR2I& aPt )>& aErrorHandler )
3577 auto checkColliding =
3584 if( !item->
IsOnLayer( silk ) || !other->IsOnLayer( mask ) )
3588 std::shared_ptr<SHAPE> otherShape = other->GetEffectiveShape( mask );
3592 if( itemShape->Collide( otherShape.get(), 0, &
actual, &pos ) )
3593 aErrorHandler( item, other, pos );
3602 checkColliding( item, other );
3606 checkColliding( item,
pad );
3617 std::swap( *
this, *
image );
3624 RECURSE_MODE::NO_RECURSE );
3626 image->RunOnChildren(
3631 RECURSE_MODE::NO_RECURSE );
3639 if(
pad->GetAttribute() != PAD_ATTRIB::SMD )
3654 return *
this == other;
3663 for(
size_t ii = 0; ii <
m_pads.size(); ++ii )
3672 for(
size_t ii = 0; ii <
m_drawings.size(); ++ii )
3681 for(
size_t ii = 0; ii <
m_zones.size(); ++ii )
3688 std::vector<PCB_FIELD*> fields, otherFields;
3693 if( fields.size() != otherFields.size() )
3696 for(
size_t ii = 0; ii < fields.size(); ++ii )
3700 if( !( *fields[ii] == *otherFields[ii] ) )
3716 double similarity = 1.0;
3725 similarity *=
pad->Similarity( *otherPad );
3734 if( itemA->
Type() != itemB->
Type() )
3735 return itemA->
Type() < itemB->
Type();
3750 if( dwgA->
GetShape() != SHAPE_T::POLY )
3763 if( dwgA->
GetShape() == SHAPE_T::ARC )
3770 else if( dwgA->
GetShape() == SHAPE_T::BEZIER )
3782 else if( dwgA->
GetShape() == SHAPE_T::POLY )
3805 return itemA < itemB;
3819 std::optional<bool> padCopperMatches;
3822 const PAD* checkPad = aFirst;
3835 padCopperMatches = aFirst->
GetSize( aLayer ).
x < aSecond->
GetSize( aLayer ).
x;
3837 padCopperMatches = aFirst->
GetSize( aLayer ).
y < aSecond->
GetSize( aLayer ).
y;
3839 padCopperMatches = aFirst->
GetShape( aLayer ) < aSecond->
GetShape( aLayer );
3842 if( padCopperMatches.has_value() )
3843 return *padCopperMatches;
3851 return aFirst < aSecond;
3856bool FOOTPRINT::cmp_padstack::operator()(
const PAD* aFirst,
const PAD* aSecond )
const
3896 if( firstShape->VertexCount() != secondShape->VertexCount() )
3897 return firstShape->VertexCount() < secondShape->VertexCount();
3899 for(
int ii = 0; ii < firstShape->VertexCount(); ++ii )
3901 if( firstShape->CVertex( ii ).x != secondShape->CVertex( ii ).x )
3902 return firstShape->CVertex( ii ).x < secondShape->CVertex( ii ).x;
3903 if( firstShape->CVertex( ii ).y != secondShape->CVertex( ii ).y )
3904 return firstShape->CVertex( ii ).y < secondShape->CVertex( ii ).y;
3923 for(
int ii = 0; ii < aFirst->
Outline()->TotalVertices(); ++ii )
3934 return aFirst < aSecond;
3939 int aMaxError,
ERROR_LOC aErrorLoc )
const
3950 clearance.x +=
pad->GetSolderMaskExpansion( padLayer );
3951 clearance.y +=
pad->GetSolderMaskExpansion( padLayer );
3970 &&
pad->GetShape( padLayer ) != PAD_SHAPE::CUSTOM )
3974 if( dummySize.
x <= 0 || dummySize.
y <= 0 )
3978 dummy.SetSize( padLayer, dummySize );
3979 dummy.TransformShapeToPolygon( aBuffer, padLayer, 0, aMaxError, aErrorLoc );
3983 pad->TransformShapeToPolygon( aBuffer, padLayer,
clearance.x, aMaxError, aErrorLoc );
3989 if( !
pad->FlashLayer( aLayer ) )
3994 pad->Padstack().ForEachUniqueLayer(
3997 processPad(
pad, l );
4002 processPad(
pad, aLayer );
4009 int aError,
ERROR_LOC aErrorLoc,
bool aIncludeText,
4010 bool aIncludeShapes,
bool aIncludePrivateItems )
const
4017 if( item->Type() ==
PCB_TEXT_T && aIncludeText )
4022 text->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4033 textbox->PCB_SHAPE::TransformShapeToPolygon( aBuffer, aLayer, 0, aError, aErrorLoc );
4040 if( item->Type() ==
PCB_SHAPE_T && aIncludeShapes )
4053 if( field->GetLayer() == aLayer && field->IsVisible() )
4054 field->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4064 std::set<KIFONT::OUTLINE_FONT*>
fonts;
4078 if( permission == PERMISSION::EDITABLE || permission == PERMISSION::INSTALLABLE )
4079 fonts.insert( outlineFont );
4085 processItem( item );
4088 processItem( field );
4133 return wxEmptyString;
4138 const std::unordered_set<wxString>& aComponentClassNames )
4158 if( zcMap.
Choices().GetCount() == 0 )
4160 zcMap.
Undefined( ZONE_CONNECTION::INHERITED );
4161 zcMap.
Map( ZONE_CONNECTION::INHERITED,
_HKI(
"Inherited" ) )
4162 .
Map( ZONE_CONNECTION::NONE,
_HKI(
"None" ) )
4163 .
Map( ZONE_CONNECTION::THERMAL,
_HKI(
"Thermal reliefs" ) )
4164 .
Map( ZONE_CONNECTION::FULL,
_HKI(
"Solid" ) )
4165 .
Map( ZONE_CONNECTION::THT_THERMAL,
_HKI(
"Thermal reliefs for PTH" ) );
4170 if( layerEnum.
Choices().GetCount() == 0 )
4178 wxPGChoices fpLayers;
4191 layer->SetChoices( fpLayers );
4196 PROPERTY_DISPLAY::PT_DEGREE ) );
4198 const wxString groupFields =
_HKI(
"Fields" );
4223 const wxString groupAttributes =
_HKI(
"Attributes" );
4237 const wxString groupOverrides =
_HKI(
"Overrides" );
4240 _HKI(
"Exempt From Courtyard Requirement" ),
4244 _HKI(
"Clearance Override" ),
4246 PROPERTY_DISPLAY::PT_SIZE ),
4249 _HKI(
"Solderpaste Margin Override" ),
4251 PROPERTY_DISPLAY::PT_SIZE ),
4254 _HKI(
"Solderpaste Margin Ratio Override" ),
4257 PROPERTY_DISPLAY::PT_RATIO ),
4260 _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 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 BOARD_ITEM * Duplicate(bool addToParentGroup, BOARD_COMMIT *aCommit=nullptr) const
Create a copy of this BOARD_ITEM.
virtual void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const
Convert the item shape to a closed polygon.
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
VECTOR2I GetFPRelativePosition() const
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.
std::unordered_set< EDA_ITEM * > & GetItems()
void AddItem(EDA_ITEM *aItem)
Add item to group.
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.
virtual void SetParent(EDA_ITEM *aParent)
bool HasFlag(EDA_ITEM_FLAGS aFlag) 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
FONT is an abstract base class for both outline and stroke fonts.
virtual bool IsOutline() const
Class OUTLINE_FONT implements outline font drawing.
EMBEDDING_PERMISSION GetEmbeddingPermission() const
virtual wxString GetClass() const =0
Return the class name.
static constexpr double LOD_HIDE
Return this constant from ViewGetLOD() to hide the item unconditionally.
static constexpr double LOD_SHOW
Return this constant from ViewGetLOD() to show the item unconditionally.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
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()
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
static const LSET & AllLayersMask()
static LSET AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
void ShapeToPolygon(SHAPE_LINE_CHAIN &aPolygon, int aScale=-1) const
Return the shape polygon in internal units in a SHAPE_LINE_CHAIN the coordinates are relatives to the...
static const int ORPHANED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
void ForEachUniqueLayer(const std::function< void(PCB_LAYER_ID)> &aMethod) const
Runs the given callable for each active unique copper layer in this padstack, meaning F_Cu for MODE::...
@ NORMAL
Shape is the same on all layers.
@ CUSTOM
Shapes can be defined on arbitrary layers.
@ FRONT_INNER_BACK
Up to three shapes can be defined (F_Cu, inner copper layers, B_Cu)
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
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
Object to handle a bitmap image that can be inserted in a PCB.
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
int GetWidth() const override
void TransformShapeToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc) 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
a few functions useful in geometry calculations.
const wxChar *const traceApi
Flag to enable debug output related to the IPC API and its plugin system.
Some functions to handle hotkeys in KiCad.
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
@ LAYER_CONFLICTS_SHADOW
Shadow layer for items flagged conflicting.
@ LAYER_FOOTPRINTS_FR
Show footprints on front.
@ LAYER_FP_REFERENCES
Show footprints references (when texts are visible).
@ LAYER_FOOTPRINTS_BK
Show footprints on back.
@ LAYER_ANCHOR
Anchor of items having an anchor point (texts, footprints).
@ LAYER_FP_VALUES
Show footprints values (when texts are visible).
PCB_LAYER_ID
A quick note on layer IDs:
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
constexpr void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
bool BoxHitTest(const VECTOR2I &aHitPoint, const BOX2I &aHittee, int aAccuracy)
Perform a point-to-box hit test.
wxString GetRefDesPrefix(const wxString &aRefDes)
Get the (non-numeric) prefix from a refdes - e.g.
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
KICOMMON_API std::optional< KICAD_T > TypeNameFromAny(const google::protobuf::Any &aMessage)
KICOMMON_API VECTOR3D UnpackVector3D(const types::Vector3D &aInput)
KICOMMON_API void PackSheetPath(types::SheetPath &aOutput, const KIID_PATH &aInput)
KICOMMON_API LIB_ID LibIdFromProto(const types::LibraryIdentifier &aId)
KICOMMON_API types::LibraryIdentifier LibIdToProto(const LIB_ID &aId)
KICOMMON_API void PackVector3D(types::Vector3D &aOutput, const VECTOR3D &aInput)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
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
ZONE_CONNECTION
How pads are covered by copper in zone.