29#include <wx/filename.h>
31#include <wx/tokenzr.h>
32#include <wx/wfstream.h>
33#include <wx/txtstrm.h>
34#include <wx/mstream.h>
35#include <wx/xml/xml.h>
93 bbox.
Merge( item->GetBoundingBox() );
102 return aPinName.BeforeFirst(
'@' );
115 wxCHECK( currentSheet,
nullptr );
160 for(
const std::unique_ptr<ELAYER>& elayer : aLayers )
179 switch ( elayer->number)
209 int roti = int( eagleDegrees );
219 wxASSERT_MSG(
false, wxString::Format( wxT(
"Unhandled orientation (%d degrees)" ),
228 bool aMirror,
bool aSpin,
int aAbsDegress )
230 int align = aEagleAlignment;
232 if( aRelDegress == 90 )
236 else if( aRelDegress == 180 )
240 else if( aRelDegress == 270 )
246 if( aMirror ==
true )
248 if( aAbsDegress == 90 || aAbsDegress == 270 )
259 else if( aAbsDegress == 0 || aAbsDegress == 180 )
352 const std::map<std::string, UTF8>* aProperties )
354 wxASSERT( !aFileName || aSchematic !=
nullptr );
374 wxXmlNode* currentNode = xmlDocument.GetRoot();
384 unique_ptr<SCH_SHEET> tempVROwner;
388 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
389 wxT(
"Can't append to a schematic with no root!" ) );
400 if( sheetPath.Last() == aAppendToMe )
412 tempVROwner = std::make_unique<SCH_SHEET>( aSchematic );
432 wxCHECK_MSG(
table,
nullptr,
"Could not load symbol lib table." );
434 m_pi.reset( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
442 wxString libTableUri = wxT(
"${KIPRJMOD}/" ) +
getLibFileName().GetFullName();
447 row.
SetURI( libTableUri );
455 m_eagleDoc = std::make_unique<EAGLE_DOC>( currentNode,
this );
483 const wxString& aLibraryPath,
484 const std::map<std::string, UTF8>* aProperties )
495 for(
const auto& [symName, libSymbol] : it->second.KiCadSymbols )
496 aSymbolNameList.push_back( symName );
502 const wxString& aLibraryPath,
503 const std::map<std::string, UTF8>* aProperties )
514 for(
const auto& [symName, libSymbol] : it->second.KiCadSymbols )
515 aSymbolList.push_back( libSymbol.get() );
521 const std::map<std::string, UTF8>* aProperties )
532 auto it2 = it->second.KiCadSymbols.find( aAliasName );
534 if( it2 != it->second.KiCadSymbols.end() )
535 return it2->second.get();
544 wxFileName fn( aLibraryPath );
546 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
547 return fn.GetModificationTime().GetValue().GetValue();
578 std::unique_ptr<EAGLE_DOC> doc = std::make_unique<EAGLE_DOC>( xmlDocument.GetRoot(),
this );
582 m_version = ( doc->version.IsEmpty() ) ? wxString( wxS(
"0.0" ) ) : doc->version;
594 wxXmlDocument xmlDocument;
595 wxFFileInputStream stream(
m_filename.GetFullPath() );
608 std::vector<uint8_t> bytes;
609 bytes.resize(
static_cast<size_t>( stream.GetLength() ) );
610 stream.Read( bytes.data(), bytes.size() );
612 if( stream.LastRead() != bytes.size() )
616 std::unique_ptr<wxXmlDocument> binDocument = binParser.
Parse( bytes );
618 xmlDocument.SetRoot( binDocument->DetachRoot() );
623 wxTextInputStream
text( stream );
624 wxString line =
text.ReadLine();
626 if( !line.StartsWith( wxT(
"<?xml" ) ) && !line.StartsWith( wxT(
"<!--" ) )
627 && !line.StartsWith( wxT(
"<eagle " ) ) )
629 THROW_IO_ERRORF(
_(
"'%s' is an Eagle binary-format file; only Eagle XML-format files can be imported." ),
633#if wxCHECK_VERSION( 3, 3, 0 )
636 if( !xmlDocument.Load( stream, wxXMLDOC_NONE, &err ) )
638 if( err.message == wxS(
"no element found" ) )
642 wxMemoryOutputStream memOutput;
645 header <<
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
646 header <<
"<!DOCTYPE eagle SYSTEM \"eagle.dtd\">\n";
648 wxScopedCharBuffer headerBuf = header.utf8_str();
649 memOutput.Write( headerBuf.data(), headerBuf.length() );
651 wxFFileInputStream stream2(
m_filename.GetFullPath() );
652 memOutput.Write( stream2 );
654 wxMemoryInputStream memInput( memOutput );
656 if( !xmlDocument.Load( memInput, wxXMLDOC_NONE, &err ) )
663 THROW_IO_ERRORF(
_(
"Unable to read file '%s'.\n'%s' at line %d, column %d, offset %d" ),
664 m_filename.GetFullPath(), err.message, err.line, err.column, err.offset );
668 if( !xmlDocument.Load( stream ) )
672 wxMemoryOutputStream memOutput;
675 header <<
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
676 header <<
"<!DOCTYPE eagle SYSTEM \"eagle.dtd\">\n";
678 wxScopedCharBuffer headerBuf = header.utf8_str();
679 memOutput.Write( headerBuf.data(), headerBuf.length() );
681 wxFFileInputStream stream2(
m_filename.GetFullPath() );
682 memOutput.Write( stream2 );
684 wxMemoryInputStream memInput( memOutput );
686 if( !xmlDocument.Load( memInput ) )
697 wxCHECK( aDrawing, );
701 if( aDrawing->library )
709 if( aDrawing->schematic )
716 for(
const std::unique_ptr<ESHEET>& esheet : aSchematic.
sheets )
718 for(
const std::unique_ptr<ENET>& enet : esheet->nets )
720 wxString netName = enet->netname;
729 for(
const auto& [modname, emodule] : aSchematic.
modules )
731 for(
const std::unique_ptr<ESHEET>& esheet : emodule->sheets )
733 for(
const std::unique_ptr<ENET>& enet : esheet->nets )
735 wxString netName = enet->netname;
750 if( aSchematic.
sheets.empty() )
757 if( variantDef->current && *variantDef->current )
762 for(
const auto& [
name, epart] : aSchematic.
parts )
765 for(
const auto& [modName, emodule] : aSchematic.
modules )
767 for(
const auto& [partName, epart] : emodule->parts )
773 for(
const auto& [libName, elibrary] : aSchematic.
libraries )
776 elib->
name = elibrary->GetName();
792 std::vector<SCH_SHEET*> eaglePages;
793 eaglePages.reserve( aSchematic.
sheets.size() );
795 for(
const std::unique_ptr<ESHEET>& esheet : aSchematic.
sheets )
799 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>(
m_rootSheet );
801 sheet->SetScreen( screen );
803 wxCHECK2( sheet && screen,
continue );
805 wxString pageNo = wxString::Format( wxT(
"%d" ),
m_sheetIndex );
813 eaglePages.push_back( sheet.release() );
818 if( !eaglePages.empty() )
843 struct MISSING_UNIT_PLACEMENT
853 std::map<SCH_SCREEN*, MISSING_UNIT_PLACEMENT> placements;
857 const SCH_SYMBOL* origSymbol = cmp.second.cmp;
859 for(
auto& unitEntry : cmp.second.units )
861 if( unitEntry.second ==
false )
865 int unit = unitEntry.first;
876 targetScreen = fallbackSheet->
GetScreen();
878 targetScreen = schematicRoot->
GetScreen();
881 auto placementIt = placements.find( targetScreen );
883 if( placementIt == placements.end() )
885 MISSING_UNIT_PLACEMENT placement;
886 placement.screen = targetScreen;
890 SCH_SHEET* targetSheet = placement.sheetpath.Last();
895 placement.newCmpPosition =
VECTOR2I( placement.sheetBbox.GetLeft(),
896 placement.sheetBbox.GetBottom() );
897 placement.maxY = placement.sheetBbox.GetY();
898 placementIt = placements.emplace( targetScreen, placement ).first;
901 MISSING_UNIT_PLACEMENT& placement = placementIt->second;
903 symbol->SetUnitSelection( &placement.sheetpath, unit );
904 symbol->SetUnit( unit );
905 symbol->SetOrientation( 0 );
906 symbol->AddHierarchicalReference( placement.sheetpath.Path(), reference, unit );
909 BOX2I cmpBbox = symbol->GetBoundingBox();
910 int posY = placement.newCmpPosition.y + cmpBbox.
GetHeight();
911 symbol->SetPosition(
VECTOR2I( placement.newCmpPosition.x, posY ) );
912 placement.newCmpPosition.x += cmpBbox.
GetWidth();
913 placement.maxY = std::max( placement.maxY, posY );
915 if( placement.newCmpPosition.x >= placement.pageSizeIU.x )
916 placement.newCmpPosition =
VECTOR2I( placement.sheetBbox.GetLeft(),
921 placement.screen->Append( symbol.release() );
934 wxCHECK( sheet && screen, );
938 std::string filename;
942 if( aSheet->description )
943 sheet->
SetName( aSheet->description.value().text );
948 replace( filename.begin(), filename.end(),
' ',
'_' );
953 fn.SetPath(
m_schematic->Project().GetProjectPath() );
954 fn.SetName( filename );
961 for(
const auto& [
name, moduleinst] : aSheet->moduleinsts )
968 for(
const std::unique_ptr<EPOLYGON>& epoly : aSheet->plain->polygons )
974 for(
const std::unique_ptr<EWIRE>& ewire : aSheet->plain->wires )
980 for(
const std::unique_ptr<ETEXT>& etext : aSheet->plain->texts )
983 for(
const std::unique_ptr<ECIRCLE>& ecircle : aSheet->plain->circles )
986 for(
const std::unique_ptr<ERECT>& erectangle : aSheet->plain->rectangles )
989 for(
const std::unique_ptr<EFRAME>& eframe : aSheet->plain->frames )
991 std::vector<SCH_ITEM*> frameItems;
1002 for(
const std::unique_ptr<EINSTANCE>& einstance : aSheet->instances )
1010 for(
const std::unique_ptr<EBUS>& ebus : aSheet->busses )
1016 loadSegments( ebus->segments, busName, wxString(),
true );
1019 for(
const std::unique_ptr<ENET>& enet : aSheet->nets )
1022 wxString netName = enet->netname;
1023 wxString netClass = wxString::Format( wxS(
"%i" ), enet->netcode );
1042 if( pageSizeIU.
x < targetSheetSize.
x )
1045 if( pageSizeIU.
y < targetSheetSize.
y )
1052 VECTOR2I sheetcentre( pageSizeIU.
x / 2, pageSizeIU.
y / 2 );
1056 VECTOR2I translation = sheetcentre - itemsCentre;
1057 translation.
x = translation.
x - translation.
x %
schIUScale.MilsToIU( 100 );
1058 translation.
y = translation.
y - translation.
y %
schIUScale.MilsToIU( 100 );
1070 std::vector<SCH_ITEM*> allItems;
1072 std::copy( screen->
Items().
begin(), screen->
Items().
end(), std::back_inserter( allItems ) );
1076 item->SetPosition( item->GetPosition() + translation );
1094 wxCHECK( currentSheet &¤tScreen, );
1100 auto it =
m_eagleDoc->drawing->schematic->modules.find( aModuleInstance->moduleinst );
1103 if( it ==
m_eagleDoc->drawing->schematic->modules.end() )
1105 THROW_IO_ERRORF(
_(
"No module instance '%s' found in schematic file:\n%s" ),
1106 aModuleInstance->name,
m_filename.GetFullPath() );
1110 fn.SetName( aModuleInstance->moduleinst );
1114 VECTOR2I size( it->second->dx.ToSchUnits(), it->second->dy.ToSchUnits() );
1116 int halfX =
KiROUND( size.
x / 2.0 );
1117 int halfY =
KiROUND( size.
y / 2.0 );
1118 int portExtWireLength =
schIUScale.mmToIU( 5.08 );
1119 VECTOR2I pos( aModuleInstance->x.ToSchUnits() - halfX,
1120 -aModuleInstance->y.ToSchUnits() - halfY );
1122 std::unique_ptr<SCH_SHEET> newSheet = std::make_unique<SCH_SHEET>( currentSheet, pos, size );
1130 if( schFile->GetFileName() == fn.GetFullPath() )
1132 newScreen = schFile;
1137 bool isNewSchFile = ( newScreen == nullptr );
1145 wxCHECK( newSheet && newScreen, );
1147 newSheet->SetScreen( newScreen );
1148 newSheet->SetFileName( fn.GetFullName() );
1149 newSheet->SetName( aModuleInstance->name );
1151 for(
const auto& [portName, port] : it->second->ports )
1154 int pinOffset = port->coord.ToSchUnits();
1157 if( port->side ==
"left" )
1161 pinPos.
y = pos.
y + halfY - pinOffset;
1162 portExtWireEndpoint = pinPos;
1163 portExtWireEndpoint.
x -= portExtWireLength;
1165 else if( port->side ==
"right" )
1168 pinPos.
x = pos.
x + size.
x;
1169 pinPos.
y = pos.
y + halfY - pinOffset;
1170 portExtWireEndpoint = pinPos;
1171 portExtWireEndpoint.
x += portExtWireLength;
1173 else if( port->side ==
"top" )
1176 pinPos.
x = pos.
x + halfX + pinOffset;
1178 portExtWireEndpoint = pinPos;
1179 portExtWireEndpoint.
y -= portExtWireLength;
1181 else if( port->side ==
"bottom" )
1184 pinPos.
x = pos.
x + halfX + pinOffset;
1185 pinPos.
y = pos.
y + size.
y;
1186 portExtWireEndpoint = pinPos;
1187 portExtWireEndpoint.
y += portExtWireLength;
1192 currentScreen->
Append( portExtWire );
1196 if( port->direction )
1198 if( *port->direction ==
"in" )
1200 else if( *port->direction ==
"out" )
1202 else if( *port->direction ==
"io" )
1204 else if( *port->direction ==
"hiz" )
1219 newSheet->AddPin( sheetPin );
1222 wxString pageNo = wxString::Format( wxT(
"%d" ),
m_sheetIndex );
1224 newSheet->SetParent( currentSheet );
1227 currentScreen->
Append( newSheet.release() );
1229 m_modules.push_back( it->second.get() );
1235 for(
const std::unique_ptr<ESHEET>& esheet : it->second->sheets )
1245 wxCHECK2( emoduleInst,
continue );
1247 refPrefix += emoduleInst->name + wxS(
":" );
1258 wxCHECK2( symbol && !symbol->
GetInstances().empty(),
continue );
1261 wxString newReference = refPrefix + inst.
m_Reference.AfterLast(
':' );
1277 int xMin = aFrame->x1.ToSchUnits();
1278 int xMax = aFrame->x2.ToSchUnits();
1279 int yMin = -aFrame->y1.ToSchUnits();
1280 int yMax = -aFrame->y2.ToSchUnits();
1283 std::swap( xMin, xMax );
1286 std::swap( yMin, yMax );
1294 aItems.push_back( lines );
1296 if( !( aFrame->border_left ==
false ) )
1303 aItems.push_back( lines );
1306 int height = yMax - yMin;
1309 int legendPosX = xMin +
schIUScale.MilsToIU( 75 );
1310 double rowSpacing = height / double( aFrame->rows );
1311 double legendPosY = yMin + ( rowSpacing / 2 );
1313 for( i = 1; i < aFrame->rows; i++ )
1315 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1319 aItems.push_back( lines );
1322 char legendChar =
'A';
1324 for( i = 0; i < aFrame->rows; i++ )
1331 legendText->
SetText( wxString( legendChar ) );
1334 aItems.push_back( legendText );
1336 legendPosY += rowSpacing;
1340 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 ) );
1378 aItems.push_back( legendText );
1380 legendPosY += rowSpacing;
1384 if( !( aFrame->border_top ==
false ) )
1391 aItems.push_back( lines );
1394 int width = xMax - xMin;
1397 int legendPosY = yMin +
schIUScale.MilsToIU( 75 );
1398 double columnSpacing = width / double( aFrame->columns );
1399 double legendPosX = xMin + ( columnSpacing / 2 );
1401 for( i = 1; i < aFrame->columns; i++ )
1403 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1407 aItems.push_back( lines );
1410 char legendChar =
'1';
1412 for( i = 0; i < aFrame->columns; i++ )
1419 legendText->
SetText( wxString( legendChar ) );
1422 aItems.push_back( legendText );
1424 legendPosX += columnSpacing;
1428 if( !( aFrame->border_bottom ==
false ) )
1435 aItems.push_back( lines );
1438 int width = xMax - xMin;
1441 int legendPosY = yMax -
schIUScale.MilsToIU( 75 );
1442 double columnSpacing = width / double( aFrame->columns );
1443 double legendPosX = xMin + ( columnSpacing / 2 );
1445 for( i = 1; i < aFrame->columns; i++ )
1447 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1451 aItems.push_back( lines );
1454 char legendChar =
'1';
1456 for( i = 0; i < aFrame->columns; i++ )
1463 legendText->
SetText( wxString( legendChar ) );
1466 aItems.push_back( legendText );
1468 legendPosX += columnSpacing;
1475 const wxString& netName,
1476 const wxString& aNetClass,
1484 size_t segmentCount = aSegments.size();
1486 for(
const std::unique_ptr<ESEGMENT>& esegment : aSegments )
1488 bool labelled =
false;
1489 bool firstWireFound =
false;
1495 for(
const std::unique_ptr<EWIRE>& ewire : esegment->wires )
1504 if( !firstWireFound )
1506 firstWire = thisWire;
1507 firstWireFound =
true;
1513 if( !desc.labels.empty() && desc.labels.front()->GetText() == netName )
1516 for(
const SEG& seg : desc.segs )
1525 segDesc.
segs.push_back( thisWire );
1529 for(
const std::unique_ptr<EJUNCTION>& ejunction : esegment->junctions )
1532 for(
const std::unique_ptr<ELABEL>& elabel : esegment->labels )
1537 wxASSERT( segDesc.
labels.empty()
1540 segDesc.
labels.push_back( label );
1544 for(
const std::unique_ptr<EPINREF>& epinref : esegment->pinRefs )
1546 wxString part = epinref->part;
1547 wxString
pin = epinref->pin;
1549 auto powerPort =
m_powerPorts.find( wxT(
"#" ) + part );
1561 if( !labelled && firstWireFound )
1563 std::unique_ptr<SCH_LABEL_BASE> label;
1575 if( segmentCount > 1 ||
m_netCounts[netName] > 1 )
1585 label->SetPosition( firstWire.
A );
1590 if( firstWire.
A.
y == firstWire.
B.
y )
1592 if( firstWire.
B.
x > firstWire.
A.
x )
1597 else if( firstWire.
A.
x == firstWire.
B.
x )
1599 if( firstWire.
B.
y > firstWire.
A.
y )
1605 screen->
Append( label.release() );
1614 if( !aPolygon->IsValidOutline() )
1617 std::unique_ptr<SCH_SHAPE> poly = std::make_unique<SCH_SHAPE>(
SHAPE_T::POLY );
1621 for(
const std::unique_ptr<EVERTEX>& evertex : aPolygon->vertices )
1623 pt =
VECTOR2I( evertex->x.ToSchUnits(), -evertex->y.ToSchUnits() );
1629 poly->GetPolyShape().Append( arc, -1, -1,
ARC_ACCURACY );
1633 poly->AddPoint( pt );
1637 prev_curve = evertex->curve;
1640 poly->SetLayer(
kiCadLayer( aPolygon->layer ) );
1644 return poly.release();
1652 start.
x = aWire->x1.ToSchUnits();
1653 start.
y = -aWire->y1.ToSchUnits();
1654 end.x = aWire->x2.ToSchUnits();
1655 end.y = -aWire->y2.ToSchUnits();
1658 endpoints =
SEG( start,
end );
1667 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>(
SHAPE_T::ARC );
1670 arc->SetCenter(
center );
1671 arc->SetStart( start );
1678 return arc.release();
1682 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>();
1684 line->SetStartPoint( start );
1685 line->SetEndPoint(
end );
1686 line->SetLayer(
kiCadLayer( aWire->layer ) );
1689 return line.release();
1697 VECTOR2I center( aCircle->x.ToSchUnits(), -aCircle->y.ToSchUnits() );
1710 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>(
SHAPE_T::RECTANGLE );
1712 rectangle->SetLayer(
kiCadLayer( aRectangle->layer ) );
1713 rectangle->SetPosition(
VECTOR2I( aRectangle->x1.ToSchUnits(), -aRectangle->y1.ToSchUnits() ) );
1714 rectangle->SetEnd(
VECTOR2I( aRectangle->x2.ToSchUnits(), -aRectangle->y2.ToSchUnits() ) );
1716 if( aRectangle->rot )
1718 VECTOR2I pos( rectangle->GetPosition() );
1725 rectangle->SetPosition( pos );
1726 rectangle->SetEnd(
end );
1732 return rectangle.release();
1738 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
1740 VECTOR2I pos( aJunction->x.ToSchUnits(), -aJunction->y.ToSchUnits() );
1742 junction->SetPosition( pos );
1744 return junction.release();
1749 const wxString& aNetName,
bool aIsBus )
1751 VECTOR2I elabelpos( aLabel->x.ToSchUnits(), -aLabel->y.ToSchUnits() );
1756 std::unique_ptr<SCH_LABEL_BASE> label;
1758 VECTOR2I textSize =
KiROUND( aLabel->size.ToSchUnits() * 0.7, aLabel->size.ToSchUnits() * 0.7 );
1760 auto findModulePort =
1761 [&]() ->
const EPORT*
1766 const auto& ports =
m_modules.back()->ports;
1767 const auto it = ports.find( aNetName );
1768 return it == ports.end() ? nullptr : it->second.get();
1771 const EPORT* port = findModulePort();
1775 auto hierLabel = std::make_unique<SCH_HIERLABEL>();
1782 if( direction ==
"in" )
1784 else if( direction ==
"out" )
1786 else if( direction ==
"io" )
1788 else if( direction ==
"hiz" )
1796 hierLabel->SetLabelShape( type );
1799 label = std::move( hierLabel );
1803 label = std::make_unique<SCH_LABEL>();
1807 label = std::make_unique<SCH_GLOBALLABEL>();
1811 label->SetPosition( elabelpos );
1812 label->SetTextSize( textSize );
1818 int angle =
KiROUND( aLabel->rot->degrees );
1837 return label.release();
1841std::pair<VECTOR2I, const SEG*>
1843 const std::vector<SEG>& aLines )
const
1846 const SEG* nearestLine =
nullptr;
1848 double d, mindistance = std::numeric_limits<double>::max();
1854 for(
const SEG& line : aLines )
1856 VECTOR2I testpoint = line.NearestPoint( aPoint );
1859 if( d < mindistance )
1862 nearestPoint = testpoint;
1863 nearestLine = &line;
1867 return std::make_pair( nearestPoint, nearestLine );
1872 const std::map<wxString, std::unique_ptr<EPART>>& aParts )
1874 wxCHECK( aInstance, );
1880 const auto partIt = aParts.find( aInstance->part );
1882 if( partIt == aParts.end() )
1884 Report( wxString::Format(
_(
"Error parsing Eagle file. Could not find '%s' "
1885 "instance but it is referenced in the schematic." ),
1892 const std::unique_ptr<EPART>& epart = partIt->second;
1894 wxString libName = epart->library;
1897 if( epart->libraryUrn )
1898 libName += wxS(
"_" ) + epart->libraryUrn->assetId;
1900 wxString gatename = epart->deviceset + wxS(
"_" ) + epart->device + wxS(
"_" ) +
1902 wxString symbolname = wxString( epart->deviceset + epart->device );
1903 wxString kiPackageName = epart->deviceset + epart->device;
1905 if( epart->technology )
1906 symbolname += *epart->technology;
1908 symbolname.Replace( wxT(
"*" ), wxEmptyString );
1909 kiPackageName.Replace( wxT(
"*" ), wxEmptyString );
1918 wxString altSymbolName = libName + wxT(
"_" ) + symbolname;
1921 wxString libIdSymbolName = altSymbolName;
1927 Report( wxString::Format( wxS(
"Eagle library '%s' not found while looking up symbol for "
1928 "deviceset '%s', device '%s', and gate '%s." ),
1929 libName, epart->deviceset, epart->device, aInstance->gate ) );
1933 const auto gateIt = libIt->second.GateToUnitMap.find( gatename );
1935 if( gateIt == libIt->second.GateToUnitMap.end() )
1937 Report( wxString::Format( wxS(
"Symbol not found for deviceset '%s', device '%s', and "
1938 "gate '%s in library '%s'." ),
1939 epart->deviceset, epart->device, aInstance->gate, libName ) );
1943 int unit = gateIt->second;
1948 auto p = elib->
package.find( kisymbolname );
1950 if( p != elib->
package.end() )
1952 package = p->second;
1956 p = elib->
package.find( kiPackageName );
1958 if( p != elib->
package.end() )
1959 package = p->second;
1963 std::map<std::string, UTF8> properties;
1970 part =
m_pi->LoadSymbol(
getLibFileName().GetFullPath(), kisymbolname, &properties );
1971 libIdSymbolName = kisymbolname;
1976 Report( wxString::Format(
_(
"Could not find '%s' in the imported library." ),
1983 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
1984 symbol->SetLibId( libId );
1985 symbol->SetUnit( unit );
1986 symbol->SetPosition(
VECTOR2I( aInstance->x.ToSchUnits(), -aInstance->y.ToSchUnits() ) );
1989 if( !package.IsEmpty() )
1991 wxString footprint =
m_schematic->Project().GetProjectName() + wxT(
":" ) + package;
1995 if( aInstance->rot )
1999 if( aInstance->rot->mirror )
2000 symbol->MirrorHorizontally( aInstance->x.ToSchUnits() );
2003 std::vector<SCH_FIELD*> partFields;
2008 for(
const SCH_FIELD* partField : partFields )
2012 if( partField->IsMandatory() )
2013 symbolField = symbol->GetField( partField->GetId() );
2015 symbolField = symbol->GetField( partField->GetName() );
2022 newField.
SetText( partField->GetText() );
2026 symbol->AddField( newField );
2031 symbolField->
SetTextPos( symbol->GetPosition() + partField->GetTextPos() );
2037 wxString reference = package.IsEmpty() ?
'#' + aInstance->part : aInstance->part;
2040 if( reference.find_last_not_of( wxT(
"0123456789" ) ) == ( reference.Length()-1 ) )
2041 reference.Append( wxT(
"0" ) );
2046 if( reference.find_first_not_of( wxT(
"0123456789" ) ) != 0 )
2047 reference.Prepend( wxT(
"UNK" ) );
2051 if( aInstance->part.find_first_not_of( wxT(
"#" ) ) != 0 )
2052 reference.Prepend( wxT(
"UNK" ) );
2055 referenceField->
SetText( reference );
2058 bool userValue =
m_userValue.at( libIdSymbolName );
2066 if( epart->value && !epart->value.CGet().IsEmpty() )
2068 valueField->
SetText( *epart->value );
2072 valueField->
SetText( kisymbolname );
2078 for(
const auto& [ attrName, attr ] : epart->attributes )
2084 if( !symbol->GetFields().empty() )
2085 newField.
SetTextPos( symbol->GetFields().back().GetPosition() );
2088 newField.
SetText( *attr->value );
2092 symbol->AddField( newField );
2095 bool valueAttributeFound =
false;
2096 bool nameAttributeFound =
false;
2099 for(
auto& [
name, eattr] : aInstance->attributes )
2103 if( eattr->name.Lower() == wxT(
"name" ) )
2106 nameAttributeFound =
true;
2108 else if( eattr->name.Lower() == wxT(
"value" ) )
2111 valueAttributeFound =
true;
2115 field = symbol->GetField( eattr->name );
2127 int absdegrees = eattr->rot ? eattr->rot->degrees : 0;
2128 bool mirror = eattr->rot ? eattr->rot->mirror :
false;
2130 if( aInstance->rot && aInstance->rot->mirror )
2133 bool spin = eattr->rot ? eattr->rot->spin :
false;
2138 int rotation = aInstance->rot ? aInstance->rot->degrees : 0;
2139 int reldegrees = ( absdegrees - rotation + 360.0 );
2147 if( aInstance->smashed && aInstance->smashed.Get() )
2149 symbol->GetField(
FIELD_T::VALUE )->SetVisible( valueAttributeFound );
2161 wxCHECK2( emoduleInst,
continue );
2163 refPrefix += emoduleInst->name + wxS(
":" );
2166 symbol->AddHierarchicalReference(
m_sheetPath.Path(), refPrefix + reference, unit );
2172 symbol->SetLibSymbol( part->
Flatten().release() );
2174 for(
const auto& [
name, variant] : epart->variants )
2178 if( variant->populate && !*variant->populate )
2179 symbolVariant.
m_DNP =
true;
2181 if( variant->value )
2184 if( variant->technology )
2186 auto eLibIt =
m_eagleDoc->drawing->schematic->libraries.find( epart->library );
2188 if( eLibIt ==
m_eagleDoc->drawing->schematic->libraries.end() )
2190 Report( wxString::Format( wxS(
"Library '%s' not found in schematic." ), epart->library ) );
2194 auto eDeviceSetIt = eLibIt->second->devicesets.find( epart->deviceset );
2196 if( eDeviceSetIt == eLibIt->second->devicesets.end() )
2198 Report( wxString::Format( wxS(
"Device set '%s' not found in library '%s'." ),
2199 epart->deviceset, epart->library ) );
2203 auto eDeviceIt = eDeviceSetIt->second->devices.find( epart->device );
2205 if( eDeviceIt == eDeviceSetIt->second->devices.end() )
2207 Report( wxString::Format( wxS(
"Device '%s' not found in device set '%s' in library '%s'." ),
2208 epart->device, epart->deviceset, epart->library ) );
2212 auto eTechnologyIt = eDeviceIt->second->technologies.find( *variant->technology );
2214 if( eTechnologyIt == eDeviceIt->second->technologies.end() )
2216 Report( wxString::Format( wxS(
"Technology '%s' not found in device '%s' in device set '%s' "
2217 "in library '%s'." ),
2218 *variant->technology, epart->device, epart->deviceset, epart->library ) );
2222 for(
const auto& attr : eTechnologyIt->second->attributes )
2227 attrValue = *attr->value;
2229 symbolVariant.
m_Fields[attr->name] = attrValue;
2236 for(
const SCH_PIN*
pin : symbol->GetLibPins() )
2242 symbol->ClearFlags();
2244 screen->
Append( symbol.release() );
2250 wxCHECK( aLibrary && aEagleLibrary,
nullptr );
2257 wxString prefix = edeviceset->prefix ? edeviceset->prefix.Get() : wxString( wxT(
"" ) );
2258 wxString deviceSetDescr;
2260 if( edeviceset->description )
2264 for(
const auto& [devname, edevice] : edeviceset->devices )
2266 std::vector<std::unique_ptr<LIB_SYMBOL>> derivedSymbols;
2269 wxString symbolName = edeviceset->name + edevice->name;
2270 symbolName.Replace( wxT(
"*" ), wxEmptyString );
2271 wxASSERT( !symbolName.IsEmpty() );
2274 if( edevice->package )
2275 aEagleLibrary->
package[symbolName] = edevice->package.Get();
2278 std::unique_ptr<LIB_SYMBOL> libSymbol = std::make_unique<LIB_SYMBOL>( symbolName );
2281 int gate_count =
static_cast<int>( edeviceset->gates.size() );
2283 if( gate_count > 1 )
2284 libSymbol->SetUnitCount( gate_count,
true );
2286 libSymbol->LockUnits(
true );
2290 if( prefix.length() == 0 )
2298 reference->
SetText( edevice->package ? prefix :
'#' + prefix );
2301 libSymbol->GetValueField().SetVisible(
true );
2304 bool ispower =
false;
2306 for(
const auto& [gateName, egate] : edeviceset->gates )
2308 const auto it = aLibrary->
symbols.find( egate->symbol );
2310 if( it == aLibrary->
symbols.end() )
2312 Report( wxString::Format( wxS(
"Eagle symbol '%s' not found in library '%s'." ),
2313 egate->symbol, aLibrary->
GetName() ) );
2317 wxString gateMapName = edeviceset->name + wxS(
"_" ) + edevice->name +
2318 wxS(
"_" ) + egate->name;
2320 ispower =
loadSymbol( it->second, libSymbol, edevice, gateindex, egate->name );
2325 std::vector<SCH_FIELD*> fields;
2326 libSymbol->GetFields( fields );
2329 field->SetCanAutoplace( canAutoplace );
2331 for(
const auto& [techname, technology ] : edevice->technologies )
2333 std::unique_ptr<LIB_SYMBOL> derivedSymbol;
2336 if( !technology->name.IsEmpty() )
2338 derivedSymbol = std::make_unique<LIB_SYMBOL>( symbolName + technology->name, libSymbol.get() );
2342 SCH_FIELD* childField = derivedSymbol->GetField( parentField->GetName() );
2352 for(
const std::unique_ptr<EATTR>& attr : technology->attributes )
2359 if( !derivedSymbol )
2360 field = libSymbol->FindFieldCaseInsensitive( attr->name );
2362 field = derivedSymbol->FindFieldCaseInsensitive( attr->name );
2366 field->
SetText( *attr->value );
2370 SCH_FIELD* newField =
new SCH_FIELD( derivedSymbol ? derivedSymbol.get() : libSymbol.get(),
2375 SCH_FIELD* parentField = libSymbol->FindFieldCaseInsensitive( attr->name );
2382 newField->
SetText( *attr->value );
2387 if( !derivedSymbol )
2388 libSymbol->AddField( newField );
2390 derivedSymbol->AddField( newField );
2395 derivedSymbols.push_back( std::move( derivedSymbol ) );
2398 if( gate_count > 1 )
2399 libSymbol->SetUnitCount( gate_count,
true );
2401 if( gate_count == 1 && ispower )
2402 libSymbol->SetGlobalPower();
2405 if( edevice->package )
2412 libName =
m_schematic->Project().GetProjectName();
2419 wxString packageString = libName + wxT(
":" ) + aEagleLibrary->
package[symbolName];
2421 libSymbol->GetFootprintField().SetText( packageString );
2424 wxString libName = libSymbol->GetName();
2425 libSymbol->SetName( libName );
2426 libSymbol->SetDescription( deviceSetDescr );
2436 libName = aEagleLibrary->
name + wxT(
"_" ) + libName;
2438 libSymbol->SetName( libName );
2442 std::map<std::string, UTF8> properties;
2448 for( std::unique_ptr<LIB_SYMBOL>& symbol : derivedSymbols )
2452 wxString tmp = aEagleLibrary->
name + wxT(
"_" ) + symbol->GetName();
2454 symbol->SetName( tmp );
2459 derivedSymbol->
SetParent( parentSymbol );
2471 aEagleLibrary->
KiCadSymbols[ libName ] = std::move( libSymbol );
2475 m_userValue.emplace( std::make_pair( libName, edeviceset->uservalue ==
true ) );
2477 for( std::unique_ptr<LIB_SYMBOL>& symbol : derivedSymbols )
2479 m_userValue.emplace( std::make_pair( symbol->GetName(), edeviceset->uservalue ==
true ) );
2480 aEagleLibrary->
KiCadSymbols[symbol->GetName()] = std::move( symbol );
2485 return aEagleLibrary;
2490 std::unique_ptr<LIB_SYMBOL>& aSymbol,
2491 const std::unique_ptr<EDEVICE>& aDevice,
int aGateNumber,
2492 const wxString& aGateName )
2494 wxCHECK( aEsymbol && aSymbol && aDevice,
false );
2496 std::vector<SCH_ITEM*> items;
2498 bool showRefDes =
false;
2499 bool showValue =
false;
2500 bool ispower =
false;
2503 for(
const std::unique_ptr<ECIRCLE>& ecircle : aEsymbol->circles )
2506 for(
const std::unique_ptr<EPIN>& epin : aEsymbol->pins )
2508 std::unique_ptr<SCH_PIN>
pin(
loadPin( aSymbol, epin, aGateNumber ) );
2513 if( epin->direction )
2517 if( epin->direction->Lower() == pinDir.first )
2519 pin->SetType( pinDir.second );
2521 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 )
2572 aSymbol->AddDrawItem( shape );
2574 for(
const std::unique_ptr<ERECT>& erectangle : aEsymbol->rectangles )
2577 for(
const std::unique_ptr<ETEXT>& etext : aEsymbol->texts )
2579 std::unique_ptr<SCH_TEXT> libtext(
loadSymbolText( aSymbol, etext, aGateNumber ) );
2581 if( libtext->GetText() == wxT(
"${REFERENCE}" ) )
2587 showRefDes = etext->text == wxT(
">NAME" );
2589 else if( libtext->GetText() == wxT(
"${VALUE}" ) )
2595 showValue = etext->text == wxT(
">VALUE" );
2597 else if( etext->text.StartsWith(
">" ) )
2601 wxString fieldName = etext->text.Mid( 1 );
2603 if( !fieldName.IsEmpty() )
2611 aSymbol->AddField( field );
2616 aSymbol->AddDrawItem( libtext.release() );
2620 for(
const std::unique_ptr<EWIRE>& ewire : aEsymbol->wires )
2621 aSymbol->AddDrawItem(
loadSymbolWire( aSymbol, ewire, aGateNumber ) );
2623 for(
const std::unique_ptr<EFRAME>& eframe : aEsymbol->frames )
2625 std::vector<SCH_ITEM*> frameItems;
2631 item->SetParent( aSymbol.get() );
2632 item->SetUnit( aGateNumber );
2633 aSymbol->AddDrawItem( item );
2637 aSymbol->GetReferenceField().SetVisible( showRefDes );
2638 aSymbol->GetValueField().SetVisible( showValue );
2640 return pincount == 1 ? ispower :
false;
2645 const std::unique_ptr<ECIRCLE>& aCircle,
2648 wxCHECK( aSymbol && aCircle,
nullptr );
2652 VECTOR2I center( aCircle->x.ToSchUnits(), -aCircle->y.ToSchUnits() );
2654 circle->SetParent( aSymbol.get() );
2658 if( aCircle->width.ToSchUnits() == 0 )
2668 circle->SetUnit( aGateNumber );
2675 const std::unique_ptr<ERECT>& aRectangle,
2678 wxCHECK( aSymbol && aRectangle,
nullptr );
2683 rectangle->
SetPosition(
VECTOR2I( aRectangle->x1.ToSchUnits(), -aRectangle->y1.ToSchUnits() ) );
2684 rectangle->
SetEnd(
VECTOR2I( aRectangle->x2.ToSchUnits(), -aRectangle->y2.ToSchUnits() ) );
2686 if( aRectangle->rot )
2699 rectangle->
SetUnit( aGateNumber );
2710 const std::unique_ptr<EWIRE>& aWire,
int aGateNumber )
2712 wxCHECK( aSymbol && aWire,
nullptr );
2716 begin.
x = aWire->x1.ToSchUnits();
2717 begin.
y = -aWire->y1.ToSchUnits();
2718 end.x = aWire->x2.ToSchUnits();
2719 end.y = -aWire->y2.ToSchUnits();
2738 ( aWire->width.ToSchUnits() /
radius );
2739 begin =
center + centerStartVector;
2773 const std::unique_ptr<EPOLYGON>& aPolygon,
2776 wxCHECK( aSymbol && aPolygon,
nullptr );
2778 if( !aPolygon->IsValidOutline() )
2784 std::optional<VECTOR2I> first_pt;
2788 for(
const std::unique_ptr<EVERTEX>& evertex : aPolygon->vertices )
2790 pt =
VECTOR2I( evertex->x.ToSchUnits(), -evertex->y.ToSchUnits() );
2792 if( !first_pt.has_value() )
2807 prev_curve = evertex->curve;
2810 if( first_pt.has_value() )
2811 poly->
AddPoint( first_pt.value() );
2822 const std::unique_ptr<EPIN>& aPin,
int aGateNumber )
2824 wxCHECK( aSymbol && aPin,
nullptr );
2826 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>( aSymbol.get() );
2827 pin->SetPosition(
VECTOR2I( aPin->x.ToSchUnits(), -aPin->y.ToSchUnits() ) );
2833 pin->SetUnit( aGateNumber );
2835 int roti = aPin->rot ? aPin->rot->degrees : 0;
2843 default: wxFAIL_MSG( wxString::Format( wxT(
"Unhandled orientation (%d degrees)." ), roti ) );
2850 wxString length = aPin->length.Get();
2852 if( length == wxT(
"short" ) )
2854 else if( length == wxT(
"middle" ) )
2856 else if( length == wxT(
"long" ) )
2858 else if( length == wxT(
"point" ) )
2869 wxString visible = aPin->visible.Get();
2871 if( visible == wxT(
"off" ) )
2873 pin->SetNameTextSize( 0 );
2874 pin->SetNumberTextSize( 0 );
2876 else if( visible == wxT(
"pad" ) )
2878 pin->SetNameTextSize( 0 );
2880 else if( visible == wxT(
"pin" ) )
2882 pin->SetNumberTextSize( 0 );
2892 if( aPin->function )
2894 wxString function = aPin->function.Get();
2896 if( function == wxT(
"dot" ) )
2898 else if( function == wxT(
"clk" ) )
2900 else if( function == wxT(
"dotclk" ) )
2904 return pin.release();
2909 const std::unique_ptr<ETEXT>& aText,
int aGateNumber )
2911 wxCHECK( aSymbol && aText,
nullptr );
2913 std::unique_ptr<SCH_TEXT> libtext = std::make_unique<SCH_TEXT>();
2916 libtext->SetParent( aSymbol.get() );
2917 libtext->SetUnit( aGateNumber );
2918 libtext->SetPosition(
VECTOR2I( aText->x.ToSchUnits(), -aText->y.ToSchUnits() ) );
2920 const wxString& eagleText = aText->text;
2921 wxString adjustedText;
2922 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2925 while( tokenizer.HasMoreTokens() )
2927 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2929 if( tokenizer.HasMoreTokens() )
2932 adjustedText += tmp;
2935 libtext->SetText( adjustedText.IsEmpty() ? wxString( wxS(
"~" ) ) : adjustedText );
2939 return libtext.release();
2945 wxCHECK( aText,
nullptr );
2947 std::unique_ptr<SCH_TEXT> schtext = std::make_unique<SCH_TEXT>();
2949 const wxString& eagleText = aText->text;
2950 wxString adjustedText;
2951 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2954 while( tokenizer.HasMoreTokens() )
2956 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2958 if( tokenizer.HasMoreTokens() )
2961 adjustedText += tmp;
2964 schtext->SetText( adjustedText.IsEmpty() ? wxString( wxS(
"\" \"" ) )
2967 schtext->SetPosition(
VECTOR2I( aText->x.ToSchUnits(), -aText->y.ToSchUnits() ) );
2969 schtext->SetItalic(
false );
2971 return schtext.release();
2976 const std::unique_ptr<ETEXT>& aAttributes )
const
2978 wxCHECK( aText && aAttributes, );
2983 if( aAttributes->ratio && aAttributes->ratio.CGet() > 12 )
2987 int degrees = aAttributes->rot ? aAttributes->rot->degrees : 0;
2988 bool mirror = aAttributes->rot ? aAttributes->rot->mirror :
false;
2989 bool spin = aAttributes->rot ? aAttributes->rot->spin :
false;
2997 wxCHECK( aField && aText, );
3021 auto onIntersection =
3033 const SEG* segAttached = segDesc.LabelAttached( label );
3035 if( segAttached && !onIntersection( labelPos ) )
3049 VECTOR2I wireDirection( segAttached->
B - segAttached->
A );
3051 if( ( wireDirection.
x == 0 ) && (wireDirection.
y == 0 ) )
3055 const VECTOR2I origPos( labelPos );
3058 bool checkPositive =
true;
3059 bool checkNegative =
true;
3064 while( ( !
move || onIntersection( labelPos ) ) && ( checkPositive || checkNegative ) )
3069 if( trial % 2 == 1 )
3071 labelPos =
VECTOR2I( origPos + wireDirection * trial / 2 );
3072 move = checkPositive = segAttached->
Contains( labelPos );
3076 labelPos =
VECTOR2I( origPos - wireDirection * trial / 2 );
3077 move = checkNegative = segAttached->
Contains( labelPos );
3087 if( wireDirection.
x == 0 )
3089 if( wireDirection.
y < 0 )
3094 else if( wireDirection.
y == 0 )
3096 if( wireDirection.
x < 0 )
3130 wxFileInputStream input( aFileName );
3135 wxTextInputStream
text( input );
3137 for(
int i = 0; i < 8; i++ )
3142 if(
text.ReadLine().Contains( wxS(
"<eagle" ) ) )
3160 if( !item->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
3164 item->SetPosition( aNewEndPoint );
3177 std::vector<SCH_LINE*> buses;
3178 std::vector<SCH_LINE*> wires;
3189 buses.push_back( line );
3190 else if( line->
IsWire() )
3191 wires.push_back( line );
3196 VECTOR2I wireStart = wire->GetStartPoint();
3197 VECTOR2I wireEnd = wire->GetEndPoint();
3201 VECTOR2I busStart = bus->GetStartPoint();
3202 VECTOR2I busEnd = bus->GetEndPoint();
3205 [](
int signX,
int signY ) ->
VECTOR2I
3217 if( wireStart.
y == wireEnd.
y && busStart.
x == busEnd.
x )
3221 if( testBusHit( wireStart ) )
3225 if( wireEnd.
x < busStart.
x )
3232 VECTOR2I p = wireStart + entrySize( -1, 0 );
3234 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
3243 screen->
Append( busEntry );
3245 wire->SetStartPoint( p );
3247 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
3256 screen->
Append( busEntry );
3258 wire->SetStartPoint( p );
3273 VECTOR2I p = wireStart + entrySize( 1, 0 );
3275 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
3284 screen->
Append( busEntry );
3286 wire->SetStartPoint( p );
3288 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
3297 screen->
Append( busEntry );
3299 wire->SetStartPoint( p );
3310 else if( testBusHit( wireEnd ) )
3314 if( wireStart.
x < busStart.
x )
3321 VECTOR2I p = wireEnd + entrySize( -1, 0 );
3323 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3332 screen->
Append( busEntry );
3334 wire->SetEndPoint( p );
3336 else if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3345 screen->
Append( busEntry );
3346 moveLabels( wire, wireEnd + entrySize( -1, 0 ) );
3347 wire->SetEndPoint( wireEnd + entrySize( -1, 0 ) );
3362 VECTOR2I p = wireEnd + entrySize( 1, 0 );
3364 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3373 screen->
Append( busEntry );
3375 wire->SetEndPoint( p );
3377 else if( testBusHit( wireEnd + entrySize( 0, 1 ) ) )
3386 screen->
Append( busEntry );
3388 wire->SetEndPoint( p );
3400 else if( wireStart.
x == wireEnd.
x && busStart.
y == busEnd.
y )
3404 if( testBusHit( wireStart ) )
3408 if( wireEnd.
y < busStart.
y )
3416 VECTOR2I p = wireStart + entrySize( 0, -1 );
3418 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3428 screen->
Append( busEntry );
3430 wire->SetStartPoint( p );
3432 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3442 screen->
Append( busEntry );
3444 wire->SetStartPoint( p );
3460 VECTOR2I p = wireStart + entrySize( 0, 1 );
3462 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3472 screen->
Append( busEntry );
3474 wire->SetStartPoint( p );
3476 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3486 screen->
Append( busEntry );
3488 wire->SetStartPoint( p );
3499 else if( testBusHit( wireEnd ) )
3503 if( wireStart.
y < busStart.
y )
3511 VECTOR2I p = wireEnd + entrySize( 0, -1 );
3513 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3523 screen->
Append( busEntry );
3525 wire->SetEndPoint( p );
3527 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3537 screen->
Append( busEntry );
3539 wire->SetEndPoint( p );
3555 VECTOR2I p = wireEnd + entrySize( 0, 1 );
3557 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3567 screen->
Append( busEntry );
3569 wire->SetEndPoint( p );
3571 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3581 screen->
Append( busEntry );
3583 wire->SetEndPoint( p );
3599 if( testBusHit( wireStart ) )
3601 VECTOR2I wirevector = wireStart - wireEnd;
3603 if( wirevector.
x > 0 )
3605 if( wirevector.
y > 0 )
3607 VECTOR2I p = wireStart + entrySize( -1, -1 );
3610 screen->
Append( busEntry );
3613 wire->SetStartPoint( p );
3617 VECTOR2I p = wireStart + entrySize( -1, 1 );
3620 screen->
Append( busEntry );
3623 wire->SetStartPoint( p );
3628 if( wirevector.
y > 0 )
3630 VECTOR2I p = wireStart + entrySize( 1, -1 );
3633 screen->
Append( busEntry );
3636 wire->SetStartPoint( p );
3640 VECTOR2I p = wireStart + entrySize( 1, 1 );
3643 screen->
Append( busEntry );
3646 wire->SetStartPoint( p );
3652 else if( testBusHit( wireEnd ) )
3654 VECTOR2I wirevector = wireStart - wireEnd;
3656 if( wirevector.
x > 0 )
3658 if( wirevector.
y > 0 )
3660 VECTOR2I p = wireEnd + entrySize( 1, 1 );
3663 screen->
Append( busEntry );
3666 wire->SetEndPoint( p );
3670 VECTOR2I p = wireEnd + entrySize( 1, -1 );
3673 screen->
Append( busEntry );
3676 wire->SetEndPoint( p );
3681 if( wirevector.
y > 0 )
3683 VECTOR2I p = wireEnd + entrySize( -1, 1 );
3686 screen->
Append( busEntry );
3689 wire->SetEndPoint( p );
3693 VECTOR2I p = wireEnd + entrySize( -1, -1 );
3696 screen->
Append( busEntry );
3699 wire->SetEndPoint( p );
3713 wxCHECK( aLabel,
nullptr );
3719 if( seg.Contains( labelPos ) )
3731 wxCHECK( aSymbol && aPin,
false );
3739 const auto& items = pointIt->second;
3741 wxCHECK( items.find( aPin ) != items.end(),
false );
3743 return items.size() > 1;
3757 int unit = aSymbol->
GetUnit();
3760 std::set<int> missingUnits;
3767 bool pinInUnit = !unit ||
pin->GetUnit() == unit;
3781 switch(
pin->GetOrientation() )
3798 aScreen->
Append( netLabel );
3801 else if( aUpdateSet )
3806 wxASSERT(
pin->GetUnit() );
3807 missingUnits.insert(
pin->GetUnit() );
3820 entry.
cmp = aSymbol;
3822 entry.
units.emplace( unit,
false );
3827 cmpIt->second.units[unit] =
false;
3830 if( !missingUnits.empty() )
3833 entry.
cmp = aSymbol;
3837 for(
int i : missingUnits )
3839 if( entry.
units.find( i ) != entry.
units.end() )
3840 entry.
units.emplace( i,
true );
3852 wxString ret = wxT(
"{" );
3854 wxStringTokenizer tokenizer( aEagleName,
"," );
3856 while( tokenizer.HasMoreTokens() )
3858 wxString member = tokenizer.GetNextToken();
3865 if( member.Freq(
'!' ) % 2 > 0 )
3866 member << wxT(
"!" );
3868 ret << member << wxS(
" " );
3883 std::unique_ptr<EPART>& epart =
m_eagleDoc->drawing->schematic->parts[aInstance->part];
3885 if( !epart || epart->deviceset.IsEmpty() )
3888 std::unique_ptr<ELIBRARY>& elibrary =
m_eagleDoc->drawing->schematic->libraries[epart->library];
3893 std::unique_ptr<EDEVICE_SET>& edeviceset = elibrary->devicesets[epart->deviceset];
3898 std::unique_ptr<EGATE>& egate = edeviceset->gates[aInstance->gate];
3903 std::unique_ptr<ESYMBOL>& esymbol = elibrary->symbols[egate->symbol];
3906 return esymbol.get();
3913 const wxString& aEagleFieldName,
3916 wxCHECK( aField && !aEagleFieldName.
IsEmpty(), );
3922 for(
const std::unique_ptr<ETEXT>&
text : esymbol->
texts )
3924 if(
text->text == aEagleFieldName )
3927 VECTOR2I pos(
text->x.ToSchUnits() + aInstance->x.ToSchUnits(),
3928 -
text->y.ToSchUnits() - aInstance->y.ToSchUnits() );
3930 bool mirror =
text->rot ?
text->rot->mirror :
false;
3932 if( aInstance->rot && aInstance->rot->mirror )
3936 pos.
y = -aInstance->y.ToSchUnits() +
text->y.ToSchUnits();
3949 std::vector<SCH_FIELD*> fields;
3954 retv = fields[0]->GetPosition();
3956 for(
size_t i = 1; i < fields.size(); i++ )
3958 if( fields[i]->GetPosition().x > retv.
x )
3959 retv.
x = fields[i]->GetPosition().x;
3961 if( fields[i]->GetPosition().y > retv.
y )
3962 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.
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 VECTOR2I GetTextSize() const
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)
GR_TEXT_H_ALIGN_T GetHorizJustify() const
virtual void SetVisible(bool aVisible)
virtual EDA_ANGLE GetTextAngle() const
void SetBold(bool aBold)
Set the text to be bold - this will also update the font if needed.
GR_TEXT_V_ALIGN_T GetVertJustify() const
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
void SetItalic(bool aItalic)
Set the text to be italic - this will also update the font if needed.
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)
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.
std::vector< const SCH_PIN * > GetGraphicalPins(int aUnit=0, int aBodyStyle=0) const
Graphical pins: Return schematic pin objects as drawn (unexpanded), filtered by unit/body.
void GetFields(std::vector< SCH_FIELD * > &aList, bool aVisibleOnly=false) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
void SetParent(LIB_SYMBOL *aParent=nullptr)
bool IsGlobalPower() const override
int GetUnitCount() const override
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
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
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.
void loadFieldAttributes(SCH_FIELD *aField, const SCH_TEXT *aText) const
Move net labels that are detached from any wire to the nearest wire.
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
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
Wires and labels of a single connection (segment in Eagle nomenclature)
std::map< VECTOR2I, std::set< const EDA_ITEM * > > m_connPoints
The fully parsed Eagle schematic file.
bool checkConnections(const SCH_SYMBOL *aSymbol, const SCH_PIN *aPin) const
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()
Checks if there are other wires or pins at the position of the tested pin.
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
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
Nets as defined in the <nets> sections of an Eagle schematic file.
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 doClone=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)
Update aItem's bounding box in the tree.
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 text size in mils. (can be changed in preference menu)
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 opt_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.
OPTIONAL_XML_ATTRIBUTE< double > opt_double
static constexpr EDA_ANGLE ANGLE_VERTICAL
#define IGNORE_PARENT_GROUP
#define IS_NEW
New item, just created.
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
@ FILLED_SHAPE
Fill with object color.
@ ERCE_BUS_ENTRY_NEEDED
Importer failed to auto-place a bus entry.
bool m_EagleImportFieldsCanAutoplace
Default CanAutoplace value for fields imported from EAGLE files.
static const std::string KiCadSchematicFileExtension
static const std::string KiCadSymbolLibFileExtension
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#define THROW_IO_ERRORF(msg,...)
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)
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)
Strip the Eagle "@<tag>" linking hint from a pin name (e.g. return 'GND' for 'GND@2')
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::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
Map references to missing symbol units data.
const SCH_SYMBOL * cmp
Screen where the parent symbol is located.
std::map< int, bool > units
Segments representing wires for intersection checking.
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()
@ 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".
wxString GetCanonicalFieldName(FIELD_T aFieldType)
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.