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 );
458 m_eagleDoc = std::make_unique<EAGLE_DOC>( currentNode,
this );
491 const wxString& aLibraryPath,
492 const std::map<std::string, UTF8>* aProperties )
503 for(
const auto& [symName, libSymbol] : it->second.KiCadSymbols )
504 aSymbolNameList.push_back( symName );
510 const wxString& aLibraryPath,
511 const std::map<std::string, UTF8>* aProperties )
522 for(
const auto& [symName, libSymbol] : it->second.KiCadSymbols )
523 aSymbolList.push_back( libSymbol.get() );
529 const std::map<std::string, UTF8>* aProperties )
540 auto it2 = it->second.KiCadSymbols.find( aAliasName );
542 if( it2 != it->second.KiCadSymbols.end() )
543 return it2->second.get();
552 wxFileName fn( aLibraryPath );
554 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
555 return fn.GetModificationTime().GetValue().GetValue();
586 std::unique_ptr<EAGLE_DOC> doc = std::make_unique<EAGLE_DOC>( xmlDocument.GetRoot(),
this );
590 m_version = ( doc->version.IsEmpty() ) ? wxString( wxS(
"0.0" ) ) : doc->version;
602 wxXmlDocument xmlDocument;
603 wxFFileInputStream stream(
m_filename.GetFullPath() );
614 std::vector<uint8_t>
bytes;
615 bytes.resize(
static_cast<size_t>( stream.GetLength() ) );
618 if( stream.LastRead() !=
bytes.size() )
622 std::unique_ptr<wxXmlDocument> binDocument = binParser.
Parse(
bytes );
624 xmlDocument.SetRoot( binDocument->DetachRoot() );
629 wxTextInputStream
text( stream );
630 wxString line =
text.ReadLine();
632 if( !line.StartsWith( wxT(
"<?xml" ) ) && !line.StartsWith( wxT(
"<!--" ) )
633 && !line.StartsWith( wxT(
"<eagle " ) ) )
635 THROW_IO_ERRORF(
_(
"'%s' is an Eagle binary-format file; only Eagle XML-format files can be imported." ),
639#if wxCHECK_VERSION( 3, 3, 0 )
642 if( !xmlDocument.Load( stream, wxXMLDOC_NONE, &err ) )
644 if( err.message == wxS(
"no element found" ) )
648 wxMemoryOutputStream memOutput;
651 header <<
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
652 header <<
"<!DOCTYPE eagle SYSTEM \"eagle.dtd\">\n";
654 wxScopedCharBuffer headerBuf = header.utf8_str();
655 memOutput.Write( headerBuf.data(), headerBuf.length() );
657 wxFFileInputStream stream2(
m_filename.GetFullPath() );
658 memOutput.Write( stream2 );
660 wxMemoryInputStream memInput( memOutput );
662 if( !xmlDocument.Load( memInput, wxXMLDOC_NONE, &err ) )
669 THROW_IO_ERRORF(
_(
"Unable to read file '%s'.\n'%s' at line %d, column %d, offset %d" ),
670 m_filename.GetFullPath(), err.message, err.line, err.column, err.offset );
674 if( !xmlDocument.Load( stream ) )
678 wxMemoryOutputStream memOutput;
681 header <<
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
682 header <<
"<!DOCTYPE eagle SYSTEM \"eagle.dtd\">\n";
684 wxScopedCharBuffer headerBuf = header.utf8_str();
685 memOutput.Write( headerBuf.data(), headerBuf.length() );
687 wxFFileInputStream stream2(
m_filename.GetFullPath() );
688 memOutput.Write( stream2 );
690 wxMemoryInputStream memInput( memOutput );
692 if( !xmlDocument.Load( memInput ) )
703 wxCHECK( aDrawing, );
707 if( aDrawing->library )
715 if( aDrawing->schematic )
722 for(
const std::unique_ptr<ESHEET>& esheet : aSchematic.
sheets )
724 for(
const std::unique_ptr<ENET>& enet : esheet->nets )
726 wxString netName = enet->netname;
735 for(
const auto& [modname, emodule] : aSchematic.
modules )
737 for(
const std::unique_ptr<ESHEET>& esheet : emodule->sheets )
739 for(
const std::unique_ptr<ENET>& enet : esheet->nets )
741 wxString netName = enet->netname;
756 if( aSchematic.
sheets.empty() )
763 if( variantDef->current.value_or(
false ) )
768 for(
const auto& [
name, epart] : aSchematic.
parts )
771 for(
const auto& [modName, emodule] : aSchematic.
modules )
773 for(
const auto& [partName, epart] : emodule->parts )
779 for(
const auto& [libName, elibrary] : aSchematic.
libraries )
782 elib->
name = elibrary->GetName();
798 std::vector<SCH_SHEET*> eaglePages;
799 eaglePages.reserve( aSchematic.
sheets.size() );
801 for(
const std::unique_ptr<ESHEET>& esheet : aSchematic.
sheets )
805 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>(
m_rootSheet );
807 sheet->SetScreen( screen );
809 wxCHECK2( sheet && screen,
continue );
811 wxString pageNo = wxString::Format( wxT(
"%d" ),
m_sheetIndex );
819 eaglePages.push_back( sheet.release() );
824 if( !eaglePages.empty() )
849 struct MISSING_UNIT_PLACEMENT
859 std::map<SCH_SCREEN*, MISSING_UNIT_PLACEMENT> placements;
863 const SCH_SYMBOL* origSymbol = cmp.second.cmp;
865 for(
auto& unitEntry : cmp.second.units )
867 if( unitEntry.second ==
false )
871 int unit = unitEntry.first;
882 targetScreen = fallbackSheet->
GetScreen();
884 targetScreen = schematicRoot->
GetScreen();
887 auto placementIt = placements.find( targetScreen );
889 if( placementIt == placements.end() )
891 MISSING_UNIT_PLACEMENT placement;
892 placement.screen = targetScreen;
896 SCH_SHEET* targetSheet = placement.sheetpath.Last();
901 placement.newCmpPosition =
VECTOR2I( placement.sheetBbox.GetLeft(),
902 placement.sheetBbox.GetBottom() );
903 placement.maxY = placement.sheetBbox.GetY();
904 placementIt = placements.emplace( targetScreen, placement ).first;
907 MISSING_UNIT_PLACEMENT& placement = placementIt->second;
909 symbol->SetUnitSelection( &placement.sheetpath, unit );
910 symbol->SetUnit( unit );
911 symbol->SetOrientation( 0 );
912 symbol->AddHierarchicalReference( placement.sheetpath.Path(), reference, unit );
915 BOX2I cmpBbox = symbol->GetBoundingBox();
916 int posY = placement.newCmpPosition.y + cmpBbox.
GetHeight();
917 symbol->SetPosition(
VECTOR2I( placement.newCmpPosition.x, posY ) );
918 placement.newCmpPosition.x += cmpBbox.
GetWidth();
919 placement.maxY = std::max( placement.maxY, posY );
921 if( placement.newCmpPosition.x >= placement.pageSizeIU.x )
922 placement.newCmpPosition =
VECTOR2I( placement.sheetBbox.GetLeft(),
927 placement.screen->Append( symbol.release() );
940 wxCHECK( sheet && screen, );
944 std::string filename;
948 if( aSheet->description )
949 sheet->
SetName( aSheet->description.value().text );
954 replace( filename.begin(), filename.end(),
' ',
'_' );
959 fn.SetPath(
m_schematic->Project().GetProjectPath() );
960 fn.SetName( filename );
967 for(
const auto& [
name, moduleinst] : aSheet->moduleinsts )
974 for(
const std::unique_ptr<EPOLYGON>& epoly : aSheet->plain->polygons )
980 for(
const std::unique_ptr<EWIRE>& ewire : aSheet->plain->wires )
986 for(
const std::unique_ptr<ETEXT>& etext : aSheet->plain->texts )
989 for(
const std::unique_ptr<ECIRCLE>& ecircle : aSheet->plain->circles )
992 for(
const std::unique_ptr<ERECT>& erectangle : aSheet->plain->rectangles )
995 for(
const std::unique_ptr<EFRAME>& eframe : aSheet->plain->frames )
997 std::vector<SCH_ITEM*> frameItems;
1008 for(
const std::unique_ptr<EINSTANCE>& einstance : aSheet->instances )
1018 for(
const std::unique_ptr<EBUS>& ebus : aSheet->busses )
1024 loadSegments( ebus->segments, busName, wxString(),
true );
1027 for(
const std::unique_ptr<ENET>& enet : aSheet->nets )
1030 wxString netName = enet->netname;
1031 wxString netClass = wxString::Format( wxS(
"%i" ), enet->netcode );
1050 if( pageSizeIU.
x < targetSheetSize.
x )
1053 if( pageSizeIU.
y < targetSheetSize.
y )
1060 VECTOR2I sheetcentre( pageSizeIU.
x / 2, pageSizeIU.
y / 2 );
1064 VECTOR2I translation = sheetcentre - itemsCentre;
1065 translation.
x = translation.
x - translation.
x %
schIUScale.MilsToIU( 100 );
1066 translation.
y = translation.
y - translation.
y %
schIUScale.MilsToIU( 100 );
1078 std::vector<SCH_ITEM*> allItems;
1080 std::copy( screen->
Items().
begin(), screen->
Items().
end(), std::back_inserter( allItems ) );
1084 item->SetPosition( item->GetPosition() + translation );
1102 wxCHECK( currentSheet &¤tScreen, );
1108 auto it =
m_eagleDoc->drawing->schematic->modules.find( aModuleInstance->moduleinst );
1111 if( it ==
m_eagleDoc->drawing->schematic->modules.end() )
1113 THROW_IO_ERRORF(
_(
"No module instance '%s' found in schematic file:\n%s" ),
1114 aModuleInstance->name,
m_filename.GetFullPath() );
1118 fn.SetName( aModuleInstance->moduleinst );
1122 VECTOR2I size( it->second->dx.ToSchUnits(), it->second->dy.ToSchUnits() );
1124 int halfX =
KiROUND( size.
x / 2.0 );
1125 int halfY =
KiROUND( size.
y / 2.0 );
1126 int portExtWireLength =
schIUScale.mmToIU( 5.08 );
1127 VECTOR2I pos( aModuleInstance->x.ToSchUnits() - halfX,
1128 -aModuleInstance->y.ToSchUnits() - halfY );
1130 std::unique_ptr<SCH_SHEET> newSheet = std::make_unique<SCH_SHEET>( currentSheet, pos, size );
1138 if( schFile->GetFileName() == fn.GetFullPath() )
1140 newScreen = schFile;
1145 bool isNewSchFile = ( newScreen == nullptr );
1153 wxCHECK( newSheet && newScreen, );
1155 newSheet->SetScreen( newScreen );
1156 newSheet->SetFileName( fn.GetFullName() );
1157 newSheet->SetName( aModuleInstance->name );
1159 for(
const auto& [portName, port] : it->second->ports )
1162 int pinOffset = port->coord.ToSchUnits();
1165 if( port->side ==
"left" )
1169 pinPos.
y = pos.
y + halfY - pinOffset;
1170 portExtWireEndpoint = pinPos;
1171 portExtWireEndpoint.
x -= portExtWireLength;
1173 else if( port->side ==
"right" )
1176 pinPos.
x = pos.
x + size.
x;
1177 pinPos.
y = pos.
y + halfY - pinOffset;
1178 portExtWireEndpoint = pinPos;
1179 portExtWireEndpoint.
x += portExtWireLength;
1181 else if( port->side ==
"top" )
1184 pinPos.
x = pos.
x + halfX + pinOffset;
1186 portExtWireEndpoint = pinPos;
1187 portExtWireEndpoint.
y -= portExtWireLength;
1189 else if( port->side ==
"bottom" )
1192 pinPos.
x = pos.
x + halfX + pinOffset;
1193 pinPos.
y = pos.
y + size.
y;
1194 portExtWireEndpoint = pinPos;
1195 portExtWireEndpoint.
y += portExtWireLength;
1200 currentScreen->
Append( portExtWire );
1204 if( port->direction.has_value() )
1206 if( port->direction.value() ==
"in" )
1208 else if( port->direction.value() ==
"out" )
1210 else if( port->direction.value() ==
"io" )
1212 else if( port->direction.value() ==
"hiz" )
1224 newSheet->AddPin( sheetPin );
1227 wxString pageNo = wxString::Format( wxT(
"%d" ),
m_sheetIndex );
1229 newSheet->SetParent( currentSheet );
1232 currentScreen->
Append( newSheet.release() );
1234 m_modules.push_back( it->second.get() );
1240 for(
const std::unique_ptr<ESHEET>& esheet : it->second->sheets )
1250 wxCHECK2( emoduleInst,
continue );
1252 refPrefix += emoduleInst->name + wxS(
":" );
1263 wxCHECK2( symbol && !symbol->
GetInstances().empty(),
continue );
1266 wxString newReference = refPrefix + inst.
m_Reference.AfterLast(
':' );
1282 int xMin = aFrame->x1.ToSchUnits();
1283 int xMax = aFrame->x2.ToSchUnits();
1284 int yMin = -aFrame->y1.ToSchUnits();
1285 int yMax = -aFrame->y2.ToSchUnits();
1288 std::swap( xMin, xMax );
1291 std::swap( yMin, yMax );
1299 aItems.push_back( lines );
1301 if( !( aFrame->border_left ==
false ) )
1306 aItems.push_back( lines );
1309 int height = yMax - yMin;
1312 int legendPosX = xMin +
schIUScale.MilsToIU( 75 );
1313 double rowSpacing = height / double( aFrame->rows );
1314 double legendPosY = yMin + ( rowSpacing / 2 );
1316 for( i = 1; i < aFrame->rows; i++ )
1318 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1322 aItems.push_back( lines );
1325 char legendChar =
'A';
1327 for( i = 0; i < aFrame->rows; i++ )
1334 legendText->
SetText( wxString( legendChar ) );
1336 aItems.push_back( legendText );
1338 legendPosY += rowSpacing;
1342 if( !( aFrame->border_right ==
false ) )
1347 aItems.push_back( lines );
1350 int height = yMax - yMin;
1353 int legendPosX = xMax -
schIUScale.MilsToIU( 75 );
1354 double rowSpacing = height / double( aFrame->rows );
1355 double legendPosY = yMin + ( rowSpacing / 2 );
1357 for( i = 1; i < aFrame->rows; i++ )
1359 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1363 aItems.push_back( lines );
1366 char legendChar =
'A';
1368 for( i = 0; i < aFrame->rows; i++ )
1375 legendText->
SetText( wxString( legendChar ) );
1377 aItems.push_back( legendText );
1379 legendPosY += rowSpacing;
1383 if( !( aFrame->border_top ==
false ) )
1388 aItems.push_back( lines );
1391 int width = xMax - xMin;
1394 int legendPosY = yMin +
schIUScale.MilsToIU( 75 );
1395 double columnSpacing = width / double( aFrame->columns );
1396 double legendPosX = xMin + ( columnSpacing / 2 );
1398 for( i = 1; i < aFrame->columns; i++ )
1400 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1404 aItems.push_back( lines );
1409 for( i = 0; i < aFrame->columns; i++ )
1416 legendText->
SetText( fmt::format(
"{}", legendNo++ ) );
1418 aItems.push_back( legendText );
1419 legendPosX += columnSpacing;
1423 if( !( aFrame->border_bottom ==
false ) )
1428 aItems.push_back( lines );
1431 int width = xMax - xMin;
1434 int legendPosY = yMax -
schIUScale.MilsToIU( 75 );
1435 double columnSpacing = width / double( aFrame->columns );
1436 double legendPosX = xMin + ( columnSpacing / 2 );
1438 for( i = 1; i < aFrame->columns; i++ )
1440 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1444 aItems.push_back( lines );
1449 for( i = 0; i < aFrame->columns; i++ )
1456 legendText->
SetText( fmt::format(
"{}", legendNo++ ) );
1458 aItems.push_back( legendText );
1459 legendPosX += columnSpacing;
1466 const wxString& netName,
const wxString& aNetClass,
bool aIsBus )
1473 size_t segmentCount = aSegments.size();
1475 for(
const std::unique_ptr<ESEGMENT>& esegment : aSegments )
1477 bool labelled =
false;
1478 bool firstWireFound =
false;
1484 for(
const std::unique_ptr<EWIRE>& ewire : esegment->wires )
1493 if( !firstWireFound )
1495 firstWire = thisWire;
1496 firstWireFound =
true;
1502 if( !desc.labels.empty() && desc.labels.front()->GetText() == netName )
1505 for(
const SEG& seg : desc.segs )
1514 segDesc.
segs.push_back( thisWire );
1518 for(
const std::unique_ptr<EJUNCTION>& ejunction : esegment->junctions )
1521 for(
const std::unique_ptr<ELABEL>& elabel : esegment->labels )
1526 wxASSERT( segDesc.
labels.empty() || segDesc.
labels.front()->GetText() == label->
GetText() );
1528 segDesc.
labels.push_back( label );
1532 for(
const std::unique_ptr<EPINREF>& epinref : esegment->pinRefs )
1534 wxString part = epinref->part;
1535 wxString
pin = epinref->pin;
1537 auto powerPort =
m_powerPorts.find( wxT(
"#" ) + part );
1546 if( !labelled && firstWireFound )
1548 std::unique_ptr<SCH_LABEL_BASE> label;
1562 if( segmentCount > 1 ||
m_netCounts[netName] > 1 )
1572 label->SetPosition( firstWire.
A );
1576 if( firstWire.
A.
y == firstWire.
B.
y )
1578 if( firstWire.
B.
x > firstWire.
A.
x )
1583 else if( firstWire.
A.
x == firstWire.
B.
x )
1585 if( firstWire.
B.
y > firstWire.
A.
y )
1592 segDesc.
labels.push_back( label.get() );
1593 screen->
Append( label.release() );
1602 if( !aPolygon->IsValidOutline() )
1605 std::unique_ptr<SCH_SHAPE> poly = std::make_unique<SCH_SHAPE>(
SHAPE_T::POLY );
1607 std::optional<double> prev_curve;
1609 for(
const std::unique_ptr<EVERTEX>& evertex : aPolygon->vertices )
1611 pt =
VECTOR2I( evertex->x.ToSchUnits(), -evertex->y.ToSchUnits() );
1613 if( prev_curve.has_value() )
1617 poly->GetPolyShape().Append( arc, -1, -1,
ARC_ACCURACY );
1621 poly->AddPoint( pt );
1625 prev_curve = evertex->curve;
1628 poly->SetLayer(
kiCadLayer( aPolygon->layer ) );
1632 return poly.release();
1640 start.
x = aWire->x1.ToSchUnits();
1641 start.
y = -aWire->y1.ToSchUnits();
1642 end.x = aWire->x2.ToSchUnits();
1643 end.y = -aWire->y2.ToSchUnits();
1646 endpoints =
SEG( start,
end );
1655 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>(
SHAPE_T::ARC );
1658 arc->SetCenter(
center );
1659 arc->SetStart( start );
1666 return arc.release();
1670 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>();
1672 line->SetStartPoint( start );
1673 line->SetEndPoint(
end );
1674 line->SetLayer(
kiCadLayer( aWire->layer ) );
1677 return line.release();
1685 VECTOR2I center( aCircle->x.ToSchUnits(), -aCircle->y.ToSchUnits() );
1698 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>(
SHAPE_T::RECTANGLE );
1700 rectangle->SetLayer(
kiCadLayer( aRectangle->layer ) );
1701 rectangle->SetPosition(
VECTOR2I( aRectangle->x1.ToSchUnits(), -aRectangle->y1.ToSchUnits() ) );
1702 rectangle->SetEnd(
VECTOR2I( aRectangle->x2.ToSchUnits(), -aRectangle->y2.ToSchUnits() ) );
1704 if( aRectangle->rot.has_value() )
1706 VECTOR2I pos( rectangle->GetPosition() );
1713 rectangle->SetPosition( pos );
1714 rectangle->SetEnd(
end );
1720 return rectangle.release();
1726 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
1728 VECTOR2I pos( aJunction->x.ToSchUnits(), -aJunction->y.ToSchUnits() );
1730 junction->SetPosition( pos );
1732 return junction.release();
1737 const wxString& aNetName,
bool aIsBus )
1739 VECTOR2I elabelpos( aLabel->x.ToSchUnits(), -aLabel->y.ToSchUnits() );
1744 std::unique_ptr<SCH_LABEL_BASE> label;
1746 VECTOR2I textSize =
KiROUND( aLabel->size.ToSchUnits() * 0.7, aLabel->size.ToSchUnits() * 0.7 );
1748 auto findModulePort =
1749 [&]() ->
const EPORT*
1754 const auto& ports =
m_modules.back()->ports;
1755 const auto it = ports.find( aNetName );
1756 return it == ports.end() ? nullptr : it->second.get();
1759 const EPORT* port = findModulePort();
1763 std::unique_ptr<SCH_HIERLABEL> hierLabel = std::make_unique<SCH_HIERLABEL>();
1770 else if( port->
direction.value() ==
"out" )
1772 else if( port->
direction.value() ==
"io" )
1774 else if( port->
direction.value() ==
"hiz" )
1778 hierLabel->SetLabelShape( type );
1780 label = std::move( hierLabel );
1784 label = std::make_unique<SCH_LABEL>();
1788 label = std::make_unique<SCH_GLOBALLABEL>();
1792 label->SetPosition( elabelpos );
1793 label->SetTextSize( textSize );
1796 if( aLabel->rot.has_value() )
1799 int angle =
KiROUND( aLabel->rot.value().degrees );
1810 return label.release();
1815 const std::vector<SEG>& aLines )
const
1818 const SEG* nearestLine =
nullptr;
1820 double d, mindistance = std::numeric_limits<double>::max();
1826 for(
const SEG& line : aLines )
1828 VECTOR2I testpoint = line.NearestPoint( aPoint );
1831 if( d < mindistance )
1834 nearestPoint = testpoint;
1835 nearestLine = &line;
1839 return std::make_pair( nearestPoint, nearestLine );
1844 const std::map<wxString, std::unique_ptr<EPART>>& aParts )
1846 wxCHECK( aInstance, );
1852 const auto partIt = aParts.find( aInstance->part );
1854 if( partIt == aParts.end() )
1856 Report( wxString::Format(
_(
"Error parsing Eagle file. Could not find '%s' "
1857 "instance but it is referenced in the schematic." ),
1864 const std::unique_ptr<EPART>& epart = partIt->second;
1866 wxString libName = epart->library;
1869 if( epart->libraryUrn.has_value() )
1870 libName += wxS(
"_" ) + epart->libraryUrn.value().assetId;
1872 wxString gatename = epart->deviceset + wxS(
"_" ) + epart->device + wxS(
"_" ) + aInstance->gate;
1873 wxString symbolname = wxString( epart->deviceset + epart->device );
1874 wxString kiPackageName = epart->deviceset + epart->device;
1876 if( epart->technology.has_value() )
1877 symbolname += epart->technology.value();
1879 symbolname.Replace( wxT(
"*" ), wxEmptyString );
1880 kiPackageName.Replace( wxT(
"*" ), wxEmptyString );
1889 wxString altSymbolName = libName + wxT(
"_" ) + symbolname;
1892 wxString libIdSymbolName = altSymbolName;
1898 Report( wxString::Format( wxS(
"Eagle library '%s' not found while looking up symbol for "
1899 "deviceset '%s', device '%s', and gate '%s." ),
1904 const auto gateIt = libIt->second.GateToUnitMap.find( gatename );
1906 if( gateIt == libIt->second.GateToUnitMap.end() )
1908 Report( wxString::Format( wxS(
"Symbol not found for deviceset '%s', device '%s', and "
1909 "gate '%s in library '%s'." ),
1914 int unit = gateIt->second;
1919 auto p = elib->
package.find( kisymbolname );
1921 if( p != elib->
package.end() )
1923 package = p->second;
1927 p = elib->
package.find( kiPackageName );
1929 if( p != elib->
package.end() )
1930 package = p->second;
1934 std::map<std::string, UTF8> properties;
1941 part =
m_pi->LoadSymbol(
getLibFileName().GetFullPath(), kisymbolname, &properties );
1942 libIdSymbolName = kisymbolname;
1947 Report( wxString::Format(
_(
"Could not find '%s' in the imported library." ),
1954 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
1955 symbol->SetLibId( libId );
1956 symbol->SetUnit( unit );
1957 symbol->SetPosition(
VECTOR2I( aInstance->x.ToSchUnits(), -aInstance->y.ToSchUnits() ) );
1960 if( !package.IsEmpty() )
1962 wxString footprint =
m_schematic->Project().GetProjectName() + wxT(
":" ) + package;
1966 if( aInstance->rot.has_value() )
1970 if( aInstance->rot.value().mirror )
1971 symbol->MirrorHorizontally( aInstance->x.ToSchUnits() );
1974 std::vector<SCH_FIELD*> partFields;
1979 for(
const SCH_FIELD* partField : partFields )
1983 if( partField->IsMandatory() )
1984 symbolField = symbol->GetField( partField->GetId() );
1986 symbolField = symbol->GetField( partField->GetName() );
1993 newField.
SetText( partField->GetText() );
1997 symbol->AddField( newField );
2002 symbolField->
SetTextPos( symbol->GetPosition() + partField->GetTextPos() );
2006 wxString reference = aInstance->part;
2007 bool referenceVisible = !reference.IsEmpty();
2011 if( package.IsEmpty() )
2012 reference.Prepend(
'#' );
2015 if( reference.find_last_not_of( wxT(
"0123456789" ) ) == ( reference.Length()-1 ) )
2016 reference.Append( wxT(
"0" ) );
2021 if( reference.find_first_not_of( wxT(
"0123456789" ) ) != 0 )
2022 reference.Prepend( wxT(
"UNK" ) );
2026 if( aInstance->part.find_first_not_of( wxT(
"#" ) ) != 0 )
2027 reference.Prepend( wxT(
"UNK" ) );
2030 referenceField->
SetVisible( referenceVisible );
2031 referenceField->
SetText( reference );
2034 bool userValue =
m_userValue.at( libIdSymbolName );
2042 if( epart->value.has_value() && !epart->value.value().IsEmpty() )
2044 valueField->
SetText( epart->value.value() );
2048 valueField->
SetText( kisymbolname );
2054 for(
const auto& [ attrName, attr ] : epart->attributes )
2060 if( !symbol->GetFields().empty() )
2061 newField.
SetTextPos( symbol->GetFields().back().GetPosition() );
2063 if( attr->value.has_value() )
2064 newField.
SetText( attr->value.value() );
2066 if( attr->display.has_value() && attr->display.value() ==
EATTR::Off )
2069 symbol->AddField( newField );
2072 bool valueAttributeFound =
false;
2073 bool nameAttributeFound =
false;
2076 for(
auto& [
name, eattr] : aInstance->attributes )
2080 if( eattr->name.Lower() == wxT(
"name" ) )
2083 nameAttributeFound =
true;
2085 else if( eattr->name.Lower() == wxT(
"value" ) )
2088 valueAttributeFound =
true;
2092 field = symbol->GetField( eattr->name );
2100 if( eattr->size.has_value() )
2104 int absdegrees = eattr->rot.has_value() ?
KiROUND( eattr->rot.value().degrees ) : 0;
2105 bool mirror = eattr->rot.has_value() ? eattr->rot.value().mirror :
false;
2106 bool spin = eattr->rot.has_value() ? eattr->rot.value().spin :
false;
2108 if( aInstance->rot.has_value() && aInstance->rot.value().mirror )
2111 if( eattr->display.has_value() && ( eattr->display.value() ==
EATTR::Off
2117 int rotation = aInstance->rot.has_value() ?
KiROUND( aInstance->rot.value().degrees ) : 0;
2118 int reldegrees =
KiROUND( absdegrees - rotation + 360.0 );
2126 if( aInstance->smashed.has_value() && aInstance->smashed.value() )
2128 symbol->GetField(
FIELD_T::VALUE )->SetVisible( valueAttributeFound );
2140 wxCHECK2( emoduleInst,
continue );
2142 refPrefix += emoduleInst->name + wxS(
":" );
2145 symbol->AddHierarchicalReference(
m_sheetPath.Path(), refPrefix + reference, unit );
2151 symbol->SetLibSymbol( part->
Flatten().release() );
2153 for(
const auto& [
name, variant] : epart->variants )
2157 if( variant->populate.has_value() && variant->populate.value() ==
false )
2158 symbolVariant.
m_DNP =
true;
2160 if( variant->value )
2163 if( variant->technology.has_value() )
2165 auto eLibIt =
m_eagleDoc->drawing->schematic->libraries.find( epart->library );
2167 if( eLibIt ==
m_eagleDoc->drawing->schematic->libraries.end() )
2169 Report( wxString::Format( wxS(
"Library '%s' not found in schematic." ), epart->library ),
2174 auto eDeviceSetIt = eLibIt->second->devicesets.find( epart->deviceset );
2176 if( eDeviceSetIt == eLibIt->second->devicesets.end() )
2178 Report( wxString::Format( wxS(
"Device set '%s' not found in library '%s'." ),
2184 auto eDeviceIt = eDeviceSetIt->second->devices.find( epart->device );
2186 if( eDeviceIt == eDeviceSetIt->second->devices.end() )
2188 Report( wxString::Format( wxS(
"Device '%s' not found in device set '%s' in library '%s'." ),
2195 auto eTechnologyIt = eDeviceIt->second->technologies.find( variant->technology.value() );
2197 if( eTechnologyIt == eDeviceIt->second->technologies.end() )
2199 Report( wxString::Format( wxS(
"Technology '%s' not found in device '%s' in device set '%s' "
2200 "in library '%s'." ),
2201 variant->technology.value(),
2208 for(
const std::unique_ptr<EATTR>& attr : eTechnologyIt->second->attributes )
2212 if( attr->value.has_value() )
2213 attrValue = attr->value.value();
2215 symbolVariant.
m_Fields[attr->name] = attrValue;
2222 for(
const SCH_PIN*
pin : symbol->GetLibPins() )
2228 symbol->ClearFlags();
2230 screen->
Append( symbol.release() );
2236 wxCHECK( aLibrary && aEagleLibrary,
nullptr );
2243 wxString prefix = edeviceset->prefix.value_or( wxEmptyString );
2244 wxString deviceSetDescr;
2246 if( edeviceset->description )
2250 for(
const auto& [devname, edevice] : edeviceset->devices )
2252 std::vector<std::unique_ptr<LIB_SYMBOL>> derivedSymbols;
2255 wxString symbolName = edeviceset->name + edevice->name;
2256 symbolName.Replace( wxT(
"*" ), wxEmptyString );
2257 wxASSERT( !symbolName.IsEmpty() );
2260 if( edevice->package.has_value() )
2261 aEagleLibrary->
package[symbolName] = edevice->package.value();
2264 std::unique_ptr<LIB_SYMBOL> libSymbol = std::make_unique<LIB_SYMBOL>( symbolName );
2267 int gate_count =
static_cast<int>( edeviceset->gates.size() );
2269 if( gate_count > 1 )
2270 libSymbol->SetUnitCount( gate_count,
true );
2272 libSymbol->LockUnits(
true );
2276 if( prefix.length() == 0 )
2284 reference->
SetText( edevice->package.has_value() ? prefix :
'#' + prefix );
2287 libSymbol->GetValueField().SetVisible(
true );
2290 bool ispower =
false;
2292 for(
const auto& [gateName, egate] : edeviceset->gates )
2294 const auto it = aLibrary->
symbols.find( egate->symbol );
2296 if( it == aLibrary->
symbols.end() )
2298 Report( wxString::Format( wxS(
"Eagle symbol '%s' not found in library '%s'." ),
2304 wxString gateMapName = edeviceset->name + wxS(
"_" ) + edevice->name + wxS(
"_" ) + egate->name;
2306 ispower =
loadSymbol( it->second, libSymbol, edevice, gateindex, egate->name );
2311 std::vector<SCH_FIELD*> fields;
2312 libSymbol->GetFields( fields );
2315 field->SetCanAutoplace( canAutoplace );
2317 for(
const auto& [techname, technology ] : edevice->technologies )
2319 std::unique_ptr<LIB_SYMBOL> derivedSymbol;
2322 if( !technology->name.IsEmpty() )
2324 derivedSymbol = std::make_unique<LIB_SYMBOL>( symbolName + technology->name, libSymbol.get() );
2328 SCH_FIELD* childField = derivedSymbol->GetField( parentField->GetName() );
2338 for(
const std::unique_ptr<EATTR>& attr : technology->attributes )
2340 if( !attr->value.has_value() )
2345 if( !derivedSymbol )
2346 field = libSymbol->FindFieldCaseInsensitive( attr->name );
2348 field = derivedSymbol->FindFieldCaseInsensitive( attr->name );
2352 field->
SetText( attr->value.value() );
2356 SCH_FIELD* newField =
new SCH_FIELD( derivedSymbol ? derivedSymbol.get() : libSymbol.get(),
2361 SCH_FIELD* parentField = libSymbol->FindFieldCaseInsensitive( attr->name );
2368 newField->
SetText( attr->value.value() );
2373 if( !derivedSymbol )
2374 libSymbol->AddField( newField );
2376 derivedSymbol->AddField( newField );
2381 derivedSymbols.push_back( std::move( derivedSymbol ) );
2384 if( gate_count > 1 )
2385 libSymbol->SetUnitCount( gate_count,
true );
2387 if( gate_count == 1 && ispower )
2388 libSymbol->SetGlobalPower();
2391 if( edevice->package.has_value() && !edevice->package.value().IsEmpty() )
2398 libName =
m_schematic->Project().GetProjectName();
2405 wxString packageString = libName + wxT(
":" ) + aEagleLibrary->
package[symbolName];
2407 libSymbol->GetFootprintField().SetText( packageString );
2410 wxString libName = libSymbol->GetName();
2411 libSymbol->SetName( libName );
2412 libSymbol->SetDescription( deviceSetDescr );
2422 libName = aEagleLibrary->
name + wxT(
"_" ) + libName;
2424 libSymbol->SetName( libName );
2428 std::map<std::string, UTF8> properties;
2432 std::unique_ptr<LIB_SYMBOL> parentSymbol = std::make_unique<LIB_SYMBOL>( *libSymbol );
2444 Report( wxString::Format(
_(
"Could not reload saved symbol '%s'" ),
2450 for( std::unique_ptr<LIB_SYMBOL>& symbol : derivedSymbols )
2454 wxString tmp = aEagleLibrary->
name + wxT(
"_" ) + symbol->GetName();
2456 symbol->SetName( tmp );
2459 std::unique_ptr<LIB_SYMBOL> derivedSymbol = std::make_unique<LIB_SYMBOL>( *symbol );
2461 derivedSymbol->SetParent( parent );
2462 m_pi->SaveSymbol(
getLibFileName().GetFullPath(), std::move( derivedSymbol ), &properties );
2474 aEagleLibrary->
KiCadSymbols[ libName ] = std::move( libSymbol );
2478 m_userValue.emplace( std::make_pair( libName, edeviceset->uservalue.value_or(
false ) ) );
2480 for( std::unique_ptr<LIB_SYMBOL>& symbol : derivedSymbols )
2482 m_userValue.emplace( std::make_pair( symbol->GetName(), edeviceset->uservalue.value_or(
false ) ) );
2483 aEagleLibrary->
KiCadSymbols[symbol->GetName()] = std::move( symbol );
2488 return aEagleLibrary;
2493 const std::unique_ptr<EDEVICE>& aDevice,
int aGateNumber,
const wxString& aGateName )
2495 wxCHECK( aEsymbol && aSymbol && aDevice,
false );
2497 std::vector<SCH_ITEM*> items;
2499 bool showRefDes =
false;
2500 bool showValue =
false;
2501 bool ispower =
false;
2504 for(
const std::unique_ptr<ECIRCLE>& ecircle : aEsymbol->circles )
2507 for(
const std::unique_ptr<EPIN>& epin : aEsymbol->pins )
2509 std::unique_ptr<SCH_PIN>
pin(
loadPin( aSymbol, epin, aGateNumber ) );
2514 if( epin->direction.has_value() )
2518 if( epin->direction.value().Lower() == pinDir.first )
2520 pin->SetType( pinDir.second );
2522 if( pinDir.first == wxT(
"sup" ) )
2530 if( aDevice->connects.size() != 0 )
2532 for(
const std::unique_ptr<ECONNECT>& connect : aDevice->connects )
2537 if( connect->gate == aGateName && epin->name == connect->pin )
2539 wxArrayString pads = wxSplit( wxString( connect->pad ),
' ' );
2541 pin->SetUnit( aGateNumber );
2544 if( pads.GetCount() > 1 )
2546 pin->SetNumberTextSize( 0 );
2549 for(
unsigned i = 0; i < pads.GetCount(); i++ )
2553 wxString padname( pads[i] );
2555 aSymbol->AddDrawItem( apin );
2564 pin->SetUnit( aGateNumber );
2565 pin->SetNumber( wxString::Format( wxT(
"%i" ), pincount ) );
2566 aSymbol->AddDrawItem(
pin.release() );
2570 for(
const std::unique_ptr<EPOLYGON>& epolygon : aEsymbol->polygons )
2573 aSymbol->AddDrawItem( shape );
2576 for(
const std::unique_ptr<ERECT>& erectangle : aEsymbol->rectangles )
2579 for(
const std::unique_ptr<ETEXT>& etext : aEsymbol->texts )
2581 std::unique_ptr<SCH_TEXT> libtext(
loadSymbolText( aSymbol, etext, aGateNumber ) );
2583 if( libtext->GetText() == wxT(
"${REFERENCE}" ) )
2586 aSymbol->GetReferenceField().SetAttributes( *libtext );
2589 showRefDes = etext->text == wxT(
">NAME" );
2591 else if( libtext->GetText() == wxT(
"${VALUE}" ) )
2594 aSymbol->GetValueField().SetAttributes( *libtext );
2597 showValue = etext->text == wxT(
">VALUE" );
2599 else if( etext->text.StartsWith(
">" ) )
2603 wxString fieldName = etext->text.Mid( 1 );
2605 if( !fieldName.IsEmpty() )
2613 aSymbol->AddField( field );
2618 aSymbol->AddDrawItem( libtext.release() );
2622 for(
const std::unique_ptr<EWIRE>& ewire : aEsymbol->wires )
2623 aSymbol->AddDrawItem(
loadSymbolWire( aSymbol, ewire, aGateNumber ) );
2625 for(
const std::unique_ptr<EFRAME>& eframe : aEsymbol->frames )
2627 std::vector<SCH_ITEM*> frameItems;
2633 item->SetParent( aSymbol.get() );
2634 item->SetUnit( aGateNumber );
2635 aSymbol->AddDrawItem( item );
2639 aSymbol->GetReferenceField().SetVisible( showRefDes );
2640 aSymbol->GetValueField().SetVisible( showValue );
2642 return pincount == 1 ? ispower :
false;
2647 const std::unique_ptr<ECIRCLE>& aCircle,
int aGateNumber )
2649 wxCHECK( aSymbol && aCircle,
nullptr );
2653 VECTOR2I center( aCircle->x.ToSchUnits(), -aCircle->y.ToSchUnits() );
2655 circle->SetParent( aSymbol.get() );
2659 if( aCircle->width.ToSchUnits() == 0 )
2669 if( aSymbol->IsMultiUnit() )
2670 circle->SetUnit( aGateNumber );
2677 const std::unique_ptr<ERECT>& aRectangle,
int aGateNumber )
2679 wxCHECK( aSymbol && aRectangle,
nullptr );
2684 rectangle->
SetPosition(
VECTOR2I( aRectangle->x1.ToSchUnits(), -aRectangle->y1.ToSchUnits() ) );
2685 rectangle->
SetEnd(
VECTOR2I( aRectangle->x2.ToSchUnits(), -aRectangle->y2.ToSchUnits() ) );
2687 if( aRectangle->rot.has_value() )
2700 if( aSymbol->IsMultiUnit() )
2701 rectangle->
SetUnit( aGateNumber );
2712 const std::unique_ptr<EWIRE>& aWire,
int aGateNumber )
2714 wxCHECK( aSymbol && aWire,
nullptr );
2718 begin.
x = aWire->x1.ToSchUnits();
2719 begin.
y = -aWire->y1.ToSchUnits();
2720 end.x = aWire->x2.ToSchUnits();
2721 end.y = -aWire->y2.ToSchUnits();
2737 if( aWire->cap.has_value() && aWire->cap.value() ==
EWIRE::FLAT && aWire->width.ToSchUnits() >= 2 *
radius )
2740 begin =
center + centerStartVector;
2756 if( aSymbol->IsMultiUnit() )
2768 if( aSymbol->IsMultiUnit() )
2779 const std::unique_ptr<EPOLYGON>& aPolygon,
int aGateNumber )
2781 wxCHECK( aSymbol && aPolygon,
nullptr );
2783 if( !aPolygon->IsValidOutline() )
2789 std::optional<double> prev_curve;
2790 std::optional<VECTOR2I> first_pt;
2794 for(
const std::unique_ptr<EVERTEX>& evertex : aPolygon->vertices )
2796 pt =
VECTOR2I( evertex->x.ToSchUnits(), -evertex->y.ToSchUnits() );
2798 if( !first_pt.has_value() )
2801 if( prev_curve.has_value() )
2813 prev_curve = evertex->curve;
2816 if( first_pt.has_value() )
2817 poly->
AddPoint( first_pt.value() );
2822 if( aSymbol->IsMultiUnit() )
2830 const std::unique_ptr<EPIN>& aPin,
int aGateNumber )
2832 wxCHECK( aSymbol && aPin,
nullptr );
2834 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>( aSymbol.get() );
2835 pin->SetPosition(
VECTOR2I( aPin->x.ToSchUnits(), -aPin->y.ToSchUnits() ) );
2842 if( aSymbol->IsMultiUnit() )
2843 pin->SetUnit( aGateNumber );
2845 int roti = aPin->rot.has_value() ?
KiROUND( aPin->rot.value().degrees ) : 0;
2853 default: wxFAIL_MSG( wxString::Format( wxT(
"Unhandled orientation (%d degrees)." ), roti ) );
2858 if( aPin->length.has_value() )
2860 if( aPin->length.value() == wxT(
"short" ) )
2862 else if( aPin->length.value() == wxT(
"middle" ) )
2864 else if( aPin->length.value() == wxT(
"long" ) )
2866 else if( aPin->length.value() == wxT(
"point" ) )
2875 if( aPin->visible.has_value() )
2877 if( aPin->visible.value() == wxT(
"off" ) )
2879 pin->SetNameTextSize( 0 );
2880 pin->SetNumberTextSize( 0 );
2882 else if( aPin->visible.value() == wxT(
"pad" ) )
2884 pin->SetNameTextSize( 0 );
2886 else if( aPin->visible.value() == wxT(
"pin" ) )
2888 pin->SetNumberTextSize( 0 );
2898 if( aPin->function.has_value() )
2900 if( aPin->function.value() == wxT(
"dot" ) )
2902 else if( aPin->function.value() == wxT(
"clk" ) )
2904 else if( aPin->function.value() == wxT(
"dotclk" ) )
2908 return pin.release();
2913 const std::unique_ptr<ETEXT>& aText,
int aGateNumber )
2915 wxCHECK( aSymbol && aText,
nullptr );
2917 std::unique_ptr<SCH_TEXT> libtext = std::make_unique<SCH_TEXT>();
2920 libtext->SetParent( aSymbol.get() );
2922 if( aSymbol->IsMultiUnit() )
2923 libtext->SetUnit( aGateNumber );
2925 libtext->SetPosition(
VECTOR2I( aText->x.ToSchUnits(), -aText->y.ToSchUnits() ) );
2927 const wxString& eagleText = aText->text;
2928 wxString adjustedText;
2929 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2932 while( tokenizer.HasMoreTokens() )
2934 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2936 if( tokenizer.HasMoreTokens() )
2939 adjustedText += tmp;
2942 libtext->SetText( adjustedText.IsEmpty() ? wxString( wxS(
"~" ) ) : adjustedText );
2946 return libtext.release();
2952 wxCHECK( aText,
nullptr );
2954 std::unique_ptr<SCH_TEXT> schtext = std::make_unique<SCH_TEXT>();
2956 const wxString& eagleText = aText->text;
2957 wxString adjustedText;
2958 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2961 while( tokenizer.HasMoreTokens() )
2963 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2965 if( tokenizer.HasMoreTokens() )
2968 adjustedText += tmp;
2971 schtext->SetText( adjustedText.IsEmpty() ? wxString( wxS(
"\" \"" ) )
2974 schtext->SetPosition(
VECTOR2I( aText->x.ToSchUnits(), -aText->y.ToSchUnits() ) );
2976 schtext->SetItalic(
false );
2978 return schtext.release();
2984 wxCHECK( aText && aAttributes, );
2989 if( aAttributes->ratio.value_or( 8 ) > 12 )
2993 int degrees = aAttributes->rot.has_value() ?
KiROUND( aAttributes->rot.value().degrees ) : 0;
2994 bool mirror = aAttributes->rot.has_value() ? aAttributes->rot.value().mirror :
false;
2995 bool spin = aAttributes->rot.has_value() ? aAttributes->rot.value().spin :
false;
3010 auto onIntersection =
3021 const SEG* segAttached = segDesc.LabelAttached( label );
3023 if( segAttached && !onIntersection( labelPos ) )
3036 VECTOR2I wireDirection( segAttached->
B - segAttached->
A );
3038 if( ( wireDirection.
x == 0 ) && (wireDirection.
y == 0 ) )
3042 const VECTOR2I origPos( labelPos );
3045 bool checkPositive =
true;
3046 bool checkNegative =
true;
3051 while( ( !
move || onIntersection( labelPos ) ) && ( checkPositive || checkNegative ) )
3056 if( trial % 2 == 1 )
3058 labelPos =
VECTOR2I( origPos + wireDirection * trial / 2 );
3059 move = checkPositive = segAttached->
Contains( labelPos );
3063 labelPos =
VECTOR2I( origPos - wireDirection * trial / 2 );
3064 move = checkNegative = segAttached->
Contains( labelPos );
3074 if( wireDirection.
x == 0 )
3076 if( wireDirection.
y < 0 )
3081 else if( wireDirection.
y == 0 )
3083 if( wireDirection.
x < 0 )
3117 wxFileInputStream input( aFileName );
3126 wxTextInputStream
text( input );
3128 for(
int i = 0; i < 8; i++ )
3133 if(
text.ReadLine().Contains( wxS(
"<eagle" ) ) )
3151 if( !item->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
3155 item->SetPosition( aNewEndPoint );
3168 std::vector<SCH_LINE*> buses;
3169 std::vector<SCH_LINE*> wires;
3180 buses.push_back( line );
3181 else if( line->
IsWire() )
3182 wires.push_back( line );
3187 VECTOR2I wireStart = wire->GetStartPoint();
3188 VECTOR2I wireEnd = wire->GetEndPoint();
3192 VECTOR2I busStart = bus->GetStartPoint();
3193 VECTOR2I busEnd = bus->GetEndPoint();
3196 [](
int signX,
int signY ) ->
VECTOR2I
3208 if( wireStart.
y == wireEnd.
y && busStart.
x == busEnd.
x )
3212 if( testBusHit( wireStart ) )
3216 if( wireEnd.
x < busStart.
x )
3223 VECTOR2I p = wireStart + entrySize( -1, 0 );
3225 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
3234 screen->
Append( busEntry );
3236 wire->SetStartPoint( p );
3238 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
3247 screen->
Append( busEntry );
3249 wire->SetStartPoint( p );
3264 VECTOR2I p = wireStart + entrySize( 1, 0 );
3266 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
3275 screen->
Append( busEntry );
3277 wire->SetStartPoint( p );
3279 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
3288 screen->
Append( busEntry );
3290 wire->SetStartPoint( p );
3301 else if( testBusHit( wireEnd ) )
3305 if( wireStart.
x < busStart.
x )
3312 VECTOR2I p = wireEnd + entrySize( -1, 0 );
3314 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3323 screen->
Append( busEntry );
3325 wire->SetEndPoint( p );
3327 else if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3336 screen->
Append( busEntry );
3337 moveLabels( wire, wireEnd + entrySize( -1, 0 ) );
3338 wire->SetEndPoint( wireEnd + entrySize( -1, 0 ) );
3353 VECTOR2I p = wireEnd + entrySize( 1, 0 );
3355 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3364 screen->
Append( busEntry );
3366 wire->SetEndPoint( p );
3368 else if( testBusHit( wireEnd + entrySize( 0, 1 ) ) )
3377 screen->
Append( busEntry );
3379 wire->SetEndPoint( p );
3391 else if( wireStart.
x == wireEnd.
x && busStart.
y == busEnd.
y )
3395 if( testBusHit( wireStart ) )
3399 if( wireEnd.
y < busStart.
y )
3407 VECTOR2I p = wireStart + entrySize( 0, -1 );
3409 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3419 screen->
Append( busEntry );
3421 wire->SetStartPoint( p );
3423 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3433 screen->
Append( busEntry );
3435 wire->SetStartPoint( p );
3451 VECTOR2I p = wireStart + entrySize( 0, 1 );
3453 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3463 screen->
Append( busEntry );
3465 wire->SetStartPoint( p );
3467 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3477 screen->
Append( busEntry );
3479 wire->SetStartPoint( p );
3490 else if( testBusHit( wireEnd ) )
3494 if( wireStart.
y < busStart.
y )
3502 VECTOR2I p = wireEnd + entrySize( 0, -1 );
3504 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3514 screen->
Append( busEntry );
3516 wire->SetEndPoint( p );
3518 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3528 screen->
Append( busEntry );
3530 wire->SetEndPoint( p );
3546 VECTOR2I p = wireEnd + entrySize( 0, 1 );
3548 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3558 screen->
Append( busEntry );
3560 wire->SetEndPoint( p );
3562 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3572 screen->
Append( busEntry );
3574 wire->SetEndPoint( p );
3590 if( testBusHit( wireStart ) )
3592 VECTOR2I wirevector = wireStart - wireEnd;
3594 if( wirevector.
x > 0 )
3596 if( wirevector.
y > 0 )
3598 VECTOR2I p = wireStart + entrySize( -1, -1 );
3601 screen->
Append( busEntry );
3604 wire->SetStartPoint( p );
3608 VECTOR2I p = wireStart + entrySize( -1, 1 );
3611 screen->
Append( busEntry );
3614 wire->SetStartPoint( p );
3619 if( wirevector.
y > 0 )
3621 VECTOR2I p = wireStart + entrySize( 1, -1 );
3624 screen->
Append( busEntry );
3627 wire->SetStartPoint( p );
3631 VECTOR2I p = wireStart + entrySize( 1, 1 );
3634 screen->
Append( busEntry );
3637 wire->SetStartPoint( p );
3643 else if( testBusHit( wireEnd ) )
3645 VECTOR2I wirevector = wireStart - wireEnd;
3647 if( wirevector.
x > 0 )
3649 if( wirevector.
y > 0 )
3651 VECTOR2I p = wireEnd + entrySize( 1, 1 );
3654 screen->
Append( busEntry );
3657 wire->SetEndPoint( p );
3661 VECTOR2I p = wireEnd + entrySize( 1, -1 );
3664 screen->
Append( busEntry );
3667 wire->SetEndPoint( p );
3672 if( wirevector.
y > 0 )
3674 VECTOR2I p = wireEnd + entrySize( -1, 1 );
3677 screen->
Append( busEntry );
3680 wire->SetEndPoint( p );
3684 VECTOR2I p = wireEnd + entrySize( -1, -1 );
3687 screen->
Append( busEntry );
3690 wire->SetEndPoint( p );
3704 wxCHECK( aLabel,
nullptr );
3710 if( seg.Contains( labelPos ) )
3722 wxCHECK( aSymbol && aPin,
false );
3730 const std::set<const EDA_ITEM*>& items = pointIt->second;
3732 wxCHECK( items.find( aPin ) != items.end(),
false );
3734 return items.size() > 1;
3747 int unit = aSymbol->
GetUnit();
3750 std::set<int> missingUnits;
3757 bool pinInUnit = !unit ||
pin->GetUnit() == unit;
3770 switch(
pin->GetOrientation() )
3779 aScreen->
Append( netLabel );
3782 else if( aUpdateSet )
3787 wxASSERT(
pin->GetUnit() );
3788 missingUnits.insert(
pin->GetUnit() );
3801 entry.
cmp = aSymbol;
3803 entry.
units.emplace( unit,
false );
3808 cmpIt->second.units[unit] =
false;
3811 if( !missingUnits.empty() )
3814 entry.
cmp = aSymbol;
3818 for(
int i : missingUnits )
3820 if( entry.
units.find( i ) != entry.
units.end() )
3821 entry.
units.emplace( i,
true );
3833 wxString ret = wxT(
"{" );
3835 wxStringTokenizer tokenizer( aEagleName,
"," );
3837 while( tokenizer.HasMoreTokens() )
3839 wxString member = tokenizer.GetNextToken();
3846 if( member.Freq(
'!' ) % 2 > 0 )
3847 member << wxT(
"!" );
3849 ret << member << wxS(
" " );
3863 std::unique_ptr<EPART>& epart =
m_eagleDoc->drawing->schematic->parts[aInstance->part];
3865 if( !epart || epart->deviceset.IsEmpty() )
3868 std::unique_ptr<ELIBRARY>& elibrary =
m_eagleDoc->drawing->schematic->libraries[epart->library];
3873 std::unique_ptr<EDEVICE_SET>& edeviceset = elibrary->devicesets[epart->deviceset];
3878 std::unique_ptr<EGATE>& egate = edeviceset->gates[aInstance->gate];
3883 std::unique_ptr<ESYMBOL>& esymbol = elibrary->symbols[egate->symbol];
3886 return esymbol.get();
3893 const wxString& aEagleFieldName,
3896 wxCHECK( aField && !aEagleFieldName.
IsEmpty(), );
3902 for(
const std::unique_ptr<ETEXT>&
text : esymbol->
texts )
3904 if(
text->text == aEagleFieldName )
3907 VECTOR2I pos(
text->x.ToSchUnits() + aInstance->x.ToSchUnits(),
3908 -
text->y.ToSchUnits() - aInstance->y.ToSchUnits() );
3910 bool mirror =
text->rot ?
text->rot->mirror :
false;
3912 if( aInstance->rot.has_value() && aInstance->rot.value().mirror )
3916 pos.
y = -aInstance->y.ToSchUnits() +
text->y.ToSchUnits();
3929 std::vector<SCH_FIELD*> fields;
3934 retv = fields[0]->GetPosition();
3936 for(
size_t i = 1; i < fields.size(); i++ )
3938 if( fields[i]->GetPosition().x > retv.
x )
3939 retv.
x = fields[i]->GetPosition().x;
3941 if( fields[i]->GetPosition().y > retv.
y )
3942 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)
virtual 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_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#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.
Implement a simple wrapper around runtime_error to isolate the errors thrown by the Eagle XML parser.
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".
static std::vector< uint8_t > bytes(const std::string &aText)
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.