29#include <magic_enum.hpp>
32#include <unordered_set>
36#include <wx/tokenzr.h>
75#include <google/protobuf/any.pb.h>
76#include <api/board/board_types.pb.h>
177 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
182 if( field->IsMandatory() )
184 PCB_FIELD* existingField = GetField( field->GetId() );
185 ptrMap[field] = existingField;
186 *existingField = *field;
187 existingField->SetParent( this );
191 PCB_FIELD* newField = static_cast<PCB_FIELD*>( field->Clone() );
192 ptrMap[field] = newField;
198 for(
PAD*
pad : aFootprint.Pads() )
200 PAD* newPad = static_cast<PAD*>( pad->Clone() );
201 ptrMap[ pad ] = newPad;
202 Add( newPad, ADD_MODE::APPEND );
206 for(
ZONE* zone : aFootprint.Zones() )
208 ZONE* newZone = static_cast<ZONE*>( zone->Clone() );
209 ptrMap[ zone ] = newZone;
210 Add( newZone, ADD_MODE::APPEND );
216 newZone->SetNetCode( -1 );
220 for(
BOARD_ITEM* item : aFootprint.GraphicalItems() )
222 BOARD_ITEM* newItem = static_cast<BOARD_ITEM*>( item->Clone() );
223 ptrMap[ item ] = newItem;
224 Add( newItem, ADD_MODE::APPEND );
230 PCB_GROUP* newGroup = static_cast<PCB_GROUP*>( group->Clone() );
231 ptrMap[ group ] = newGroup;
232 Add( newGroup, ADD_MODE::APPEND );
235 for(
PCB_POINT* point : aFootprint.Points() )
237 PCB_POINT* newPoint = static_cast<PCB_POINT*>( point->Clone() );
238 ptrMap[ point ] = newPoint;
239 Add( newPoint, ADD_MODE::APPEND );
245 PCB_GROUP* newGroup = static_cast<PCB_GROUP*>( ptrMap[ group ] );
247 newGroup->GetItems().clear();
249 for( EDA_ITEM* member : group->GetItems() )
251 if( ptrMap.count( member ) )
252 newGroup->AddItem( ptrMap[ member ] );
256 for(
auto& [
name, file ] : aFootprint.EmbeddedFileMap() )
265 *
this = std::move( aFootprint );
305 board->IncrementTimeStamp();
312 types::FootprintInstance footprint;
314 footprint.mutable_id()->set_value(
m_Uuid.AsStdString() );
315 footprint.mutable_position()->set_x_nm(
GetPosition().x );
316 footprint.mutable_position()->set_y_nm(
GetPosition().y );
319 footprint.set_locked(
IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
320 : kiapi::common::types::LockedState::LS_UNLOCKED );
322 google::protobuf::Any buf;
324 buf.UnpackTo( footprint.mutable_reference_field() );
326 buf.UnpackTo( footprint.mutable_value_field() );
328 buf.UnpackTo( footprint.mutable_datasheet_field() );
330 buf.UnpackTo( footprint.mutable_description_field() );
332 types::FootprintAttributes* attrs = footprint.mutable_attributes();
338 attrs->set_do_not_populate(
IsDNP() );
342 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_THROUGH_HOLE );
344 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_SMD );
346 attrs->set_mounting_style( types::FootprintMountingStyle::FMS_UNSPECIFIED );
348 types::Footprint* def = footprint.mutable_definition();
353 def->mutable_attributes()->set_keywords(
GetKeywords().ToUTF8() );
357 types::FootprintDesignRuleOverrides* overrides = footprint.mutable_overrides();
371 overrides->set_zone_connection(
376 types::NetTieDefinition* netTie = def->add_net_ties();
377 wxStringTokenizer tokenizer(
group,
", \t\r\n", wxTOKEN_STRTOK );
379 while( tokenizer.HasMoreTokens() )
380 netTie->add_pad_number( tokenizer.GetNextToken().ToUTF8() );
386 types::JumperSettings* jumpers = def->mutable_jumpers();
391 types::JumperGroup* jumperGroup = jumpers->add_groups();
393 for(
const wxString& padName :
group )
394 jumperGroup->add_pad_names( padName.ToUTF8() );
399 if( item->IsMandatory() )
402 google::protobuf::Any* itemMsg = def->add_items();
403 item->Serialize( *itemMsg );
406 for(
const PAD* item :
Pads() )
408 google::protobuf::Any* itemMsg = def->add_items();
409 item->Serialize( *itemMsg );
414 google::protobuf::Any* itemMsg = def->add_items();
415 item->Serialize( *itemMsg );
420 google::protobuf::Any* itemMsg = def->add_items();
421 item->Serialize( *itemMsg );
426 google::protobuf::Any* itemMsg = def->add_items();
427 types::Footprint3DModel modelMsg;
428 modelMsg.set_filename(
model.m_Filename.ToUTF8() );
432 modelMsg.set_visible(
model.m_Show );
433 modelMsg.set_opacity(
model.m_Opacity );
434 itemMsg->PackFrom( modelMsg );
439 footprint.set_symbol_sheet_name(
m_sheetname.ToUTF8() );
440 footprint.set_symbol_sheet_filename(
m_sheetfile.ToUTF8() );
441 footprint.set_symbol_footprint_filters(
m_filters.ToUTF8() );
443 aContainer.PackFrom( footprint );
450 types::FootprintInstance footprint;
452 if( !aContainer.UnpackTo( &footprint ) )
459 SetLocked( footprint.locked() == kiapi::common::types::LockedState::LS_LOCKED );
461 google::protobuf::Any buf;
462 types::Field mandatoryField;
464 if( footprint.has_reference_field() )
466 mandatoryField = footprint.reference_field();
468 buf.PackFrom( mandatoryField );
472 if( footprint.has_value_field() )
474 mandatoryField = footprint.value_field();
476 buf.PackFrom( mandatoryField );
480 if( footprint.has_datasheet_field() )
482 mandatoryField = footprint.datasheet_field();
484 buf.PackFrom( mandatoryField );
488 if( footprint.has_description_field() )
490 mandatoryField = footprint.description_field();
492 buf.PackFrom( mandatoryField );
498 switch( footprint.attributes().mounting_style() )
500 case types::FootprintMountingStyle::FMS_THROUGH_HOLE:
504 case types::FootprintMountingStyle::FMS_SMD:
512 SetBoardOnly( footprint.attributes().not_in_schematic() );
516 SetDNP( footprint.attributes().do_not_populate() );
523 SetKeywords( footprint.definition().attributes().keywords() );
525 const types::FootprintDesignRuleOverrides& overrides = footprint.overrides();
527 if( overrides.has_copper_clearance() )
532 if( overrides.has_solder_mask() && overrides.solder_mask().has_solder_mask_margin() )
537 if( overrides.has_solder_paste() )
539 const types::SolderPasteOverrides& pasteSettings = overrides.solder_paste();
541 if( pasteSettings.has_solder_paste_margin() )
546 if( pasteSettings.has_solder_paste_margin_ratio() )
556 for(
const types::NetTieDefinition& netTieMsg : footprint.definition().net_ties() )
560 for(
const std::string&
pad : netTieMsg.pad_number() )
561 group.Append( wxString::Format( wxT(
"%s, " ),
pad ) );
570 for(
const types::JumperGroup& groupMsg : footprint.definition().jumpers().groups() )
572 std::set<wxString>
group;
574 for(
const std::string& padName : groupMsg.pad_names() )
575 group.insert( wxString::FromUTF8( padName ) );
583 for(
int layerMsg : footprint.definition().private_layers() )
588 privateLayers.
set( layer );
594 m_sheetname = wxString::FromUTF8( footprint.symbol_sheet_name() );
595 m_sheetfile = wxString::FromUTF8( footprint.symbol_sheet_filename() );
596 m_filters = wxString::FromUTF8( footprint.symbol_footprint_filters() );
601 if( !field->IsMandatory() )
607 board->UncacheChildrenById(
this );
616 for(
const google::protobuf::Any& itemMsg : footprint.definition().items() )
624 if( itemMsg.type_url() ==
"type.googleapis.com/kiapi.board.types.Footprint3DModel" )
626 types::Footprint3DModel modelMsg;
628 if( !itemMsg.UnpackTo( &modelMsg ) )
633 model.m_Filename = wxString::FromUTF8( modelMsg.filename() );
634 model.m_Show = modelMsg.visible();
635 model.m_Opacity = modelMsg.opacity();
644 wxLogTrace(
traceApi, wxString::Format( wxS(
"Attempting to unpack unknown type %s "
645 "from footprint message, skipping" ),
646 itemMsg.type_url() ) );
654 if( item && item->Deserialize( itemMsg ) )
666 if( field->GetId() == aFieldType )
681 if( field->GetId() == aFieldType )
691 return GetField( aFieldName ) !=
nullptr;
699 if( field->GetName() == aFieldName )
715 if( !field->IsVisible() || field->GetText().IsEmpty() )
719 aVector.push_back( field );
722 std::sort( aVector.begin(), aVector.end(),
725 return lhs->GetOrdinal() < rhs->GetOrdinal();
735 ordinal = std::max( ordinal, field->GetOrdinal() + 1 );
742 bool aStyleShapes,
bool aStyleDimensions,
bool aStyleBarcodes )
747 field->StyleFromSettings(
board.GetDesignSettings(),
true );
752 switch( item->Type() )
757 item->StyleFromSettings(
board.GetDesignSettings(),
true );
762 if( aStyleShapes && !item->IsOnCopperLayer() )
763 item->StyleFromSettings(
board.GetDesignSettings(),
true );
772 if( aStyleDimensions )
773 item->StyleFromSettings(
board.GetDesignSettings(),
true );
779 item->StyleFromSettings(
board.GetDesignSettings(),
true );
792 std::vector< BOARD_ITEM* > item_list;
795 item_list.push_back( field );
798 item_list.push_back(
pad );
801 item_list.push_back( gr_item );
806 item_list.push_back(
group );
810 item_list.push_back( zone );
814 item_list.push_back( point );
816 bool changed =
false;
822 item->ResetUuidDirect();
838 m_pos = aOther.m_pos;
859 board->UncacheChildrenById(
this );
867 for(
PCB_FIELD* field : aOther.m_fields )
870 aOther.m_fields.clear();
878 for(
PAD*
pad : aOther.Pads() )
881 aOther.Pads().clear();
889 for(
ZONE* item : aOther.Zones() )
897 item->SetNetCode( -1 );
900 aOther.Zones().clear();
908 for(
BOARD_ITEM* item : aOther.GraphicalItems() )
911 aOther.GraphicalItems().clear();
922 aOther.Groups().clear();
930 for(
PCB_POINT* point : aOther.Points() )
933 aOther.Points().clear();
947 aOther.m_componentClassCacheProxy->GetStaticComponentClass() );
950 aOther.m_fields.clear();
951 aOther.Pads().clear();
952 aOther.Zones().clear();
953 aOther.GraphicalItems().clear();
954 aOther.m_initial_comments =
nullptr;
988 board->UncacheChildrenById(
this );
990 std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
1001 ptrMap[field] = newField;
1014 ptrMap[
pad ] = newPad;
1026 ZONE* newZone =
static_cast<ZONE*
>( zone->Clone() );
1027 ptrMap[ zone ] = newZone;
1046 ptrMap[ item ] = newItem;
1062 newGroup->
AddItem( ptrMap[ member ] );
1076 ptrMap[ point ] = newItem;
1107 *
this = *
static_cast<const FOOTPRINT*
>( aOther );
1134 aVars->push_back( wxT(
"REFERENCE" ) );
1135 aVars->push_back( wxT(
"VALUE" ) );
1136 aVars->push_back( wxT(
"LAYER" ) );
1137 aVars->push_back( wxT(
"FOOTPRINT_LIBRARY" ) );
1138 aVars->push_back( wxT(
"FOOTPRINT_NAME" ) );
1139 aVars->push_back( wxT(
"SHORT_NET_NAME(<pad_number>)" ) );
1140 aVars->push_back( wxT(
"NET_NAME(<pad_number>)" ) );
1141 aVars->push_back( wxT(
"NET_CLASS(<pad_number>)" ) );
1142 aVars->push_back( wxT(
"PIN_NAME(<pad_number>)" ) );
1151 if( token->IsSameAs( wxT(
"REFERENCE" ) ) )
1156 else if( token->IsSameAs( wxT(
"VALUE" ) ) )
1161 else if( token->IsSameAs( wxT(
"LAYER" ) ) )
1166 else if( token->IsSameAs( wxT(
"FOOTPRINT_LIBRARY" ) ) )
1168 *token =
m_fpid.GetUniStringLibNickname();
1171 else if( token->IsSameAs( wxT(
"FOOTPRINT_NAME" ) ) )
1173 *token =
m_fpid.GetUniStringLibItemName();
1176 else if( token->StartsWith( wxT(
"SHORT_NET_NAME(" ) )
1177 || token->StartsWith( wxT(
"NET_NAME(" ) )
1178 || token->StartsWith( wxT(
"NET_CLASS(" ) )
1179 || token->StartsWith( wxT(
"PIN_NAME(" ) ) )
1181 wxString padNumber = token->AfterFirst(
'(' );
1182 padNumber = padNumber.BeforeLast(
')' );
1186 if(
pad->GetNumber() == padNumber )
1188 if( token->StartsWith( wxT(
"SHORT_NET_NAME" ) ) )
1189 *token =
pad->GetShortNetname();
1190 else if( token->StartsWith( wxT(
"NET_NAME" ) ) )
1191 *token =
pad->GetNetname();
1192 else if( token->StartsWith( wxT(
"NET_CLASS" ) ) )
1193 *token =
pad->GetNetClassName();
1195 *token =
pad->GetPinFunction();
1203 *token = field->GetShownText(
false, aDepth + 1 );
1222 return it !=
m_variants.end() ? &it->second :
nullptr;
1230 return it !=
m_variants.end() ? &it->second :
nullptr;
1236 if( aVariant.
GetName().IsEmpty()
1248 it->second = std::move( updated );
1258 if( aVariantName.IsEmpty()
1261 wxASSERT_MSG(
false, wxT(
"Variant name cannot be empty or default." ) );
1275 auto inserted =
m_variants.emplace( aVariantName, std::move( variant ) );
1276 return &inserted.first->second;
1288 if( aNewName.IsEmpty()
1299 auto existingIt =
m_variants.find( aNewName );
1301 if( existingIt !=
m_variants.end() && existingIt != it )
1304 if( it->first == aNewName )
1310 m_variants.emplace( aNewName, std::move( variant ) );
1329 return variant->
GetDNP();
1381 return field->GetText();
1405 switch( aBoardItem->
Type() )
1431 m_pads.push_back(
static_cast<PAD*
>( aBoardItem ) );
1433 m_pads.push_front(
static_cast<PAD*
>( aBoardItem ) );
1439 m_zones.push_back(
static_cast<ZONE*
>( aBoardItem ) );
1454 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Markers go at the board level, even in the footprint editor" ) );
1458 wxFAIL_MSG( wxT(
"FOOTPRINT::Add(): Nested footprints not supported" ) );
1470 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Add(): BOARD_ITEM type (%d) not handled" ),
1471 aBoardItem->
Type() ) );
1482 board->CacheItemSubtreeById( aBoardItem );
1490 switch( aBoardItem->
Type() )
1495 if( *it == aBoardItem )
1517 if( *it == aBoardItem )
1527 for(
auto it =
m_pads.begin(); it !=
m_pads.end(); ++it )
1529 if( *it ==
static_cast<PAD*
>( aBoardItem ) )
1541 if( *it ==
static_cast<ZONE*
>( aBoardItem ) )
1553 if( *it ==
static_cast<PCB_GROUP*
>( aBoardItem ) )
1563 wxFAIL_MSG( wxT(
"FOOTPRINT::Remove(): Markers go at the board level, even in the footprint editor" ) );
1567 wxFAIL_MSG( wxT(
"FOOTPRINT::Remove(): Nested footprints not supported" ) );
1573 if( *it ==
static_cast<PCB_POINT*
>( aBoardItem ) )
1583 wxFAIL_MSG( wxString::Format( wxT(
"FOOTPRINT::Remove() needs work: BOARD_ITEM type (%d) not handled" ),
1584 aBoardItem->
Type() ) );
1589 board->UncacheItemSubtreeById( aBoardItem );
1614 switch(
pad->GetProperty() )
1632 switch(
pad->GetAttribute() )
1639 if(
pad->IsOnCopperLayer() )
1667 return _(
"Through hole" );
1669 return _(
"Other" );
1682 wxStringTokenizer keywordTokenizer(
GetKeywords(), wxS(
" \t\r\n" ), wxTOKEN_STRTOK );
1684 while( keywordTokenizer.HasMoreTokens() )
1705 if(
dummy.IsFlipped() )
1709 bbox.
Merge(
pad->GetBoundingBox() );
1761 std::vector<PCB_TEXT*> texts;
1762 bool isFPEdit =
board &&
board->IsFootprintHolder();
1783 texts.push_back(
static_cast<PCB_TEXT*
>( item ) );
1801 bbox.
Merge( item->GetBoundingBox() );
1807 if( field->IsReference() || field->IsValue() )
1810 texts.push_back( field );
1814 bbox.
Merge(
pad->GetBoundingBox() );
1817 bbox.
Merge( zone->GetBoundingBox() );
1820 bbox.
Merge( point->GetBoundingBox() );
1825 if( aIncludeText || noDrawItems )
1842 bool valueLayerIsVisible =
true;
1843 bool refLayerIsVisible =
true;
1861 if( (
Value().IsVisible() && valueLayerIsVisible ) || noDrawItems )
1866 if( (
Reference().IsVisible() && refLayerIsVisible ) || noDrawItems )
1879 if( aIncludeText || noDrawItems )
1897 std::vector<PCB_TEXT*> texts;
1899 bool isFPEdit =
board &&
board->IsFootprintHolder();
1909 if( ( aLayers & item->GetLayerSet() ).none() )
1917 bbox.
Merge( item->GetBoundingBox() );
1922 if( ( aLayers &
pad->GetLayerSet() ).none() )
1925 bbox.
Merge(
pad->GetBoundingBox() );
1930 if( ( aLayers & zone->GetLayerSet() ).none() )
1933 bbox.
Merge( zone->GetBoundingBox() );
1941 if( ( aLayers & point->GetLayerSet() ).none() )
1944 bbox.
Merge( point->GetBoundingBox() );
1954 bool isFPEdit =
board &&
board->IsFootprintHolder();
1980 pad->Padstack().ForEachUniqueLayer(
1994 const SHAPE_POLY_SET& layerPoly = *zone->GetFilledPolysList( layer );
2010 const int halfsize =
pcbIUScale.mmToIU( 1.0 );
2021 std::vector<VECTOR2I> convex_hull;
2030 for(
const VECTOR2I& pt : convex_hull )
2043 bool isFPEdit =
board &&
board->IsFootprintHolder();
2053 if( item->IsOnLayer( aLayer ) )
2067 if(
pad->IsOnLayer( aLayer ) )
2073 if( zone->GetIsRuleArea() )
2076 if( zone->IsOnLayer( aLayer ) )
2078 const std::shared_ptr<SHAPE_POLY_SET>& layerPoly = zone->GetFilledPolysList( aLayer );
2080 for(
int ii = 0; ii < layerPoly->OutlineCount(); ii++ )
2081 rawPolys.
AddOutline( layerPoly->COutline( ii ) );
2085 std::vector<VECTOR2I> convex_hull;
2090 for(
const VECTOR2I& pt : convex_hull )
2103 variant =
board->GetCurrentVariant();
2117 aList.emplace_back(
_(
"Footprint Name" ),
GetFPID().GetLibItemName().wx_str() );
2119 aList.emplace_back(
_(
"Pads" ), wxString::Format( wxT(
"%zu" ), padCount ) );
2122 wxString::Format(
_(
"Keywords: %s" ),
GetKeywords() ) );
2131 case F_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Front" ) );
break;
2132 case B_Cu: aList.emplace_back(
_(
"Board Side" ),
_(
"Back (Flipped)" ) );
break;
2136 aList.emplace_back(
_(
"Rotation" ), wxString::Format( wxT(
"%.4g" ),
GetOrientation().AsDegrees() ) );
2138 auto addToken = []( wxString* aStr,
const wxString& aAttr )
2140 if( !aStr->IsEmpty() )
2141 *aStr += wxT(
", " );
2150 addToken( &status,
_(
"Locked" ) );
2153 addToken( &status,
_(
"autoplaced" ) );
2156 addToken( &attrs,
_(
"not in schematic" ) );
2159 addToken( &attrs,
_(
"exclude from pos files" ) );
2162 addToken( &attrs,
_(
"exclude from BOM" ) );
2165 addToken( &attrs,
_(
"DNP" ) );
2167 aList.emplace_back(
_(
"Status: " ) + status,
_(
"Attributes:" ) + wxS(
" " ) + attrs );
2171 aList.emplace_back(
_(
"Component Class" ),
2175 msg.Printf(
_(
"Footprint: %s" ),
m_fpid.GetUniStringLibId() );
2177 aList.emplace_back( msg, msg2 );
2181 aList.emplace_back( msg, msg2 );
2189 if(
board->IsFootprintHolder() )
2221 if(
pad->IsOnLayer( aLayer ) )
2227 if( zone->IsOnLayer( aLayer ) )
2233 if( field->IsOnLayer( aLayer ) )
2239 if( item->IsOnLayer( aLayer ) )
2251 if(
pad->IsOnLayer( aLayer ) &&
pad->HitTest( aPosition, aAccuracy ) )
2257 if( zone->IsOnLayer( aLayer ) && zone->HitTest( aPosition, aAccuracy ) )
2263 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer )
2264 && item->HitTest( aPosition, aAccuracy ) )
2276 std::vector<BOARD_ITEM*> items;
2280 if(
pad->IsOnLayer( aLayer ) )
2281 items.push_back(
pad );
2286 if( zone->IsOnLayer( aLayer ) )
2287 items.push_back( zone );
2292 if( item->Type() !=
PCB_TEXT_T && item->IsOnLayer( aLayer ) )
2293 items.push_back( item );
2302 if( !aContained && item->HitTest( aRect, aContained, aAccuracy ) )
2304 else if( aContained && !item->HitTest( aRect, aContained, aAccuracy ) )
2311 return !items.empty() && aContained;
2330 BOX2I arect = aRect;
2350 if(
pad->HitTest( arect,
false, 0 ) )
2356 if( zone->HitTest( arect,
false, 0 ) )
2362 if( point->HitTest( arect,
false, 0 ) )
2373 if( item->Type() !=
PCB_TEXT_T && item->HitTest( arect,
false, 0 ) )
2387 using std::ranges::all_of;
2388 using std::ranges::any_of;
2395 [&](
const auto* aItem )
2397 return aItem && aItem->HitTest( aPoly, aContained );
2403 auto drawings =
m_drawings | std::views::filter( [](
const auto* aItem )
2414 return all_of( drawings, hitTest )
2415 && all_of(
m_pads, hitTest )
2416 && all_of(
m_zones, hitTest );
2421 return any_of( drawings, hitTest )
2422 || any_of(
m_pads, hitTest )
2423 || any_of(
m_zones, hitTest );
2430 bool can_select = aSearchAfterMe ? false :
true;
2434 if( !can_select &&
pad == aSearchAfterMe )
2440 if( can_select &&
pad->GetNumber() == aPadNumber )
2452 if(
pad->m_Uuid == aUuid )
2465 if( !(
pad->GetLayerSet() & aLayerMask ).any() )
2468 if(
pad->HitTest( aPosition ) )
2478 std::vector<const PAD*> retv;
2482 if( ( aIgnore && aIgnore ==
pad ) || (
pad->GetNumber() != aPadNumber ) )
2485 retv.push_back(
pad );
2513 std::set<wxString> usedNumbers;
2525 if(
pad->GetNumber().IsEmpty() )
2535 usedNumbers.insert(
pad->GetNumber() );
2556 auto isElectricalPadNumber = [](
const wxString& num ) ->
bool
2563 while( i < num.size() && wxIsalpha( num[i] ) )
2571 if( i == num.size() )
2574 for(
size_t j = i; j < num.size(); ++j )
2576 if( !wxIsdigit( num[j] ) )
2583 std::set<wxString> counted;
2595 const wxString& num =
pad->GetNumber();
2597 if( isElectricalPadNumber( num ) )
2598 counted.insert( num );
2601 return static_cast<unsigned>( counted.size() );
2607 if(
nullptr == a3DModel )
2650 const std::vector<KICAD_T>& aScanTypes )
2652#if 0 && defined(DEBUG)
2653 std::cout <<
GetClass().mb_str() <<
' ';
2656 bool drawingsScanned =
false;
2658 for(
KICAD_T scanType : aScanTypes )
2706 if( !drawingsScanned )
2714 drawingsScanned =
true;
2750 if( reference.IsEmpty() )
2751 reference =
_(
"<no reference designator>" );
2753 return wxString::Format(
_(
"Footprint %s" ), reference );
2759 return wxString::Format( wxT(
"%s (%s)" ),
2798 aFunction( drawing );
2804 catch( std::bad_function_call& )
2806 wxFAIL_MSG( wxT(
"Error running FOOTPRINT::RunOnChildren" ) );
2813 std::vector<int> layers;
2815 layers.reserve( 6 );
2821 wxASSERT_MSG(
false, wxT(
"Illegal layer" ) );
2838 bool f_silk =
false, b_silk =
false, non_silk =
false;
2842 if( item->GetLayer() ==
F_SilkS )
2844 else if( item->GetLayer() ==
B_SilkS )
2850 if( ( f_silk || b_silk ) && !non_silk &&
m_pads.empty() )
2887 constexpr double MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY = 1.5;
2890 return MINIMAL_ZOOM_LEVEL_FOR_VISIBILITY;
2903 int biggest_clearance =
board->GetMaxClearanceValue();
2904 area.
Inflate( biggest_clearance );
2915 if( aName.find_first_of( invalids ) != std::string::npos )
2929 static const wxChar invalidChars[] = wxT(
"%$<>\t\n\r\"\\/:");
2930 static const wxChar invalidCharsReadable[] = wxT(
"% $ < > 'tab' 'return' 'line feed' \\ \" / :");
2933 return invalidCharsReadable;
2935 return invalidChars;
2941 if( aMoveVector.
x == 0 && aMoveVector.
y == 0 )
2955 EDA_ANGLE newOrientation = orientation + aAngle;
2962 field->KeepUpright();
2967 static_cast<PCB_TEXT*
>( item )->KeepUpright();
2974 wxASSERT( aLayer ==
F_Cu || aLayer ==
B_Cu );
3064 field->EDA_TEXT::Offset(
delta );
3070 zone->Move(
delta );
3073 item->Move(
delta );
3076 point->Move(
delta );
3114 field->Move( moveVector );
3118 pad->Move( moveVector );
3122 item->Move( moveVector );
3126 zone->Move( moveVector );
3164 field->Rotate( rotationCenter, angleChange );
3167 pad->Rotate( rotationCenter, angleChange );
3170 zone->Rotate( rotationCenter, angleChange );
3173 item->Rotate( rotationCenter, angleChange );
3176 point->Rotate( rotationCenter, angleChange );
3210 const BOARD_ITEM* aItem,
bool addToFootprint )
3214 switch( aItem->
Type() )
3218 PAD* new_pad =
new PAD( *
static_cast<const PAD*
>( aItem ) );
3221 if( addToFootprint )
3222 m_pads.push_back( new_pad );
3230 ZONE* new_zone =
new ZONE( *
static_cast<const ZONE*
>( aItem ) );
3233 if( addToFootprint )
3234 m_zones.push_back( new_zone );
3236 new_item = new_zone;
3245 if( addToFootprint )
3248 new_item = new_point;
3260 switch(
static_cast<const PCB_FIELD*
>( aItem )->GetId() )
3269 if( addToFootprint )
3272 new_item = new_text;
3281 if( addToFootprint )
3284 new_item = new_shape;
3293 if( addToFootprint )
3296 new_item = new_barcode;
3305 if( addToFootprint )
3308 new_item = new_image;
3317 if( addToFootprint )
3320 new_item = new_textbox;
3333 if( addToFootprint )
3336 new_item = dimension;
3344 if( addToFootprint )
3346 group->RunOnChildren(
3366 wxFAIL_MSG( wxT(
"Duplication not supported for items of class " ) + aItem->
GetClass() );
3376 std::set<wxString> usedNumbers;
3380 usedNumbers.insert(
pad->GetNumber() );
3387 while( usedNumbers.count( wxString::Format( wxT(
"%s%d" ), prefix, num ) ) )
3390 return wxString::Format( wxT(
"%s%d" ), prefix, num );
3398 if(
group.contains( aPadNumber ) )
3402 return std::nullopt;
3453 for(
int jj = 0; jj < aPolySet.
HoleCount( ii ); jj++ )
3457 return aPolySet.
Area();
3472 return markerShape.
Area();
3476 double combinedArea = 0.0;
3481 return combinedArea;
3532 double width =
static_cast<const PCB_TRACK*
>( aItem )->GetWidth();
3533 return width * width;
3537 static_cast<const PAD*
>( aItem )->Padstack().ForEachUniqueLayer(
3547 const ZONE* zone =
static_cast<const ZONE*
>( aItem );
3597 for(
int i = 0; i < aCollector.
GetCount(); ++i )
3601 switch( item->
Type() )
3633 double footprintRegionArea =
polygonArea( footprintRegion );
3634 double uncoveredRegionArea = footprintRegionArea -
polygonArea( coveredRegion );
3635 double coveredArea = footprintRegionArea - uncoveredRegionArea;
3638 if( footprintRegionArea == 0 )
3641 double ratio = coveredArea / footprintRegionArea;
3648 return std::min( ratio, 1.0 );
3654 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
3675 shape->AddShape(
pad->GetEffectiveShape( aLayer, aFlash )->Clone() );
3680 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3682 shape->AddShape( item->GetEffectiveShape( aLayer, aFlash )->Clone() );
3729 std::vector<PCB_SHAPE*> list_front;
3730 std::vector<PCB_SHAPE*> list_back;
3731 std::map<int, int> front_width_histogram;
3732 std::map<int, int> back_width_histogram;
3739 list_back.push_back( shape );
3746 list_front.push_back( shape );
3751 if( !list_front.size() && !list_back.size() )
3755 int chainingEpsilon =
pcbIUScale.mmToIU( 0.02 );
3758 true, aErrorHandler ) )
3768 auto max = std::max_element( front_width_histogram.begin(), front_width_histogram.end(),
3769 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3771 return a.second < b.second;
3774 if( max != front_width_histogram.end() )
3797 auto max = std::max_element( back_width_histogram.begin(), back_width_histogram.end(),
3798 [](
const std::pair<int, int>& a,
const std::pair<int, int>& b )
3800 return a.second < b.second;
3803 if( max != back_width_histogram.end() )
3826 std::map<PCB_LAYER_ID, std::vector<PCB_SHAPE*>> layer_shapes;
3832 if( item->Type() != PCB_SHAPE_T )
3835 for( PCB_LAYER_ID layer : item->GetLayerSet() )
3837 if( !IsCopperLayer( layer ) )
3840 if( board && !board->GetEnabledLayers().Contains( layer ) )
3843 layer_shapes[layer].push_back( static_cast<PCB_SHAPE*>( item ) );
3847 for(
size_t ii = 0; ii < m_pads.size(); ++ii )
3850 bool has_nettie =
false;
3852 auto it = map.find(
pad->GetNumber() );
3854 if( it == map.end() || it->second < 0 )
3857 for(
size_t jj = ii + 1; jj < m_pads.size(); ++jj )
3859 PAD* other = m_pads[ jj ];
3861 auto it2 = map.find( other->
GetNumber() );
3863 if( it2 == map.end() || it2->second < 0 )
3866 if( it2->second == it->second )
3868 m_netTieCache[
pad].insert(
pad->GetNetCode() );
3870 m_netTieCache[other].insert( other->
GetNetCode() );
3871 m_netTieCache[other].insert(
pad->GetNetCode() );
3879 for(
auto& [ layer, shapes ] : layer_shapes )
3881 auto pad_shape =
pad->GetEffectiveShape( layer );
3883 for(
auto other_shape : shapes )
3885 auto shape = other_shape->GetEffectiveShape( layer );
3887 if( pad_shape->Collide( shape.get() ) )
3889 std::set<int>& nettie = m_netTieCache[
pad];
3890 m_netTieCache[other_shape].insert( nettie.begin(), nettie.end() );
3900 std::map<wxString, int> padNumberToGroupIdxMap;
3903 padNumberToGroupIdxMap[
pad->GetNumber() ] = -1;
3906 [&]( wxString aPad,
int aGroup )
3908 aPad.Trim(
true ).Trim(
false );
3910 if( !aPad.IsEmpty() )
3911 padNumberToGroupIdxMap[ aPad ] = aGroup;
3920 for( wxUniCharRef ch :
group )
3929 switch(
static_cast<unsigned char>( ch ) )
3936 processPad(
pad, ii );
3946 processPad(
pad, ii );
3949 return padNumberToGroupIdxMap;
3959 int groupIdx = padToNetTieGroupMap[ aPad->
GetNumber() ];
3960 std::vector<PAD*> otherPads;
3966 if( padToNetTieGroupMap[
pad->GetNumber() ] == groupIdx )
3967 otherPads.push_back(
pad );
3980 if( setAttr && likelyAttr && setAttr != likelyAttr )
3984 switch( likelyAttr )
3987 msg.Printf(
_(
"(expected 'Through hole'; actual '%s')" ),
GetTypeName() );
3990 msg.Printf(
_(
"(expected 'SMD'; actual '%s')" ),
GetTypeName() );
3995 (aErrorHandler)( msg );
4001 const std::function<
void(
const PAD*,
int,
4002 const wxString& )>& aErrorHandler )
4004 if( aErrorHandler ==
nullptr )
4009 pad->CheckPad( aUnitsProvider,
false,
4010 [&](
int errorCode,
const wxString& msg )
4012 aErrorHandler(
pad, errorCode, msg );
4020 const VECTOR2I& )>& aErrorHandler )
4022 std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
4037 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
4040 if( checkedPairs.find( { a, b } ) == checkedPairs.end() )
4042 checkedPairs[ { a, b } ] = 1;
4054 std::shared_ptr<SHAPE_SEGMENT> holeA =
pad->GetEffectiveHoleShape();
4057 if( holeA->Collide( holeB->GetSeg(), 0 ) )
4074 SHAPE* padShape =
pad->GetEffectiveShape( l ).get();
4077 if( padShape->
Collide( otherShape, 0,
nullptr, &pos ) )
4090 const VECTOR2I& )>& aErrorHandler )
4099 std::vector<BOARD_ITEM*> copperItems;
4103 if( item->IsOnCopperLayer() )
4104 copperItems.push_back( item );
4106 item->RunOnChildren(
4110 copperItems.push_back( descendent );
4117 if( !zone->GetIsRuleArea() && zone->IsOnCopperLayer() )
4118 copperItems.push_back( zone );
4123 if( field->IsOnCopperLayer() )
4124 copperItems.push_back( field );
4134 std::map<int, std::vector<const PAD*>> outlineIdxToPadsMap;
4138 if( item->IsOnLayer( layer ) )
4148 for(
int ii = 0; ii < copperOutlines.
OutlineCount(); ++ii )
4150 if(
pad->GetEffectiveShape( layer )->Collide( &copperOutlines.
Outline( ii ), 0 ) )
4151 outlineIdxToPadsMap[ ii ].emplace_back(
pad );
4158 for(
const auto& [ outlineIdx, pads ] : outlineIdxToPadsMap )
4160 if( pads.size() > 1 )
4162 const PAD* firstPad = pads[0];
4163 int firstGroupIdx = padNumberToGroupIdxMap[ firstPad->
GetNumber() ];
4165 for(
size_t ii = 1; ii < pads.size(); ++ii )
4167 const PAD* thisPad = pads[ii];
4168 int thisGroupIdx = padNumberToGroupIdxMap[ thisPad->
GetNumber() ];
4170 if( thisGroupIdx < 0 || thisGroupIdx != firstGroupIdx )
4179 if( item->HitTest( pos, 1 ) )
4181 shortingItem = item;
4187 aErrorHandler( shortingItem, firstPad, thisPad, pos );
4189 aErrorHandler( firstPad, thisPad,
nullptr, pos );
4200 std::set<wxString> padNumbers;
4209 msg.Printf(
_(
"(net-tie pad group contains unknown pad number %s)" ), padNumber );
4210 aErrorHandler( msg );
4212 else if( !padNumbers.insert(
pad->GetNumber() ).second )
4214 msg.Printf(
_(
"(pad %s appears in more than one net-tie pad group)" ), padNumber );
4215 aErrorHandler( msg );
4223 const VECTOR2I& aPt )>& aErrorHandler )
4225 auto checkColliding =
4240 if( itemShape->Collide( otherShape.get(), 0, &
actual, &pos ) )
4241 aErrorHandler( item, other, pos );
4250 checkColliding( item, other );
4254 checkColliding( item,
pad );
4265 std::swap( *
this, *
image );
4274 image->RunOnChildren(
4302 return *
this == other;
4311 for(
size_t ii = 0; ii <
m_pads.size(); ++ii )
4320 for(
size_t ii = 0; ii <
m_drawings.size(); ++ii )
4329 for(
size_t ii = 0; ii <
m_zones.size(); ++ii )
4339 std::vector<PCB_FIELD*> fields, otherFields;
4344 if( fields.size() != otherFields.size() )
4347 for(
size_t ii = 0; ii < fields.size(); ++ii )
4351 if( !( *fields[ii] == *otherFields[ii] ) )
4367 double similarity = 1.0;
4376 similarity *=
pad->Similarity( *otherPad );
4388 if( aPtA.
x != aPtB.
x )
4389 return aPtA.
x < aPtB.
x;
4391 if( aPtA.
y != aPtB.
y )
4392 return aPtA.
y < aPtB.
y;
4394 return std::nullopt;
4400 if( itemA->
Type() != itemB->
Type() )
4401 return itemA->
Type() < itemB->
Type();
4406 switch( itemA->
Type() )
4445 for(
int ii = 0; ii < dwgA->
GetPolyShape().TotalVertices(); ++ii )
4447 if( std::optional<bool> cmp =
4530 return itemA < itemB;
4542 std::optional<bool> padCopperMatches;
4545 const PAD* checkPad = aFirst;
4558 padCopperMatches = aFirst->
GetSize( aLayer ).
x < aSecond->
GetSize( aLayer ).
x;
4560 padCopperMatches = aFirst->
GetSize( aLayer ).
y < aSecond->
GetSize( aLayer ).
y;
4562 padCopperMatches = aFirst->
GetShape( aLayer ) < aSecond->
GetShape( aLayer );
4565 if( padCopperMatches.has_value() )
4566 return *padCopperMatches;
4574 return aFirst < aSecond;
4579bool FOOTPRINT::cmp_padstack::operator()(
const PAD* aFirst,
const PAD* aSecond )
const
4619 if( firstShape->VertexCount() != secondShape->VertexCount() )
4620 return firstShape->VertexCount() < secondShape->VertexCount();
4622 for(
int ii = 0; ii < firstShape->VertexCount(); ++ii )
4624 if( std::optional<bool> cmp =
cmp_points_opt( firstShape->CVertex( ii ), secondShape->CVertex( ii ) ) )
4646 for(
int ii = 0; ii < aFirst->
Outline()->TotalVertices(); ++ii )
4648 if( std::optional<bool> cmp =
4658 return aFirst < aSecond;
4663 int aMaxError,
ERROR_LOC aErrorLoc )
const
4674 clearance.x +=
pad->GetSolderMaskExpansion( padLayer );
4675 clearance.y +=
pad->GetSolderMaskExpansion( padLayer );
4698 if( dummySize.
x <= 0 || dummySize.
y <= 0 )
4702 dummy.SetSize( padLayer, dummySize );
4703 dummy.TransformShapeToPolygon( aBuffer, padLayer, 0, aMaxError, aErrorLoc );
4707 pad->TransformShapeToPolygon( aBuffer, padLayer,
clearance.x, aMaxError, aErrorLoc );
4713 if( !
pad->FlashLayer( aLayer ) )
4718 pad->Padstack().ForEachUniqueLayer(
4721 processPad(
pad, l );
4726 processPad(
pad, aLayer );
4733 int aError,
ERROR_LOC aErrorLoc,
bool aIncludeText,
4734 bool aIncludeShapes,
bool aIncludePrivateItems )
const
4741 if( item->Type() ==
PCB_TEXT_T && aIncludeText )
4746 text->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4757 textbox->PCB_SHAPE::TransformShapeToPolygon( aBuffer, aLayer, 0, aError, aErrorLoc );
4764 if( item->Type() ==
PCB_SHAPE_T && aIncludeShapes )
4785 if( ( aLayer ==
UNDEFINED_LAYER || field->GetLayer() == aLayer ) && field->IsVisible() )
4786 field->TransformTextToPolySet( aBuffer, aClearance, aError, aErrorLoc );
4796 std::set<KIFONT::OUTLINE_FONT*>
fonts;
4810 if( permission == PERMISSION::EDITABLE || permission == PERMISSION::INSTALLABLE )
4811 fonts.insert( outlineFont );
4817 processItem( item );
4820 processItem( field );
4865 return wxEmptyString;
4870 const std::unordered_set<wxString>& aComponentClassNames )
4919 LSET padLayers =
pad->GetLayerSet();
4920 padLayers |= boardCopper;
4921 pad->SetLayerSet( padLayers );
4933 if( zcMap.
Choices().GetCount() == 0 )
4945 if( layerEnum.
Choices().GetCount() == 0 )
4953 wxPGChoices fpLayers;
4964 auto isNotFootprintHolder =
4970 return !
board->IsFootprintHolder();
4977 layer->SetChoices( fpLayers );
4978 layer->SetAvailableFunc( isNotFootprintHolder );
4986 const wxString groupFields =
_HKI(
"Fields" );
4992 const wxString propertyFields =
_HKI(
"Footprint Properties" );
5010 const wxString groupAttributes =
_HKI(
"Attributes" );
5024 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 & GetBezierC2() const
const VECTOR2I & GetEllipseCenter() const
EDA_ANGLE GetEllipseEndAngle() const
int GetEllipseMajorRadius() const
SHAPE_POLY_SET & GetPolyShape()
EDA_ANGLE GetEllipseRotation() const
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
EDA_ANGLE GetEllipseStartAngle() const
const VECTOR2I & GetBezierC1() const
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
const EDA_ANGLE & GetTextAngle() const
virtual const wxString & GetText() const
Return the string associated with the text object.
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
double GetLineSpacing() const
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
int GetTextThickness() const
VECTOR2I GetTextSize() const
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
EMBEDDED_FILES & operator=(EMBEDDED_FILES &&other) noexcept
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Load a file from disk and adds it to the collection.
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
const PADSTACK & Padstack() const
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
PAD_DRILL_SHAPE GetDrillShape() const
const std::shared_ptr< SHAPE_POLY_SET > & GetEffectivePolygon(PCB_LAYER_ID aLayer, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
std::optional< int > GetLocalSolderMaskMargin() const
VECTOR2I GetSolderPasteMargin(PCB_LAYER_ID aLayer) const
Usually < 0 (mask shape smaller than pad)because the margin can be dependent on the pad size,...
bool HasDrilledHole() const override
std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const override
Return a SHAPE_SEGMENT object representing the pad's hole.
const VECTOR2I & GetSize(PCB_LAYER_ID aLayer) const
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
A set of BOARD_ITEMs (i.e., without duplicates).
A PCB_POINT is a 0-dimensional point that is used to mark a position on a PCB, or more usually a foot...
Object to handle a bitmap image that can be inserted in a PCB.
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
int GetWidth() const override
void TransformShapeToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, KIGFX::RENDER_SETTINGS *aRenderSettings=nullptr) const override
Convert the item shape to a polyset.
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the shape to a closed polygon.
STROKE_PARAMS GetStroke() const override
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
bool IsBorderEnabled() const
Disables the border, this is done by changing the stroke internally.
void TransformTextToPolySet(SHAPE_POLY_SET &aBuffer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc) const
Function TransformTextToPolySet Convert the text to a polygonSet describing the actual character stro...
virtual VECTOR2I GetPosition() const override
PROPERTY_BASE & SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Set a callback function to determine whether an object provides this property.
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.
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.
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