35#include <wx/wfstream.h>
58 wxFFileOutputStream stream( aOutFileName );
66 return xdoc.Save( stream, 2 );
109 xroot->AddChild( xchains );
127 wxString description;
129 nlohmann::ordered_map<wxString, wxString> fields;
140 wxString ref = aSymbol->
GetRef( &aSheet );
150 wxString ref2 = symbol2->
GetRef( &sheet );
152 if( ref2.CmpNoCase( ref ) != 0 )
162 if( !candidate.IsEmpty() && ( unit < minUnit || value.IsEmpty() ) )
168 if( !candidate.IsEmpty() && ( unit < minUnit || footprint.IsEmpty() ) )
169 footprint = candidate;
175 if( !candidate.IsEmpty() && ( unit < minUnit ||
datasheet.IsEmpty() ) )
182 if( !candidate.IsEmpty() && ( unit < minUnit || description.IsEmpty() ) )
183 description = candidate;
188 if( field.IsMandatory() || field.IsPrivate() )
191 if( unit < minUnit || fields.count( field.GetName() ) == 0 )
194 fields[field.GetName()] = field.GetShownText( &aSheet,
false );
196 fields[field.GetName()] = field.GetText();
200 minUnit = std::min( unit, minUnit );
220 description = descriptionField->
GetShownText( &aSheet,
false );
222 description = descriptionField->
GetText();
226 if( field.IsMandatory() || field.IsPrivate() )
230 fields[field.GetName()] = field.GetShownText( &aSheet,
false );
232 fields[field.GetName()] = field.GetText();
244 aNode->AddChild(
node( wxT(
"value" ), wxT(
"~" ) ) );
246 if( footprint.size() )
252 if( description.size() )
256 aNode->AddChild( xfields =
node( wxT(
"fields" ) ) );
258 for(
const auto& [ fieldName, fieldValue ] : fields )
262 xfields->AddChild( xfield );
269 XNODE* xcomps =
node( wxT(
"components" ) );
291 b->GetRef( &sheet,
false ),
true ) < 0 );
294 std::set<
SCH_SYMBOL*,
decltype( cmp )> ordered_symbols( cmp );
295 std::multiset<
SCH_SYMBOL*,
decltype( cmp )> extra_units( cmp );
300 auto test = ordered_symbols.insert( symbol );
304 if( ( *(
test.first ) )->m_Uuid > symbol->
m_Uuid )
306 extra_units.insert( *(
test.first ) );
307 ordered_symbols.erase(
test.first );
308 ordered_symbols.insert( symbol );
312 extra_units.insert( symbol );
317 for(
EDA_ITEM* item : ordered_symbols )
337 xcomps->AddChild( xcomp =
node( wxT(
"comp" ) ) );
343 xcomp->AddChild( xlibsource =
node( wxT(
"libsource" ) ) );
374 std::vector<SCH_FIELD>& fields = symbol->
GetFields();
378 if( field.IsMandatory() || field.IsPrivate() )
381 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
382 xproperty->
AddAttribute( wxT(
"name" ), field.GetCanonicalName() );
385 xproperty->
AddAttribute( wxT(
"value" ), field.GetShownText( &sheet,
false ) );
387 xproperty->
AddAttribute( wxT(
"value" ), field.GetText() );
390 for(
const SCH_FIELD& sheetField : sheet.Last()->GetFields() )
392 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
393 xproperty->
AddAttribute( wxT(
"name" ), sheetField.GetCanonicalName() );
398 xproperty->
AddAttribute( wxT(
"value" ), sheetField.GetShownText( &sheet,
false ) );
400 xproperty->
AddAttribute( wxT(
"value" ), sheetField.GetText() );
405 if( baseExcludedFromBOM )
407 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
408 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"exclude_from_bom" ) );
413 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
414 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"exclude_from_board" ) );
419 if( baseExcludedFromPosFiles )
421 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
422 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"exclude_from_pos_files" ) );
425 const bool baseDnp = symbol->
ResolveDNP( &sheet ) || sheet.GetDNP();
429 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
435 const std::set<wxString>& variantNames =
m_schematic->GetVariantNames();
437 if( !variantNames.empty() )
440 XNODE* xvariants =
nullptr;
442 for(
const auto& variantName : variantNames )
444 XNODE* xvariant =
nullptr;
446 auto addToVariant = [
this, &xvariant, &variantName](
XNODE* child ) ->
void
453 xvariant =
node( wxT(
"variant" ) );
456 xvariant->AddChild( child );
459 auto addBinaryProp = [
this, &addToVariant]( wxString
const&
name,
bool base,
460 bool effective ) ->
void
462 if( base == effective )
465 XNODE* xvarprop =
node( wxT(
"property" ) );
467 xvarprop->
AddAttribute( wxT(
"value" ), effective ? wxT(
"1" ) : wxT(
"0" ) );
468 addToVariant( xvarprop );
471 bool effectiveDnp = symbol->
ResolveDNP( &sheet, variantName ) || sheet.GetDNP( variantName );
472 addBinaryProp( wxT(
"dnp" ), baseDnp, effectiveDnp );
475 || sheet.GetExcludedFromBOM( variantName );
476 addBinaryProp( wxT(
"exclude_from_bom" ), baseExcludedFromBOM, effectiveExcludedFromBOM );
479 || sheet.GetExcludedFromSim( variantName );
480 addBinaryProp( wxT(
"exclude_from_sim" ), baseExcludedFromSim, effectiveExcludedFromSim );
483 addBinaryProp( wxT(
"exclude_from_pos_files" ), baseExcludedFromPosFiles,
484 effectiveExcludedFromPosFiles );
490 variant = &instance.
m_Variants.at( variantName );
494 XNODE* xprop =
node( wxT(
"property" ) );
495 xprop->
AddAttribute( wxT(
"name" ), wxT(
"symbol_override" ) );
497 addToVariant( xprop );
502 XNODE* xfields =
nullptr;
504 for(
const auto& [fieldName, fieldValue] : variant->
m_Fields )
506 const wxString baseValue =
507 symbol->
GetFieldText( fieldName, &sheet, wxEmptyString );
509 if( fieldValue == baseValue )
513 xfields =
node( wxT(
"fields" ) );
515 wxString resolvedValue = fieldValue;
518 resolvedValue = symbol->
ResolveText( fieldValue, &sheet );
522 xfields->AddChild( xfield );
532 const wxString& fieldName = baseField.GetName();
534 if( variant->
m_Fields.contains( fieldName ) )
537 const wxString baseValue =
538 symbol->
GetFieldText( fieldName, &sheet, wxEmptyString );
539 const wxString variantValue =
542 if( variantValue == baseValue )
546 xfields =
node( wxT(
"fields" ) );
548 wxString resolvedValue = variantValue;
551 resolvedValue = symbol->
ResolveText( variantValue, &sheet );
557 xfields->AddChild( xfield );
564 std::vector<SCH_FIELD*> altFields;
565 altSymbol->GetFields( altFields );
567 for(
const SCH_FIELD* altField : altFields )
569 const wxString& fieldName = altField->GetName();
572 || variant->
m_Fields.contains( fieldName )
573 || altField->GetText().IsEmpty() )
579 xfields =
node( wxT(
"fields" ) );
581 wxString resolvedValue = altField->GetText();
584 resolvedValue = symbol->
ResolveText( resolvedValue, &sheet );
589 xfields->AddChild( xfield );
594 addToVariant( xfields );
600 xvariants =
node( wxT(
"variants" ) );
602 xvariants->AddChild( xvariant );
607 xcomp->AddChild( xvariants );
610 if(
const std::unique_ptr<LIB_SYMBOL>& part = symbol->
GetLibSymbolRef() )
612 if( part->GetKeyWords().size() )
614 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
615 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"ki_keywords" ) );
616 xproperty->
AddAttribute( wxT(
"value" ), part->GetKeyWords() );
619 if( !part->GetFPFilters().IsEmpty() )
623 for(
const wxString&
filter : part->GetFPFilters() )
626 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
627 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"ki_fp_filters" ) );
628 xproperty->
AddAttribute( wxT(
"value" ), filters.Trim(
false ) );
631 if( part->GetDuplicatePinNumbersAreJumpers() )
632 xcomp->AddChild(
node( wxT(
"duplicate_pin_numbers_are_jumpers" ), wxT(
"1" ) ) );
634 const std::vector<std::set<wxString>>& jumperGroups = part->JumperPinGroups();
636 if( !jumperGroups.empty() )
639 xcomp->AddChild( xproperty =
node( wxT(
"jumper_pin_groups" ) ) );
641 for(
const std::set<wxString>&
group : jumperGroups )
643 xproperty->AddChild( groupNode =
node( wxT(
"group" ) ) );
645 for(
const wxString& pinName :
group )
646 groupNode->AddChild(
node( wxT(
"pin" ), pinName ) );
652 xcomp->AddChild( xsheetpath =
node( wxT(
"sheetpath" ) ) );
654 xsheetpath->
AddAttribute( wxT(
"names" ), sheet.PathHumanReadable() );
655 xsheetpath->
AddAttribute( wxT(
"tstamps" ), sheet.PathAsString() );
658 std::vector<wxString> compClassNames =
661 if( compClassNames.size() > 0 )
663 XNODE* xcompclasslist;
664 xcomp->AddChild( xcompclasslist =
node( wxT(
"component_classes" ) ) );
666 for(
const wxString& compClass : compClassNames )
673 xcomp->AddChild( xunits =
node( wxT(
"tstamps" ) ) );
675 auto range = extra_units.equal_range( symbol );
679 for(
auto it = range.first; it != range.second; ++it )
681 uuid = ( *it )->m_Uuid.AsString();
688 xunits->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, uuid ) );
693 xunits->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, uuid ) );
697 xcomp->AddChild( xunitInfo =
node( wxT(
"units" ) ) );
712 const std::vector<LIB_SYMBOL::UNIT_PIN_INFO>& defaultUnitInfo = libSym->GetUnitPinInfo();
713 std::map<int, SCH_SYMBOL*> symbolByUnit;
721 int unit = aUnitSymbol->GetUnitSelection( &sheet );
724 symbolByUnit.try_emplace( unit, aUnitSymbol );
727 addUnitSymbol( symbol );
729 auto extraUnitRange = extra_units.equal_range( symbol );
733 for(
auto it = extraUnitRange.first; it != extraUnitRange.second; ++it )
734 addUnitSymbol( *it );
738 for(
size_t unitIdx = 0; unitIdx < defaultUnitInfo.size(); ++unitIdx )
741 auto symbolIt = symbolByUnit.find( unitIdx + 1 );
743 if( symbolIt != symbolByUnit.end() )
745 const std::unique_ptr<LIB_SYMBOL>& unitLibSym = symbolIt->second->GetLibSymbolRef();
749 const std::vector<LIB_SYMBOL::UNIT_PIN_INFO>& unitSpecificInfo =
750 unitLibSym->GetUnitPinInfo();
752 if( unitIdx < unitSpecificInfo.size() )
753 unitInfo = unitSpecificInfo[unitIdx];
758 xunitInfo->AddChild( xunit =
node( wxT(
"unit" ) ) );
762 xunit->AddChild( xpins =
node( wxT(
"pins" ) ) );
767 xpins->AddChild( xpin =
node( wxT(
"pin" ) ) );
791 std::map<SCH_SCREEN*, int> screenVisits;
794 screenVisits[sheet.LastScreen()]++;
802 wxString instancePrefix = sheet.PathAsString();
807 wxString groupName =
group->GetName();
809 if( screenVisits[sheet.LastScreen()] > 1 )
810 groupName = wxString::Format( wxT(
"%s (%s)" ), groupName, sheet.PathHumanReadable() );
813 xcomps->AddChild( xgroup =
node( wxT(
"group" ) ) );
816 xgroup->
AddAttribute( wxT(
"uuid" ), instancePrefix +
group->m_Uuid.AsString() );
820 xgroup->AddChild( xmembers =
node( wxT(
"members" ) ) );
827 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
828 xmember->
AddAttribute( wxT(
"uuid" ), instancePrefix + member->m_Uuid.AsString() );
834 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
835 xmember->
AddAttribute( wxT(
"uuid" ), instancePrefix + member->m_Uuid.AsString() );
840 std::vector<SCH_SHEET_PATH> descendantSheets;
850 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
852 descendantSheet.PathAsString() + descendantItem->m_Uuid.AsString() );
868 XNODE* xvariants =
node( wxT(
"variants" ) );
870 std::set<wxString> variantNames =
m_schematic->GetVariantNames();
872 for(
const wxString& variantName : variantNames )
875 xvariants->AddChild( xvariant =
node( wxT(
"variant" ) ) );
878 wxString description =
m_schematic->GetVariantDescription( variantName );
880 if( !description.IsEmpty() )
881 xvariant->
AddAttribute( wxT(
"description" ), description );
891 std::vector<SCH_SHEET_PATH> symbolSheets;
892 symbolSheets.push_back( aSymbolSheet );
899 const wxString ref = aSymbol->
GetRef( &aSymbolSheet );
907 wxString ref2 = symbol2->
GetRef( &sheet );
910 if( ref2.CmpNoCase( ref ) != 0 )
913 if( otherUnit == primaryUnit )
916 symbolSheets.push_back( sheet );
918 std::unordered_set<wxString> otherClassNames =
920 compClassNames.insert( otherClassNames.begin(), otherClassNames.end() );
930 if( symbolSheetPath.IsContainedWithin( sheetPath ) )
932 compClassNames.insert( sheetCompClasses.begin(), sheetCompClasses.end() );
937 std::vector<wxString> sortedCompClassNames( compClassNames.begin(), compClassNames.end() );
938 std::sort( sortedCompClassNames.begin(), sortedCompClassNames.end(),
939 [](
const wxString& str1,
const wxString& str2 )
941 return str1.Cmp( str2 ) < 0;
944 return sortedCompClassNames;
951 XNODE* xdesign =
node( wxT(
"design" ) );
957 wxFileName sourceFileName;
960 xdesign->AddChild(
node( wxT(
"source" ),
m_schematic->GetFileName() ) );
967 const std::map<wxString, wxString>& properties =
m_schematic->Project().GetTextVars();
969 for(
const std::pair<const wxString, wxString>& prop : properties )
971 xdesign->AddChild( xtextvar =
node( wxT(
"textvar" ), prop.second ) );
978 unsigned sheetIndex = 1;
982 screen = sheet.LastScreen();
984 xdesign->AddChild( xsheet =
node( wxT(
"sheet" ) ) );
987 sheetTxt.Printf( wxT(
"%u" ), sheetIndex++ );
989 xsheet->
AddAttribute( wxT(
"name" ), sheet.PathHumanReadable() );
990 xsheet->
AddAttribute( wxT(
"tstamps" ), sheet.PathAsString() );
995 xsheet->AddChild( xtitleBlock =
node( wxT(
"title_block" ) ) );
1003 sourceFileName = wxFileName( screen->
GetFileName() );
1004 xtitleBlock->AddChild(
node( wxT(
"source" ), sourceFileName.GetFullName() ) );
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" ) ) );
1030 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1034 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1038 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1049 XNODE* xlibs =
node( wxT(
"libraries" ) );
1054 wxString libNickname = *it;
1061 xlibs->AddChild( xlibrary =
node( wxT(
"library" ) ) );
1062 xlibrary->
AddAttribute( wxT(
"logical" ), libNickname );
1063 xlibrary->AddChild(
node( wxT(
"uri" ), *uri ) );
1075 XNODE* xlibparts =
node( wxT(
"libparts" ) );
1076 std::vector<SCH_FIELD*> fieldList;
1082 wxString libNickname = lcomp->GetLibId().GetLibNickname();;
1085 if( !libNickname.IsEmpty() )
1089 xlibparts->AddChild( xlibpart =
node( wxT(
"libpart" ) ) );
1091 xlibpart->
AddAttribute( wxT(
"part" ), lcomp->GetName() );
1094 if( !lcomp->GetDescription().IsEmpty() )
1095 xlibpart->AddChild(
node( wxT(
"description" ), lcomp->GetDescription() ) );
1097 if( !lcomp->GetDatasheetField().GetText().IsEmpty() )
1098 xlibpart->AddChild(
node( wxT(
"docs" ), lcomp->GetDatasheetField().GetText() ) );
1101 if( lcomp->GetFPFilters().GetCount() )
1104 xlibpart->AddChild( xfootprints =
node( wxT(
"footprints" ) ) );
1106 for(
unsigned i = 0; i < lcomp->GetFPFilters().GetCount(); ++i )
1108 if( !lcomp->GetFPFilters()[i].IsEmpty() )
1109 xfootprints->AddChild(
node( wxT(
"fp" ), lcomp->GetFPFilters()[i] ) );
1115 lcomp->GetFields( fieldList );
1118 xlibpart->AddChild( xfields =
node(
"fields" ) );
1120 for(
const SCH_FIELD* field : fieldList )
1123 xfields->AddChild( xfield =
node( wxT(
"field" ), field->GetText() ) );
1124 xfield->
AddAttribute( wxT(
"name" ), field->GetCanonicalName() );
1130 std::vector<SCH_PIN*> pinList = lcomp->GetGraphicalPins( 0, 0 );
1142 for(
int ii = 0; ii < (int)pinList.size()-1; ii++ )
1144 if( pinList[ii]->GetNumber() == pinList[ii+1]->GetNumber() )
1146 pinList.erase(pinList.begin() + ii + 1);
1151 wxLogTrace(
"CVPCB_PINCOUNT",
1152 wxString::Format(
"makeLibParts: lib='%s' part='%s' pinList(size)=%zu",
1153 libNickname, lcomp->GetName(), pinList.size() ) );
1155 if( pinList.size() )
1159 xlibpart->AddChild( pins =
node( wxT(
"pins" ) ) );
1161 for(
unsigned i=0; i<pinList.size(); ++i )
1163 SCH_PIN* basePin = pinList[i];
1165 bool stackedValid =
false;
1169 if( stackedValid && !expandedNums.empty() )
1171 for(
const wxString& num : expandedNums )
1174 pins->AddChild(
pin =
node( wxT(
"pin" ) ) );
1175 pin->AddAttribute( wxT(
"num" ), num );
1179 wxLogTrace(
"CVPCB_PINCOUNT",
1180 wxString::Format(
"makeLibParts: -> pin num='%s' name='%s' (expanded)",
1187 pins->AddChild(
pin =
node( wxT(
"pin" ) ) );
1192 wxLogTrace(
"CVPCB_PINCOUNT",
1193 wxString::Format(
"makeLibParts: -> pin num='%s' name='%s'",
1209 wxString netCodeTxt;
1211 XNODE* xnet =
nullptr;
1233 NET_RECORD(
const wxString& aName ) :
1235 m_HasNoConnect(
false )
1240 bool m_HasNoConnect;
1241 std::vector<NET_NODE> m_Nodes;
1244 std::vector<NET_RECORD*> nets;
1246 std::shared_ptr<NET_SETTINGS> netSettings;
1249 netSettings =
m_schematic->Project().GetProjectFile().NetSettings();
1251 for(
const auto& [ key, subgraphs ] :
m_schematic->ConnectionGraph()->GetNetMap() )
1253 wxString net_name = key.Name;
1254 NET_RECORD* net_record =
nullptr;
1259 if( subgraphs.empty() )
1262 nets.emplace_back(
new NET_RECORD( net_name ) );
1263 net_record = nets.back();
1272 std::shared_ptr<NETCLASS> nc = netSettings->GetEffectiveNetClass( key.Name );
1280 bool nc = subgraph->GetNoConnect() && subgraph->GetNoConnect()->Type() ==
SCH_NO_CONNECT_T;
1284 net_record->m_HasNoConnect =
true;
1286 for(
SCH_ITEM* item : subgraph->GetItems() )
1304 net_record->m_Nodes.emplace_back(
pin, sheet );
1311 std::sort( nets.begin(), nets.end(),
1312 [](
const NET_RECORD* a,
const NET_RECORD*b )
1314 return StrNumCmp( a->m_Name, b->m_Name ) < 0;
1317 for(
int i = 0; i < (int) nets.size(); ++i )
1319 NET_RECORD* net_record = nets[i];
1324 std::sort( net_record->m_Nodes.begin(), net_record->m_Nodes.end(),
1327 wxString refA = a.m_Pin->GetParentSymbol()->GetRef( &a.m_Sheet );
1328 wxString refB = b.m_Pin->GetParentSymbol()->GetRef( &b.m_Sheet );
1331 return a.m_Pin->GetShownNumber() < b.m_Pin->GetShownNumber();
1342 wxString refA = a.m_Pin->GetParentSymbol()->GetRef( &a.m_Sheet );
1343 wxString refB = b.m_Pin->GetParentSymbol()->GetRef( &b.m_Sheet );
1345 return refA == refB && a.m_Pin->GetShownNumber() == b.m_Pin->GetShownNumber();
1350 bool allNetPinsStacked =
true;
1352 if( net_record->m_Nodes.size() > 1 )
1354 SCH_PIN* firstPin = net_record->m_Nodes.begin()->m_Pin;
1356 std::all_of( net_record->m_Nodes.begin() + 1, net_record->m_Nodes.end(),
1359 return firstPin->GetParent() == node.m_Pin->GetParent()
1360 && firstPin->GetPosition() == node.m_Pin->GetPosition()
1361 && firstPin->GetName() == node.m_Pin->GetName();
1365 for(
const NET_NODE& netNode : net_record->m_Nodes )
1367 wxString refText = netNode.m_Pin->GetParentSymbol()->GetRef( &netNode.m_Sheet );
1370 if( refText[0] == wxChar(
'#' ) )
1376 std::vector<wxString> nums =
resolvePadNumbers( netNode.m_Pin, netNode.m_Sheet );
1382 wxString baseName = netNode.m_Pin->GetShownName();
1383 wxString pinType = netNode.m_Pin->GetCanonicalElectricalTypeName();
1387 netCodeTxt.Printf( wxT(
"%d" ), i + 1 );
1389 xnets->AddChild( xnet =
node( wxT(
"net" ) ) );
1391 xnet->
AddAttribute( wxT(
"name" ), net_record->m_Name );
1392 xnet->
AddAttribute( wxT(
"class" ), net_record->m_Class );
1397 for(
const wxString& num : nums )
1399 xnet->AddChild( xnode =
node( wxT(
"node" ) ) );
1403 wxString fullName = baseName.IsEmpty() ? num : baseName + wxT(
"_" ) + num;
1405 if( !baseName.IsEmpty() || nums.size() > 1 )
1408 wxString typeAttr = pinType;
1410 if( net_record->m_HasNoConnect
1411 && ( net_record->m_Nodes.size() == 1 || allNetPinsStacked ) )
1413 typeAttr += wxT(
"+no_connect" );
1421 for( NET_RECORD* record : nets )
1429 const auto& committed =
m_schematic->ConnectionGraph()->GetCommittedNetChains();
1431 if( committed.empty() )
1434 XNODE* xchains =
node( wxT(
"net_chains" ) );
1436 for(
const std::unique_ptr<SCH_NETCHAIN>&
chain : committed )
1442 xchains->AddChild( xchain =
node( wxT(
"net_chain" ) ) );
1445 if( !
chain->GetNetClass().IsEmpty() )
1454 const std::shared_ptr<NET_SETTINGS>& ns = pf.
NetSettings();
1458 wxString className = ns->GetNetChainClass(
chain->GetName() );
1460 if( !className.IsEmpty() )
1461 xchain->
AddAttribute( wxT(
"net_chain_class" ), className );
1469 wxString::Format( wxT(
"#%02X%02X%02X%02X" ),
1470 (
int) std::clamp(
KiROUND( c.
r * 255.0 ), 0, 255 ),
1471 (
int) std::clamp(
KiROUND( c.
g * 255.0 ), 0, 255 ),
1472 (
int) std::clamp(
KiROUND( c.
b * 255.0 ), 0, 255 ),
1473 (
int) std::clamp(
KiROUND( c.
a * 255.0 ), 0, 255 ) ) );
1477 xchain->AddChild( xmembers =
node( wxT(
"members" ) ) );
1483 for(
const wxString& net :
chain->GetNets() )
1489 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
1493 if( !
chain->GetTerminalRef( 0 ).IsEmpty() || !
chain->GetTerminalRef( 1 ).IsEmpty() )
1496 xchain->AddChild( xterms =
node( wxT(
"terminal_pins" ) ) );
1498 for(
int i = 0; i < 2; ++i )
1500 if(
chain->GetTerminalRef( i ).IsEmpty() )
1504 xterms->AddChild( xterm =
node( wxT(
"terminal_pin" ) ) );
1516 const wxString& aTextualContent )
1518 XNODE* n =
new XNODE( wxXML_ELEMENT_NODE, aName );
1520 if( aTextualContent.Len() > 0 )
1521 n->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, aTextualContent ) );
1538 auto getComponentClassFields = [&](
const std::vector<SCH_FIELD>& fields,
const SCH_SHEET_PATH* sheetPath )
1540 std::unordered_set<wxString> componentClasses;
1544 if( field.GetCanonicalName() == wxT(
"Component Class" ) )
1546 if( field.GetShownText( sheetPath,
false ) != wxEmptyString )
1547 componentClasses.insert( field.GetShownText( sheetPath,
false ) );
1551 return componentClasses;
1559 std::unordered_set<wxString> sheetComponentClasses;
1560 const std::unordered_set<SCH_RULE_AREA*>& sheetRuleAreas = sheetItem->
GetRuleAreaCache();
1566 std::unordered_set<wxString> ruleAreaComponentClasses =
1567 getComponentClassFields( label->GetFields(), &sheet );
1568 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 subgraph is a set of items that are electrically connected on a single sheet.
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.
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.
bool WriteNetlist(const wxString &aOutFileName, unsigned aNetlistOptions, REPORTER &aReporter) override
Write generic netlist to aOutFileName.
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.
void addSymbolFields(XNODE *aNode, SCH_SYMBOL *aSymbol, const SCH_SHEET_PATH &aSheet, const SCH_SHEET_LIST &aSheetList)
Holder for multi-unit symbol fields.
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)
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.
virtual const wxString & GetText() const override
Return the string associated with the text object.
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0, const wxString &aVariantName=wxEmptyString) 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 constexpr char SYNTHETIC_NET_PREFIX[]
Prefix used when synthesising net names for unnamed subgraphs.
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...
bool GetExcludedFromBOM() const
const SCH_SHEET * GetSheet(unsigned aIndex) const
bool GetExcludedFromBoard() const
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.
wxString GetDescription() const override
bool UseLibIdLookup() const
wxString GetFieldText(const wxString &aFieldName, const SCH_SHEET_PATH *aPath=nullptr, const wxString &aVariantName=wxEmptyString) const
wxString GetSchSymbolLibraryName() const
const wxString GetValue(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText, const wxString &aVariantName=wxEmptyString) const override
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
const wxString GetFootprintFieldText(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText, const wxString &aVariantName=wxEmptyString) const
wxString GetShownDescription(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
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, int aFlags)
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.
@ 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
wxString GetCanonicalFieldName(FIELD_T aFieldType)
const SHAPE_LINE_CHAIN chain
wxLogTrace helper definitions.