35#include <wx/wfstream.h>
58 wxFFileOutputStream stream( aOutFileName );
66 return xdoc.Save( stream, 2 );
113 xroot->AddChild( xchains );
130 wxString description;
132 nlohmann::ordered_map<wxString, wxString> fields;
143 wxString ref = aSymbol->
GetRef( &aSheet );
153 wxString ref2 = symbol2->
GetRef( &sheet );
155 if( ref2.CmpNoCase( ref ) != 0 )
165 if( !candidate.IsEmpty() && ( unit < minUnit || value.IsEmpty() ) )
171 if( !candidate.IsEmpty() && ( unit < minUnit || footprint.IsEmpty() ) )
172 footprint = candidate;
178 if( !candidate.IsEmpty() && ( unit < minUnit ||
datasheet.IsEmpty() ) )
185 if( !candidate.IsEmpty() && ( unit < minUnit || description.IsEmpty() ) )
186 description = candidate;
191 if( field.IsMandatory() || field.IsPrivate() )
194 if( unit < minUnit || fields.count( field.GetName() ) == 0 )
195 fields[field.GetName()] = field.GetShownText( &aSheet,
m_resolveTextVars, aVariant );
198 minUnit = std::min( unit, minUnit );
215 if( field.IsMandatory() || field.IsPrivate() )
218 fields[field.GetName()] = field.GetShownText( &aSheet,
m_resolveTextVars, aVariant );
230 aNode->AddChild(
node( wxT(
"value" ), wxT(
"~" ) ) );
232 if( footprint.size() )
238 if( description.size() )
242 aNode->AddChild( xfields =
node( wxT(
"fields" ) ) );
244 for(
const auto& [ fieldName, fieldValue ] : fields )
248 xfields->AddChild( xfield );
255 XNODE* xcomps =
node( wxT(
"components" ) );
280 b->GetRef( &sheet,
false ),
true ) < 0 );
283 std::set<
SCH_SYMBOL*,
decltype( cmp )> ordered_symbols( cmp );
284 std::multiset<
SCH_SYMBOL*,
decltype( cmp )> extra_units( cmp );
289 auto test = ordered_symbols.insert( symbol );
293 if( ( *(
test.first ) )->m_Uuid > symbol->
m_Uuid )
295 extra_units.insert( *(
test.first ) );
296 ordered_symbols.erase(
test.first );
297 ordered_symbols.insert( symbol );
301 extra_units.insert( symbol );
306 for(
EDA_ITEM* item : ordered_symbols )
318 if( forBOM && ( sheet.GetExcludedFromBOM(
m_schematic->GetCurrentVariant() )
324 if( forBoard && ( sheet.GetExcludedFromBoard(
m_schematic->GetCurrentVariant() )
335 xcomps->AddChild( xcomp =
node( wxT(
"comp" ) ) );
341 xcomp->AddChild( xlibsource =
node( wxT(
"libsource" ) ) );
369 std::vector<SCH_FIELD>& fields = symbol->
GetFields();
373 if( field.IsMandatory() || field.IsPrivate() )
376 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
377 xproperty->
AddAttribute( wxT(
"name" ), field.GetUntranslatedName() );
383 for(
const SCH_FIELD& sheetField : sheet.Last()->GetFields() )
385 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
386 xproperty->
AddAttribute( wxT(
"name" ), sheetField.GetUntranslatedName() );
395 if( symbol->
ResolveExcludedFromBOM( &sheet, exportVariant ) || sheet.GetExcludedFromBOM( exportVariant ) )
397 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
398 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"exclude_from_bom" ) );
402 || sheet.GetExcludedFromSim( exportVariant ) )
404 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
405 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"exclude_from_sim" ) );
409 || sheet.GetExcludedFromBoard( exportVariant ) )
411 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
412 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"exclude_from_board" ) );
419 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
420 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"exclude_from_pos_files" ) );
423 const bool baseDnp = symbol->
ResolveDNP( &sheet ) || sheet.GetDNP();
425 if( symbol->
ResolveDNP( &sheet, exportVariant ) || sheet.GetDNP( exportVariant ) )
427 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
433 const std::set<wxString>& variantNames =
m_schematic->GetVariantNames();
438 XNODE* xvariants =
nullptr;
440 for(
const auto& variantName : variantNames )
442 XNODE* xvariant =
nullptr;
445 [
this, &xvariant, &variantName](
XNODE* child ) ->
void
452 xvariant =
node( wxT(
"variant" ) );
455 xvariant->AddChild( child );
459 [
this, &addToVariant]( wxString
const&
name,
bool base,
bool effective ) ->
void
461 if( base == effective )
464 XNODE* xvarprop =
node( wxT(
"property" ) );
466 xvarprop->
AddAttribute( wxT(
"value" ), effective ? wxT(
"1" ) : wxT(
"0" ) );
467 addToVariant( xvarprop );
470 bool effectiveDnp = symbol->
ResolveDNP( &sheet, variantName ) || sheet.GetDNP( variantName );
471 addBinaryProp( wxT(
"dnp" ), baseDnp, effectiveDnp );
474 || sheet.GetExcludedFromBOM( variantName );
475 addBinaryProp( wxT(
"exclude_from_bom" ), baseExcludedFromBOM, effectiveExcludedFromBOM );
478 || sheet.GetExcludedFromSim( variantName );
479 addBinaryProp( wxT(
"exclude_from_sim" ), baseExcludedFromSim, effectiveExcludedFromSim );
482 addBinaryProp( wxT(
"exclude_from_pos_files" ), baseExcludedFromPosFiles,
483 effectiveExcludedFromPosFiles );
489 variant = &instance.
m_Variants.at( variantName );
493 XNODE* xprop =
node( wxT(
"property" ) );
494 xprop->
AddAttribute( wxT(
"name" ), wxT(
"symbol_override" ) );
496 addToVariant( xprop );
501 XNODE* xfields =
nullptr;
503 for(
const auto& [fieldName, fieldValue] : variant->
m_Fields )
505 const wxString baseValue = symbol->
GetFieldText( fieldName, &sheet, wxEmptyString );
507 if( fieldValue == baseValue )
511 xfields =
node( wxT(
"fields" ) );
513 wxString resolvedValue = fieldValue;
516 resolvedValue = symbol->
ResolveText( fieldValue, &sheet );
520 xfields->AddChild( xfield );
530 const wxString& fieldName = baseField.GetName();
532 if( variant->
m_Fields.contains( fieldName ) )
535 const wxString baseValue = symbol->
GetFieldText( fieldName, &sheet, wxEmptyString );
536 const wxString variantValue = symbol->
GetFieldText( fieldName, &sheet, variantName );
538 if( variantValue == baseValue )
542 xfields =
node( wxT(
"fields" ) );
544 wxString resolvedValue = variantValue;
547 resolvedValue = symbol->
ResolveText( variantValue, &sheet );
551 xfields->AddChild( xfield );
558 std::vector<SCH_FIELD*> altFields;
559 altSymbol->GetFields( altFields );
561 for(
const SCH_FIELD* altField : altFields )
563 const wxString& fieldName = altField->GetName();
566 || variant->
m_Fields.contains( fieldName )
567 || altField->GetText().IsEmpty() )
573 xfields =
node( wxT(
"fields" ) );
575 wxString resolvedValue = altField->GetText();
578 resolvedValue = symbol->
ResolveText( resolvedValue, &sheet );
582 xfields->AddChild( xfield );
587 addToVariant( xfields );
593 xvariants =
node( wxT(
"variants" ) );
595 xvariants->AddChild( xvariant );
600 xcomp->AddChild( xvariants );
603 if(
const std::unique_ptr<LIB_SYMBOL>& part = symbol->
GetLibSymbolRef() )
605 if( part->GetKeyWords().size() )
607 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
608 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"ki_keywords" ) );
609 xproperty->
AddAttribute( wxT(
"value" ), part->GetKeyWords() );
612 if( !part->GetFPFilters().IsEmpty() )
616 for(
const wxString&
filter : part->GetFPFilters() )
619 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
620 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"ki_fp_filters" ) );
621 xproperty->
AddAttribute( wxT(
"value" ), filters.Trim(
false ) );
624 if( part->GetDuplicatePinNumbersAreJumpers() )
625 xcomp->AddChild(
node( wxT(
"duplicate_pin_numbers_are_jumpers" ), wxT(
"1" ) ) );
627 const std::vector<std::set<wxString>>& jumperGroups = part->JumperPinGroups();
629 if( !jumperGroups.empty() )
632 xcomp->AddChild( xproperty =
node( wxT(
"jumper_pin_groups" ) ) );
634 for(
const std::set<wxString>&
group : jumperGroups )
636 xproperty->AddChild( groupNode =
node( wxT(
"group" ) ) );
638 for(
const wxString& pinName :
group )
639 groupNode->AddChild(
node( wxT(
"pin" ), pinName ) );
645 xcomp->AddChild( xsheetpath =
node( wxT(
"sheetpath" ) ) );
647 xsheetpath->
AddAttribute( wxT(
"names" ), sheet.PathHumanReadable() );
648 xsheetpath->
AddAttribute( wxT(
"tstamps" ), sheet.PathAsString() );
653 if( compClassNames.size() > 0 )
655 XNODE* xcompclasslist;
656 xcomp->AddChild( xcompclasslist =
node( wxT(
"component_classes" ) ) );
658 for(
const wxString& compClass : compClassNames )
663 xcomp->AddChild( xunits =
node( wxT(
"tstamps" ) ) );
665 auto range = extra_units.equal_range( symbol );
669 for(
auto it = range.first; it != range.second; ++it )
671 uuid = ( *it )->m_Uuid.AsString();
678 xunits->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, uuid ) );
683 xunits->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, uuid ) );
687 xcomp->AddChild( xunitInfo =
node( wxT(
"units" ) ) );
702 const std::vector<LIB_SYMBOL::UNIT_PIN_INFO>& defaultUnitInfo = libSym->GetUnitPinInfo();
703 std::map<int, SCH_SYMBOL*> symbolByUnit;
711 int unit = aUnitSymbol->GetUnitSelection( &sheet );
714 symbolByUnit.try_emplace( unit, aUnitSymbol );
717 addUnitSymbol( symbol );
719 auto extraUnitRange = extra_units.equal_range( symbol );
723 for(
auto it = extraUnitRange.first; it != extraUnitRange.second; ++it )
724 addUnitSymbol( *it );
728 for(
size_t unitIdx = 0; unitIdx < defaultUnitInfo.size(); ++unitIdx )
731 auto symbolIt = symbolByUnit.find( unitIdx + 1 );
733 if( symbolIt != symbolByUnit.end() )
735 const std::unique_ptr<LIB_SYMBOL>& unitLibSym = symbolIt->second->GetLibSymbolRef();
739 const std::vector<LIB_SYMBOL::UNIT_PIN_INFO>& unitSpecificInfo =
740 unitLibSym->GetUnitPinInfo();
742 if( unitIdx < unitSpecificInfo.size() )
743 unitInfo = unitSpecificInfo[unitIdx];
748 xunitInfo->AddChild( xunit =
node( wxT(
"unit" ) ) );
752 xunit->AddChild( xpins =
node( wxT(
"pins" ) ) );
757 xpins->AddChild( xpin =
node( wxT(
"pin" ) ) );
781 std::map<SCH_SCREEN*, int> screenVisits;
784 screenVisits[sheet.LastScreen()]++;
792 wxString instancePrefix = sheet.PathAsString();
797 wxString groupName =
group->GetName();
799 if( screenVisits[sheet.LastScreen()] > 1 )
800 groupName = wxString::Format( wxT(
"%s (%s)" ), groupName, sheet.PathHumanReadable() );
803 xcomps->AddChild( xgroup =
node( wxT(
"group" ) ) );
806 xgroup->
AddAttribute( wxT(
"uuid" ), instancePrefix +
group->m_Uuid.AsString() );
810 xgroup->AddChild( xmembers =
node( wxT(
"members" ) ) );
817 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
818 xmember->
AddAttribute( wxT(
"uuid" ), instancePrefix + member->m_Uuid.AsString() );
824 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
825 xmember->
AddAttribute( wxT(
"uuid" ), instancePrefix + member->m_Uuid.AsString() );
830 std::vector<SCH_SHEET_PATH> descendantSheets;
840 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
842 descendantSheet.PathAsString() + descendantItem->m_Uuid.AsString() );
858 XNODE* xvariants =
node( wxT(
"variants" ) );
860 std::set<wxString> variantNames =
m_schematic->GetVariantNames();
862 for(
const wxString& variantName : variantNames )
865 xvariants->AddChild( xvariant =
node( wxT(
"variant" ) ) );
868 wxString description =
m_schematic->GetVariantDescription( variantName );
870 if( !description.IsEmpty() )
871 xvariant->
AddAttribute( wxT(
"description" ), description );
881 std::vector<SCH_SHEET_PATH> symbolSheets;
882 symbolSheets.push_back( aSymbolSheet );
889 const wxString ref = aSymbol->
GetRef( &aSymbolSheet );
897 wxString ref2 = symbol2->
GetRef( &sheet );
900 if( ref2.CmpNoCase( ref ) != 0 )
903 if( otherUnit == primaryUnit )
906 symbolSheets.push_back( sheet );
908 std::unordered_set<wxString> otherClassNames =
910 compClassNames.insert( otherClassNames.begin(), otherClassNames.end() );
920 if( symbolSheetPath.IsContainedWithin( sheetPath ) )
921 compClassNames.insert( sheetCompClasses.begin(), sheetCompClasses.end() );
925 std::vector<wxString> sortedCompClassNames( compClassNames.begin(), compClassNames.end() );
926 std::sort( sortedCompClassNames.begin(), sortedCompClassNames.end(),
927 [](
const wxString& str1,
const wxString& str2 )
929 return str1.Cmp( str2 ) < 0;
932 return sortedCompClassNames;
939 XNODE* xdesign =
node( wxT(
"design" ) );
945 wxFileName sourceFileName;
948 xdesign->AddChild(
node( wxT(
"source" ),
m_schematic->GetFileName() ) );
955 const std::map<wxString, wxString>& properties =
m_schematic->Project().GetTextVars();
957 for(
const std::pair<const wxString, wxString>& prop : properties )
959 xdesign->AddChild( xtextvar =
node( wxT(
"textvar" ), prop.second ) );
966 unsigned sheetIndex = 1;
970 screen = sheet.LastScreen();
972 xdesign->AddChild( xsheet =
node( wxT(
"sheet" ) ) );
975 sheetTxt.Printf( wxT(
"%u" ), sheetIndex++ );
977 xsheet->
AddAttribute( wxT(
"name" ), sheet.PathHumanReadable() );
978 xsheet->
AddAttribute( wxT(
"tstamps" ), sheet.PathAsString() );
983 xsheet->AddChild( xtitleBlock =
node( wxT(
"title_block" ) ) );
991 sourceFileName = wxFileName( screen->
GetFileName() );
992 xtitleBlock->AddChild(
node( wxT(
"source" ), sourceFileName.GetFullName() ) );
994 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
998 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1002 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1006 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1010 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1014 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1018 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1022 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1026 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1037 XNODE* xlibs =
node( wxT(
"libraries" ) );
1048 xlibs->AddChild( xlibrary =
node( wxT(
"library" ) ) );
1049 xlibrary->
AddAttribute( wxT(
"logical" ), libNickname );
1050 xlibrary->AddChild(
node( wxT(
"uri" ), *uri ) );
1060 XNODE* xlibparts =
node( wxT(
"libparts" ) );
1061 std::vector<SCH_FIELD*> fieldList;
1067 wxString libNickname = lcomp->GetLibId().GetLibNickname();;
1070 if( !libNickname.IsEmpty() )
1074 xlibparts->AddChild( xlibpart =
node( wxT(
"libpart" ) ) );
1076 xlibpart->
AddAttribute( wxT(
"part" ), lcomp->GetName() );
1079 if( !lcomp->GetDescription().IsEmpty() )
1080 xlibpart->AddChild(
node( wxT(
"description" ), lcomp->GetDescription() ) );
1082 if( !lcomp->GetDatasheetField().GetText().IsEmpty() )
1083 xlibpart->AddChild(
node( wxT(
"docs" ), lcomp->GetDatasheetField().GetText() ) );
1086 if( lcomp->GetFPFilters().GetCount() )
1089 xlibpart->AddChild( xfootprints =
node( wxT(
"footprints" ) ) );
1091 for(
unsigned i = 0; i < lcomp->GetFPFilters().GetCount(); ++i )
1093 if( !lcomp->GetFPFilters()[i].IsEmpty() )
1094 xfootprints->AddChild(
node( wxT(
"fp" ), lcomp->GetFPFilters()[i] ) );
1100 lcomp->GetFields( fieldList );
1103 xlibpart->AddChild( xfields =
node(
"fields" ) );
1105 for(
const SCH_FIELD* field : fieldList )
1108 xfields->AddChild( xfield =
node( wxT(
"field" ), field->GetText() ) );
1109 xfield->
AddAttribute( wxT(
"name" ), field->GetUntranslatedName() );
1115 std::vector<SCH_PIN*> pinList = lcomp->GetGraphicalPins( 0, 0 );
1127 for(
int ii = 0; ii < (int)pinList.size()-1; ii++ )
1129 if( pinList[ii]->GetNumber() == pinList[ii+1]->GetNumber() )
1131 pinList.erase(pinList.begin() + ii + 1);
1136 wxLogTrace(
"CVPCB_PINCOUNT",
1137 wxString::Format(
"makeLibParts: lib='%s' part='%s' pinList(size)=%zu",
1138 libNickname, lcomp->GetName(), pinList.size() ) );
1140 if( pinList.size() )
1144 xlibpart->AddChild( pins =
node( wxT(
"pins" ) ) );
1146 for(
unsigned i=0; i<pinList.size(); ++i )
1148 SCH_PIN* basePin = pinList[i];
1150 bool stackedValid =
false;
1154 if( stackedValid && !expandedNums.empty() )
1156 for(
const wxString& num : expandedNums )
1159 pins->AddChild(
pin =
node( wxT(
"pin" ) ) );
1160 pin->AddAttribute( wxT(
"num" ), num );
1164 wxLogTrace(
"CVPCB_PINCOUNT",
1165 wxString::Format(
"makeLibParts: -> pin num='%s' name='%s' (expanded)",
1172 pins->AddChild(
pin =
node( wxT(
"pin" ) ) );
1177 wxLogTrace(
"CVPCB_PINCOUNT",
1178 wxString::Format(
"makeLibParts: -> pin num='%s' name='%s'",
1194 wxString netCodeTxt;
1196 XNODE* xnet =
nullptr;
1218 NET_RECORD(
const wxString& aName ) :
1220 m_HasNoConnect(
false )
1225 bool m_HasNoConnect;
1226 std::vector<NET_NODE> m_Nodes;
1229 std::vector<NET_RECORD*> nets;
1231 std::shared_ptr<NET_SETTINGS> netSettings;
1234 netSettings =
m_schematic->Project().GetProjectFile().NetSettings();
1241 nets.emplace_back(
new NET_RECORD( netName ) );
1242 NET_RECORD* net_record = nets.back();
1243 net_record->m_HasNoConnect = net.hasNoConnect;
1247 if(
const auto netclass = netSettings->GetEffectiveNetClass( net.name ) )
1251 for(
const auto& [
pin, sheet] : net.pins )
1260 if( forBOM && ( sheet.GetExcludedFromBOM( currentVariant )
1266 if( forBoard && ( sheet.GetExcludedFromBoard( currentVariant )
1272 net_record->m_Nodes.emplace_back(
pin, sheet );
1277 std::sort( nets.begin(), nets.end(),
1278 [](
const NET_RECORD* a,
const NET_RECORD*b )
1280 return StrNumCmp( a->m_Name, b->m_Name ) < 0;
1283 for(
int i = 0; i < (int) nets.size(); ++i )
1285 NET_RECORD* net_record = nets[i];
1290 std::sort( net_record->m_Nodes.begin(), net_record->m_Nodes.end(),
1293 wxString refA = a.m_Pin->GetParentSymbol()->GetRef( &a.m_Sheet );
1294 wxString refB = b.m_Pin->GetParentSymbol()->GetRef( &b.m_Sheet );
1297 return a.m_Pin->GetShownNumber() < b.m_Pin->GetShownNumber();
1308 wxString refA = a.m_Pin->GetParentSymbol()->GetRef( &a.m_Sheet );
1309 wxString refB = b.m_Pin->GetParentSymbol()->GetRef( &b.m_Sheet );
1311 return refA == refB && a.m_Pin->GetShownNumber() == b.m_Pin->GetShownNumber();
1316 bool allNetPinsStacked =
true;
1318 if( net_record->m_Nodes.size() > 1 )
1320 SCH_PIN* firstPin = net_record->m_Nodes.begin()->m_Pin;
1321 allNetPinsStacked = std::all_of( net_record->m_Nodes.begin() + 1, net_record->m_Nodes.end(),
1324 return firstPin->GetParent() == node.m_Pin->GetParent()
1325 && firstPin->GetPosition() == node.m_Pin->GetPosition()
1326 && firstPin->GetName() == node.m_Pin->GetName();
1330 for(
const NET_NODE& netNode : net_record->m_Nodes )
1332 wxString refText = netNode.m_Pin->GetParentSymbol()->GetRef( &netNode.m_Sheet );
1335 if( refText[0] == wxChar(
'#' ) )
1341 std::vector<wxString> nums =
resolvePadNumbers( netNode.m_Pin, netNode.m_Sheet );
1347 wxString baseName = netNode.m_Pin->GetShownName();
1348 wxString pinType = netNode.m_Pin->GetCanonicalElectricalTypeName();
1352 netCodeTxt.Printf( wxT(
"%d" ), i + 1 );
1354 xnets->AddChild( xnet =
node( wxT(
"net" ) ) );
1356 xnet->
AddAttribute( wxT(
"name" ), net_record->m_Name );
1357 xnet->
AddAttribute( wxT(
"class" ), net_record->m_Class );
1362 for(
const wxString& num : nums )
1364 xnet->AddChild( xnode =
node( wxT(
"node" ) ) );
1368 wxString fullName = baseName.IsEmpty() ? num : baseName + wxT(
"_" ) + num;
1370 if( !baseName.IsEmpty() || nums.size() > 1 )
1373 wxString typeAttr = pinType;
1375 if( net_record->m_HasNoConnect
1376 && ( net_record->m_Nodes.size() == 1 || allNetPinsStacked ) )
1378 typeAttr += wxT(
"+no_connect" );
1386 for( NET_RECORD* record : nets )
1394 const auto& committed =
m_schematic->NetChains().GetCommittedNetChains();
1396 if( committed.empty() )
1399 XNODE* xchains =
node( wxT(
"net_chains" ) );
1401 for(
const std::unique_ptr<SCH_NETCHAIN>&
chain : committed )
1407 xchains->AddChild( xchain =
node( wxT(
"net_chain" ) ) );
1410 if( !
chain->GetNetClass().IsEmpty() )
1419 const std::shared_ptr<NET_SETTINGS>& ns = pf.
NetSettings();
1423 wxString className = ns->GetNetChainClass(
chain->GetName() );
1425 if( !className.IsEmpty() )
1426 xchain->
AddAttribute( wxT(
"net_chain_class" ), className );
1434 wxString::Format( wxT(
"#%02X%02X%02X%02X" ),
1435 (
int) std::clamp(
KiROUND( c.
r * 255.0 ), 0, 255 ),
1436 (
int) std::clamp(
KiROUND( c.
g * 255.0 ), 0, 255 ),
1437 (
int) std::clamp(
KiROUND( c.
b * 255.0 ), 0, 255 ),
1438 (
int) std::clamp(
KiROUND( c.
a * 255.0 ), 0, 255 ) ) );
1442 xchain->AddChild( xmembers =
node( wxT(
"members" ) ) );
1448 for(
const wxString& net :
chain->GetNets() )
1454 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
1458 if( !
chain->GetTerminalRef( 0 ).IsEmpty() || !
chain->GetTerminalRef( 1 ).IsEmpty() )
1461 xchain->AddChild( xterms =
node( wxT(
"terminal_pins" ) ) );
1463 for(
int i = 0; i < 2; ++i )
1465 if(
chain->GetTerminalRef( i ).IsEmpty() )
1469 xterms->AddChild( xterm =
node( wxT(
"terminal_pin" ) ) );
1482 XNODE* n =
new XNODE( wxXML_ELEMENT_NODE, aName );
1484 if( aTextualContent.Len() > 0 )
1485 n->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, aTextualContent ) );
1504 auto getComponentClassFields =
1505 [&](
const std::vector<SCH_FIELD>& fields,
const SCH_SHEET_PATH* sheetPath )
1507 std::unordered_set<wxString> componentClasses;
1511 if( field.GetUntranslatedName() == wxT(
"Component Class" ) )
1518 return componentClasses;
1526 std::unordered_set<wxString> sheetComponentClasses;
1527 const std::unordered_set<SCH_RULE_AREA*>& sheetRuleAreas = sheetItem->
GetRuleAreaCache();
1533 std::unordered_set<wxString> ruleAreaComponentClasses = getComponentClassFields( label->GetFields(),
1535 sheetComponentClasses.insert( ruleAreaComponentClasses.begin(), ruleAreaComponentClasses.end() );
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
wxString GetBuildVersion()
Get the full KiCad version string.
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
A base class for most all the KiCad significant classes used in schematics and boards.
A color representation with 4 components: red, green, blue, alpha.
wxString AsString() const
std::optional< wxString > GetFullURI(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, bool aSubstituted=false)
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
const wxString GetUniStringLibNickname() const
Define a library symbol object.
SCHEMATIC * m_schematic
The schematic we're generating a netlist for.
SCH_SYMBOL * findNextSymbol(EDA_ITEM *aItem, const SCH_SHEET_PATH &aSheetPath)
Check if the given symbol should be processed for netlisting.
std::set< LIB_SYMBOL *, LIB_SYMBOL_LESS_THAN > m_libParts
unique library symbols used. LIB_SYMBOL items are sorted by names
std::vector< wxString > resolvePadNumbers(const SCH_PIN *aPin, const SCH_SHEET_PATH &aSheetPath) const
Resolve aPin to its effective pad number(s) for every netlist path (issue #2282).
UNIQUE_STRINGS m_referencesAlreadyFound
Used for "multiple symbols per package" symbols to avoid processing a lib symbol more than once.
SCH_SHEET_LIST m_exportSheets
std::vector< EXPORT_NET > m_exportNets
void getSheetComponentClasses()
std::map< SCH_SHEET_PATH, std::unordered_set< wxString > > m_sheetComponentClasses
Map of all sheets to component classes covering the whole sheet.
XNODE * makeDesignHeader()
Fill out a project "design" header into an XML node.
XNODE * makeLibraries()
Fill out an XML node with a list of used libraries and returns it.
XNODE * node(const wxString &aName, const wxString &aTextualContent=wxEmptyString)
A convenience function that creates a new XNODE with an optional textual child.
XNODE * makeListOfNets(unsigned aCtl)
Fill out an XML node with a list of nets and returns it.
RESOLUTION_CONTEXT m_resolveTextVars
bool writeNetlist(const wxString &aOutFileName, unsigned aNetlistOptions, REPORTER &aReporter) override
Write generic netlist to aOutFileName.
std::vector< wxString > getComponentClassNamesForAllSymbolUnits(SCH_SYMBOL *aSymbol, const SCH_SHEET_PATH &aSymbolSheet, const SCH_SHEET_LIST &aSheetList)
Finds all component class names attached to any sub-unit of a given symbol.
XNODE * makeSymbols(unsigned aCtl)
void addSymbolFields(XNODE *aNode, SCH_SYMBOL *aSymbol, const SCH_SHEET_PATH &aSheet, const SCH_SHEET_LIST &aSheetList, const wxString &aVariant)
Holder for multi-unit symbol fields.
XNODE * makeRoot(unsigned aCtl=GNL_ALL)
Build the entire document tree for the generic export.
std::set< wxString > m_libraries
XNODE * makeLibParts()
Fill out an XML node with the unique library parts and returns it.
virtual LIBRARY_MANAGER & GetLibraryManager() const
The backing store for a PROJECT, in JSON format.
std::shared_ptr< NET_SETTINGS > & NetSettings()
Container for project specific data.
A pure virtual class used to derive REPORTER objects from.
wxString GetShownText(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, const wxString &aVariantName=wxEmptyString, int aDepth=0) const
A set of SCH_ITEMs (i.e., without duplicates).
Base class for any item which can be embedded within the SCHEMATIC container class,...
bool ResolveExcludedFromPosFiles(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const
const std::unordered_set< SCH_RULE_AREA * > & GetRuleAreaCache() const
Get the cache of rule areas enclosing this item.
bool ResolveExcludedFromBOM(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const
wxString ResolveText(const wxString &aText, const SCH_SHEET_PATH *aPath, int aDepth=0) const
bool ResolveExcludedFromBoard(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const
bool ResolveDNP(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const
bool ResolveExcludedFromSim(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const
static bool IsPersistableNet(const wxString &aNet)
Synthetic keys do not survive a reload, so only named nets are written out.
std::vector< wxString > GetStackedPinNumbers(bool *aValid=nullptr) const
wxString GetCanonicalElectricalTypeName() const
const wxString & GetShownName() const
const wxString & GetShownNumber() const
const wxString & GetFileName() const
TITLE_BLOCK & GetTitleBlock()
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
void GetSheetsWithinPath(std::vector< SCH_SHEET_PATH > &aSheets, const SCH_SHEET_PATH &aSheetPath) const
Add a SCH_SHEET_PATH object to aSheets for each sheet in the list that are contained within aSheetPat...
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Variant information for a schematic symbol.
std::optional< LIB_ID > m_SymbolOverride
Alternate library symbol to substitute for the base symbol in this variant, if any.
bool UseLibIdLookup() const
wxString GetFieldText(const wxString &aFieldName, const SCH_SHEET_PATH *aPath=nullptr, const wxString &aVariantName=wxEmptyString) const
wxString GetSchSymbolLibraryName() const
const wxString GetFootprintFieldText(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, const wxString &aVariantName=wxEmptyString) const
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
wxString GetShownDescription(RESOLUTION_CONTEXT aContext, int aDepth=0) const override
const LIB_ID & GetLibId() const override
LIB_SYMBOL * GetVariantLibSymbol(const wxString &aVariantName, const SCH_SHEET_PATH &aPath) const
Resolve the alternate library symbol for a given variant.
bool GetInstance(SCH_SYMBOL_INSTANCE &aInstance, const KIID_PATH &aSheetPath, bool aTestFromEnd=false) const
const wxString GetValue(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, const wxString &aVariantName=wxEmptyString) const override
int GetUnitSelection(const SCH_SHEET_PATH *aSheet) const
Return the instance-specific unit selection for the given sheet path.
int GetUnitCount() const override
Return the number of units per package of the symbol.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
std::unordered_set< wxString > GetComponentClassNames(const SCH_SHEET_PATH *aPath) const
Return the component classes this symbol belongs in.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
Hold the information shown in the lower right corner of a plot, printout, or editing view.
const wxString & GetCompany() const
const wxString & GetRevision() const
const wxString & GetDate() const
const wxString & GetComment(int aIdx) const
const wxString & GetTitle() const
std::map< wxString, wxString > m_Fields
An extension of wxXmlNode that can format its contents as KiCad-style s-expressions.
void AddAttribute(const wxString &aName, const wxString &aValue) override
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, RESOLUTION_CONTEXT aContext)
void remove_duplicates(_Container &__c)
Deletes all duplicate values from __c.
static bool sortPinsByNumber(SCH_PIN *aPin1, SCH_PIN *aPin2)
PGM_BASE & Pgm()
The global program "get" accessor.
Class to handle a set of SCH_ITEMs.
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
wxString UnescapeString(const wxString &aSource)
wxString GetISO8601CurrentDateTime()
std::vector< wxString > m_pinNumbers
One refdes -> net membership row collected from the NETDEF section.
A simple container for schematic symbol instance information.
std::map< wxString, SCH_SYMBOL_VARIANT > m_Variants
A list of symbol variants.
wxString GetDefaultFieldName(FIELD_T aFieldId, TRANSLATION aTranslation)
Return a default symbol field name for a mandatory field type.
@ DESCRIPTION
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ DATASHEET
name of datasheet
const SHAPE_LINE_CHAIN chain
wxLogTrace helper definitions.