25#include <magic_enum.hpp>
29#include <unordered_set>
33#include <wx/tokenzr.h>
73#include <google/protobuf/any.pb.h>
74#include <api/board/board_types.pb.h>
174 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
179 if( field->IsMandatory() )
181 PCB_FIELD* existingField = GetField( field->GetId() );
182 ptrMap[field] = existingField;
183 *existingField = *field;
184 existingField->SetParent( this );
188 PCB_FIELD* newField = static_cast<PCB_FIELD*>( field->Clone() );
189 ptrMap[field] = newField;
195 for(
PAD*
pad : aFootprint.Pads() )
197 PAD* newPad = static_cast<PAD*>( pad->Clone() );
198 ptrMap[ pad ] = newPad;
199 Add( newPad, ADD_MODE::APPEND );
203 for(
ZONE* zone : aFootprint.Zones() )
205 ZONE* newZone = static_cast<ZONE*>( zone->Clone() );
206 ptrMap[ zone ] = newZone;
207 Add( newZone, ADD_MODE::APPEND );
213 newZone->SetNetCode( -1 );
217 for(
BOARD_ITEM* item : aFootprint.GraphicalItems() )
219 BOARD_ITEM* newItem = static_cast<BOARD_ITEM*>( item->Clone() );
220 ptrMap[ item ] = newItem;
221 Add( newItem, ADD_MODE::APPEND );
227 PCB_GROUP* newGroup = static_cast<PCB_GROUP*>( group->Clone() );
228 ptrMap[ group ] = newGroup;
229 Add( newGroup, ADD_MODE::APPEND );
232 for(
PCB_POINT* point : aFootprint.Points() )
234 PCB_POINT* newPoint = static_cast<PCB_POINT*>( point->Clone() );
235 ptrMap[ point ] = newPoint;
236 Add( newPoint, ADD_MODE::APPEND );
242 PCB_GROUP* newGroup = static_cast<PCB_GROUP*>( ptrMap[ group ] );
244 newGroup->GetItems().clear();
246 for( EDA_ITEM* member : group->GetItems() )
248 if( ptrMap.count( member ) )
249 newGroup->AddItem( ptrMap[ member ] );
263 *
this = std::move( aFootprint );
303 board->IncrementTimeStamp();
310 types::FootprintInstance footprint;
312 footprint.mutable_id()->set_value(
m_Uuid.AsStdString() );
313 footprint.mutable_position()->set_x_nm(
GetPosition().x );
314 footprint.mutable_position()->set_y_nm(
GetPosition().y );
317 footprint.set_locked(
IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
318 : kiapi::common::types::LockedState::LS_UNLOCKED );
320 google::protobuf::Any buf;
322 buf.UnpackTo( footprint.mutable_reference_field() );
324 buf.UnpackTo( footprint.mutable_value_field() );
326 buf.UnpackTo( footprint.mutable_datasheet_field() );
328 buf.UnpackTo( footprint.mutable_description_field() );
330 types::FootprintAttributes* attrs = footprint.mutable_attributes();
336 attrs->set_do_not_populate(
IsDNP() );
340 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_THROUGH_HOLE );
342 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_SMD );
344 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_UNSPECIFIED );
346 types::Footprint* def = footprint.mutable_definition();
351 def->mutable_attributes()->set_keywords(
GetKeywords().ToUTF8() );
355 types::FootprintDesignRuleOverrides* overrides = footprint.mutable_overrides();
369 overrides->set_zone_connection(
374 types::NetTieDefinition* netTie = def->add_net_ties();
375 wxStringTokenizer tokenizer(
group,
", \t\r\n", wxTOKEN_STRTOK );
377 while( tokenizer.HasMoreTokens() )
378 netTie->add_pad_number( tokenizer.GetNextToken().ToUTF8() );
384 types::JumperSettings* jumpers = def->mutable_jumpers();
389 types::JumperGroup* jumperGroup = jumpers->add_groups();
391 for(
const wxString& padName :
group )
392 jumperGroup->add_pad_names( padName.ToUTF8() );
397 if( item->IsMandatory() )
400 google::protobuf::Any* itemMsg = def->add_items();
401 item->Serialize( *itemMsg );
404 for(
const PAD* item :
Pads() )
406 google::protobuf::Any* itemMsg = def->add_items();
407 item->Serialize( *itemMsg );
412 google::protobuf::Any* itemMsg = def->add_items();
413 item->Serialize( *itemMsg );
418 google::protobuf::Any* itemMsg = def->add_items();
419 item->Serialize( *itemMsg );
424 google::protobuf::Any* itemMsg = def->add_items();
425 types::Footprint3DModel modelMsg;
426 modelMsg.set_filename(
model.m_Filename.ToUTF8() );
430 modelMsg.set_visible(
model.m_Show );
431 modelMsg.set_opacity(
model.m_Opacity );
432 itemMsg->PackFrom( modelMsg );
437 footprint.set_symbol_sheet_name(
m_sheetname.ToUTF8() );
438 footprint.set_symbol_sheet_filename(
m_sheetfile.ToUTF8() );
439 footprint.set_symbol_footprint_filters(
m_filters.ToUTF8() );
441 aContainer.PackFrom( footprint );
448 types::FootprintInstance footprint;
450 if( !aContainer.UnpackTo( &footprint ) )
457 SetLocked( footprint.locked() == kiapi::common::types::LockedState::LS_LOCKED );
459 google::protobuf::Any buf;
460 types::Field mandatoryField;
462 if( footprint.has_reference_field() )
464 mandatoryField = footprint.reference_field();
466 buf.PackFrom( mandatoryField );
470 if( footprint.has_value_field() )
472 mandatoryField = footprint.value_field();
474 buf.PackFrom( mandatoryField );
478 if( footprint.has_datasheet_field() )
480 mandatoryField = footprint.datasheet_field();
482 buf.PackFrom( mandatoryField );
486 if( footprint.has_description_field() )
488 mandatoryField = footprint.description_field();
490 buf.PackFrom( mandatoryField );
496 switch( footprint.attributes().mounting_style() )
498 case types::FootprintMountingStyle::FMS_THROUGH_HOLE:
502 case types::FootprintMountingStyle::FMS_SMD:
510 SetBoardOnly( footprint.attributes().not_in_schematic() );
514 SetDNP( footprint.attributes().do_not_populate() );
521 SetKeywords( footprint.definition().attributes().keywords() );
523 const types::FootprintDesignRuleOverrides& overrides = footprint.overrides();
525 if( overrides.has_copper_clearance() )
530 if( overrides.has_solder_mask() && overrides.solder_mask().has_solder_mask_margin() )
535 if( overrides.has_solder_paste() )
537 const types::SolderPasteOverrides& pasteSettings = overrides.solder_paste();
539 if( pasteSettings.has_solder_paste_margin() )
544 if( pasteSettings.has_solder_paste_margin_ratio() )
554 for(
const types::NetTieDefinition& netTieMsg : footprint.definition().net_ties() )
558 for(
const std::string&
pad : netTieMsg.pad_number() )
559 group.Append( wxString::Format( wxT(
"%s, " ),
pad ) );
568 for(
const types::JumperGroup& groupMsg : footprint.definition().jumpers().groups() )
570 std::set<wxString>
group;
572 for(
const std::string& padName : groupMsg.pad_names() )
573 group.insert( wxString::FromUTF8( padName ) );
581 for(
int layerMsg : footprint.definition().private_layers() )
586 privateLayers.
set( layer );
592 m_sheetname = wxString::FromUTF8( footprint.symbol_sheet_name() );
593 m_sheetfile = wxString::FromUTF8( footprint.symbol_sheet_filename() );
594 m_filters = wxString::FromUTF8( footprint.symbol_footprint_filters() );
599 if( !field->IsMandatory() )
605 board->UncacheChildrenById(
this );
614 for(
const google::protobuf::Any& itemMsg : footprint.definition().items() )
622 if( itemMsg.type_url() ==
"type.googleapis.com/kiapi.board.types.Footprint3DModel" )
624 types::Footprint3DModel modelMsg;
626 if( !itemMsg.UnpackTo( &modelMsg ) )
631 model.m_Filename = wxString::FromUTF8( modelMsg.filename() );
632 model.m_Show = modelMsg.visible();
633 model.m_Opacity = modelMsg.opacity();
642 wxLogTrace(
traceApi, wxString::Format( wxS(
"Attempting to unpack unknown type %s "
643 "from footprint message, skipping" ),
644 itemMsg.type_url() ) );
652 if( item && item->Deserialize( itemMsg ) )
664 if( field->GetId() == aFieldType )
679 if( field->GetId() == aFieldType )
689 return GetField( aFieldName ) !=
nullptr;
697 if( field->GetName() == aFieldName )
713 if( !field->IsVisible() || field->GetText().IsEmpty() )
717 aVector.push_back( field );
720 std::sort( aVector.begin(), aVector.end(),
723 return lhs->GetOrdinal() < rhs->GetOrdinal();
733 ordinal = std::max( ordinal, field->GetOrdinal() + 1 );
740 bool aStyleShapes,
bool aStyleDimensions,
bool aStyleBarcodes )
745 field->StyleFromSettings(
board.GetDesignSettings(),
true );
750 switch( item->Type() )
755 item->StyleFromSettings(
board.GetDesignSettings(),
true );
760 if( aStyleShapes && !item->IsOnCopperLayer() )
761 item->StyleFromSettings(
board.GetDesignSettings(),
true );
770 if( aStyleDimensions )
771 item->StyleFromSettings(
board.GetDesignSettings(),
true );
777 item->StyleFromSettings(
board.GetDesignSettings(),
true );
790 std::vector< BOARD_ITEM* > item_list;
793 item_list.push_back( field );
796 item_list.push_back(
pad );
799 item_list.push_back( gr_item );
804 item_list.push_back(
group );
808 item_list.push_back( zone );
812 item_list.push_back( point );
814 bool changed =
false;
820 item->ResetUuidDirect();
857 board->UncacheChildrenById(
this );
865 for(
PCB_FIELD* field : aOther.m_fields )
868 aOther.m_fields.clear();
876 for(
PAD*
pad : aOther.Pads() )
879 aOther.Pads().clear();
887 for(
ZONE* item : aOther.Zones() )
895 item->SetNetCode( -1 );
898 aOther.Zones().clear();
906 for(
BOARD_ITEM* item : aOther.GraphicalItems() )
909 aOther.GraphicalItems().clear();
920 aOther.Groups().clear();
928 for(
PCB_POINT* point : aOther.Points() )
931 aOther.Points().clear();
945 aOther.m_componentClassCacheProxy->GetStaticComponentClass() );
948 aOther.m_fields.clear();
949 aOther.Pads().clear();
950 aOther.Zones().clear();
951 aOther.GraphicalItems().clear();
952 aOther.m_initial_comments =
nullptr;
986 board->UncacheChildrenById(
this );
988 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
999 ptrMap[field] = newField;
1012 ptrMap[
pad ] = newPad;
1024 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
1025 ptrMap[ zone ] = newZone;
1044 ptrMap[ item ] = newItem;
1060 newGroup->
AddItem( ptrMap[ member ] );
1074 ptrMap[ point ] = newItem;
1105 *
this = *
static_cast<const FOOTPRINT*
>( aOther );
1132 aVars->push_back( wxT(
"REFERENCE" ) );
1133 aVars->push_back( wxT(
"VALUE" ) );
1134 aVars->push_back( wxT(
"LAYER" ) );
1135 aVars->push_back( wxT(
"FOOTPRINT_LIBRARY" ) );
1136 aVars->push_back( wxT(
"FOOTPRINT_NAME" ) );
1137 aVars->push_back( wxT(
"SHORT_NET_NAME(<pad_number>)" ) );
1138 aVars->push_back( wxT(
"NET_NAME(<pad_number>)" ) );
1139 aVars->push_back( wxT(
"NET_CLASS(<pad_number>)" ) );
1140 aVars->push_back( wxT(
"PIN_NAME(<pad_number>)" ) );
1149 if( token->IsSameAs( wxT(
"REFERENCE" ) ) )
1154 else if( token->IsSameAs( wxT(
"VALUE" ) ) )
1159 else if( token->IsSameAs( wxT(
"LAYER" ) ) )
1164 else if( token->IsSameAs( wxT(
"FOOTPRINT_LIBRARY" ) ) )
1166 *token =
m_fpid.GetUniStringLibNickname();
1169 else if( token->IsSameAs( wxT(
"FOOTPRINT_NAME" ) ) )
1171 *token =
m_fpid.GetUniStringLibItemName();
1174 else if( token->StartsWith( wxT(
"SHORT_NET_NAME(" ) )
1175 || token->StartsWith( wxT(
"NET_NAME(" ) )
1176 || token->StartsWith( wxT(
"NET_CLASS(" ) )
1177 || token->StartsWith( wxT(
"PIN_NAME(" ) ) )
1179 wxString padNumber = token->AfterFirst(
'(' );
1180 padNumber = padNumber.BeforeLast(
')' );
1184 if(
pad->GetNumber() == padNumber )
1186 if( token->StartsWith( wxT(
"SHORT_NET_NAME" ) ) )
1187 *token =
pad->GetShortNetname();
1188 else if( token->StartsWith( wxT(
"NET_NAME" ) ) )
1189 *token =
pad->GetNetname();
1190 else if( token->StartsWith( wxT(
"NET_CLASS" ) ) )
1191 *token =
pad->GetNetClassName();
1193 *token =
pad->GetPinFunction();
1201 *token = field->GetShownText(
false, aDepth + 1 );
1220 return it !=
m_variants.end() ? &it->second :
nullptr;
1228 return it !=
m_variants.end() ? &it->second :
nullptr;
1234 if( aVariant.
GetName().IsEmpty()
1246 it->second = std::move( updated );
1256 if( aVariantName.IsEmpty()
1259 wxASSERT_MSG(
false, wxT(
"Variant name cannot be empty or default." ) );
1273 auto inserted =
m_variants.emplace( aVariantName, std::move( variant ) );
1274 return &inserted.first->second;
1286 if( aNewName.IsEmpty()
1297 auto existingIt =
m_variants.find( aNewName );
1299 if( existingIt !=
m_variants.end() && existingIt != it )
1302 if( it->first == aNewName )
1308 m_variants.emplace( aNewName, std::move( variant ) );
1327 return variant->
GetDNP();
1379 return field->GetText();
1403 switch( aBoardItem->
Type() )
1429 m_pads.push_back(
static_cast<PAD*
>( aBoardItem ) );
1431 m_pads.push_front(
static_cast<PAD*
>( aBoardItem ) );
1437 m_zones.push_back(
static_cast<ZONE*
>( aBoardItem ) );
1452 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Markers go at the board level, even in the footprint editor" ) );
1456 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Nested footprints not supported" ) );
1468 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Add(): BOARD_ITEM type (%d) not handled" ),
1469 aBoardItem->
Type() ) );
1480 board->CacheItemSubtreeById( aBoardItem );
1488 switch( aBoardItem->
Type() )
1493 if( *it == aBoardItem )
1515 if( *it == aBoardItem )
1525 for(
auto it =
m_pads.begin(); it !=
m_pads.end(); ++it )
1527 if( *it ==
static_cast<PAD*
>( aBoardItem ) )
1539 if( *it ==
static_cast<ZONE*
>( aBoardItem ) )
1551 if( *it ==
static_cast<PCB_GROUP*
>( aBoardItem ) )
1561 wxFAIL_MSG( wxT(
"FOOTPRINT::Remove(): Markers go at the board level, even in the footprint editor" ) );
1565 wxFAIL_MSG( wxT(
"FOOTPRINT::Remove(): Nested footprints not supported" ) );
1571 if( *it ==
static_cast<PCB_POINT*
>( aBoardItem ) )
1581 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
1582 aBoardItem->
Type() ) );
1587 board->UncacheItemSubtreeById( aBoardItem );
1612 switch(
pad->GetProperty() )
1630 switch(
pad->GetAttribute() )
1637 if(
pad->IsOnCopperLayer() )
1665 return _(
"Through hole" );
1667 return _(
"Other" );
1680 wxStringTokenizer keywordTokenizer(
GetKeywords(), wxS(
" \t\r\n" ), wxTOKEN_STRTOK );
1682 while( keywordTokenizer.HasMoreTokens() )
1703 if(
dummy.IsFlipped() )
1707 bbox.
Merge(
pad->GetBoundingBox() );
1759 std::vector<PCB_TEXT*> texts;
1760 bool isFPEdit =
board &&
board->IsFootprintHolder();
1781 texts.push_back(
static_cast<PCB_TEXT*
>( item ) );
1799 bbox.
Merge( item->GetBoundingBox() );
1805 if( field->IsReference() || field->IsValue() )
1808 texts.push_back( field );
1812 bbox.
Merge(
pad->GetBoundingBox() );
1815 bbox.
Merge( zone->GetBoundingBox() );
1818 bbox.
Merge( point->GetBoundingBox() );
1823 if( aIncludeText || noDrawItems )
1840 bool valueLayerIsVisible =
true;
1841 bool refLayerIsVisible =
true;
1859 if( (
Value().IsVisible() && valueLayerIsVisible ) || noDrawItems )
1864 if( (
Reference().IsVisible() && refLayerIsVisible ) || noDrawItems )
1877 if( aIncludeText || noDrawItems )
1895 std::vector<PCB_TEXT*> texts;
1897 bool isFPEdit =
board &&
board->IsFootprintHolder();
1907 if( ( aLayers & item->GetLayerSet() ).none() )
1915 bbox.
Merge( item->GetBoundingBox() );
1920 if( ( aLayers &
pad->GetLayerSet() ).none() )
1923 bbox.
Merge(
pad->GetBoundingBox() );
1928 if( ( aLayers & zone->GetLayerSet() ).none() )
1931 bbox.
Merge( zone->GetBoundingBox() );
1939 if( ( aLayers & point->GetLayerSet() ).none() )
1942 bbox.
Merge( point->GetBoundingBox() );
1952 bool isFPEdit =
board &&
board->IsFootprintHolder();
1978 pad->Padstack().ForEachUniqueLayer(
1992 const SHAPE_POLY_SET& layerPoly = *zone->GetFilledPolysList( layer );
2008 const int halfsize =
pcbIUScale.mmToIU( 1.0 );
2019 std::vector<VECTOR2I> convex_hull;
2028 for(
const VECTOR2I& pt : convex_hull )
2041 bool isFPEdit =
board &&
board->IsFootprintHolder();
2051 if( item->IsOnLayer( aLayer ) )
2065 if(
pad->IsOnLayer( aLayer ) )
2071 if( zone->GetIsRuleArea() )
2074 if( zone->IsOnLayer( aLayer ) )
2076 const std::shared_ptr<SHAPE_POLY_SET>& layerPoly = zone->GetFilledPolysList( aLayer );
2078 for(
int ii = 0; ii < layerPoly->OutlineCount(); ii++ )
2079 rawPolys.
AddOutline( layerPoly->COutline( ii ) );
2083 std::vector<VECTOR2I> convex_hull;
2088 for(
const VECTOR2I& pt : convex_hull )
2101 variant =
board->GetCurrentVariant();
2115 aList.emplace_back(
_(
"Footprint Name" ),
GetFPID().GetLibItemName().wx_str() );
2117 aList.emplace_back(
_(
"Pads" ), wxString::Format( wxT(
"%zu" ), padCount ) );
2120 wxString::Format(
_(
"Keywords: %s" ),
GetKeywords() ) );
2129 case F_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Front" ) );
break;
2130 case B_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Back (Flipped)" ) );
break;
2134 aList.emplace_back(
_(
"Rotation" ), wxString::Format( wxT(
"%.4g" ),
GetOrientation().AsDegrees() ) );
2136 auto addToken = []( wxString* aStr,
const wxString& aAttr )
2138 if( !aStr->IsEmpty() )
2139 *aStr += wxT(
", " );
2148 addToken( &status,
_(
"Locked" ) );
2151 addToken( &status,
_(
"autoplaced" ) );
2154 addToken( &attrs,
_(
"not in schematic" ) );
2157 addToken( &attrs,
_(
"exclude from pos files" ) );
2160 addToken( &attrs,
_(
"exclude from BOM" ) );
2163 addToken( &attrs,
_(
"DNP" ) );
2165 aList.emplace_back(
_(
"Status: " ) + status,
_(
"Attributes:" ) + wxS(
" " ) + attrs );
2169 aList.emplace_back(
_(
"Component Class" ),
2173 msg.Printf(
_(
"Footprint: %s" ),
m_fpid.GetUniStringLibId() );
2175 aList.emplace_back( msg, msg2 );
2179 aList.emplace_back( msg, msg2 );
2187 if(
board->IsFootprintHolder() )
2219 if(
pad->IsOnLayer( aLayer ) )
2225 if( zone->IsOnLayer( aLayer ) )
2231 if( field->IsOnLayer( aLayer ) )
2237 if( item->IsOnLayer( aLayer ) )
2249 if(
pad->IsOnLayer( aLayer ) &&
pad->HitTest( aPosition, aAccuracy ) )
2255 if( zone->IsOnLayer( aLayer ) && zone->HitTest( aPosition, aAccuracy ) )
2261 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer )
2262 && item->HitTest( aPosition, aAccuracy ) )
2274 std::vector<BOARD_ITEM*> items;
2278 if(
pad->IsOnLayer( aLayer ) )
2279 items.push_back(
pad );
2284 if( zone->IsOnLayer( aLayer ) )
2285 items.push_back( zone );
2290 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer ) )
2291 items.push_back( item );
2300 if( !aContained && item->HitTest( aRect, aContained, aAccuracy ) )
2302 else if( aContained && !item->HitTest( aRect, aContained, aAccuracy ) )
2309 return !items.empty() && aContained;
2328 BOX2I arect = aRect;
2348 if(
pad->HitTest( arect,
false, 0 ) )
2354 if( zone->HitTest( arect,
false, 0 ) )
2360 if( point->HitTest( arect,
false, 0 ) )
2371 if( item->Type() !=
PCB_TEXT_T && item->HitTest( arect,
false, 0 ) )
2385 using std::ranges::all_of;
2386 using std::ranges::any_of;
2393 [&](
const auto* aItem )
2395 return aItem && aItem->HitTest( aPoly, aContained );
2401 auto drawings =
m_drawings | std::views::filter( [](
const auto* aItem )
2412 return all_of( drawings, hitTest )
2413 && all_of(
m_pads, hitTest )
2414 && all_of(
m_zones, hitTest );
2419 return any_of( drawings, hitTest )
2420 || any_of(
m_pads, hitTest )
2421 || any_of(
m_zones, hitTest );
2428 bool can_select = aSearchAfterMe ? false :
true;
2432 if( !can_select &&
pad == aSearchAfterMe )
2438 if( can_select &&
pad->GetNumber() == aPadNumber )
2450 if(
pad->m_Uuid == aUuid )
2463 if( !(
pad->GetLayerSet() & aLayerMask ).any() )
2466 if(
pad->HitTest( aPosition ) )
2476 std::vector<const PAD*> retv;
2480 if( ( aIgnore && aIgnore ==
pad ) || (
pad->GetNumber() != aPadNumber ) )
2483 retv.push_back(
pad );
2511 std::set<wxString> usedNumbers;
2523 if(
pad->GetNumber().IsEmpty() )
2533 usedNumbers.insert(
pad->GetNumber() );
2554 auto isElectricalPadNumber = [](
const wxString& num ) ->
bool
2561 while( i < num.size() && wxIsalpha( num[i] ) )
2569 if( i == num.size() )
2572 for(
size_t j = i; j < num.size(); ++j )
2574 if( !wxIsdigit( num[j] ) )
2581 std::set<wxString> counted;
2593 const wxString& num =
pad->GetNumber();
2595 if( isElectricalPadNumber( num ) )
2596 counted.insert( num );
2599 return static_cast<unsigned>( counted.size() );
2605 if(
nullptr == a3DModel )
2648 const std::vector<KICAD_T>& aScanTypes )
2650#if 0 && defined(DEBUG)
2651 std::cout <<
GetClass().mb_str() <<
' ';
2654 bool drawingsScanned =
false;
2656 for(
KICAD_T scanType : aScanTypes )
2704 if( !drawingsScanned )
2712 drawingsScanned =
true;
2748 if( reference.IsEmpty() )
2749 reference =
_(
"<no reference designator>" );
2751 return wxString::Format(
_(
"Footprint %s" ), reference );
2757 return wxString::Format( wxT(
"%s (%s)" ),
2796 aFunction( drawing );
2802 catch( std::bad_function_call& )
2804 wxFAIL_MSG( wxT(
"Error running FOOTPRINT::RunOnChildren" ) );
2811 std::vector<int> layers;
2813 layers.reserve( 6 );
2819 wxASSERT_MSG(
false, wxT(
"Illegal layer" ) );
2836 bool f_silk =
false, b_silk =
false, non_silk =
false;
2840 if( item->GetLayer() ==
F_SilkS )
2842 else if( item->GetLayer() ==
B_SilkS )
2848 if( ( f_silk || b_silk ) && !non_silk &&
m_pads.empty() )
2885 constexpr double MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY = 1.5;
2888 return MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY;
2901 int biggest_clearance =
board->GetMaxClearanceValue();
2902 area.
Inflate( biggest_clearance );
2913 if( aName.find_first_of( invalids ) != std::string::npos )
2925 static const wxChar invalidCharsReadable[] = wxT(
"% $ < > 'tab' 'return' 'line feed' \\ \" / :");
2928 return invalidCharsReadable;
2930 return invalidChars.wc_str();
2936 if( aMoveVector.
x == 0 && aMoveVector.
y == 0 )
2950 EDA_ANGLE newOrientation = orientation + aAngle;
2957 field->KeepUpright();
2962 static_cast<PCB_TEXT*
>( item )->KeepUpright();
2969 wxASSERT( aLayer ==
F_Cu || aLayer ==
B_Cu );
3024 field->OnFootprintTransformed();
3027 pad->OnFootprintTransformed();
3030 zone->OnFootprintTransformed();
3038 item->OnFootprintTransformed();
3043 point->OnFootprintTransformed();
3084 if( !std::isfinite( aScaleX ) || !std::isfinite( aScaleY ) || aScaleX <= 0.0 || aScaleY <= 0.0 )
3089 const double ratioX = aScaleX / oldSx;
3090 const double ratioY = aScaleY / oldSy;
3091 const double linearFactor = ( aScaleX + aScaleY ) / ( oldSx + oldSy );
3099 pad->OnFootprintRescaled( ratioX, ratioY, linearFactor,
anchor, parentRotate );
3102 field->OnFootprintRescaled( ratioX, ratioY, linearFactor,
anchor, parentRotate );
3105 item->OnFootprintRescaled( ratioX, ratioY, linearFactor,
anchor, parentRotate );
3108 zone->OnFootprintRescaled( ratioX, ratioY, linearFactor,
anchor, parentRotate );
3111 point->OnFootprintTransformed();
3139 field->OnFootprintTransformed();
3142 pad->OnFootprintTransformed();
3145 zone->OnFootprintTransformed();
3148 point->OnFootprintTransformed();
3156 item->OnFootprintTransformed();
3160 item->Move(
delta );
3200 field->Move( moveVector );
3204 pad->Move( moveVector );
3208 item->Move( moveVector );
3212 zone->Move( moveVector );
3216 point->Move( moveVector );
3255 field->OnFootprintTransformed();
3258 pad->OnFootprintTransformed();
3261 zone->OnFootprintTransformed();
3264 point->OnFootprintTransformed();
3272 item->OnFootprintTransformed();
3276 item->Rotate( rotationCenter, angleChange );
3312 const BOARD_ITEM* aItem,
bool addToFootprint )
3316 switch( aItem->
Type() )
3320 PAD* new_pad =
new PAD( *
static_cast<const PAD*
>( aItem ) );
3323 if( addToFootprint )
3324 m_pads.push_back( new_pad );
3332 ZONE* new_zone =
new ZONE( *
static_cast<const ZONE*
>( aItem ) );
3335 if( addToFootprint )
3336 m_zones.push_back( new_zone );
3338 new_item = new_zone;
3347 if( addToFootprint )
3350 new_item = new_point;
3362 switch(
static_cast<const PCB_FIELD*
>( aItem )->GetId() )
3371 if( addToFootprint )
3374 new_item = new_text;
3383 if( addToFootprint )
3386 new_item = new_shape;
3395 if( addToFootprint )
3398 new_item = new_barcode;
3407 if( addToFootprint )
3410 new_item = new_image;
3419 if( addToFootprint )
3422 new_item = new_textbox;
3435 if( addToFootprint )
3438 new_item = dimension;
3446 if( addToFootprint )
3448 group->RunOnChildren(
3468 wxFAIL_MSG( wxT(
"Duplication not supported for items of class " ) + aItem->
GetClass() );
3478 std::set<wxString> usedNumbers;
3482 usedNumbers.insert(
pad->GetNumber() );
3489 while( usedNumbers.count( wxString::Format( wxT(
"%s%d" ), prefix, num ) ) )
3492 return wxString::Format( wxT(
"%s%d" ), prefix, num );
3500 if(
group.contains( aPadNumber ) )
3504 return std::nullopt;
3555 for(
int jj = 0; jj < aPolySet.
HoleCount( ii ); jj++ )
3559 return aPolySet.
Area();
3574 return markerShape.
Area();
3578 double combinedArea = 0.0;
3583 return combinedArea;
3634 double width =
static_cast<const PCB_TRACK*
>( aItem )->GetWidth();
3635 return width * width;
3639 static_cast<const PAD*
>( aItem )->Padstack().ForEachUniqueLayer(
3649 const ZONE* zone =
static_cast<const ZONE*
>( aItem );
3699 for(
int i = 0; i < aCollector.
GetCount(); ++i )
3703 switch( item->
Type() )
3735 double footprintRegionArea =
polygonArea( footprintRegion );
3736 double uncoveredRegionArea = footprintRegionArea -
polygonArea( coveredRegion );
3737 double coveredArea = footprintRegionArea - uncoveredRegionArea;
3740 if( footprintRegionArea == 0 )
3743 double ratio = coveredArea / footprintRegionArea;
3750 return std::min( ratio, 1.0 );
3756 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
3777 shape->AddShape(
pad->GetEffectiveShape( aLayer, aFlash )->Clone() );
3782 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3784 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3831 std::vector<PCB_SHAPE*> list_front;
3832 std::vector<PCB_SHAPE*> list_back;
3833 std::map<int, int> front_width_histogram;
3834 std::map<int, int> back_width_histogram;
3841 list_back.push_back( shape );
3848 list_front.push_back( shape );
3853 if( !list_front.size() && !list_back.size() )
3857 int chainingEpsilon =
pcbIUScale.mmToIU( 0.02 );
3860 true, aErrorHandler ) )
3870 auto max = std::max_element( front_width_histogram.begin(), front_width_histogram.end(),
3871 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3873 return a.second < b.second;
3876 if( max != front_width_histogram.end() )
3899 auto max = std::max_element( back_width_histogram.begin(), back_width_histogram.end(),
3900 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3902 return a.second < b.second;
3905 if( max != back_width_histogram.end() )
3928 std::map<PCB_LAYER_ID, std::vector<PCB_SHAPE*>> layer_shapes;
3934 if( item->Type() != PCB_SHAPE_T )
3937 for( PCB_LAYER_ID layer : item->GetLayerSet() )
3939 if( !IsCopperLayer( layer ) )
3942 if( board && !board->GetEnabledLayers().Contains( layer ) )
3945 layer_shapes[layer].push_back( static_cast<PCB_SHAPE*>( item ) );
3949 for(
size_t ii = 0; ii < m_pads.size(); ++ii )
3952 bool has_nettie =
false;
3954 auto it = map.find(
pad->GetNumber() );
3956 if( it == map.end() || it->second < 0 )
3959 for(
size_t jj = ii + 1; jj < m_pads.size(); ++jj )
3961 PAD* other = m_pads[ jj ];
3963 auto it2 = map.find( other->
GetNumber() );
3965 if( it2 == map.end() || it2->second < 0 )
3968 if( it2->second == it->second )
3970 m_netTieCache[
pad].insert(
pad->GetNetCode() );
3972 m_netTieCache[other].insert( other->
GetNetCode() );
3973 m_netTieCache[other].insert(
pad->GetNetCode() );
3981 for(
auto& [ layer, shapes ] : layer_shapes )
3983 auto pad_shape =
pad->GetEffectiveShape( layer );
3985 for(
auto other_shape : shapes )
3987 auto shape = other_shape->GetEffectiveShape( layer );
3989 if( pad_shape->Collide( shape.get() ) )
3991 std::set<int>& nettie = m_netTieCache[
pad];
3992 m_netTieCache[other_shape].insert( nettie.begin(), nettie.end() );
4002 std::map<wxString, int> padNumberToGroupIdxMap;
4005 padNumberToGroupIdxMap[
pad->GetNumber() ] = -1;
4008 [&]( wxString aPad,
int aGroup )
4010 aPad.Trim(
true ).Trim(
false );
4012 if( !aPad.IsEmpty() )
4013 padNumberToGroupIdxMap[ aPad ] = aGroup;
4022 for( wxUniCharRef ch :
group )
4031 switch(
static_cast<unsigned char>( ch ) )
4038 processPad(
pad, ii );
4048 processPad(
pad, ii );
4051 return padNumberToGroupIdxMap;
4061 int groupIdx = padToNetTieGroupMap[ aPad->
GetNumber() ];
4062 std::vector<PAD*> otherPads;
4068 if( padToNetTieGroupMap[
pad->GetNumber() ] == groupIdx )
4069 otherPads.push_back(
pad );
4082 if( setAttr && likelyAttr && setAttr != likelyAttr )
4086 switch( likelyAttr )
4089 msg.Printf(
_(
"(expected 'Through hole'; actual '%s')" ),
GetTypeName() );
4092 msg.Printf(
_(
"(expected 'SMD'; actual '%s')" ),
GetTypeName() );
4097 (aErrorHandler)( msg );
4103 const std::function<
void(
const PAD*,
int,
4104 const wxString& )>& aErrorHandler )
4106 if( aErrorHandler ==
nullptr )
4111 pad->CheckPad( aUnitsProvider,
false,
4112 [&](
int errorCode,
const wxString& msg )
4114 aErrorHandler(
pad, errorCode, msg );
4122 const VECTOR2I& )>& aErrorHandler )
4124 std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
4139 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
4142 if( checkedPairs.find( { a, b } ) == checkedPairs.end() )
4144 checkedPairs[ { a, b } ] = 1;
4156 std::shared_ptr<SHAPE_SEGMENT> holeA =
pad->GetEffectiveHoleShape();
4159 if( holeA->Collide( holeB->GetSeg(), 0 ) )
4176 SHAPE* padShape =
pad->GetEffectiveShape( l ).get();
4179 if( padShape->
Collide( otherShape, 0,
nullptr, &pos ) )
4192 const VECTOR2I& )>& aErrorHandler )
4201 std::vector<BOARD_ITEM*> copperItems;
4205 if( item->IsOnCopperLayer() )
4206 copperItems.push_back( item );
4208 item->RunOnChildren(
4212 copperItems.push_back( descendent );
4219 if( !zone->GetIsRuleArea() && zone->IsOnCopperLayer() )
4220 copperItems.push_back( zone );
4225 if( field->IsOnCopperLayer() )
4226 copperItems.push_back( field );
4236 std::map<int, std::vector<const PAD*>> outlineIdxToPadsMap;
4240 if( item->IsOnLayer( layer ) )
4250 for(
int ii = 0; ii < copperOutlines.
OutlineCount(); ++ii )
4252 if(
pad->GetEffectiveShape( layer )->Collide( &copperOutlines.
Outline( ii ), 0 ) )
4253 outlineIdxToPadsMap[ ii ].emplace_back(
pad );
4260 for(
const auto& [ outlineIdx, pads ] : outlineIdxToPadsMap )
4262 if( pads.size() > 1 )
4264 const PAD* firstPad = pads[0];
4265 int firstGroupIdx = padNumberToGroupIdxMap[ firstPad->
GetNumber() ];
4267 for(
size_t ii = 1; ii < pads.size(); ++ii )
4269 const PAD* thisPad = pads[ii];
4270 int thisGroupIdx = padNumberToGroupIdxMap[ thisPad->
GetNumber() ];
4272 if( thisGroupIdx < 0 || thisGroupIdx != firstGroupIdx )
4281 if( item->HitTest( pos, 1 ) )
4283 shortingItem = item;
4289 aErrorHandler( shortingItem, firstPad, thisPad, pos );
4291 aErrorHandler( firstPad, thisPad,
nullptr, pos );
4302 std::set<wxString> padNumbers;
4311 msg.Printf(
_(
"(net-tie pad group contains unknown pad number %s)" ), padNumber );
4312 aErrorHandler( msg );
4314 else if( !padNumbers.insert(
pad->GetNumber() ).second )
4316 msg.Printf(
_(
"(pad %s appears in more than one net-tie pad group)" ), padNumber );
4317 aErrorHandler( msg );
4325 const VECTOR2I& aPt )>& aErrorHandler )
4327 auto checkColliding =
4342 if( itemShape->Collide( otherShape.get(), 0, &
actual, &pos ) )
4343 aErrorHandler( item, other, pos );
4352 checkColliding( item, other );
4356 checkColliding( item,
pad );
4367 std::swap( *
this, *
image );
4376 image->RunOnChildren(
4404 return *
this == other;
4413 for(
size_t ii = 0; ii <
m_pads.size(); ++ii )
4422 for(
size_t ii = 0; ii <
m_drawings.size(); ++ii )
4431 for(
size_t ii = 0; ii <
m_zones.size(); ++ii )
4441 std::vector<PCB_FIELD*> fields, otherFields;
4446 if( fields.size() != otherFields.size() )
4449 for(
size_t ii = 0; ii < fields.size(); ++ii )
4453 if( !( *fields[ii] == *otherFields[ii] ) )
4469 double similarity = 1.0;
4478 similarity *=
pad->Similarity( *otherPad );
4490 if( aPtA.
x != aPtB.
x )
4491 return aPtA.
x < aPtB.
x;
4493 if( aPtA.
y != aPtB.
y )
4494 return aPtA.
y < aPtB.
y;
4496 return std::nullopt;
4502 if( itemA->
Type() != itemB->
Type() )
4503 return itemA->
Type() < itemB->
Type();
4508 switch( itemA->
Type() )
4630 return itemA < itemB;
4642 std::optional<bool> padCopperMatches;
4645 const PAD* checkPad = aFirst;
4658 padCopperMatches = aFirst->
GetSize( aLayer ).
x < aSecond->
GetSize( aLayer ).
x;
4660 padCopperMatches = aFirst->
GetSize( aLayer ).
y < aSecond->
GetSize( aLayer ).
y;
4662 padCopperMatches = aFirst->
GetShape( aLayer ) < aSecond->
GetShape( aLayer );
4665 if( padCopperMatches.has_value() )
4666 return *padCopperMatches;
4674 return aFirst < aSecond;
4679bool FOOTPRINT::cmp_padstack::operator()(
const PAD* aFirst,
const PAD* aSecond )
const
4719 if( firstShape->VertexCount() != secondShape->VertexCount() )
4720 return firstShape->VertexCount() < secondShape->VertexCount();
4722 for(
int ii = 0; ii < firstShape->VertexCount(); ++ii )
4724 if( std::optional<bool> cmp =
cmp_points_opt( firstShape->CVertex( ii ), secondShape->CVertex( ii ) ) )
4758 return aFirst < aSecond;
4763 int aMaxError,
ERROR_LOC aErrorLoc )
const
4774 clearance.x +=
pad->GetSolderMaskExpansion( padLayer );
4775 clearance.y +=
pad->GetSolderMaskExpansion( padLayer );
4798 if( dummySize.
x <= 0 || dummySize.
y <= 0 )
4802 dummy.SetSize( padLayer, dummySize );
4803 dummy.TransformShapeToPolygon( aBuffer, padLayer, 0, aMaxError, aErrorLoc );
4807 pad->TransformShapeToPolygon( aBuffer, padLayer,
clearance.x, aMaxError, aErrorLoc );
4813 if( !
pad->FlashLayer( aLayer ) )
4818 pad->Padstack().ForEachUniqueLayer(
4821 processPad(
pad, l );
4826 processPad(
pad, aLayer );
4833 int aError,
ERROR_LOC aErrorLoc,
bool aIncludeText,
4834 bool aIncludeShapes,
bool aIncludePrivateItems )
const
4841 if( item->Type() ==
PCB_TEXT_T && aIncludeText )
4846 text->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4857 textbox->PCB_SHAPE::TransformShapeToPolygon( aBuffer, aLayer, 0, aError, aErrorLoc );
4864 if( item->Type() ==
PCB_SHAPE_T && aIncludeShapes )
4885 if( ( aLayer ==
UNDEFINED_LAYER || field->GetLayer() == aLayer ) && field->IsVisible() )
4886 field->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4896 std::set<KIFONT::OUTLINE_FONT*>
fonts;
4910 if( permission == PERMISSION::EDITABLE || permission == PERMISSION::INSTALLABLE )
4911 fonts.insert( outlineFont );
4917 processItem( item );
4920 processItem( field );
4965 return wxEmptyString;
4970 const std::unordered_set<wxString>& aComponentClassNames )
5019 LSET padLayers =
pad->GetLayerSet();
5020 padLayers |= boardCopper;
5021 pad->SetLayerSet( padLayers );
5033 if( zcMap.
Choices().GetCount() == 0 )
5045 if( layerEnum.
Choices().GetCount() == 0 )
5053 wxPGChoices fpLayers;
5064 auto isNotFootprintHolder =
5070 return !
board->IsFootprintHolder();
5077 layer->SetChoices( fpLayers );
5078 layer->SetAvailableFunc( isNotFootprintHolder );
5094 const wxString groupFields =
_HKI(
"Fields" );
5100 const wxString propertyFields =
_HKI(
"Footprint Properties" );
5118 const wxString groupAttributes =
_HKI(
"Attributes" );
5132 const wxString groupOverrides =
_HKI(
"Overrides" );
types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
std::unique_ptr< EDA_ITEM > CreateItemForType(KICAD_T aType, EDA_ITEM *aContainer)
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
constexpr EDA_IU_SCALE pcbIUScale
constexpr int ARC_LOW_DEF
BITMAPS
A list of all bitmap identifiers.
#define DEFAULT_COURTYARD_WIDTH
BASE_SET & set(size_t pos)
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
Abstract interface for BOARD_ITEMs capable of storing other items inside.
BOARD_ITEM_CONTAINER(BOARD_ITEM *aParent, KICAD_T aType)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
BOARD_ITEM(BOARD_ITEM *aParent, KICAD_T idtype, PCB_LAYER_ID aLayer=F_Cu)
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
void SetUuidDirect(const KIID &aUuid)
Raw UUID assignment.
virtual BOARD_ITEM * Duplicate(bool addToParentGroup, BOARD_COMMIT *aCommit=nullptr) const
Create a copy of this BOARD_ITEM.
virtual void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const
Convert the item shape to a closed polygon.
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
VECTOR2I GetFPRelativePosition() const
virtual void TransformShapeToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, KIGFX::RENDER_SETTINGS *aRenderSettings=nullptr) const
Convert the item shape to a polyset.
BOARD_ITEM & operator=(const BOARD_ITEM &aOther)
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.
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayer) const
int GetCopperLayerCount() const
COMPONENT_CLASS_MANAGER & GetComponentClassManager()
Gets the component class manager.
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
constexpr size_type GetWidth() const
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr const Vec GetCenter() const
constexpr size_type GetHeight() const
constexpr bool Contains(const Vec &aPoint) const
constexpr coord_type GetTop() const
constexpr bool Intersects(const BOX2< Vec > &aRect) const
constexpr coord_type GetBottom() const
virtual int Accuracy() const =0
int GetCount() const
Return the number of objects in the list.
const COMPONENT_CLASS * GetStaticComponentClass() const
Gets the static component class.
COMPONENT_CLASS * GetEffectiveStaticComponentClass(const std::unordered_set< wxString > &classNames)
Gets an effective component class for the given constituent class names.
A lightweight representation of a component class.
int AsTenthsOfADegree() const
bool IsType(FRAME_T aType) const
The base class for create windows for drawing purpose.
std::unordered_set< EDA_ITEM * > & GetItems()
void AddItem(EDA_ITEM *aItem)
Add item to group.
virtual void ClearEditFlags()
void SetFlags(EDA_ITEM_FLAGS aMask)
KICAD_T Type() const
Returns the type of object.
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
static INSPECT_RESULT IterateForward(std::deque< T > &aList, INSPECTOR inspector, void *testData, const std::vector< KICAD_T > &scanTypes)
This changes first parameter to avoid the DList and use the main queue instead.
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
virtual void SetParent(EDA_ITEM *aParent)
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
int GetEllipseMinorRadius() const
const VECTOR2I & GetEllipseCenter() const
EDA_ANGLE GetEllipseEndAngle() const
int GetEllipseMajorRadius() const
EDA_ANGLE GetEllipseRotation() const
EDA_ANGLE GetEllipseStartAngle() const
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual const wxString & GetText() const
Return the string associated with the text object.
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
double GetLineSpacing() const
virtual void SetText(const wxString &aText)
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.
bool m_embedFonts
If set, fonts will be embedded in the element on save.
ENUM_MAP & Map(T aValue, const wxString &aName)
static ENUM_MAP< T > & Instance()
ENUM_MAP & Undefined(T aValue)
wxString m_Filename
The 3D shape filename in 3D library.
Used when the right click button is pressed, or when the select tool is in effect.
const COLLECTORS_GUIDE * GetGuide() const
Class that other classes need to inherit from, in order to be inspectable.
FONT is an abstract base class for both outline and stroke fonts.
virtual bool IsOutline() const
Class OUTLINE_FONT implements outline font drawing.
EMBEDDING_PERMISSION GetEmbeddingPermission() const
virtual wxString GetClass() const =0
Return the class name.
static constexpr double LOD_HIDE
Return this constant from ViewGetLOD() to hide the item unconditionally.
static constexpr double LOD_SHOW
Return this constant from ViewGetLOD() to show the item unconditionally.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
LSET is a set of PCB_LAYER_IDs.
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
static const LSET & SideSpecificMask()
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
static const LSET & AllLayersMask()
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
void ShapeToPolygon(SHAPE_LINE_CHAIN &aPolygon, int aScale=-1) const
Return the shape polygon in internal units in a SHAPE_LINE_CHAIN the coordinates are relatives to the...
static const int ORPHANED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
void ForEachUniqueLayer(const std::function< void(PCB_LAYER_ID)> &aMethod) const
Runs the given callable for each active unique copper layer in this padstack, meaning F_Cu for MODE::...
@ NORMAL
Shape is the same on all layers.
@ CUSTOM
Shapes can be defined on arbitrary layers.
@ FRONT_INNER_BACK
Up to three shapes can be defined (F_Cu, inner copper layers, B_Cu)
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer, FLASHING flashPTHPads=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
const BOX2I GetBoundingBox() const override
The bounding box is cached, so this will be efficient most of the time.
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
int GetDrillSizeY() const
PAD_ATTRIB GetAttribute() const
const wxString & GetNumber() const
VECTOR2I GetPosition() const override
int GetDrillSizeX() const
PAD_SHAPE GetShape(PCB_LAYER_ID aLayer) const
int GetSolderMaskExpansion(PCB_LAYER_ID aLayer) const
VECTOR2I GetSize(PCB_LAYER_ID aLayer) const
const PADSTACK & Padstack() const
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
PAD_DRILL_SHAPE GetDrillShape() const
const std::shared_ptr< SHAPE_POLY_SET > & GetEffectivePolygon(PCB_LAYER_ID aLayer, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
std::optional< int > GetLocalSolderMaskMargin() const
VECTOR2I GetSolderPasteMargin(PCB_LAYER_ID aLayer) const
Usually < 0 (mask shape smaller than pad)because the margin can be dependent on the pad size,...
bool HasDrilledHole() const override
std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const override
Return a SHAPE_SEGMENT object representing the pad's hole.
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
A set of BOARD_ITEMs (i.e., without duplicates).
A PCB_POINT is a 0-dimensional point that is used to mark a position on a PCB, or more usually a foot...
Object to handle a bitmap image that can be inserted in a PCB.
VECTOR2I GetLibraryBezierC1() const
int GetWidth() const override
void TransformShapeToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, KIGFX::RENDER_SETTINGS *aRenderSettings=nullptr) const override
Convert the item shape to a polyset.
VECTOR2I GetLibraryEnd() const
VECTOR2I GetLibraryStart() const
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
SHAPE_POLY_SET GetLibraryPolyShape() const
VECTOR2I GetLibraryBezierC2() const
VECTOR2I GetLibraryArcMid() const
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...
EDA_ANGLE GetTextAngle() const override
int GetTextThickness() const override
void SetTextAngle(const EDA_ANGLE &aAngle) override
VECTOR2I GetTextSize() const override
PROPERTY_BASE & SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Set a callback function to determine whether an object provides this property.
PROPERTY_BASE & SetIsHiddenFromLibraryEditors(bool aIsHidden=true)
Provide class metadata.Helper macro to map type hashes to names.
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
PROPERTY_BASE & ReplaceProperty(size_t aBase, const wxString &aName, PROPERTY_BASE *aNew, const wxString &aGroup=wxEmptyString)
Replace an existing property for a specific type.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
double Area(bool aAbsolute=true) const
Return the area of this chain.
const VECTOR2I NearestPoint(const VECTOR2I &aP, bool aAllowInternalShapePoints=true) const
Find a point on the line chain that is closest to point aP.
Represent a set of closed polygons.
void BooleanAdd(const SHAPE_POLY_SET &b)
Perform boolean polyset union.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
double Area()
Return the area of this poly set.
bool Collide(const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the shape aShape than aClearance,...
int TotalVertices() const
Return total number of vertices stored in the set.
int FullPointCount() const
Return the number of points in the shape poly set.
int HoleCount(int aOutline) const
Returns the number of holes in a given outline.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
void Simplify()
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the reference to aHole-th hole in the aIndex-th outline.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
void BooleanIntersection(const SHAPE_POLY_SET &b)
Perform boolean polyset intersection.
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the index-th vertex in a given hole outline within a given outline.
int OutlineCount() const
Return the number of outlines in the set.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
Represent a simple polygon consisting of a zero-thickness closed chain of connected line segments.
An abstract shape on 2D plane.
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
Handle a list of polygons defining a copper zone.
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
SHAPE_POLY_SET * Outline()
bool SetNetCode(int aNetCode, bool aNoAssert) override
Override that clamps the netcode to 0 when this zone is in copper-thieving fill mode.
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
SHAPE_POLY_SET GetLibraryOutline() const
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the zone shape to a closed polygon Used in filling zones calculations Circles and arcs are ap...
unsigned GetAssignedPriority() const
This file is part of the common library.
bool ConvertOutlineToPolygon(std::vector< PCB_SHAPE * > &aShapeList, SHAPE_POLY_SET &aPolygons, int aErrorMax, int aChainingEpsilon, bool aAllowDisjoint, OUTLINE_ERROR_HANDLER *aErrorHandler, bool aAllowUseArcsInPolygons)
Build a polygon set with holes from a PCB_SHAPE list.
const std::function< void(const wxString &msg, BOARD_ITEM *itemA, BOARD_ITEM *itemB, const VECTOR2I &pt)> OUTLINE_ERROR_HANDLER
void BuildConvexHull(std::vector< VECTOR2I > &aResult, const std::vector< VECTOR2I > &aPoly)
Calculate the convex hull of a list of points in counter-clockwise order.
@ CHAMFER_ACUTE_CORNERS
Acute angles are chamfered.
@ DRCE_DRILLED_HOLES_TOO_CLOSE
@ DRCE_DRILLED_HOLES_COLOCATED
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_180
const INSPECTOR_FUNC & INSPECTOR
std::function passed to nested users by ref, avoids copying std::function.
#define COURTYARD_CONFLICT
temporary set when moving footprints having courtyard overlapping
#define MALFORMED_F_COURTYARD
#define MALFORMED_B_COURTYARD
#define STRUCT_DELETED
flag indication structures to be erased
#define MALFORMED_COURTYARDS
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
@ FRAME_FOOTPRINT_CHOOSER
a few functions useful in geometry calculations.
const wxChar *const traceApi
Flag to enable debug output related to the IPC API and its plugin system.
Some functions to handle hotkeys in KiCad.
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
@ LAYER_CONFLICTS_SHADOW
Shadow layer for items flagged conflicting.
@ LAYER_FOOTPRINTS_FR
Show footprints on front.
@ LAYER_FP_REFERENCES
Show footprints references (when texts are visible).
@ LAYER_FOOTPRINTS_BK
Show footprints on back.
@ LAYER_ANCHOR
Anchor of items having an anchor point (texts, footprints).
@ LAYER_FP_VALUES
Show footprints values (when texts are visible).
PCB_LAYER_ID
A quick note on layer IDs:
bool IsValidLayer(int aLayerId)
Test whether a given integer is a valid layer index, i.e.
const wxString & GetLibFilenameForbiddenChars()
Characters illegal in a footprint library filename.
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
constexpr void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
@ LEFT_RIGHT
Flip left to right (around the Y axis)
@ TOP_BOTTOM
Flip top to bottom (around the X axis)
bool BoxHitTest(const VECTOR2I &aHitPoint, const BOX2I &aHittee, int aAccuracy)
Perform a point-to-box hit test.
wxString GetRefDesPrefix(const wxString &aRefDes)
Get the (non-numeric) prefix from a refdes - e.g.
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
KICOMMON_API KIID_PATH UnpackSheetPath(const types::SheetPath &aInput)
KICOMMON_API std::optional< KICAD_T > TypeNameFromAny(const google::protobuf::Any &aMessage)
KICOMMON_API VECTOR3D UnpackVector3D(const types::Vector3D &aInput)
KICOMMON_API void PackSheetPath(types::SheetPath &aOutput, const KIID_PATH &aInput)
KICOMMON_API void PackLibId(types::LibraryIdentifier *aOutput, const LIB_ID &aId)
KICOMMON_API LIB_ID UnpackLibId(const types::LibraryIdentifier &aId)
KICOMMON_API void PackVector3D(types::Vector3D &aOutput, const VECTOR3D &aInput)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
@ SMD
Smd pad, appears on the solder paste layer (default)
@ PTH
Plated through hole pad.
@ FIDUCIAL_LOCAL
a fiducial (usually a smd) local to the parent footprint
@ FIDUCIAL_GLBL
a fiducial (usually a smd) for the full board
@ MECHANICAL
a pad used for mechanical support
@ PRESSFIT
a PTH with a hole diameter with tight tolerances for press fit pin
@ HEATSINK
a pad used as heat sink, usually in SMD footprints
@ NONE
no special fabrication property
@ TESTPOINT
a test point pad
@ CASTELLATED
a pad with a castellated through hole
@ BGA
Smd pad, used in BGA footprints.
BARCODE class definition.
Class to handle a set of BOARD_ITEMs.
#define NO_SETTER(owner, type)
@ PT_DEGREE
Angle expressed in degrees.
@ PT_SIZE
Size expressed in distance units (mm/inch)
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Collection of utility functions for component reference designators (refdes)
std::vector< FAB_LAYER_COLOR > dummy
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
wxString GetDefaultVariantName()
int GetTrailingInt(const wxString &aStr)
Gets the trailing int, if any, from a string.
wxString UnescapeString(const wxString &aSource)
A structure for storing weighted search terms.
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ DESCRIPTION
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
@ DATASHEET
name of datasheet
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
wxString GetCanonicalFieldName(FIELD_T aFieldType)
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
@ PCB_ZONE_T
class ZONE, a copper pour area
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
@ PCB_MARKER_T
class PCB_MARKER, a marker used to show something
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
@ PCB_POINT_T
class PCB_POINT, a 0-dimensional point
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
VECTOR2< int32_t > VECTOR2I
ZONE_CONNECTION
How pads are covered by copper in zone.
@ THERMAL
Use thermal relief for pads.
@ THT_THERMAL
Thermal relief only for THT pads.
@ NONE
Pads are not covered.
@ FULL
pads are covered by copper