29#include <fmt/format.h>
30#include <wx/filename.h>
32#include <wx/tokenzr.h>
33#include <wx/wfstream.h>
34#include <wx/txtstrm.h>
35#include <wx/mstream.h>
36#include <wx/xml/xml.h>
94 bbox.
Merge( item->GetBoundingBox() );
103 return aPinName.BeforeFirst(
'@' );
116 wxCHECK( currentSheet,
nullptr );
161 for(
const std::unique_ptr<ELAYER>& elayer : aLayers )
180 switch ( elayer->number)
210 int roti = int( eagleDegrees );
220 wxASSERT_MSG(
false, wxString::Format( wxT(
"Unhandled orientation (%d degrees)" ),
229 bool aMirror,
bool aSpin,
int aAbsDegress )
231 int align = aEagleAlignment;
233 if( aRelDegress == 90 )
237 else if( aRelDegress == 180 )
241 else if( aRelDegress == 270 )
247 if( aMirror ==
true )
249 if( aAbsDegress == 90 || aAbsDegress == 270 )
260 else if( aAbsDegress == 0 || aAbsDegress == 180 )
353 const std::map<std::string, UTF8>* aProperties )
355 wxASSERT( !aFileName || aSchematic !=
nullptr );
375 wxXmlNode* currentNode = xmlDocument.GetRoot();
385 unique_ptr<SCH_SHEET> tempVROwner;
389 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
390 wxT(
"Can't append to a schematic with no root!" ) );
401 if( sheetPath.Last() == aAppendToMe )
413 tempVROwner = std::make_unique<SCH_SHEET>( aSchematic );
433 wxCHECK_MSG(
table,
nullptr,
"Could not load symbol lib table." );
435 m_pi.reset( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
443 wxString libTableUri = wxT(
"${KIPRJMOD}/" ) +
getLibFileName().GetFullName();
448 row.
SetURI( libTableUri );
456 m_eagleDoc = std::make_unique<EAGLE_DOC>( currentNode,
this );
484 const wxString& aLibraryPath,
485 const std::map<std::string, UTF8>* aProperties )
496 for(
const auto& [symName, libSymbol] : it->second.KiCadSymbols )
497 aSymbolNameList.push_back( symName );
503 const wxString& aLibraryPath,
504 const std::map<std::string, UTF8>* aProperties )
515 for(
const auto& [symName, libSymbol] : it->second.KiCadSymbols )
516 aSymbolList.push_back( libSymbol.get() );
522 const std::map<std::string, UTF8>* aProperties )
533 auto it2 = it->second.KiCadSymbols.find( aAliasName );
535 if( it2 != it->second.KiCadSymbols.end() )
536 return it2->second.get();
545 wxFileName fn( aLibraryPath );
547 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
548 return fn.GetModificationTime().GetValue().GetValue();
579 std::unique_ptr<EAGLE_DOC> doc = std::make_unique<EAGLE_DOC>( xmlDocument.GetRoot(),
this );
583 m_version = ( doc->version.IsEmpty() ) ? wxString( wxS(
"0.0" ) ) : doc->version;
595 wxXmlDocument xmlDocument;
596 wxFFileInputStream stream(
m_filename.GetFullPath() );
607 std::vector<uint8_t> bytes;
608 bytes.resize(
static_cast<size_t>( stream.GetLength() ) );
609 stream.Read( bytes.data(), bytes.size() );
611 if( stream.LastRead() != bytes.size() )
615 std::unique_ptr<wxXmlDocument> binDocument = binParser.
Parse( bytes );
617 xmlDocument.SetRoot( binDocument->DetachRoot() );
622 wxTextInputStream
text( stream );
623 wxString line =
text.ReadLine();
625 if( !line.StartsWith( wxT(
"<?xml" ) ) && !line.StartsWith( wxT(
"<!--" ) )
626 && !line.StartsWith( wxT(
"<eagle " ) ) )
628 THROW_IO_ERRORF(
_(
"'%s' is an Eagle binary-format file; only Eagle XML-format files can be imported." ),
632#if wxCHECK_VERSION( 3, 3, 0 )
635 if( !xmlDocument.Load( stream, wxXMLDOC_NONE, &err ) )
637 if( err.message == wxS(
"no element found" ) )
641 wxMemoryOutputStream memOutput;
644 header <<
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
645 header <<
"<!DOCTYPE eagle SYSTEM \"eagle.dtd\">\n";
647 wxScopedCharBuffer headerBuf = header.utf8_str();
648 memOutput.Write( headerBuf.data(), headerBuf.length() );
650 wxFFileInputStream stream2(
m_filename.GetFullPath() );
651 memOutput.Write( stream2 );
653 wxMemoryInputStream memInput( memOutput );
655 if( !xmlDocument.Load( memInput, wxXMLDOC_NONE, &err ) )
662 THROW_IO_ERRORF(
_(
"Unable to read file '%s'.\n'%s' at line %d, column %d, offset %d" ),
663 m_filename.GetFullPath(), err.message, err.line, err.column, err.offset );
667 if( !xmlDocument.Load( stream ) )
671 wxMemoryOutputStream memOutput;
674 header <<
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
675 header <<
"<!DOCTYPE eagle SYSTEM \"eagle.dtd\">\n";
677 wxScopedCharBuffer headerBuf = header.utf8_str();
678 memOutput.Write( headerBuf.data(), headerBuf.length() );
680 wxFFileInputStream stream2(
m_filename.GetFullPath() );
681 memOutput.Write( stream2 );
683 wxMemoryInputStream memInput( memOutput );
685 if( !xmlDocument.Load( memInput ) )
696 wxCHECK( aDrawing, );
700 if( aDrawing->library )
708 if( aDrawing->schematic )
715 for(
const std::unique_ptr<ESHEET>& esheet : aSchematic.
sheets )
717 for(
const std::unique_ptr<ENET>& enet : esheet->nets )
719 wxString netName = enet->netname;
728 for(
const auto& [modname, emodule] : aSchematic.
modules )
730 for(
const std::unique_ptr<ESHEET>& esheet : emodule->sheets )
732 for(
const std::unique_ptr<ENET>& enet : esheet->nets )
734 wxString netName = enet->netname;
749 if( aSchematic.
sheets.empty() )
756 if( variantDef->current.value_or(
false ) )
761 for(
const auto& [
name, epart] : aSchematic.
parts )
764 for(
const auto& [modName, emodule] : aSchematic.
modules )
766 for(
const auto& [partName, epart] : emodule->parts )
772 for(
const auto& [libName, elibrary] : aSchematic.
libraries )
775 elib->
name = elibrary->GetName();
791 std::vector<SCH_SHEET*> eaglePages;
792 eaglePages.reserve( aSchematic.
sheets.size() );
794 for(
const std::unique_ptr<ESHEET>& esheet : aSchematic.
sheets )
798 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>(
m_rootSheet );
800 sheet->SetScreen( screen );
802 wxCHECK2( sheet && screen,
continue );
804 wxString pageNo = wxString::Format( wxT(
"%d" ),
m_sheetIndex );
812 eaglePages.push_back( sheet.release() );
817 if( !eaglePages.empty() )
842 struct MISSING_UNIT_PLACEMENT
852 std::map<SCH_SCREEN*, MISSING_UNIT_PLACEMENT> placements;
856 const SCH_SYMBOL* origSymbol = cmp.second.cmp;
858 for(
auto& unitEntry : cmp.second.units )
860 if( unitEntry.second ==
false )
864 int unit = unitEntry.first;
875 targetScreen = fallbackSheet->
GetScreen();
877 targetScreen = schematicRoot->
GetScreen();
880 auto placementIt = placements.find( targetScreen );
882 if( placementIt == placements.end() )
884 MISSING_UNIT_PLACEMENT placement;
885 placement.screen = targetScreen;
889 SCH_SHEET* targetSheet = placement.sheetpath.Last();
894 placement.newCmpPosition =
VECTOR2I( placement.sheetBbox.GetLeft(),
895 placement.sheetBbox.GetBottom() );
896 placement.maxY = placement.sheetBbox.GetY();
897 placementIt = placements.emplace( targetScreen, placement ).first;
900 MISSING_UNIT_PLACEMENT& placement = placementIt->second;
902 symbol->SetUnitSelection( &placement.sheetpath, unit );
903 symbol->SetUnit( unit );
904 symbol->SetOrientation( 0 );
905 symbol->AddHierarchicalReference( placement.sheetpath.Path(), reference, unit );
908 BOX2I cmpBbox = symbol->GetBoundingBox();
909 int posY = placement.newCmpPosition.y + cmpBbox.
GetHeight();
910 symbol->SetPosition(
VECTOR2I( placement.newCmpPosition.x, posY ) );
911 placement.newCmpPosition.x += cmpBbox.
GetWidth();
912 placement.maxY = std::max( placement.maxY, posY );
914 if( placement.newCmpPosition.x >= placement.pageSizeIU.x )
915 placement.newCmpPosition =
VECTOR2I( placement.sheetBbox.GetLeft(),
920 placement.screen->Append( symbol.release() );
933 wxCHECK( sheet && screen, );
937 std::string filename;
941 if( aSheet->description )
942 sheet->
SetName( aSheet->description.value().text );
947 replace( filename.begin(), filename.end(),
' ',
'_' );
952 fn.SetPath(
m_schematic->Project().GetProjectPath() );
953 fn.SetName( filename );
960 for(
const auto& [
name, moduleinst] : aSheet->moduleinsts )
967 for(
const std::unique_ptr<EPOLYGON>& epoly : aSheet->plain->polygons )
973 for(
const std::unique_ptr<EWIRE>& ewire : aSheet->plain->wires )
979 for(
const std::unique_ptr<ETEXT>& etext : aSheet->plain->texts )
982 for(
const std::unique_ptr<ECIRCLE>& ecircle : aSheet->plain->circles )
985 for(
const std::unique_ptr<ERECT>& erectangle : aSheet->plain->rectangles )
988 for(
const std::unique_ptr<EFRAME>& eframe : aSheet->plain->frames )
990 std::vector<SCH_ITEM*> frameItems;
1001 for(
const std::unique_ptr<EINSTANCE>& einstance : aSheet->instances )
1011 for(
const std::unique_ptr<EBUS>& ebus : aSheet->busses )
1017 loadSegments( ebus->segments, busName, wxString(),
true );
1020 for(
const std::unique_ptr<ENET>& enet : aSheet->nets )
1023 wxString netName = enet->netname;
1024 wxString netClass = wxString::Format( wxS(
"%i" ), enet->netcode );
1043 if( pageSizeIU.
x < targetSheetSize.
x )
1046 if( pageSizeIU.
y < targetSheetSize.
y )
1053 VECTOR2I sheetcentre( pageSizeIU.
x / 2, pageSizeIU.
y / 2 );
1057 VECTOR2I translation = sheetcentre - itemsCentre;
1058 translation.
x = translation.
x - translation.
x %
schIUScale.MilsToIU( 100 );
1059 translation.
y = translation.
y - translation.
y %
schIUScale.MilsToIU( 100 );
1071 std::vector<SCH_ITEM*> allItems;
1073 std::copy( screen->
Items().
begin(), screen->
Items().
end(), std::back_inserter( allItems ) );
1077 item->SetPosition( item->GetPosition() + translation );
1095 wxCHECK( currentSheet &¤tScreen, );
1101 auto it =
m_eagleDoc->drawing->schematic->modules.find( aModuleInstance->moduleinst );
1104 if( it ==
m_eagleDoc->drawing->schematic->modules.end() )
1106 THROW_IO_ERRORF(
_(
"No module instance '%s' found in schematic file:\n%s" ),
1107 aModuleInstance->name,
m_filename.GetFullPath() );
1111 fn.SetName( aModuleInstance->moduleinst );
1115 VECTOR2I size( it->second->dx.ToSchUnits(), it->second->dy.ToSchUnits() );
1117 int halfX =
KiROUND( size.
x / 2.0 );
1118 int halfY =
KiROUND( size.
y / 2.0 );
1119 int portExtWireLength =
schIUScale.mmToIU( 5.08 );
1120 VECTOR2I pos( aModuleInstance->x.ToSchUnits() - halfX,
1121 -aModuleInstance->y.ToSchUnits() - halfY );
1123 std::unique_ptr<SCH_SHEET> newSheet = std::make_unique<SCH_SHEET>( currentSheet, pos, size );
1131 if( schFile->GetFileName() == fn.GetFullPath() )
1133 newScreen = schFile;
1138 bool isNewSchFile = ( newScreen == nullptr );
1146 wxCHECK( newSheet && newScreen, );
1148 newSheet->SetScreen( newScreen );
1149 newSheet->SetFileName( fn.GetFullName() );
1150 newSheet->SetName( aModuleInstance->name );
1152 for(
const auto& [portName, port] : it->second->ports )
1155 int pinOffset = port->coord.ToSchUnits();
1158 if( port->side ==
"left" )
1162 pinPos.
y = pos.
y + halfY - pinOffset;
1163 portExtWireEndpoint = pinPos;
1164 portExtWireEndpoint.
x -= portExtWireLength;
1166 else if( port->side ==
"right" )
1169 pinPos.
x = pos.
x + size.
x;
1170 pinPos.
y = pos.
y + halfY - pinOffset;
1171 portExtWireEndpoint = pinPos;
1172 portExtWireEndpoint.
x += portExtWireLength;
1174 else if( port->side ==
"top" )
1177 pinPos.
x = pos.
x + halfX + pinOffset;
1179 portExtWireEndpoint = pinPos;
1180 portExtWireEndpoint.
y -= portExtWireLength;
1182 else if( port->side ==
"bottom" )
1185 pinPos.
x = pos.
x + halfX + pinOffset;
1186 pinPos.
y = pos.
y + size.
y;
1187 portExtWireEndpoint = pinPos;
1188 portExtWireEndpoint.
y += portExtWireLength;
1193 currentScreen->
Append( portExtWire );
1197 if( port->direction.has_value() )
1199 if( port->direction.value() ==
"in" )
1201 else if( port->direction.value() ==
"out" )
1203 else if( port->direction.value() ==
"io" )
1205 else if( port->direction.value() ==
"hiz" )
1217 newSheet->AddPin( sheetPin );
1220 wxString pageNo = wxString::Format( wxT(
"%d" ),
m_sheetIndex );
1222 newSheet->SetParent( currentSheet );
1225 currentScreen->
Append( newSheet.release() );
1227 m_modules.push_back( it->second.get() );
1233 for(
const std::unique_ptr<ESHEET>& esheet : it->second->sheets )
1243 wxCHECK2( emoduleInst,
continue );
1245 refPrefix += emoduleInst->name + wxS(
":" );
1256 wxCHECK2( symbol && !symbol->
GetInstances().empty(),
continue );
1259 wxString newReference = refPrefix + inst.
m_Reference.AfterLast(
':' );
1275 int xMin = aFrame->x1.ToSchUnits();
1276 int xMax = aFrame->x2.ToSchUnits();
1277 int yMin = -aFrame->y1.ToSchUnits();
1278 int yMax = -aFrame->y2.ToSchUnits();
1281 std::swap( xMin, xMax );
1284 std::swap( yMin, yMax );
1292 aItems.push_back( lines );
1294 if( !( aFrame->border_left ==
false ) )
1299 aItems.push_back( lines );
1302 int height = yMax - yMin;
1305 int legendPosX = xMin +
schIUScale.MilsToIU( 75 );
1306 double rowSpacing = height / double( aFrame->rows );
1307 double legendPosY = yMin + ( rowSpacing / 2 );
1309 for( i = 1; i < aFrame->rows; i++ )
1311 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1315 aItems.push_back( lines );
1318 char legendChar =
'A';
1320 for( i = 0; i < aFrame->rows; i++ )
1327 legendText->
SetText( wxString( legendChar ) );
1329 aItems.push_back( legendText );
1331 legendPosY += rowSpacing;
1335 if( !( aFrame->border_right ==
false ) )
1340 aItems.push_back( lines );
1343 int height = yMax - yMin;
1346 int legendPosX = xMax -
schIUScale.MilsToIU( 75 );
1347 double rowSpacing = height / double( aFrame->rows );
1348 double legendPosY = yMin + ( rowSpacing / 2 );
1350 for( i = 1; i < aFrame->rows; i++ )
1352 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1356 aItems.push_back( lines );
1359 char legendChar =
'A';
1361 for( i = 0; i < aFrame->rows; i++ )
1368 legendText->
SetText( wxString( legendChar ) );
1370 aItems.push_back( legendText );
1372 legendPosY += rowSpacing;
1376 if( !( aFrame->border_top ==
false ) )
1381 aItems.push_back( lines );
1384 int width = xMax - xMin;
1387 int legendPosY = yMin +
schIUScale.MilsToIU( 75 );
1388 double columnSpacing = width / double( aFrame->columns );
1389 double legendPosX = xMin + ( columnSpacing / 2 );
1391 for( i = 1; i < aFrame->columns; i++ )
1393 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1397 aItems.push_back( lines );
1402 for( i = 0; i < aFrame->columns; i++ )
1409 legendText->
SetText( fmt::format(
"{}", legendNo++ ) );
1411 aItems.push_back( legendText );
1412 legendPosX += columnSpacing;
1416 if( !( aFrame->border_bottom ==
false ) )
1421 aItems.push_back( lines );
1424 int width = xMax - xMin;
1427 int legendPosY = yMax -
schIUScale.MilsToIU( 75 );
1428 double columnSpacing = width / double( aFrame->columns );
1429 double legendPosX = xMin + ( columnSpacing / 2 );
1431 for( i = 1; i < aFrame->columns; i++ )
1433 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1437 aItems.push_back( lines );
1442 for( i = 0; i < aFrame->columns; i++ )
1449 legendText->
SetText( fmt::format(
"{}", legendNo++ ) );
1451 aItems.push_back( legendText );
1452 legendPosX += columnSpacing;
1459 const wxString& netName,
const wxString& aNetClass,
bool aIsBus )
1466 size_t segmentCount = aSegments.size();
1468 for(
const std::unique_ptr<ESEGMENT>& esegment : aSegments )
1470 bool labelled =
false;
1471 bool firstWireFound =
false;
1477 for(
const std::unique_ptr<EWIRE>& ewire : esegment->wires )
1486 if( !firstWireFound )
1488 firstWire = thisWire;
1489 firstWireFound =
true;
1495 if( !desc.labels.empty() && desc.labels.front()->GetText() == netName )
1498 for(
const SEG& seg : desc.segs )
1507 segDesc.
segs.push_back( thisWire );
1511 for(
const std::unique_ptr<EJUNCTION>& ejunction : esegment->junctions )
1514 for(
const std::unique_ptr<ELABEL>& elabel : esegment->labels )
1519 wxASSERT( segDesc.
labels.empty() || segDesc.
labels.front()->GetText() == label->
GetText() );
1521 segDesc.
labels.push_back( label );
1525 for(
const std::unique_ptr<EPINREF>& epinref : esegment->pinRefs )
1527 wxString part = epinref->part;
1528 wxString
pin = epinref->pin;
1530 auto powerPort =
m_powerPorts.find( wxT(
"#" ) + part );
1539 if( !labelled && firstWireFound )
1541 std::unique_ptr<SCH_LABEL_BASE> label;
1553 if( segmentCount > 1 ||
m_netCounts[netName] > 1 )
1563 label->SetPosition( firstWire.
A );
1567 if( firstWire.
A.
y == firstWire.
B.
y )
1569 if( firstWire.
B.
x > firstWire.
A.
x )
1574 else if( firstWire.
A.
x == firstWire.
B.
x )
1576 if( firstWire.
B.
y > firstWire.
A.
y )
1582 screen->
Append( label.release() );
1591 if( !aPolygon->IsValidOutline() )
1594 std::unique_ptr<SCH_SHAPE> poly = std::make_unique<SCH_SHAPE>(
SHAPE_T::POLY );
1596 std::optional<double> prev_curve;
1598 for(
const std::unique_ptr<EVERTEX>& evertex : aPolygon->vertices )
1600 pt =
VECTOR2I( evertex->x.ToSchUnits(), -evertex->y.ToSchUnits() );
1602 if( prev_curve.has_value() )
1606 poly->GetPolyShape().Append( arc, -1, -1,
ARC_ACCURACY );
1610 poly->AddPoint( pt );
1614 prev_curve = evertex->curve;
1617 poly->SetLayer(
kiCadLayer( aPolygon->layer ) );
1621 return poly.release();
1629 start.
x = aWire->x1.ToSchUnits();
1630 start.
y = -aWire->y1.ToSchUnits();
1631 end.x = aWire->x2.ToSchUnits();
1632 end.y = -aWire->y2.ToSchUnits();
1635 endpoints =
SEG( start,
end );
1644 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>(
SHAPE_T::ARC );
1647 arc->SetCenter(
center );
1648 arc->SetStart( start );
1655 return arc.release();
1659 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>();
1661 line->SetStartPoint( start );
1662 line->SetEndPoint(
end );
1663 line->SetLayer(
kiCadLayer( aWire->layer ) );
1666 return line.release();
1674 VECTOR2I center( aCircle->x.ToSchUnits(), -aCircle->y.ToSchUnits() );
1687 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>(
SHAPE_T::RECTANGLE );
1689 rectangle->SetLayer(
kiCadLayer( aRectangle->layer ) );
1690 rectangle->SetPosition(
VECTOR2I( aRectangle->x1.ToSchUnits(), -aRectangle->y1.ToSchUnits() ) );
1691 rectangle->SetEnd(
VECTOR2I( aRectangle->x2.ToSchUnits(), -aRectangle->y2.ToSchUnits() ) );
1693 if( aRectangle->rot.has_value() )
1695 VECTOR2I pos( rectangle->GetPosition() );
1702 rectangle->SetPosition( pos );
1703 rectangle->SetEnd(
end );
1709 return rectangle.release();
1715 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
1717 VECTOR2I pos( aJunction->x.ToSchUnits(), -aJunction->y.ToSchUnits() );
1719 junction->SetPosition( pos );
1721 return junction.release();
1726 const wxString& aNetName,
bool aIsBus )
1728 VECTOR2I elabelpos( aLabel->x.ToSchUnits(), -aLabel->y.ToSchUnits() );
1733 std::unique_ptr<SCH_LABEL_BASE> label;
1735 VECTOR2I textSize =
KiROUND( aLabel->size.ToSchUnits() * 0.7, aLabel->size.ToSchUnits() * 0.7 );
1737 auto findModulePort =
1738 [&]() ->
const EPORT*
1743 const auto& ports =
m_modules.back()->ports;
1744 const auto it = ports.find( aNetName );
1745 return it == ports.end() ? nullptr : it->second.get();
1748 const EPORT* port = findModulePort();
1752 std::unique_ptr<SCH_HIERLABEL> hierLabel = std::make_unique<SCH_HIERLABEL>();
1759 else if( port->
direction.value() ==
"out" )
1761 else if( port->
direction.value() ==
"io" )
1763 else if( port->
direction.value() ==
"hiz" )
1767 hierLabel->SetLabelShape( type );
1769 label = std::move( hierLabel );
1773 label = std::make_unique<SCH_LABEL>();
1777 label = std::make_unique<SCH_GLOBALLABEL>();
1781 label->SetPosition( elabelpos );
1782 label->SetTextSize( textSize );
1785 if( aLabel->rot.has_value() )
1788 int angle =
KiROUND( aLabel->rot.value().degrees );
1799 return label.release();
1804 const std::vector<SEG>& aLines )
const
1807 const SEG* nearestLine =
nullptr;
1809 double d, mindistance = std::numeric_limits<double>::max();
1815 for(
const SEG& line : aLines )
1817 VECTOR2I testpoint = line.NearestPoint( aPoint );
1820 if( d < mindistance )
1823 nearestPoint = testpoint;
1824 nearestLine = &line;
1828 return std::make_pair( nearestPoint, nearestLine );
1833 const std::map<wxString, std::unique_ptr<EPART>>& aParts )
1835 wxCHECK( aInstance, );
1841 const auto partIt = aParts.find( aInstance->part );
1843 if( partIt == aParts.end() )
1845 Report( wxString::Format(
_(
"Error parsing Eagle file. Could not find '%s' "
1846 "instance but it is referenced in the schematic." ),
1853 const std::unique_ptr<EPART>& epart = partIt->second;
1855 wxString libName = epart->library;
1858 if( epart->libraryUrn.has_value() )
1859 libName += wxS(
"_" ) + epart->libraryUrn.value().assetId;
1861 wxString gatename = epart->deviceset + wxS(
"_" ) + epart->device + wxS(
"_" ) + aInstance->gate;
1862 wxString symbolname = wxString( epart->deviceset + epart->device );
1863 wxString kiPackageName = epart->deviceset + epart->device;
1865 if( epart->technology.has_value() )
1866 symbolname += epart->technology.value();
1868 symbolname.Replace( wxT(
"*" ), wxEmptyString );
1869 kiPackageName.Replace( wxT(
"*" ), wxEmptyString );
1878 wxString altSymbolName = libName + wxT(
"_" ) + symbolname;
1881 wxString libIdSymbolName = altSymbolName;
1887 Report( wxString::Format( wxS(
"Eagle library '%s' not found while looking up symbol for "
1888 "deviceset '%s', device '%s', and gate '%s." ),
1893 const auto gateIt = libIt->second.GateToUnitMap.find( gatename );
1895 if( gateIt == libIt->second.GateToUnitMap.end() )
1897 Report( wxString::Format( wxS(
"Symbol not found for deviceset '%s', device '%s', and "
1898 "gate '%s in library '%s'." ),
1903 int unit = gateIt->second;
1908 auto p = elib->
package.find( kisymbolname );
1910 if( p != elib->
package.end() )
1912 package = p->second;
1916 p = elib->
package.find( kiPackageName );
1918 if( p != elib->
package.end() )
1919 package = p->second;
1923 std::map<std::string, UTF8> properties;
1930 part =
m_pi->LoadSymbol(
getLibFileName().GetFullPath(), kisymbolname, &properties );
1931 libIdSymbolName = kisymbolname;
1936 Report( wxString::Format(
_(
"Could not find '%s' in the imported library." ),
1943 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
1944 symbol->SetLibId( libId );
1945 symbol->SetUnit( unit );
1946 symbol->SetPosition(
VECTOR2I( aInstance->x.ToSchUnits(), -aInstance->y.ToSchUnits() ) );
1949 if( !package.IsEmpty() )
1951 wxString footprint =
m_schematic->Project().GetProjectName() + wxT(
":" ) + package;
1955 if( aInstance->rot.has_value() )
1959 if( aInstance->rot.value().mirror )
1960 symbol->MirrorHorizontally( aInstance->x.ToSchUnits() );
1963 std::vector<SCH_FIELD*> partFields;
1968 for(
const SCH_FIELD* partField : partFields )
1972 if( partField->IsMandatory() )
1973 symbolField = symbol->GetField( partField->GetId() );
1975 symbolField = symbol->GetField( partField->GetName() );
1982 newField.
SetText( partField->GetText() );
1986 symbol->AddField( newField );
1991 symbolField->
SetTextPos( symbol->GetPosition() + partField->GetTextPos() );
1995 wxString reference = aInstance->part;
1996 bool referenceVisible = !reference.IsEmpty();
2000 if( package.IsEmpty() )
2001 reference.Prepend(
'#' );
2004 if( reference.find_last_not_of( wxT(
"0123456789" ) ) == ( reference.Length()-1 ) )
2005 reference.Append( wxT(
"0" ) );
2010 if( reference.find_first_not_of( wxT(
"0123456789" ) ) != 0 )
2011 reference.Prepend( wxT(
"UNK" ) );
2015 if( aInstance->part.find_first_not_of( wxT(
"#" ) ) != 0 )
2016 reference.Prepend( wxT(
"UNK" ) );
2019 referenceField->
SetVisible( referenceVisible );
2020 referenceField->
SetText( reference );
2023 bool userValue =
m_userValue.at( libIdSymbolName );
2031 if( epart->value.has_value() && !epart->value.value().IsEmpty() )
2033 valueField->
SetText( epart->value.value() );
2037 valueField->
SetText( kisymbolname );
2043 for(
const auto& [ attrName, attr ] : epart->attributes )
2049 if( !symbol->GetFields().empty() )
2050 newField.
SetTextPos( symbol->GetFields().back().GetPosition() );
2052 if( attr->value.has_value() )
2053 newField.
SetText( attr->value.value() );
2055 if( attr->display.has_value() && attr->display.value() ==
EATTR::Off )
2058 symbol->AddField( newField );
2061 bool valueAttributeFound =
false;
2062 bool nameAttributeFound =
false;
2065 for(
auto& [
name, eattr] : aInstance->attributes )
2069 if( eattr->name.Lower() == wxT(
"name" ) )
2072 nameAttributeFound =
true;
2074 else if( eattr->name.Lower() == wxT(
"value" ) )
2077 valueAttributeFound =
true;
2081 field = symbol->GetField( eattr->name );
2089 if( eattr->size.has_value() )
2093 int absdegrees = eattr->rot.has_value() ?
KiROUND( eattr->rot.value().degrees ) : 0;
2094 bool mirror = eattr->rot.has_value() ? eattr->rot.value().mirror :
false;
2095 bool spin = eattr->rot.has_value() ? eattr->rot.value().spin :
false;
2097 if( aInstance->rot.has_value() && aInstance->rot.value().mirror )
2100 if( eattr->display.has_value() && ( eattr->display.value() ==
EATTR::Off
2106 int rotation = aInstance->rot.has_value() ?
KiROUND( aInstance->rot.value().degrees ) : 0;
2107 int reldegrees =
KiROUND( absdegrees - rotation + 360.0 );
2115 if( aInstance->smashed.has_value() && aInstance->smashed.value() )
2117 symbol->GetField(
FIELD_T::VALUE )->SetVisible( valueAttributeFound );
2129 wxCHECK2( emoduleInst,
continue );
2131 refPrefix += emoduleInst->name + wxS(
":" );
2134 symbol->AddHierarchicalReference(
m_sheetPath.Path(), refPrefix + reference, unit );
2140 symbol->SetLibSymbol( part->
Flatten().release() );
2142 for(
const auto& [
name, variant] : epart->variants )
2146 if( variant->populate.has_value() && variant->populate.value() ==
false )
2147 symbolVariant.
m_DNP =
true;
2149 if( variant->value )
2152 if( variant->technology.has_value() )
2154 auto eLibIt =
m_eagleDoc->drawing->schematic->libraries.find( epart->library );
2156 if( eLibIt ==
m_eagleDoc->drawing->schematic->libraries.end() )
2158 Report( wxString::Format( wxS(
"Library '%s' not found in schematic." ), epart->library ),
2163 auto eDeviceSetIt = eLibIt->second->devicesets.find( epart->deviceset );
2165 if( eDeviceSetIt == eLibIt->second->devicesets.end() )
2167 Report( wxString::Format( wxS(
"Device set '%s' not found in library '%s'." ),
2173 auto eDeviceIt = eDeviceSetIt->second->devices.find( epart->device );
2175 if( eDeviceIt == eDeviceSetIt->second->devices.end() )
2177 Report( wxString::Format( wxS(
"Device '%s' not found in device set '%s' in library '%s'." ),
2184 auto eTechnologyIt = eDeviceIt->second->technologies.find( variant->technology.value() );
2186 if( eTechnologyIt == eDeviceIt->second->technologies.end() )
2188 Report( wxString::Format( wxS(
"Technology '%s' not found in device '%s' in device set '%s' "
2189 "in library '%s'." ),
2190 variant->technology.value(),
2197 for(
const std::unique_ptr<EATTR>& attr : eTechnologyIt->second->attributes )
2201 if( attr->value.has_value() )
2202 attrValue = attr->value.value();
2204 symbolVariant.
m_Fields[attr->name] = attrValue;
2211 for(
const SCH_PIN*
pin : symbol->GetLibPins() )
2217 symbol->ClearFlags();
2219 screen->
Append( symbol.release() );
2225 wxCHECK( aLibrary && aEagleLibrary,
nullptr );
2232 wxString prefix = edeviceset->prefix.value_or( wxEmptyString );
2233 wxString deviceSetDescr;
2235 if( edeviceset->description )
2239 for(
const auto& [devname, edevice] : edeviceset->devices )
2241 std::vector<std::unique_ptr<LIB_SYMBOL>> derivedSymbols;
2244 wxString symbolName = edeviceset->name + edevice->name;
2245 symbolName.Replace( wxT(
"*" ), wxEmptyString );
2246 wxASSERT( !symbolName.IsEmpty() );
2249 if( edevice->package.has_value() )
2250 aEagleLibrary->
package[symbolName] = edevice->package.value();
2253 std::unique_ptr<LIB_SYMBOL> libSymbol = std::make_unique<LIB_SYMBOL>( symbolName );
2256 int gate_count =
static_cast<int>( edeviceset->gates.size() );
2258 if( gate_count > 1 )
2259 libSymbol->SetUnitCount( gate_count,
true );
2261 libSymbol->LockUnits(
true );
2265 if( prefix.length() == 0 )
2273 reference->
SetText( edevice->package.has_value() ? prefix :
'#' + prefix );
2276 libSymbol->GetValueField().SetVisible(
true );
2279 bool ispower =
false;
2281 for(
const auto& [gateName, egate] : edeviceset->gates )
2283 const auto it = aLibrary->
symbols.find( egate->symbol );
2285 if( it == aLibrary->
symbols.end() )
2287 Report( wxString::Format( wxS(
"Eagle symbol '%s' not found in library '%s'." ),
2293 wxString gateMapName = edeviceset->name + wxS(
"_" ) + edevice->name + wxS(
"_" ) + egate->name;
2295 ispower =
loadSymbol( it->second, libSymbol, edevice, gateindex, egate->name );
2300 std::vector<SCH_FIELD*> fields;
2301 libSymbol->GetFields( fields );
2304 field->SetCanAutoplace( canAutoplace );
2306 for(
const auto& [techname, technology ] : edevice->technologies )
2308 std::unique_ptr<LIB_SYMBOL> derivedSymbol;
2311 if( !technology->name.IsEmpty() )
2313 derivedSymbol = std::make_unique<LIB_SYMBOL>( symbolName + technology->name, libSymbol.get() );
2317 SCH_FIELD* childField = derivedSymbol->GetField( parentField->GetName() );
2327 for(
const std::unique_ptr<EATTR>& attr : technology->attributes )
2329 if( !attr->value.has_value() )
2334 if( !derivedSymbol )
2335 field = libSymbol->FindFieldCaseInsensitive( attr->name );
2337 field = derivedSymbol->FindFieldCaseInsensitive( attr->name );
2341 field->
SetText( attr->value.value() );
2345 SCH_FIELD* newField =
new SCH_FIELD( derivedSymbol ? derivedSymbol.get() : libSymbol.get(),
2350 SCH_FIELD* parentField = libSymbol->FindFieldCaseInsensitive( attr->name );
2357 newField->
SetText( attr->value.value() );
2362 if( !derivedSymbol )
2363 libSymbol->AddField( newField );
2365 derivedSymbol->AddField( newField );
2370 derivedSymbols.push_back( std::move( derivedSymbol ) );
2373 if( gate_count > 1 )
2374 libSymbol->SetUnitCount( gate_count,
true );
2376 if( gate_count == 1 && ispower )
2377 libSymbol->SetGlobalPower();
2380 if( edevice->package.has_value() && !edevice->package.value().IsEmpty() )
2387 libName =
m_schematic->Project().GetProjectName();
2394 wxString packageString = libName + wxT(
":" ) + aEagleLibrary->
package[symbolName];
2396 libSymbol->GetFootprintField().SetText( packageString );
2399 wxString libName = libSymbol->GetName();
2400 libSymbol->SetName( libName );
2401 libSymbol->SetDescription( deviceSetDescr );
2411 libName = aEagleLibrary->
name + wxT(
"_" ) + libName;
2413 libSymbol->SetName( libName );
2417 std::map<std::string, UTF8> properties;
2421 std::unique_ptr<LIB_SYMBOL> parentSymbol = std::make_unique<LIB_SYMBOL>( *libSymbol );
2433 Report( wxString::Format(
_(
"Could not reload saved symbol '%s'" ),
2439 for( std::unique_ptr<LIB_SYMBOL>& symbol : derivedSymbols )
2443 wxString tmp = aEagleLibrary->
name + wxT(
"_" ) + symbol->GetName();
2445 symbol->SetName( tmp );
2448 std::unique_ptr<LIB_SYMBOL> derivedSymbol = std::make_unique<LIB_SYMBOL>( *symbol );
2450 derivedSymbol->SetParent( parent );
2451 m_pi->SaveSymbol(
getLibFileName().GetFullPath(), std::move( derivedSymbol ), &properties );
2463 aEagleLibrary->
KiCadSymbols[ libName ] = std::move( libSymbol );
2467 m_userValue.emplace( std::make_pair( libName, edeviceset->uservalue.value_or(
false ) ) );
2469 for( std::unique_ptr<LIB_SYMBOL>& symbol : derivedSymbols )
2471 m_userValue.emplace( std::make_pair( symbol->GetName(), edeviceset->uservalue.value_or(
false ) ) );
2472 aEagleLibrary->
KiCadSymbols[symbol->GetName()] = std::move( symbol );
2477 return aEagleLibrary;
2482 const std::unique_ptr<EDEVICE>& aDevice,
int aGateNumber,
const wxString& aGateName )
2484 wxCHECK( aEsymbol && aSymbol && aDevice,
false );
2486 std::vector<SCH_ITEM*> items;
2488 bool showRefDes =
false;
2489 bool showValue =
false;
2490 bool ispower =
false;
2493 for(
const std::unique_ptr<ECIRCLE>& ecircle : aEsymbol->circles )
2496 for(
const std::unique_ptr<EPIN>& epin : aEsymbol->pins )
2498 std::unique_ptr<SCH_PIN>
pin(
loadPin( aSymbol, epin, aGateNumber ) );
2503 if( epin->direction.has_value() )
2507 if( epin->direction.value().Lower() == pinDir.first )
2509 pin->SetType( pinDir.second );
2511 if( pinDir.first == wxT(
"sup" ) )
2519 if( aDevice->connects.size() != 0 )
2521 for(
const std::unique_ptr<ECONNECT>& connect : aDevice->connects )
2526 if( connect->gate == aGateName && epin->name == connect->pin )
2528 wxArrayString pads = wxSplit( wxString( connect->pad ),
' ' );
2530 pin->SetUnit( aGateNumber );
2533 if( pads.GetCount() > 1 )
2535 pin->SetNumberTextSize( 0 );
2538 for(
unsigned i = 0; i < pads.GetCount(); i++ )
2542 wxString padname( pads[i] );
2544 aSymbol->AddDrawItem( apin );
2553 pin->SetUnit( aGateNumber );
2554 pin->SetNumber( wxString::Format( wxT(
"%i" ), pincount ) );
2555 aSymbol->AddDrawItem(
pin.release() );
2559 for(
const std::unique_ptr<EPOLYGON>& epolygon : aEsymbol->polygons )
2562 aSymbol->AddDrawItem( shape );
2565 for(
const std::unique_ptr<ERECT>& erectangle : aEsymbol->rectangles )
2568 for(
const std::unique_ptr<ETEXT>& etext : aEsymbol->texts )
2570 std::unique_ptr<SCH_TEXT> libtext(
loadSymbolText( aSymbol, etext, aGateNumber ) );
2572 if( libtext->GetText() == wxT(
"${REFERENCE}" ) )
2575 aSymbol->GetReferenceField().SetAttributes( *libtext );
2578 showRefDes = etext->text == wxT(
">NAME" );
2580 else if( libtext->GetText() == wxT(
"${VALUE}" ) )
2583 aSymbol->GetValueField().SetAttributes( *libtext );
2586 showValue = etext->text == wxT(
">VALUE" );
2588 else if( etext->text.StartsWith(
">" ) )
2592 wxString fieldName = etext->text.Mid( 1 );
2594 if( !fieldName.IsEmpty() )
2602 aSymbol->AddField( field );
2607 aSymbol->AddDrawItem( libtext.release() );
2611 for(
const std::unique_ptr<EWIRE>& ewire : aEsymbol->wires )
2612 aSymbol->AddDrawItem(
loadSymbolWire( aSymbol, ewire, aGateNumber ) );
2614 for(
const std::unique_ptr<EFRAME>& eframe : aEsymbol->frames )
2616 std::vector<SCH_ITEM*> frameItems;
2622 item->SetParent( aSymbol.get() );
2623 item->SetUnit( aGateNumber );
2624 aSymbol->AddDrawItem( item );
2628 aSymbol->GetReferenceField().SetVisible( showRefDes );
2629 aSymbol->GetValueField().SetVisible( showValue );
2631 return pincount == 1 ? ispower :
false;
2636 const std::unique_ptr<ECIRCLE>& aCircle,
int aGateNumber )
2638 wxCHECK( aSymbol && aCircle,
nullptr );
2642 VECTOR2I center( aCircle->x.ToSchUnits(), -aCircle->y.ToSchUnits() );
2644 circle->SetParent( aSymbol.get() );
2648 if( aCircle->width.ToSchUnits() == 0 )
2658 if( aSymbol->IsMultiUnit() )
2659 circle->SetUnit( aGateNumber );
2666 const std::unique_ptr<ERECT>& aRectangle,
int aGateNumber )
2668 wxCHECK( aSymbol && aRectangle,
nullptr );
2673 rectangle->
SetPosition(
VECTOR2I( aRectangle->x1.ToSchUnits(), -aRectangle->y1.ToSchUnits() ) );
2674 rectangle->
SetEnd(
VECTOR2I( aRectangle->x2.ToSchUnits(), -aRectangle->y2.ToSchUnits() ) );
2676 if( aRectangle->rot.has_value() )
2689 if( aSymbol->IsMultiUnit() )
2690 rectangle->
SetUnit( aGateNumber );
2701 const std::unique_ptr<EWIRE>& aWire,
int aGateNumber )
2703 wxCHECK( aSymbol && aWire,
nullptr );
2707 begin.
x = aWire->x1.ToSchUnits();
2708 begin.
y = -aWire->y1.ToSchUnits();
2709 end.x = aWire->x2.ToSchUnits();
2710 end.y = -aWire->y2.ToSchUnits();
2726 if( aWire->cap.has_value() && aWire->cap.value() ==
EWIRE::FLAT && aWire->width.ToSchUnits() >= 2 *
radius )
2729 begin =
center + centerStartVector;
2745 if( aSymbol->IsMultiUnit() )
2757 if( aSymbol->IsMultiUnit() )
2768 const std::unique_ptr<EPOLYGON>& aPolygon,
int aGateNumber )
2770 wxCHECK( aSymbol && aPolygon,
nullptr );
2772 if( !aPolygon->IsValidOutline() )
2778 std::optional<double> prev_curve;
2779 std::optional<VECTOR2I> first_pt;
2783 for(
const std::unique_ptr<EVERTEX>& evertex : aPolygon->vertices )
2785 pt =
VECTOR2I( evertex->x.ToSchUnits(), -evertex->y.ToSchUnits() );
2787 if( !first_pt.has_value() )
2790 if( prev_curve.has_value() )
2802 prev_curve = evertex->curve;
2805 if( first_pt.has_value() )
2806 poly->
AddPoint( first_pt.value() );
2811 if( aSymbol->IsMultiUnit() )
2819 const std::unique_ptr<EPIN>& aPin,
int aGateNumber )
2821 wxCHECK( aSymbol && aPin,
nullptr );
2823 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>( aSymbol.get() );
2824 pin->SetPosition(
VECTOR2I( aPin->x.ToSchUnits(), -aPin->y.ToSchUnits() ) );
2831 if( aSymbol->IsMultiUnit() )
2832 pin->SetUnit( aGateNumber );
2834 int roti = aPin->rot.has_value() ?
KiROUND( aPin->rot.value().degrees ) : 0;
2842 default: wxFAIL_MSG( wxString::Format( wxT(
"Unhandled orientation (%d degrees)." ), roti ) );
2847 if( aPin->length.has_value() )
2849 if( aPin->length.value() == wxT(
"short" ) )
2851 else if( aPin->length.value() == wxT(
"middle" ) )
2853 else if( aPin->length.value() == wxT(
"long" ) )
2855 else if( aPin->length.value() == wxT(
"point" ) )
2864 if( aPin->visible.has_value() )
2866 if( aPin->visible.value() == wxT(
"off" ) )
2868 pin->SetNameTextSize( 0 );
2869 pin->SetNumberTextSize( 0 );
2871 else if( aPin->visible.value() == wxT(
"pad" ) )
2873 pin->SetNameTextSize( 0 );
2875 else if( aPin->visible.value() == wxT(
"pin" ) )
2877 pin->SetNumberTextSize( 0 );
2887 if( aPin->function.has_value() )
2889 if( aPin->function.value() == wxT(
"dot" ) )
2891 else if( aPin->function.value() == wxT(
"clk" ) )
2893 else if( aPin->function.value() == wxT(
"dotclk" ) )
2897 return pin.release();
2902 const std::unique_ptr<ETEXT>& aText,
int aGateNumber )
2904 wxCHECK( aSymbol && aText,
nullptr );
2906 std::unique_ptr<SCH_TEXT> libtext = std::make_unique<SCH_TEXT>();
2909 libtext->SetParent( aSymbol.get() );
2911 if( aSymbol->IsMultiUnit() )
2912 libtext->SetUnit( aGateNumber );
2914 libtext->SetPosition(
VECTOR2I( aText->x.ToSchUnits(), -aText->y.ToSchUnits() ) );
2916 const wxString& eagleText = aText->text;
2917 wxString adjustedText;
2918 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2921 while( tokenizer.HasMoreTokens() )
2923 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2925 if( tokenizer.HasMoreTokens() )
2928 adjustedText += tmp;
2931 libtext->SetText( adjustedText.IsEmpty() ? wxString( wxS(
"~" ) ) : adjustedText );
2935 return libtext.release();
2941 wxCHECK( aText,
nullptr );
2943 std::unique_ptr<SCH_TEXT> schtext = std::make_unique<SCH_TEXT>();
2945 const wxString& eagleText = aText->text;
2946 wxString adjustedText;
2947 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2950 while( tokenizer.HasMoreTokens() )
2952 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2954 if( tokenizer.HasMoreTokens() )
2957 adjustedText += tmp;
2960 schtext->SetText( adjustedText.IsEmpty() ? wxString( wxS(
"\" \"" ) )
2963 schtext->SetPosition(
VECTOR2I( aText->x.ToSchUnits(), -aText->y.ToSchUnits() ) );
2965 schtext->SetItalic(
false );
2967 return schtext.release();
2973 wxCHECK( aText && aAttributes, );
2978 if( aAttributes->ratio.value_or( 8 ) > 12 )
2982 int degrees = aAttributes->rot.has_value() ?
KiROUND( aAttributes->rot.value().degrees ) : 0;
2983 bool mirror = aAttributes->rot.has_value() ? aAttributes->rot.value().mirror :
false;
2984 bool spin = aAttributes->rot.has_value() ? aAttributes->rot.value().spin :
false;
2999 auto onIntersection =
3010 const SEG* segAttached = segDesc.LabelAttached( label );
3012 if( segAttached && !onIntersection( labelPos ) )
3025 VECTOR2I wireDirection( segAttached->
B - segAttached->
A );
3027 if( ( wireDirection.
x == 0 ) && (wireDirection.
y == 0 ) )
3031 const VECTOR2I origPos( labelPos );
3034 bool checkPositive =
true;
3035 bool checkNegative =
true;
3040 while( ( !
move || onIntersection( labelPos ) ) && ( checkPositive || checkNegative ) )
3045 if( trial % 2 == 1 )
3047 labelPos =
VECTOR2I( origPos + wireDirection * trial / 2 );
3048 move = checkPositive = segAttached->
Contains( labelPos );
3052 labelPos =
VECTOR2I( origPos - wireDirection * trial / 2 );
3053 move = checkNegative = segAttached->
Contains( labelPos );
3063 if( wireDirection.
x == 0 )
3065 if( wireDirection.
y < 0 )
3070 else if( wireDirection.
y == 0 )
3072 if( wireDirection.
x < 0 )
3106 wxFileInputStream input( aFileName );
3115 wxTextInputStream
text( input );
3117 for(
int i = 0; i < 8; i++ )
3122 if(
text.ReadLine().Contains( wxS(
"<eagle" ) ) )
3140 if( !item->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
3144 item->SetPosition( aNewEndPoint );
3157 std::vector<SCH_LINE*> buses;
3158 std::vector<SCH_LINE*> wires;
3169 buses.push_back( line );
3170 else if( line->
IsWire() )
3171 wires.push_back( line );
3176 VECTOR2I wireStart = wire->GetStartPoint();
3177 VECTOR2I wireEnd = wire->GetEndPoint();
3181 VECTOR2I busStart = bus->GetStartPoint();
3182 VECTOR2I busEnd = bus->GetEndPoint();
3185 [](
int signX,
int signY ) ->
VECTOR2I
3197 if( wireStart.
y == wireEnd.
y && busStart.
x == busEnd.
x )
3201 if( testBusHit( wireStart ) )
3205 if( wireEnd.
x < busStart.
x )
3212 VECTOR2I p = wireStart + entrySize( -1, 0 );
3214 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
3223 screen->
Append( busEntry );
3225 wire->SetStartPoint( p );
3227 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
3236 screen->
Append( busEntry );
3238 wire->SetStartPoint( p );
3253 VECTOR2I p = wireStart + entrySize( 1, 0 );
3255 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
3264 screen->
Append( busEntry );
3266 wire->SetStartPoint( p );
3268 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
3277 screen->
Append( busEntry );
3279 wire->SetStartPoint( p );
3290 else if( testBusHit( wireEnd ) )
3294 if( wireStart.
x < busStart.
x )
3301 VECTOR2I p = wireEnd + entrySize( -1, 0 );
3303 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3312 screen->
Append( busEntry );
3314 wire->SetEndPoint( p );
3316 else if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3325 screen->
Append( busEntry );
3326 moveLabels( wire, wireEnd + entrySize( -1, 0 ) );
3327 wire->SetEndPoint( wireEnd + entrySize( -1, 0 ) );
3342 VECTOR2I p = wireEnd + entrySize( 1, 0 );
3344 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3353 screen->
Append( busEntry );
3355 wire->SetEndPoint( p );
3357 else if( testBusHit( wireEnd + entrySize( 0, 1 ) ) )
3366 screen->
Append( busEntry );
3368 wire->SetEndPoint( p );
3380 else if( wireStart.
x == wireEnd.
x && busStart.
y == busEnd.
y )
3384 if( testBusHit( wireStart ) )
3388 if( wireEnd.
y < busStart.
y )
3396 VECTOR2I p = wireStart + entrySize( 0, -1 );
3398 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3408 screen->
Append( busEntry );
3410 wire->SetStartPoint( p );
3412 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3422 screen->
Append( busEntry );
3424 wire->SetStartPoint( p );
3440 VECTOR2I p = wireStart + entrySize( 0, 1 );
3442 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3452 screen->
Append( busEntry );
3454 wire->SetStartPoint( p );
3456 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3466 screen->
Append( busEntry );
3468 wire->SetStartPoint( p );
3479 else if( testBusHit( wireEnd ) )
3483 if( wireStart.
y < busStart.
y )
3491 VECTOR2I p = wireEnd + entrySize( 0, -1 );
3493 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3503 screen->
Append( busEntry );
3505 wire->SetEndPoint( p );
3507 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3517 screen->
Append( busEntry );
3519 wire->SetEndPoint( p );
3535 VECTOR2I p = wireEnd + entrySize( 0, 1 );
3537 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3547 screen->
Append( busEntry );
3549 wire->SetEndPoint( p );
3551 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3561 screen->
Append( busEntry );
3563 wire->SetEndPoint( p );
3579 if( testBusHit( wireStart ) )
3581 VECTOR2I wirevector = wireStart - wireEnd;
3583 if( wirevector.
x > 0 )
3585 if( wirevector.
y > 0 )
3587 VECTOR2I p = wireStart + entrySize( -1, -1 );
3590 screen->
Append( busEntry );
3593 wire->SetStartPoint( p );
3597 VECTOR2I p = wireStart + entrySize( -1, 1 );
3600 screen->
Append( busEntry );
3603 wire->SetStartPoint( p );
3608 if( wirevector.
y > 0 )
3610 VECTOR2I p = wireStart + entrySize( 1, -1 );
3613 screen->
Append( busEntry );
3616 wire->SetStartPoint( p );
3620 VECTOR2I p = wireStart + entrySize( 1, 1 );
3623 screen->
Append( busEntry );
3626 wire->SetStartPoint( p );
3632 else if( testBusHit( wireEnd ) )
3634 VECTOR2I wirevector = wireStart - wireEnd;
3636 if( wirevector.
x > 0 )
3638 if( wirevector.
y > 0 )
3640 VECTOR2I p = wireEnd + entrySize( 1, 1 );
3643 screen->
Append( busEntry );
3646 wire->SetEndPoint( p );
3650 VECTOR2I p = wireEnd + entrySize( 1, -1 );
3653 screen->
Append( busEntry );
3656 wire->SetEndPoint( p );
3661 if( wirevector.
y > 0 )
3663 VECTOR2I p = wireEnd + entrySize( -1, 1 );
3666 screen->
Append( busEntry );
3669 wire->SetEndPoint( p );
3673 VECTOR2I p = wireEnd + entrySize( -1, -1 );
3676 screen->
Append( busEntry );
3679 wire->SetEndPoint( p );
3693 wxCHECK( aLabel,
nullptr );
3699 if( seg.Contains( labelPos ) )
3711 wxCHECK( aSymbol && aPin,
false );
3719 const std::set<const EDA_ITEM*>& items = pointIt->second;
3721 wxCHECK( items.find( aPin ) != items.end(),
false );
3723 return items.size() > 1;
3736 int unit = aSymbol->
GetUnit();
3739 std::set<int> missingUnits;
3746 bool pinInUnit = !unit ||
pin->GetUnit() == unit;
3759 switch(
pin->GetOrientation() )
3768 aScreen->
Append( netLabel );
3771 else if( aUpdateSet )
3776 wxASSERT(
pin->GetUnit() );
3777 missingUnits.insert(
pin->GetUnit() );
3790 entry.
cmp = aSymbol;
3792 entry.
units.emplace( unit,
false );
3797 cmpIt->second.units[unit] =
false;
3800 if( !missingUnits.empty() )
3803 entry.
cmp = aSymbol;
3807 for(
int i : missingUnits )
3809 if( entry.
units.find( i ) != entry.
units.end() )
3810 entry.
units.emplace( i,
true );
3822 wxString ret = wxT(
"{" );
3824 wxStringTokenizer tokenizer( aEagleName,
"," );
3826 while( tokenizer.HasMoreTokens() )
3828 wxString member = tokenizer.GetNextToken();
3835 if( member.Freq(
'!' ) % 2 > 0 )
3836 member << wxT(
"!" );
3838 ret << member << wxS(
" " );
3852 std::unique_ptr<EPART>& epart =
m_eagleDoc->drawing->schematic->parts[aInstance->part];
3854 if( !epart || epart->deviceset.IsEmpty() )
3857 std::unique_ptr<ELIBRARY>& elibrary =
m_eagleDoc->drawing->schematic->libraries[epart->library];
3862 std::unique_ptr<EDEVICE_SET>& edeviceset = elibrary->devicesets[epart->deviceset];
3867 std::unique_ptr<EGATE>& egate = edeviceset->gates[aInstance->gate];
3872 std::unique_ptr<ESYMBOL>& esymbol = elibrary->symbols[egate->symbol];
3875 return esymbol.get();
3882 const wxString& aEagleFieldName,
3885 wxCHECK( aField && !aEagleFieldName.
IsEmpty(), );
3891 for(
const std::unique_ptr<ETEXT>&
text : esymbol->
texts )
3893 if(
text->text == aEagleFieldName )
3896 VECTOR2I pos(
text->x.ToSchUnits() + aInstance->x.ToSchUnits(),
3897 -
text->y.ToSchUnits() - aInstance->y.ToSchUnits() );
3899 bool mirror =
text->rot ?
text->rot->mirror :
false;
3901 if( aInstance->rot.has_value() && aInstance->rot.value().mirror )
3905 pos.
y = -aInstance->y.ToSchUnits() +
text->y.ToSchUnits();
3918 std::vector<SCH_FIELD*> fields;
3923 retv = fields[0]->GetPosition();
3925 for(
size_t i = 1; i < fields.size(); i++ )
3927 if( fields[i]->GetPosition().x > retv.
x )
3928 retv.
x = fields[i]->GetPosition().x;
3930 if( fields[i]->GetPosition().y > retv.
y )
3931 retv.
y = fields[i]->GetPosition().y;
constexpr EDA_IU_SCALE schIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
constexpr size_type GetWidth() const
constexpr Vec Centre() const
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr size_type GetHeight() const
constexpr const SizeVec & GetSize() const
Read-only parser for the pre-v6 binary Eagle .brd format.
std::unique_ptr< wxXmlDocument > Parse(const std::vector< uint8_t > &aBytes)
Parse a binary Eagle board into an XML DOM compatible with the XML walker.
static bool IsBinaryEagle(wxInputStream &aStream)
Probe the first two bytes for the binary magic without changing the stream position.
void SetFlags(EDA_ITEM_FLAGS aMask)
virtual void SetParent(EDA_ITEM *aParent)
virtual void SetEnd(const VECTOR2I &aEnd)
void SetCenter(const VECTOR2I &aCenter)
SHAPE_POLY_SET & GetPolyShape()
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
virtual void SetWidth(int aWidth)
void SetFillMode(FILL_T aFill)
virtual void SetStart(const VECTOR2I &aStart)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
virtual const wxString & GetText() const
Return the string associated with the text object.
virtual void SetTextPos(const VECTOR2I &aPoint)
virtual int GetTextHeight() const
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
void SetBold(bool aBold)
Set the text to be bold - this will also update the font if needed.
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
EE_TYPE Overlapping(const BOX2I &aRect) const
ee_rtree::Iterator begin() const
Return a read/write iterator that points to the first.
ee_rtree::Iterator end() const
Return a read/write iterator that points to one past the last element in the EE_RTREE.
EE_TYPE OfType(KICAD_T aType) const
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
RAII class to set and restore the fontconfig reporter.
virtual void Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) const
PROGRESS_REPORTER * m_progressReporter
Progress reporter to track the progress of the operation, may be nullptr.
virtual bool CanReadLibrary(const wxString &aFileName) const
Checks if this IO object can read the specified library file/directory.
void ReloadLibraryEntry(const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH)
Synchronously recreates the plugin for and reloads the given library.
std::optional< LIBRARY_TABLE * > ProjectTable() const
Retrieves the project library table for this adapter type, or nullopt if one doesn't exist.
void SetNickname(const wxString &aNickname)
void SetType(const wxString &aType)
void SetURI(const wxString &aUri)
A logical library item identifier and consists of various portions much like a URI.
static UTF8 FixIllegalChars(const UTF8 &aLibItemName, bool aLib)
Replace illegal LIB_ID item name characters with underscores '_'.
Define a library symbol object.
void GetFields(std::vector< SCH_FIELD * > &aList, bool aVisibleOnly=false) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
bool IsGlobalPower() const override
int GetUnitCount() const override
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
std::vector< SCH_PIN * > GetGraphicalPins(int aUnit=0, int aBodyStyle=0) const override
Graphical pins: Return schematic pin objects as drawn (unexpanded), filtered by unit/body.
static LOAD_INFO_REPORTER & GetInstance()
static bool ParseBusVector(const wxString &aBus, wxString *aName, std::vector< wxString > *aMemberList)
Parse a bus vector (e.g.
Describe the page size and margins of a paper page on which to eventually print or plot.
void SetHeightMils(double aHeightInMils)
const VECTOR2D GetSizeIU(double aIUScale) const
Gets the page size in internal units.
void SetWidthMils(double aWidthInMils)
static SYMBOL_LIBRARY_ADAPTER * SymbolLibAdapter(PROJECT *aProject)
Accessor for project symbol library manager adapter.
Holds all the data relating to one schematic.
PROJECT & Project() const
Return a reference to the project this schematic is part of.
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
Class for a wire to bus entry.
virtual const wxString & GetText() const override
Return the string associated with the text object.
void SetCanAutoplace(bool aCanPlace)
void ImportValues(const SCH_FIELD &aSource)
Copy parameters from a SCH_FIELD source.
bool IsEmpty()
Return true if both the name and value of the field are empty.
void SetPosition(const VECTOR2I &aPosition) override
void SetName(const wxString &aName)
void SetText(const wxString &aText) override
void SetSpinStyle(SPIN_STYLE aSpinStyle) override
std::unique_ptr< EAGLE_DOC > m_eagleDoc
The fully parsed Eagle schematic file.
SCH_ITEM * loadWire(const std::unique_ptr< EWIRE > &aWire, SEG &endpoints)
void loadTextAttributes(EDA_TEXT *aText, const std::unique_ptr< ETEXT > &aAttributes) const
void loadSegments(const std::vector< std::unique_ptr< ESEGMENT > > &aSegments, const wxString &aNetName, const wxString &aNetClass, bool aIsBus=false)
void loadModuleInstance(const std::unique_ptr< EMODULEINST > &aModuleInstance)
void ensureLoadedLibrary(const wxString &aLibraryPath)
void loadSchematic(const ESCHEMATIC &aSchematic)
SCH_TEXT * loadPlainText(const std::unique_ptr< ETEXT > &aSchText)
void loadSheet(const std::unique_ptr< ESHEET > &aSheet)
void loadLayerDefs(const std::vector< std::unique_ptr< ELAYER > > &aLayers)
VECTOR2I getLastSymbolFieldPosition(const LIB_SYMBOL *aPart)
const ESYMBOL * getEagleSymbol(const std::unique_ptr< EINSTANCE > &aInstance)
EAGLE_LIBRARY * loadLibrary(const ELIBRARY *aLibrary, EAGLE_LIBRARY *aEagleLib)
wxXmlDocument loadXmlDocument(const wxString &aFileName)
wxString translateEagleBusName(const wxString &aEagleName) const
Translate an Eagle-style bus name into one that is KiCad-compatible.
std::map< wxString, wxString > m_powerPorts
map from symbol reference to global label equivalent
SCH_SHEET_PATH m_sheetPath
The current sheet path of the schematic being loaded.
wxString m_libName
Library name to save symbols.
SCH_TEXT * loadSymbolText(std::unique_ptr< LIB_SYMBOL > &aSymbol, const std::unique_ptr< ETEXT > &aText, int aGateNumber)
std::pair< VECTOR2I, const SEG * > findNearestLinePoint(const VECTOR2I &aPoint, const std::vector< SEG > &aLines) const
std::map< wxString, long long > m_timestamps
void adjustNetLabels()
Move net labels that are detached from any wire to the nearest wire.
SCH_LABEL_BASE * loadLabel(const std::unique_ptr< ELABEL > &aLabel, const wxString &aNetName, bool aIsBus=false)
void loadInstance(const std::unique_ptr< EINSTANCE > &aInstance, const std::map< wxString, std::unique_ptr< EPART > > &aParts)
LIB_SYMBOL * LoadSymbol(const wxString &aLibraryPath, const wxString &aAliasName, const std::map< std::string, UTF8 > *aProperties) override
Load a LIB_SYMBOL object having aPartName from the aLibraryPath containing a library format that this...
std::unordered_map< wxString, bool > m_userValue
deviceset/@uservalue for device.
int GetModifyHash() const override
Return the modification hash from the library cache.
std::map< wxString, int > m_netCounts
std::map< wxString, EAGLE_LIBRARY > m_eagleLibs
bool loadSymbol(const std::unique_ptr< ESYMBOL > &aEsymbol, std::unique_ptr< LIB_SYMBOL > &aSymbol, const std::unique_ptr< EDEVICE > &aDevice, int aGateNumber, const wxString &aGateName)
SCH_SHEET * getCurrentSheet()
void loadDrawing(const std::unique_ptr< EDRAWING > &aDrawing)
void EnumerateSymbolLib(wxArrayString &aSymbolNameList, const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties) override
Populate a list of LIB_SYMBOL alias names contained within the library aLibraryPath.
SCH_SHAPE * loadSymbolPolyLine(std::unique_ptr< LIB_SYMBOL > &aSymbol, const std::unique_ptr< EPOLYGON > &aPolygon, int aGateNumber)
std::vector< VECTOR2I > m_wireIntersections
Wire intersection points, used for quick checks whether placing a net label in a particular place wou...
std::map< VECTOR2I, std::set< const EDA_ITEM * > > m_connPoints
Positions of pins and wire endings mapped to its parent.
bool checkConnections(const SCH_SYMBOL *aSymbol, const SCH_PIN *aPin) const
Checks if there are other wires or pins at the position of the tested pin.
IO_RELEASER< SCH_IO > m_pi
PI to create KiCad symbol library.
SCH_SHAPE * loadRectangle(const std::unique_ptr< ERECT > &aRect)
void addBusEntries()
This function finds best way to place a bus entry symbol for when an Eagle wire segment ends on an Ea...
bool CanReadSchematicFile(const wxString &aFileName) const override
Checks if this SCH_IO can read the specified schematic file.
void addImplicitConnections(SCH_SYMBOL *aSymbol, SCH_SCREEN *aScreen, bool aUpdateSet)
Create net labels to emulate implicit connections in Eagle.
std::map< int, SCH_LAYER_ID > m_layerMap
SCH_LAYER_ID kiCadLayer(int aEagleLayer)
Return the matching layer or return LAYER_NOTES.
SCH_SHEET * LoadSchematicFile(const wxString &aFileName, SCHEMATIC *aSchematic, SCH_SHEET *aAppendToMe=nullptr, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load information from some input file format that this SCH_IO implementation knows about,...
SCH_PIN * loadPin(std::unique_ptr< LIB_SYMBOL > &aSymbol, const std::unique_ptr< EPIN > &aPin, int aGateNumber)
SCH_SHAPE * loadCircle(const std::unique_ptr< ECIRCLE > &aCircle)
wxFileName getLibFileName()
SCH_SHAPE * loadSymbolRectangle(std::unique_ptr< LIB_SYMBOL > &aSymbol, const std::unique_ptr< ERECT > &aRectangle, int aGateNumber)
SCH_JUNCTION * loadJunction(const std::unique_ptr< EJUNCTION > &aJunction)
wxString m_version
Eagle file version.
void getEagleSymbolFieldAttributes(const std::unique_ptr< EINSTANCE > &aInstance, const wxString &aEagleFieldName, SCH_FIELD *aField)
std::map< wxString, const EPART * > m_partlist
void moveLabels(SCH_LINE *aWire, const VECTOR2I &aNewEndPoint)
Move any labels on the wire to the new end point of the wire.
bool checkHeader(const wxString &aFileName) const
SCHEMATIC * m_schematic
Passed to Load(), the schematic object being loaded.
void countNets(const ESCHEMATIC &aSchematic)
SCH_SHEET * m_rootSheet
The root sheet of the schematic being loaded.
SCH_SHAPE * loadPolyLine(const std::unique_ptr< EPOLYGON > &aPolygon)
SCH_SHAPE * loadSymbolCircle(std::unique_ptr< LIB_SYMBOL > &aSymbol, const std::unique_ptr< ECIRCLE > &aCircle, int aGateNumber)
SCH_SCREEN * getCurrentScreen()
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this IO object can read the specified library file/directory.
std::map< wxString, EAGLE_MISSING_CMP > m_missingCmps
Map references to missing symbol units data.
void loadFrame(const std::unique_ptr< EFRAME > &aFrame, std::vector< SCH_ITEM * > &aItems, SCH_LAYER_ID aLayer=LAYER_NOTES)
std::vector< SEG_DESC > m_segments
Segments representing wires for intersection checking.
std::vector< EMODULE * > m_modules
The current module stack being loaded.
std::vector< EMODULEINST * > m_moduleInstances
SCH_ITEM * loadSymbolWire(std::unique_ptr< LIB_SYMBOL > &aSymbol, const std::unique_ptr< EWIRE > &aWire, int aGateNumber)
long long getLibraryTimestamp(const wxString &aLibraryPath) const
static const char * PropBuffering
The property used internally by the plugin to enable cache buffering which prevents the library file ...
virtual bool CanReadSchematicFile(const wxString &aFileName) const
Checks if this SCH_IO can read the specified schematic file.
SCH_IO(const wxString &aName)
Base class for any item which can be embedded within the SCHEMATIC container class,...
SCH_ITEM * Duplicate(bool addToParentGroup, SCH_COMMIT *aCommit=nullptr, bool aDoClone=false) const
Routine to create a new copy of given item.
void SetLayer(SCH_LAYER_ID aLayer)
virtual void SetUnit(int aUnit)
void SetShape(LABEL_FLAG_SHAPE aShape)
void SetPosition(const VECTOR2I &aPosition) override
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Segment description base class to describe items which have 2 end points (track, wire,...
bool IsWire() const
Return true if the line is a wire.
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
VECTOR2I GetEndPoint() const
VECTOR2I GetStartPoint() const
bool IsBus() const
Return true if the line is a bus.
void SetEndPoint(const VECTOR2I &aPosition)
void SetNumber(const wxString &aNumber)
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
void UpdateSymbolLinks(REPORTER *aReporter=nullptr)
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in the full schematic.
const PAGE_INFO & GetPageSettings() const
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
void SetPageSettings(const PAGE_INFO &aPageSettings)
EE_RTREE & Items()
Get the full RTree, usually for iterating.
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
void Update(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Refresh a changed item in the tree and invalidate connectivity.
void SetPosition(const VECTOR2I &aPos) override
void SetStroke(const STROKE_PARAMS &aStroke) override
VECTOR2I GetCenter() const
void AddPoint(const VECTOR2I &aPosition)
VECTOR2I GetPosition() const override
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Define a sheet pin (label) used in sheets to create hierarchical schematics.
void SetPosition(const VECTOR2I &aPosition) override
void SetSide(SHEET_SIDE aEdge)
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
void SetFileName(const wxString &aFilename)
bool LocatePathOfScreen(SCH_SCREEN *aScreen, SCH_SHEET_PATH *aList)
Search the existing hierarchy for an instance of screen loaded from aFileName.
void SetName(const wxString &aName)
SCH_SCREEN * GetScreen() const
void AutoplaceFields(SCH_SCREEN *aScreen, AUTOPLACE_ALGO aAlgo) override
Variant information for a schematic symbol.
const std::vector< SCH_SYMBOL_INSTANCE > & GetInstances() const
void AddHierarchicalReference(const KIID_PATH &aPath, const wxString &aRef, int aUnit)
Add a full hierarchical reference to this symbol.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
VECTOR2I GetPinPhysicalPosition(const SCH_PIN *Pin) const
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
VECTOR2I GetPosition() const override
void SetPosition(const VECTOR2I &aPosition) override
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
bool Contains(const SEG &aSeg) const
SHAPE_ARC & ConstructFromStartEndAngle(const VECTOR2I &aStart, const VECTOR2I &aEnd, const EDA_ANGLE &aAngle, double aWidth=0)
Construct this arc from the given start, end and angle.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
Simple container to manage line stroke parameters.
An interface to the global shared library manager that is schematic-specific and linked to one projec...
std::optional< LIB_STATUS > LoadOne(LIB_DATA *aLib) override
Loads or reloads the given library, if it exists.
std::map< wxString, wxString > m_Fields
double Distance(const VECTOR2< extended_type > &aVector) const
Compute the distance between two vectors.
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
#define DEFAULT_SCH_ENTRY_SIZE
The default bus and wire entry size in mils.
wxString escapeName(const wxString &aNetName)
Translates Eagle special characters to their counterparts in KiCad.
wxString interpretText(const wxString &aText)
Interprets special characters in Eagle text and converts them to KiCAD notation.
size_t GetNodeCount(const wxXmlNode *aNode)
Fetch the number of XML nodes within aNode.
VECTOR2I ConvertEagleTextSize(const std::optional< wxString > &font, const ECOORD &size)
Converts Eagle's text size to KiCad text size depending on the font used.
VECTOR2I ConvertArcCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, double aAngle)
Convert an Eagle curve end to a KiCad center for S_ARC.
wxString convertDescription(wxString aDescr)
Converts Eagle's HTML description into KiCad description format.
static constexpr EDA_ANGLE ANGLE_VERTICAL
@ FILLED_SHAPE
Fill with object color.
#define IGNORE_PARENT_GROUP
#define IS_NEW
New item, just created.
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
@ ERCE_BUS_ENTRY_NEEDED
Importer failed to auto-place a bus entry.
bool m_EagleImportFieldsCanAutoplace
Default CanAutoplace value for fields imported from EAGLE files.
#define THROW_IO_ERRORF(msg,...)
#define THROW_IO_CANCELLED()
static const std::string KiCadSchematicFileExtension
static const std::string KiCadSymbolLibFileExtension
SCH_LAYER_ID
Eeschema drawing layers.
@ PT_INPUT
usual pin input: must be connected
@ PT_NC
not connected (must be left open)
@ PT_TRISTATE
tri state bus pin
@ PT_BIDI
input or output (like port for a microprocessor)
@ PT_OPENCOLLECTOR
pin type open collector
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin.
@ 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.
static wxString extractNetName(const wxString &aPinName)
Strip the Eagle "@<tag>" linking hint from a pin name (e.g. return 'GND' for 'GND@2')
static const std::map< wxString, ELECTRICAL_PINTYPE > pinDirectionsMap
Map of EAGLE pin type values to KiCad pin type values.
static SYMBOL_ORIENTATION_T kiCadComponentRotation(float eagleDegrees)
static void eagleToKicadAlignment(EDA_TEXT *aText, int aEagleAlignment, int aRelDegress, bool aMirror, bool aSpin, int aAbsDegress)
static BOX2I getSheetBbox(SCH_SHEET *aSheet)
Compute a bounding box for all items in a schematic sheet.
LABEL_FLAG_SHAPE
Label and flag shapes used with text objects.
LABEL_SHAPE
Specific enums for property manager (not used elsewhere)
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
SHEET_SIDE
Define the edge of the sheet that the sheet pin is positioned.
std::optional< VECTOR2I > OPT_VECTOR2I
wxString UnescapeString(const wxString &aSource)
bool ReplaceIllegalFileNameChars(std::string &aName, int aReplaceChar)
Checks aName for illegal file name characters.
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
wxString UnescapeHTML(const wxString &aString)
Return a new wxString unescaped from HTML format.
std::map< wxString, std::unique_ptr< LIB_SYMBOL > > KiCadSymbols
std::unordered_map< wxString, wxString > package
std::unordered_map< wxString, int > GateToUnitMap
Map Eagle gate unit number (which are strings) to KiCad library symbol unit number.
std::map< wxString, std::unique_ptr< EDEVICE_SET > > devicesets
wxString GetName() const
Fetch the fully unique library name.
std::map< wxString, std::unique_ptr< ESYMBOL > > symbols
std::optional< wxString > direction
std::map< wxString, std::unique_ptr< EMODULE > > modules
std::vector< std::unique_ptr< ESHEET > > sheets
std::map< wxString, std::unique_ptr< EPART > > parts
std::map< wxString, std::unique_ptr< ELIBRARY > > libraries
std::map< wxString, std::unique_ptr< EVARIANTDEF > > variantdefs
std::vector< std::unique_ptr< ETEXT > > texts
const SCH_SYMBOL * cmp
Link to the parent symbol.
SCH_SCREEN * screen
Screen where the parent symbol is located.
std::map< int, bool > units
Wires and labels of a single connection (segment in Eagle nomenclature)
std::vector< SCH_LABEL_BASE * > labels
const SEG * LabelAttached(const SCH_LABEL_BASE *aLabel) const
Test if a particular label is attached to any of the stored segments.
A simple container for schematic symbol instance information.
SYMBOL_ORIENTATION_T
enum used in RotationMiroir()
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".
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
bool TestSegmentHit(const VECTOR2I &aRefPoint, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
VECTOR2< int32_t > VECTOR2I
Definition of file extensions used in Kicad.