23#include <boost/property_tree/ptree.hpp>
49#include <fmt/ranges.h>
54 const std::map<wxString, wxString>& aNetByPin )
56 std::vector<wxString> nets;
60 for(
const wxString& pinNum : aPins )
62 auto it = aNetByPin.find( pinNum );
63 nets.push_back( it != aNetByPin.end() ? it->second : wxString() );
68 for(
const std::pair<const wxString, wxString>&
kv : aNetByPin )
69 nets.push_back(
kv.second );
78 const wxString& aVariantName,
const std::map<wxString, wxString>& aPcbNetsByPad,
79 std::map<wxString, wxString>& aPcbNetsByLogicalPin )
84 bool logicalPinsValid =
false;
85 const std::vector<wxString> logicalPins =
pin->GetStackedPinNumbers( &logicalPinsValid );
87 if( !logicalPinsValid || logicalPins.empty() )
91 bool padsValid =
false;
92 const std::vector<wxString> pads =
95 if( !padsValid || pads.empty() )
99 std::set<wxString> pcbNets;
101 for(
const wxString&
pad : pads )
103 auto it = aPcbNetsByPad.find(
pad );
104 pcbNets.insert( it != aPcbNetsByPad.end() ? it->second : wxString() );
109 if( pcbNets.size() != 1 )
112 const wxString& pcbNet = *pcbNets.begin();
114 for(
const wxString& pinNum : logicalPins )
116 auto [it, inserted] = aPcbNetsByLogicalPin.emplace( pinNum, pcbNet );
120 if( !inserted && it->second != pcbNet )
130 const std::vector<BACKANNOTATE_UNIT_SWAP_CANDIDATE>& aCandidates,
131 const std::map<wxString, wxString>& aPcbPinMap )
135 if( aCandidates.size() < 2 )
137 plan.m_mappingOk =
true;
141 std::map<size_t, size_t> desiredTarget;
142 std::set<size_t> usedTargets;
144 for(
size_t candidateIdx = 0; candidateIdx < aCandidates.size(); ++candidateIdx )
147 std::map<wxString, wxString> pcbNetsByPin;
151 auto it = aPcbPinMap.find( pinNum );
152 pcbNetsByPin[pinNum] = ( it != aPcbPinMap.end() ) ? it->second : wxString();
156 bool matched =
false;
158 for(
size_t matchIdx = 0; matchIdx < aCandidates.size(); ++matchIdx )
160 if( usedTargets.count( matchIdx ) )
164 std::vector<wxString> schNets =
167 if( pcbNets == schNets )
169 desiredTarget[candidateIdx] = matchIdx;
170 usedTargets.insert( matchIdx );
180 plan.m_mappingOk =
true;
181 plan.m_identity =
true;
183 for(
size_t candidateIdx = 0; candidateIdx < aCandidates.size(); ++candidateIdx )
185 auto it = desiredTarget.find( candidateIdx );
187 if( it == desiredTarget.end() || it->second != candidateIdx )
189 plan.m_identity =
false;
194 if(
plan.m_identity )
197 std::set<size_t> visited;
199 for(
size_t startIdx = 0; startIdx < aCandidates.size(); ++startIdx )
201 if( visited.count( startIdx ) )
204 std::vector<size_t> cycle;
205 size_t curIdx = startIdx;
207 while( !visited.count( curIdx ) )
209 visited.insert( curIdx );
210 cycle.push_back( curIdx );
212 auto nextIt = desiredTarget.find( curIdx );
214 if( nextIt == desiredTarget.end() || nextIt->second == curIdx )
217 curIdx = nextIt->second;
220 if( cycle.size() < 2 )
223 for(
size_t i = cycle.size() - 1; i > 0; --i )
225 size_t firstIdx = cycle[i - 1];
226 size_t secondIdx = cycle[i];
228 plan.m_steps.push_back( { firstIdx, secondIdx,
229 aCandidates[firstIdx].m_currentUnit,
230 aCandidates[secondIdx].m_currentUnit } );
231 plan.m_swappedCandidateIndices.insert( firstIdx );
232 plan.m_swappedCandidateIndices.insert( secondIdx );
241 bool aProcessFootprints,
bool aProcessValues,
bool aProcessReferences,
242 bool aProcessNetNames,
bool aProcessAttributes,
bool aProcessOtherFields,
243 bool aPreferUnitSwaps,
bool aPreferPinSwaps,
bool aDryRun ) :
290 "stand-alone mode.\n"
291 "You must launch the KiCad project manager and create a project." ) );
299 wxFileName fn(
m_frame->Prj().GetProjectFullName() );
300 fn.SetExt( FILEEXT::PcbFileExtension );
313 std::string nullPayload;
321 auto getStr = [](
const PTREE& pt ) -> wxString
323 return UTF8( pt.front().first );
333 Scan( &doc, &lexer );
335 PTREE& tree = doc.get_child(
"pcb_netlist" );
339 for(
const std::pair<const std::string, PTREE>& item : tree )
341 wxString
path, value, footprint;
342 bool dnp =
false, exBOM =
false, exSim =
false, exPosFiles =
false;
343 std::map<wxString, wxString> pinNetMap, fieldsMap;
344 wxASSERT( item.first ==
"ref" );
345 wxString ref = getStr( item.second );
352 path = getStr( item.second.get_child(
"timestamp" ) );
356 msg.Printf(
_(
"Footprint '%s' has no assigned symbol." ),
DescribeRef( ref ) );
361 footprint = getStr( item.second.get_child(
"fpid" ) );
362 value = getStr( item.second.get_child(
"value" ) );
365 boost::optional<const PTREE&> fields = item.second.get_child_optional(
"fields" );
370 for(
const std::pair<const std::string, PTREE>& field : fields.get() )
372 if( field.first !=
"field" )
376 const auto& fieldName = field.second.get_child_optional(
"name" );
377 const std::string& fieldValue = field.second.back().first;
382 fieldsMap[getStr( fieldName.get() )] = wxString::FromUTF8( fieldValue );
388 for(
const auto& child : item.second )
390 if( child.first !=
"property" )
393 auto property = child.second;
394 auto name =
property.get_child_optional(
"name" );
399 if(
name.get().front().first ==
"dnp" )
401 else if(
name.get().front().first ==
"exclude_from_bom" )
403 else if(
name.get().front().first ==
"exclude_from_sim" )
405 else if(
name.get().front().first ==
"exclude_from_pos_files" )
409 boost::optional<const PTREE&> nets = item.second.get_child_optional(
"nets" );
413 for(
const std::pair<const std::string, PTREE>& pin_net : nets.get() )
415 wxASSERT( pin_net.first ==
"pin_net" );
416 wxString pinNumber =
UTF8( pin_net.second.front().first );
417 wxString netName =
UTF8( pin_net.second.back().first );
418 pinNetMap[ pinNumber ] = netName;
424 wxLogWarning(
"Cannot parse PCB netlist for back-annotation." );
433 msg.Printf(
_(
"Footprints '%s' and '%s' linked to same symbol." ),
441 std::shared_ptr<PCB_FP_DATA> data = std::make_shared<PCB_FP_DATA>(
442 ref, footprint, value, dnp, exBOM, exSim, exPosFiles, pinNetMap, fieldsMap );
454 bool foundInMultiunit =
false;
459 refIndex = refList.FindRef( pcbPath );
461 refIndex = refList.FindRefByFullPath( pcbPath );
467 foundInMultiunit =
true;
469 for(
size_t i = 0; i < refList.GetCount(); ++i )
471 refList[ i ].GetSymbol()->ClearFlags(
SKIP_STRUCT );
479 if( foundInMultiunit )
483 refIndex =
m_refs.FindRef( pcbPath );
485 refIndex =
m_refs.FindRefByFullPath( pcbPath );
495 m_reporter.ReportTail( wxString::Format(
_(
"Cannot find symbol for footprint '%s'." ),
509 return SCH_REFERENCE_LIST::sortByTimeStamp( a.first, b.first );
518 while( i <
m_refs.GetCount() &&
m_refs[i].GetPath() != item.first.GetPath() )
524 m_reporter.ReportTail( wxString::Format(
_(
"Footprint '%s' is not present on PCB. "
525 "Corresponding symbols in schematic must be "
526 "manually deleted (if desired)." ),
538 "annotated schematic." ) ) )
551 std::optional<SCH_CONNECTIVITY::PUBLICATION_HOLD> hold( std::in_place,
m_frame->Schematic().Connectivity() );
553 std::set<CHANGELIST_ITEM*> unitSwapItems;
560 const wxString variantName =
m_frame->Schematic().GetCurrentVariant();
564 std::map<std::shared_ptr<PCB_FP_DATA>, std::vector<CHANGELIST_ITEM*>> changesPerFp;
566 msg.Printf( wxT(
"DEBUG(unit-swap): grouped changelist into %zu footprint(s) for unit-swap processing:" ),
567 changesPerFp.size() );
574 changesPerFp[item.second].push_back( &item );
575 msg += wxT(
" " ) + item.first.GetRef();
581 for(
auto& fpChangelistPair : changesPerFp )
583 std::set<SCH_SYMBOL*> swappedSymbols;
584 std::set<CHANGELIST_ITEM*> swappedItems;
585 std::shared_ptr<PCB_FP_DATA> fp = fpChangelistPair.first;
586 auto& changedFpItems = fpChangelistPair.second;
599 std::map<wxString, wxString> schNetsByPin;
600 std::map<wxString, wxString> pcbNetsByPin;
601 std::vector<wxString> unitPinNumbers;
602 std::vector<wxString> schNetsInUnitOrder;
603 std::vector<wxString> pcbNetsInUnitOrder;
607 std::vector<SYM_UNIT> symbolUnits;
608 std::map<wxString, wxString> pcbNetsByLogicalPin;
609 bool mappingValid =
true;
611 std::map<LIB_SYMBOL*, std::vector<LIB_SYMBOL::UNIT_PIN_INFO>> unitPinsByLibSymbol;
614 [&](
SCH_SYMBOL* symbol,
int unitNumber ) -> std::vector<wxString>
616 if( unitNumber <= 0 )
627 auto found = unitPinsByLibSymbol.find( libSymbol );
629 if( found == unitPinsByLibSymbol.end() )
630 found = unitPinsByLibSymbol.emplace( libSymbol, libSymbol->
GetUnitPinInfo() ).first;
632 const std::vector<LIB_SYMBOL::UNIT_PIN_INFO>& unitInfos = found->second;
634 if( unitNumber >
static_cast<int>( unitInfos.size() ) )
637 return unitInfos[unitNumber - 1].m_pinNumbers;
652 symbolUnit.sym = symbol;
653 symbolUnit.screen = screen;
656 symbolUnit.changeItem = changedItem;
658 int currentUnit = ref.
GetUnit();
660 if( currentUnit <= 0 )
663 if( currentUnit <= 0 )
664 currentUnit = symbol->
GetUnit();
666 symbolUnit.currentUnit = currentUnit;
667 symbolUnit.unitPinNumbers = getUnitPins( symbol, symbolUnit.currentUnit );
673 mappingValid =
false;
679 const wxString schNet =
pin->GetConnectionName( &sheetPath,
false,
true ).value_or( wxString() );
681 for(
const wxString& pinNum :
pin->GetStackedPinNumbers() )
683 symbolUnit.pcbNetsByPin[pinNum] = pcbNetsByLogicalPin.at( pinNum );
684 symbolUnit.schNetsByPin[pinNum] = schNet;
688 symbolUnit.pcbNetsInUnitOrder =
netsInUnitOrder( symbolUnit.unitPinNumbers, symbolUnit.pcbNetsByPin );
689 symbolUnit.schNetsInUnitOrder =
netsInUnitOrder( symbolUnit.unitPinNumbers, symbolUnit.schNetsByPin );
691 symbolUnits.push_back( symbolUnit );
694 auto vectorToString =
695 [](
const std::vector<wxString>& values ) -> wxString
697 return fmt::format(
L"{}", fmt::join( values,
L", " ) );
701 [vectorToString](
const std::map<wxString, wxString>& pinMap ) -> wxString
703 std::vector<wxString> entries;
705 for(
const std::pair<const wxString, wxString>&
pin : pinMap )
706 entries.push_back(
pin.first +
'=' +
pin.second );
708 return vectorToString( entries );
711 msg.Printf( wxT(
"DEBUG(unit-swap): footprint %s processed (%zu units, dryRun=%d)." ), fp->m_ref,
712 symbolUnits.size(),
m_dryRun ? 1 : 0 );
716 std::sort( symbolUnits.begin(), symbolUnits.end(),
717 [](
const SYM_UNIT& a,
const SYM_UNIT& b )
719 return a.ref < b.ref;
722 for(
const SYM_UNIT& su : symbolUnits )
724 wxString pcbPins = mapToString( su.pcbNetsByPin );
725 wxString schPins = mapToString( su.schNetsByPin );
726 wxString unitPins = vectorToString( su.unitPinNumbers );
727 wxString pcbUnitNetSeq = vectorToString( su.pcbNetsInUnitOrder );
728 wxString schUnitNetSeq = vectorToString( su.schNetsInUnitOrder );
730 msg.Printf( wxT(
"DEBUG(unit-swap): unit %d: %s pcbPins[%s] schPins[%s] unitPins[%s] pcbUnitNets[%s] "
731 "schUnitNets[%s]." ),
732 su.currentUnit, su.ref, pcbPins, schPins, unitPins, pcbUnitNetSeq, schUnitNetSeq );
736 if( !mappingValid || symbolUnits.size() < 2 )
739 std::vector<BACKANNOTATE_UNIT_SWAP_CANDIDATE>
candidates;
741 for(
const SYM_UNIT& symbolUnit : symbolUnits )
744 candidate.
m_ref = symbolUnit.ref;
753 if( !
plan.m_mappingOk )
755 msg.Printf( wxT(
"DEBUG(unit-swap): mapping failed for footprint %s." ), fp->m_ref );
760 if(
plan.m_identity )
762 msg.Printf( wxT(
"DEBUG(unit-swap): footprint %s already aligned (identity mapping)." ), fp->m_ref );
769 for(
size_t candidateIdx :
plan.m_swappedCandidateIndices )
770 commit.
Modify( symbolUnits[candidateIdx].sym, symbolUnits[candidateIdx].screen );
777 int aUnit = a.currentUnit;
778 int bUnit = b.currentUnit;
782 a.sym->SetUnit( bUnit );
783 b.sym->SetUnit( aUnit );
786 a.sym->SetUnitSelection( sheet, bUnit );
789 b.sym->SetUnitSelection( sheet, aUnit );
792 a.currentUnit = bUnit;
793 b.currentUnit = aUnit;
795 swappedSymbols.insert( a.sym );
796 swappedSymbols.insert( b.sym );
800 swappedItems.insert( a.changeItem );
801 unitSwapItems.insert( a.changeItem );
806 swappedItems.insert( b.changeItem );
807 unitSwapItems.insert( b.changeItem );
810 wxString baseRef = a.sym->GetRef( a.sheetPath,
false );
811 wxString unitAString = a.sym->SubReference( aUnit,
false );
812 wxString unitBString = b.sym->SubReference( bUnit,
false );
814 if( unitAString.IsEmpty() )
815 unitAString.Printf( wxT(
"%d" ), aUnit );
817 if( unitBString.IsEmpty() )
818 unitBString.Printf( wxT(
"%d" ), bUnit );
820 msg.Printf(
_(
"Swap %s unit %s with unit %s." ),
828 msg.Printf( wxT(
"DEBUG(unit-swap): applied %zu swap steps for footprint %s." ),
829 plan.m_steps.size(), fp->m_ref );
837 SCH_SYMBOL* symbol = changedItem->first.GetSymbol();
842 if( swappedItems.count( changedItem ) || swappedSymbols.count( symbol ) )
845 int updatedUnit = symbol->
GetUnitSelection( &changedItem->first.GetSheetPath() );
846 changedItem->first.SetUnit( updatedUnit );
866 bool skip = ( ref.
GetSymbol()->GetFlags() &
SKIP_STRUCT ) > 0 || unitSwapItems.count( &item ) > 0;
869 [](
bool b ) -> wxString
871 return b ?
_(
"true" ) :
_(
"false" );
881 msg.Printf(
_(
"Change %s reference designator to '%s'." ),
895 msg.Printf(
_(
"Change %s footprint assignment from '%s' to '%s'." ),
910 msg.Printf(
_(
"Change %s value from '%s' to '%s'." ),
924 msg.Printf(
_(
"Change %s 'Do not populate' from '%s' to '%s'." ),
926 boolString( oldDNP ),
927 boolString( fpData.
m_DNP ) );
938 msg.Printf(
_(
"Change %s 'Exclude from bill of materials' from '%s' to '%s'." ),
940 boolString( oldExBOM ),
952 msg.Printf(
_(
"Change %s 'Exclude from simulation' from '%s' to '%s'." ),
954 boolString( oldExSim ),
966 msg.Printf(
_(
"Change %s 'Exclude from position files' from '%s' to '%s'." ),
DescribeRef( ref.
GetRef() ),
975 std::set<wxString> swappedPins;
983 for(
const std::pair<const wxString, wxString>& entry : fpData.
m_pinMap )
985 const wxString& pinNumber = entry.first;
986 const wxString& shortNetName = entry.second;
990 if( swappedPins.count( pinNumber ) > 0 )
995 msg.Printf(
_(
"Cannot find %s pin '%s'." ),
1003 const std::optional<wxString> netName =
pin->GetConnectionName( &ref.
GetSheetPath(),
false,
true );
1005 if( netName && *netName != shortNetName )
1013 for(
const std::pair<const wxString, wxString>& field : fpData.
m_fieldsMap )
1015 const wxString& fpFieldName = field.first;
1016 const wxString& fpFieldValue = field.second;
1035 msg.Printf(
_(
"Change %s field '%s' value to '%s'." ),
1041 symField->
SetText( fpFieldValue );
1047 if( symField ==
nullptr )
1050 msg.Printf(
_(
"Add %s field '%s' with value '%s'." ),
1058 newField.
SetText( fpFieldValue );
1071 std::vector<wxString> fieldsToDelete;
1075 if( field.IsMandatory() )
1081 msg.Printf(
_(
"Delete %s field '%s.'" ),
1085 fieldsToDelete.push_back( field.GetName() );
1092 for(
const wxString& fieldName : fieldsToDelete )
1100 unitSwapItems.erase( &item );
1110 m_frame->UpdateNetHighlightStatus();
1112 commit.
Push(
_(
"Update Schematic from PCB" ) );
1155 ORIENT o = orientations[ 0 ];
1164 for(
const ORIENT& i : orientations )
1166 if( i.flag == symbolOrientation )
1173 for(
int i = 0; i < o.n_rots; i++ )
1188 if( !connectedItems.insert( aItem ).second )
1191 std::vector<SCH_ITEM*> neighbors;
1197 neighbors = connection->ConnectedItems();
1204 for(
SCH_ITEM* connectedItem : neighbors )
1214 std::set<wxString> swappedPins;
1224 wxCHECK(
m_frame, swappedPins );
1231 wxString currentNet;
1235 std::vector<PIN_CHANGE> mismatches;
1238 std::map<wxString, std::vector<size_t>> pinsByCurrentNet;
1241 for(
const std::pair<const wxString, wxString>& entry : aFpData.
m_pinMap )
1243 const wxString& pinNumber = entry.first;
1244 const wxString& desiredNet = entry.second;
1253 if( !
pin ||
pin->IsPower() || !
pin->IsConnectable() )
1256 wxString currentNet =
1257 pin->GetConnectionName( &aReference.
GetSheetPath(),
false,
true ).value_or( wxString() );
1259 if( desiredNet.IsEmpty() || currentNet.IsEmpty() )
1262 if( desiredNet == currentNet )
1265 size_t idx = mismatches.size();
1266 mismatches.push_back( {
pin, pinNumber, currentNet, desiredNet } );
1267 pinsByCurrentNet[currentNet].push_back( idx );
1270 if( mismatches.size() < 2 )
1275 std::vector<bool> handled( mismatches.size(),
false );
1276 std::vector<SCH_PIN*> swappedPinObjects;
1277 bool swappedLibPins =
false;
1280 bool allowPinSwaps =
false;
1281 wxString currentProjectName =
m_frame->Prj().GetProjectName();
1284 allowPinSwaps =
m_frame->eeconfig()->m_Input.allow_unconstrained_pin_swaps;
1286 std::set<wxString> sharedSheetPaths;
1287 std::set<wxString> sharedProjectNames;
1289 &sharedSheetPaths, &sharedProjectNames );
1291 std::set<wxString> friendlySheetNames;
1293 if( sharedSheetSymbol && !sharedSheetPaths.empty() )
1298 for(
size_t i = 0; i < mismatches.size(); ++i )
1304 PIN_CHANGE& change = mismatches[i];
1307 auto range = pinsByCurrentNet.find( change.targetNet );
1310 if( range == pinsByCurrentNet.end() )
1314 size_t partnerIdx = std::numeric_limits<size_t>::max();
1317 for(
size_t candidateIdx : range->second )
1319 if( candidateIdx == i || handled[candidateIdx] )
1322 PIN_CHANGE& candidate = mismatches[candidateIdx];
1326 if( candidate.targetNet == change.currentNet )
1328 partnerIdx = candidateIdx;
1335 if( partnerIdx == std::numeric_limits<size_t>::max() )
1338 PIN_CHANGE&
partner = mismatches[partnerIdx];
1342 if( change.pin->GetParentSymbol() !=
partner.pin->GetParentSymbol() )
1345 if( !allowPinSwaps || sharedSheetSymbol )
1347 if( !sharedProjectNames.empty() )
1349 std::vector<wxString> otherProjects;
1351 for(
const wxString&
name : sharedProjectNames )
1353 if( !currentProjectName.IsEmpty() &&
name.IsSameAs( currentProjectName ) )
1356 otherProjects.push_back(
name );
1361 if( projects.IsEmpty() )
1363 msg.Printf(
_(
"Would swap %s pins %s and %s to match PCB, but the symbol is shared across other projects." ),
1370 msg.Printf(
_(
"Would swap %s pins %s and %s to match PCB, but the symbol is shared across other "
1376 else if( !friendlySheetNames.empty() )
1380 msg.Printf(
_(
"Would swap %s pins %s and %s to match PCB, but the symbol is used by multiple sheet "
1381 "instances (%s)." ),
1386 else if( sharedSheetSymbol )
1388 msg.Printf(
_(
"Would swap %s pins %s and %s to match PCB, but the symbol is shared." ),
1395 msg.Printf(
_(
"Would swap %s pins %s and %s to match PCB, but unconstrained pin swaps are disabled in "
1396 "the schematic preferences." ),
1404 handled[partnerIdx] =
true;
1410 wxCHECK2( aCommit,
continue );
1421 handled[partnerIdx] =
true;
1424 swappedPins.insert( change.pinNumber );
1425 swappedPins.insert(
partner.pinNumber );
1426 swappedPinObjects.push_back( change.pin );
1427 swappedPinObjects.push_back(
partner.pin );
1431 msg.Printf(
_(
"Swap %s pins %s and %s to match PCB." ),
1439 if( swappedPinObjects.empty() )
1444 if( swappedLibPins )
1447 m_frame->UpdateItem( aSymbol,
false,
true );
1456 for(
SCH_PIN* swappedPin : swappedPinObjects )
1457 cleanupSelection.
Add( swappedPin );
1459 lwbTool->TrimOverLappingWires( aCommit, &cleanupSelection );
1460 lwbTool->AddJunctionsIfNeeded( aCommit, &cleanupSelection );
1464 m_frame->Schematic().CleanUp( aCommit );
1473 const wxString& aOldName,
const wxString& aNewName )
1481 std::set<SCH_ITEM*> connectedItems;
1487 for(
SCH_ITEM* item : connectedItems )
1491 if( priority > driverPriority )
1494 driverPriority = priority;
1498 switch( driver->
Type() )
1506 msg.Printf(
_(
"Change %s pin %s net label from '%s' to '%s'." ),
1522 if(
static_cast<SCH_PIN*
>( driver )->IsPower() )
1524 msg.Printf(
_(
"Net %s cannot be changed to %s because it is driven by a power pin." ),
1536 SCH_ITEM* resolvedDriver =
nullptr;
1545 : std::optional<SCH_SHEET_PATH>();
1547 if(
path && net->Driver() )
1549 resolvedDriver = net->Driver();
1550 driverSheet = *
path;
1569 msg.Printf(
_(
"Change %s pin %s net label from '%s' to '%s'." ),
DescribeRef( aRef ),
1585 static_cast<SCH_LABEL_BASE*
>( resolvedDriver )->SetText( aNewName );
1595 msg.Printf(
_(
"Add label '%s' to %s pin %s net." ),
1610 aCommit->
Add( label, screen );
bool CollectBackannotatePcbNets(const SCH_SYMBOL &aSymbol, const SCH_SHEET_PATH &aSheetPath, const wxString &aVariantName, const std::map< wxString, wxString > &aPcbNetsByPad, std::map< wxString, wxString > &aPcbNetsByLogicalPin)
Append this unit's PCB nets to a map keyed by logical pin number, resolving pin-to-pad mappings.
static std::vector< wxString > netsInUnitOrder(const std::vector< wxString > &aPins, const std::map< wxString, wxString > &aNetByPin)
void addConnections(SCH_ITEM *aItem, const SCH_SHEET_PATH &aSheetPath, std::set< SCH_ITEM * > &connectedItems)
static SPIN_STYLE orientLabel(SCH_PIN *aPin)
BACKANNOTATE_UNIT_SWAP_PLAN PlanBackannotateUnitSwaps(const std::vector< BACKANNOTATE_UNIT_SWAP_CANDIDATE > &aCandidates, const std::map< wxString, wxString > &aPcbPinMap)
Compute a pure unit-swap plan from schematic-side unit definitions and PCB nets keyed by logical pin ...
bool CollectBackannotatePcbNets(const SCH_SYMBOL &aSymbol, const SCH_SHEET_PATH &aSheetPath, const wxString &aVariantName, const std::map< wxString, wxString > &aPcbNetsByPad, std::map< wxString, wxString > &aPcbNetsByLogicalPin)
Append this unit's PCB nets to a map keyed by logical pin number, resolving pin-to-pad mappings.
BACKANNOTATE_UNIT_SWAP_PLAN PlanBackannotateUnitSwaps(const std::vector< BACKANNOTATE_UNIT_SWAP_CANDIDATE > &aCandidates, const std::map< wxString, wxString > &aPcbPinMap)
Compute a pure unit-swap plan from schematic-side unit definitions and PCB nets keyed by logical pin ...
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
bool BackAnnotateSymbols(const std::string &aNetlist)
Run back annotation algorithm.
SCH_MULTI_UNIT_REFERENCE_MAP m_multiUnitsRefs
std::deque< CHANGELIST_ITEM > m_changelist
std::pair< SCH_REFERENCE, std::shared_ptr< PCB_FP_DATA > > CHANGELIST_ITEM
bool m_processOtherFields
void getPcbModulesFromString(const std::string &aPayload)
Parse netlist sent over KiWay express mail interface and fill m_pcbFootprints.
void checkForUnusedSymbols()
Check if some symbols are not represented in PCB footprints and vice versa.
SCH_REFERENCE_LIST m_refs
bool FetchNetlistFromPCB(std::string &aNetlist)
Get netlist from the Pcbnew.
PCB_FOOTPRINTS_MAP m_pcbFootprints
BACK_ANNOTATE(SCH_EDIT_FRAME *aFrame, REPORTER &aReporter, bool aRelinkFootprints, bool aProcessFootprints, bool aProcessValues, bool aProcessReferences, bool aProcessNetNames, bool aProcessAttributes, bool aProcessOtherFields, bool aPreferUnitSwaps, bool aPreferPinSwaps, bool aDryRun)
std::set< wxString > applyPinSwaps(SCH_SYMBOL *aSymbol, const SCH_REFERENCE &aReference, const PCB_FP_DATA &aFpData, SCH_COMMIT *aCommit)
Handle footprint pad net swaps with symbol pin swaps where possible.
void processNetNameChange(SCH_COMMIT *aCommit, const wxString &aRef, SCH_PIN *aPin, const SCH_SHEET_PATH &aSheet, const wxString &aOldName, const wxString &aNewName)
void getChangeList()
Create changelist.
void applyChangelist()
Apply changelist to the schematic.
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
Calculate the connectivity of a schematic and generate netlists.
A subgraph is a set of items that are electrically connected on a single sheet.
PRIORITY GetDriverPriority()
const SCH_ITEM * GetDriver() const
static PRIORITY GetDriverPriority(SCH_ITEM *aDriver)
Return the priority (higher is more important) of a candidate driver.
const SCH_SHEET_PATH & GetSheet() const
Implement a lexical analyzer for the SPECCTRA DSN file format.
virtual VECTOR2I GetPosition() const
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 void SetParent(EDA_ITEM *aParent)
EDA_ITEM_FLAGS GetFlags() const
virtual void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
virtual void SetTextPos(const VECTOR2I &aPoint)
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
virtual void SetVisible(bool aVisible)
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
virtual bool OpenProjectFiles(const std::vector< wxString > &aFileList, int aCtl=0)
Open a project or set of files given by aFileList.
Define a library symbol object.
std::vector< UNIT_PIN_INFO > GetUnitPinInfo() const
Return pin-number lists for each unit, ordered consistently for gate swapping.
static REPORTER & GetInstance()
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & ReportHead(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Places the report at the beginning of the list for objects that support ordering.
These are loaded from Eeschema settings but then overwritten by the project settings.
Holds all the data relating to one schematic.
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
SCH_CONNECTIVITY::FACADE & Connectivity() const
CONNECTION_GRAPH * ConnectionGraph() const
Commit for the schematic and symbol editors.
void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
std::optional< NET_VIEW > GetSubgraphForItem(const KIID &aItem, const KIID_PATH &aPath) const
std::optional< ITEM_VIEW > Connection(const KIID &aItem, const KIID_PATH &aPath) const
Schematic editor (Eeschema) main window.
wxString GetUntranslatedName() const
Get the untranslated field name for storage, variable look-up, etc.
wxString GetShownText(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, const wxString &aVariantName=wxEmptyString, int aDepth=0) const
void SetText(const wxString &aText) override
Base class for any item which can be embedded within the SCHEMATIC container class,...
const SYMBOL * GetParentSymbol() const
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
const std::vector< SCH_ITEM * > & ConnectedItems(const SCH_SHEET_PATH &aPath) const
Retrieve the set of items connected to this item on the given sheet.
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
SCH_PIN * GetLibPin() const
PIN_ORIENTATION GetOrientation() const
const wxString & GetShownNumber() const
A helper to define a symbol's reference designator in a schematic.
const SCH_SHEET_PATH & GetSheetPath() const
const wxString GetFootprint() const
SCH_SYMBOL * GetSymbol() const
const wxString GetValue() const
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
std::optional< SCH_SHEET_PATH > GetSheetPathByKIIDPath(const KIID_PATH &aPath, bool aIncludeLastSheet=true) const
Finds a SCH_SHEET_PATH that matches the provided KIID_PATH.
void GetMultiUnitSymbols(SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, SYMBOL_FILTER aSymbolFilter) const
Add a SCH_REFERENCE_LIST object to aRefList for each same-reference set of multi-unit parts in the li...
void GetSymbols(SCH_REFERENCE_LIST &aReferences, SYMBOL_FILTER aSymbolFilter, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_SCREEN * LastScreen()
const KIID_PATH & PathRef() const
Borrow the cached path until this sheet path is modified or destroyed.
bool GetExcludedFromSim(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
virtual void SetDNP(bool aEnable, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
void RemoveField(const wxString &aFieldName)
Remove a user field from the symbol.
void SetExcludedFromSim(bool aEnable, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
Set or clear the exclude from simulation flag.
std::vector< const SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
bool GetExcludedFromBOM(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
void UpdatePins()
Updates the cache of SCH_PIN objects for each pin.
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
void SetFootprintFieldText(const wxString &aFootprint)
VECTOR2I GetPosition() const override
void SetExcludedFromPosFiles(bool aEnable, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
void SetValueFieldText(const wxString &aValue, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString)
bool GetExcludedFromPosFiles(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
bool GetExcludedFromBoard(const SCH_SHEET_PATH *aInstance=nullptr, 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.
SCH_PIN * GetPin(const wxString &number) const
Find a symbol pin by number.
int GetOrientation() const override
Get the display symbol orientation.
void SetExcludedFromBOM(bool aEnable, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
Set or clear the exclude from schematic bill of materials flag.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
virtual bool GetDNP(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
Set or clear the 'Do Not Populate' flag.
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.
virtual void Add(EDA_ITEM *aItem)
A null aItem is ignored; the selection never holds null members.
Spin style for labels of all kinds on schematics.
SPIN_STYLE MirrorX()
Mirror the label spin style across the X axis or simply swaps up and bottom.
SPIN_STYLE MirrorY()
Mirror the label spin style across the Y axis or simply swaps left and right.
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
wxString DescribeRef(const wxString &aRef)
Returns a user-visible HTML string describing a footprint reference designator.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
#define IS_NEW
New item, just created.
#define SKIP_STRUCT
flag indicating that the structure should be ignored
static wxString From_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
static std::vector< PENDING_PROPERTY > plan(const EDA_ITEM &aSource, const EDA_ITEM &aTarget, const std::set< wxString > &aEnabledKeys)
Target properties to write, paired with values read off the source.
@ PIN_UP
The pin extends upwards from the connection point: Probably on the bottom side of the symbol.
@ PIN_RIGHT
The pin extends rightwards from the connection point.
@ PIN_LEFT
The pin extends leftwards from the connection point: Probably on the right side of the symbol.
@ PIN_DOWN
The pin extends downwards from the connection: Probably on the top side of the symbol.
void Scan(PTREE *aTree, DSNLEXER *aLexer)
Fill an empty PTREE with information from a KiCad s-expression stream.
boost::property_tree::ptree PTREE
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
@ SYMBOL_FILTER_NON_POWER
wxString EscapeHTML(const wxString &aString)
Return a new wxString escaped for embedding in HTML.
std::vector< wxString > ExpandStackedPinNotation(const wxString &aPinName, bool *aValid)
Expand stacked pin notation like [1,2,3], [1-4], [A1-A4], or [AA1-AA3,AB4,CD12-CD14] into individual ...
void AccumulateDescriptions(wxString &aDesc, const T &aItemCollection)
Build a comma-separated list from a collection of wxStrings.
std::vector< wxString > m_unitPinNumbers
std::map< wxString, wxString > m_schNetsByPin
Container for Pcbnew footprint data.
std::map< wxString, wxString > m_pinMap
bool m_excludeFromPosFiles
std::map< wxString, wxString > m_fieldsMap
wxString GetDefaultFieldName(FIELD_T aFieldId, TRANSLATION aTranslation)
Return a default symbol field name for a mandatory field type.
@ USER
The field ID hasn't been set yet; field is invalid.
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
static std::vector< int > candidates(const SEGMENT_INDEX &aIndex, const SEG &aQuery, int aPadding)
VECTOR2< int32_t > VECTOR2I
Definition of file extensions used in Kicad.