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>
90 bbox.
Merge( item->GetBoundingBox() );
99 return aPinName.BeforeFirst(
'@' );
112 wxCHECK( currentSheet,
nullptr );
157 for(
const std::unique_ptr<ELAYER>& elayer : aLayers )
176 switch ( elayer->number)
206 int roti = int( eagleDegrees );
216 wxASSERT_MSG(
false, wxString::Format( wxT(
"Unhandled orientation (%d degrees)" ),
225 bool aMirror,
bool aSpin,
int aAbsDegress )
227 int align = aEagleAlignment;
229 if( aRelDegress == 90 )
233 else if( aRelDegress == 180 )
237 else if( aRelDegress == 270 )
243 if( aMirror ==
true )
245 if( aAbsDegress == 90 || aAbsDegress == 270 )
256 else if( aAbsDegress == 0 || aAbsDegress == 180 )
350 const std::map<std::string, UTF8>* aProperties )
352 wxASSERT( !aFileName || aSchematic !=
nullptr );
372 wxXmlNode* currentNode = xmlDocument.GetRoot();
378 unique_ptr<SCH_SHEET> deleter( aAppendToMe ?
nullptr :
m_rootSheet );
385 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
386 wxT(
"Can't append to a schematic with no root!" ) );
397 if( sheetPath.Last() == aAppendToMe )
408 m_rootSheet->SetFileName( newFilename.GetFullPath() );
427 wxCHECK_MSG(
table,
nullptr,
"Could not load symbol lib table." );
429 m_pi.reset( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
437 wxString libTableUri = wxT(
"${KIPRJMOD}/" ) +
getLibFileName().GetFullName();
442 row.
SetURI( libTableUri );
450 m_eagleDoc = std::make_unique<EAGLE_DOC>( currentNode,
this );
469 const wxString& aLibraryPath,
470 const std::map<std::string, UTF8>* aProperties )
481 for(
const auto& [symName, libSymbol] : it->second.KiCadSymbols )
482 aSymbolNameList.push_back( symName );
488 const wxString& aLibraryPath,
489 const std::map<std::string, UTF8>* aProperties )
500 for(
const auto& [symName, libSymbol] : it->second.KiCadSymbols )
501 aSymbolList.push_back( libSymbol.get() );
507 const std::map<std::string, UTF8>* aProperties )
518 auto it2 = it->second.KiCadSymbols.find( aAliasName );
520 if( it2 != it->second.KiCadSymbols.end() )
521 return it2->second.get();
530 wxFileName fn( aLibraryPath );
532 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
533 return fn.GetModificationTime().GetValue().GetValue();
564 std::unique_ptr<EAGLE_DOC> doc = std::make_unique<EAGLE_DOC>( xmlDocument.GetRoot(),
this );
568 m_version = ( doc->version.IsEmpty() ) ? wxString( wxS(
"0.0" ) ) : doc->version;
580 wxXmlDocument xmlDocument;
581 wxFFileInputStream stream(
m_filename.GetFullPath() );
586 wxString::Format(
_(
"Unable to read file '%s'." ),
m_filename.GetFullPath() ) );
590 wxTextInputStream
text( stream );
591 wxString line =
text.ReadLine();
593 if( !line.StartsWith( wxT(
"<?xml" ) ) && !line.StartsWith( wxT(
"<!--" ) )
594 && !line.StartsWith( wxT(
"<eagle " ) ) )
596 THROW_IO_ERROR( wxString::Format(
_(
"'%s' is an Eagle binary-format file; "
597 "only Eagle XML-format files can be imported." ),
601#if wxCHECK_VERSION( 3, 3, 0 )
604 if( !xmlDocument.Load( stream, wxXMLDOC_NONE, &err ) )
606 if( err.message == wxS(
"no element found" ) )
610 wxMemoryOutputStream memOutput;
613 header <<
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
614 header <<
"<!DOCTYPE eagle SYSTEM \"eagle.dtd\">\n";
616 wxScopedCharBuffer headerBuf = header.utf8_str();
617 memOutput.Write( headerBuf.data(), headerBuf.length() );
619 wxFFileInputStream stream2(
m_filename.GetFullPath() );
620 memOutput.Write( stream2 );
622 wxMemoryInputStream memInput( memOutput );
624 if( !xmlDocument.Load( memInput, wxXMLDOC_NONE, &err ) )
631 THROW_IO_ERROR( wxString::Format(
_(
"Unable to read file '%s'.\n'%s' at line %d, column %d, offset %d" ),
632 m_filename.GetFullPath(), err.message, err.line, err.column,
637 if( !xmlDocument.Load( stream ) )
641 wxMemoryOutputStream memOutput;
644 header <<
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
645 header <<
"<!DOCTYPE eagle SYSTEM \"eagle.dtd\">\n";
647 wxScopedCharBuffer headerBuf = header.utf8_str();
648 memOutput.Write( headerBuf.data(), headerBuf.length() );
650 wxFFileInputStream stream2(
m_filename.GetFullPath() );
651 memOutput.Write( stream2 );
653 wxMemoryInputStream memInput( memOutput );
655 if( !xmlDocument.Load( memInput ) )
668 wxCHECK( aDrawing, );
672 if( aDrawing->library )
680 if( aDrawing->schematic )
687 for(
const std::unique_ptr<ESHEET>& esheet : aSchematic.
sheets )
689 for(
const std::unique_ptr<ENET>& enet : esheet->nets )
691 wxString netName = enet->netname;
700 for(
const auto& [modname, emodule] : aSchematic.
modules )
702 for(
const std::unique_ptr<ESHEET>& esheet : emodule->sheets )
704 for(
const std::unique_ptr<ENET>& enet : esheet->nets )
706 wxString netName = enet->netname;
721 if( aSchematic.
sheets.empty() )
725 for(
const auto& [
name, epart] : aSchematic.
parts )
728 for(
const auto& [modName, emodule] : aSchematic.
modules )
730 for(
const auto& [partName, epart] : emodule->parts )
736 for(
const auto& [libName, elibrary] : aSchematic.
libraries )
739 elib->
name = elibrary->GetName();
753 for(
const std::unique_ptr<ESHEET>& esheet : aSchematic.
sheets )
757 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>(
m_rootSheet );
759 sheet->SetScreen( screen );
762 wxCHECK2( sheet && screen,
continue );
764 wxString pageNo = wxString::Format( wxT(
"%d" ),
m_sheetIndex );
774 wxCHECK2( currentScreen,
continue );
790 int maxY = sheetBbox.
GetY();
797 const SCH_SYMBOL* origSymbol = cmp.second.cmp;
799 for(
auto& unitEntry : cmp.second.units )
801 if( unitEntry.second ==
false )
805 int unit = unitEntry.first;
809 symbol->SetUnitSelection( &sheetpath, unit );
810 symbol->SetUnit( unit );
811 symbol->SetOrientation( 0 );
812 symbol->AddHierarchicalReference( sheetpath.
Path(), reference, unit );
815 BOX2I cmpBbox = symbol->GetBoundingBox();
816 int posY = newCmpPosition.
y + cmpBbox.
GetHeight();
817 symbol->SetPosition(
VECTOR2I( newCmpPosition.
x, posY ) );
819 maxY = std::max( maxY, posY );
821 if( newCmpPosition.
x >= pageSizeIU.
x )
826 m_rootSheet->GetScreen()->Append( symbol.release() );
839 wxCHECK( sheet && screen, );
843 std::string filename;
850 if( aSheet->description )
851 sheet->
SetName( aSheet->description.value().text );
856 replace( filename.begin(), filename.end(),
' ',
'_' );
858 fn.SetName( filename );
864 for(
const auto& [
name, moduleinst] : aSheet->moduleinsts )
871 for(
const std::unique_ptr<EPOLYGON>& epoly : aSheet->plain->polygons )
874 for(
const std::unique_ptr<EWIRE>& ewire : aSheet->plain->wires )
880 for(
const std::unique_ptr<ETEXT>& etext : aSheet->plain->texts )
883 for(
const std::unique_ptr<ECIRCLE>& ecircle : aSheet->plain->circles )
886 for(
const std::unique_ptr<ERECT>& erectangle : aSheet->plain->rectangles )
889 for(
const std::unique_ptr<EFRAME>& eframe : aSheet->plain->frames )
891 std::vector<SCH_ITEM*> frameItems;
902 for(
const std::unique_ptr<EINSTANCE>& einstance : aSheet->instances )
910 for(
const std::unique_ptr<EBUS>& ebus : aSheet->busses )
919 for(
const std::unique_ptr<ENET>& enet : aSheet->nets )
922 wxString netName = enet->netname;
923 wxString netClass = wxString::Format( wxS(
"%i" ), enet->netcode );
942 if( pageSizeIU.
x < targetSheetSize.
x )
945 if( pageSizeIU.
y < targetSheetSize.
y )
952 VECTOR2I sheetcentre( pageSizeIU.
x / 2, pageSizeIU.
y / 2 );
956 VECTOR2I translation = sheetcentre - itemsCentre;
957 translation.
x = translation.
x - translation.
x %
schIUScale.MilsToIU( 100 );
958 translation.
y = translation.
y - translation.
y %
schIUScale.MilsToIU( 100 );
970 std::vector<SCH_ITEM*> allItems;
972 std::copy( screen->
Items().
begin(), screen->
Items().
end(), std::back_inserter( allItems ) );
976 item->SetPosition( item->GetPosition() + translation );
994 wxCHECK( currentSheet &¤tScreen, );
1000 auto it =
m_eagleDoc->drawing->schematic->modules.find( aModuleInstance->moduleinst );
1003 if( it ==
m_eagleDoc->drawing->schematic->modules.end() )
1005 THROW_IO_ERROR( wxString::Format(
_(
"No module instance '%s' found in schematic "
1007 aModuleInstance->name,
m_filename.GetFullPath() ) );
1011 fn.SetName( aModuleInstance->moduleinst );
1015 VECTOR2I size( it->second->dx.ToSchUnits(), it->second->dy.ToSchUnits() );
1017 int halfX =
KiROUND( size.
x / 2.0 );
1018 int halfY =
KiROUND( size.
y / 2.0 );
1019 int portExtWireLength =
schIUScale.mmToIU( 5.08 );
1020 VECTOR2I pos( aModuleInstance->x.ToSchUnits() - halfX,
1021 -aModuleInstance->y.ToSchUnits() - halfY );
1023 std::unique_ptr<SCH_SHEET> newSheet = std::make_unique<SCH_SHEET>( currentSheet, pos, size );
1031 if( schFile->GetFileName() == fn.GetFullPath() )
1033 newScreen = schFile;
1038 bool isNewSchFile = ( newScreen == nullptr );
1046 wxCHECK( newSheet && newScreen, );
1048 newSheet->SetScreen( newScreen );
1049 newSheet->SetFileName( fn.GetFullName() );
1050 newSheet->SetName( aModuleInstance->name );
1052 for(
const auto& [portName, port] : it->second->ports )
1055 int pinOffset = port->coord.ToSchUnits();
1058 if( port->side ==
"left" )
1062 pinPos.
y = pos.
y + halfY - pinOffset;
1063 portExtWireEndpoint = pinPos;
1064 portExtWireEndpoint.
x -= portExtWireLength;
1066 else if( port->side ==
"right" )
1069 pinPos.
x = pos.
x + size.
x;
1070 pinPos.
y = pos.
y + halfY - pinOffset;
1071 portExtWireEndpoint = pinPos;
1072 portExtWireEndpoint.
x += portExtWireLength;
1074 else if( port->side ==
"top" )
1077 pinPos.
x = pos.
x + halfX + pinOffset;
1079 portExtWireEndpoint = pinPos;
1080 portExtWireEndpoint.
y -= portExtWireLength;
1082 else if( port->side ==
"bottom" )
1085 pinPos.
x = pos.
x + halfX + pinOffset;
1086 pinPos.
y = pos.
y + size.
y;
1087 portExtWireEndpoint = pinPos;
1088 portExtWireEndpoint.
y += portExtWireLength;
1093 currentScreen->
Append( portExtWire );
1097 if( port->direction )
1099 if( *port->direction ==
"in" )
1101 else if( *port->direction ==
"out" )
1103 else if( *port->direction ==
"io" )
1105 else if( *port->direction ==
"hiz" )
1120 newSheet->AddPin( sheetPin );
1123 wxString pageNo = wxString::Format( wxT(
"%d" ),
m_sheetIndex );
1125 newSheet->SetParent( currentSheet );
1128 currentScreen->
Append( newSheet.release() );
1130 m_modules.push_back( it->second.get() );
1136 for(
const std::unique_ptr<ESHEET>& esheet : it->second->sheets )
1146 wxCHECK2( emoduleInst,
continue );
1148 refPrefix += emoduleInst->name + wxS(
":" );
1159 wxCHECK2( symbol && !symbol->
GetInstances().empty(),
continue );
1162 wxString newReference = refPrefix + inst.
m_Reference.AfterLast(
':' );
1176 std::vector<SCH_ITEM*>& aItems )
1178 int xMin = aFrame->x1.ToSchUnits();
1179 int xMax = aFrame->x2.ToSchUnits();
1180 int yMin = -aFrame->y1.ToSchUnits();
1181 int yMax = -aFrame->y2.ToSchUnits();
1184 std::swap( xMin, xMax );
1187 std::swap( yMin, yMax );
1195 aItems.push_back( lines );
1197 if( !( aFrame->border_left ==
false ) )
1204 aItems.push_back( lines );
1207 int height = yMax - yMin;
1210 int legendPosX = xMin +
schIUScale.MilsToIU( 75 );
1211 double rowSpacing = height / double( aFrame->rows );
1212 double legendPosY = yMin + ( rowSpacing / 2 );
1214 for( i = 1; i < aFrame->rows; i++ )
1216 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1220 aItems.push_back( lines );
1223 char legendChar =
'A';
1225 for( i = 0; i < aFrame->rows; i++ )
1231 legendText->
SetText( wxString( legendChar ) );
1234 aItems.push_back( legendText );
1236 legendPosY += rowSpacing;
1240 if( !( aFrame->border_right ==
false ) )
1247 aItems.push_back( lines );
1250 int height = yMax - yMin;
1253 int legendPosX = xMax -
schIUScale.MilsToIU( 75 );
1254 double rowSpacing = height / double( aFrame->rows );
1255 double legendPosY = yMin + ( rowSpacing / 2 );
1257 for( i = 1; i < aFrame->rows; i++ )
1259 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1263 aItems.push_back( lines );
1266 char legendChar =
'A';
1268 for( i = 0; i < aFrame->rows; i++ )
1274 legendText->
SetText( wxString( legendChar ) );
1277 aItems.push_back( legendText );
1279 legendPosY += rowSpacing;
1283 if( !( aFrame->border_top ==
false ) )
1290 aItems.push_back( lines );
1293 int width = xMax - xMin;
1296 int legendPosY = yMin +
schIUScale.MilsToIU( 75 );
1297 double columnSpacing = width / double( aFrame->columns );
1298 double legendPosX = xMin + ( columnSpacing / 2 );
1300 for( i = 1; i < aFrame->columns; i++ )
1302 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1306 aItems.push_back( lines );
1309 char legendChar =
'1';
1311 for( i = 0; i < aFrame->columns; i++ )
1317 legendText->
SetText( wxString( legendChar ) );
1320 aItems.push_back( legendText );
1322 legendPosX += columnSpacing;
1326 if( !( aFrame->border_bottom ==
false ) )
1333 aItems.push_back( lines );
1336 int width = xMax - xMin;
1339 int legendPosY = yMax -
schIUScale.MilsToIU( 75 );
1340 double columnSpacing = width / double( aFrame->columns );
1341 double legendPosX = xMin + ( columnSpacing / 2 );
1343 for( i = 1; i < aFrame->columns; i++ )
1345 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1349 aItems.push_back( lines );
1352 char legendChar =
'1';
1354 for( i = 0; i < aFrame->columns; i++ )
1360 legendText->
SetText( wxString( legendChar ) );
1363 aItems.push_back( legendText );
1365 legendPosX += columnSpacing;
1372 const wxString& netName,
1373 const wxString& aNetClass )
1380 size_t segmentCount = aSegments.size();
1382 for(
const std::unique_ptr<ESEGMENT>& esegment : aSegments )
1384 bool labelled =
false;
1385 bool firstWireFound =
false;
1391 for(
const std::unique_ptr<EWIRE>& ewire : esegment->wires )
1400 if( !firstWireFound )
1402 firstWire = thisWire;
1403 firstWireFound =
true;
1409 if( !desc.labels.empty() && desc.labels.front()->GetText() == netName )
1412 for(
const SEG& seg : desc.segs )
1421 segDesc.
segs.push_back( thisWire );
1425 for(
const std::unique_ptr<EJUNCTION>& ejunction : esegment->junctions )
1428 for(
const std::unique_ptr<ELABEL>& elabel : esegment->labels )
1433 wxASSERT( segDesc.
labels.empty()
1436 segDesc.
labels.push_back( label );
1440 for(
const std::unique_ptr<EPINREF>& epinref : esegment->pinRefs )
1442 wxString part = epinref->part;
1443 wxString
pin = epinref->pin;
1445 auto powerPort =
m_powerPorts.find( wxT(
"#" ) + part );
1457 if( !labelled && firstWireFound )
1459 std::unique_ptr<SCH_LABEL_BASE> label;
1464 else if( segmentCount > 1 )
1469 label->SetPosition( firstWire.
A );
1474 if( firstWire.
B.
x > firstWire.
A.
x )
1479 screen->
Append( label.release() );
1488 std::unique_ptr<SCH_SHAPE> poly = std::make_unique<SCH_SHAPE>(
SHAPE_T::POLY );
1492 for(
const std::unique_ptr<EVERTEX>& evertex : aPolygon->vertices )
1494 pt =
VECTOR2I( evertex->x.ToSchUnits(), -evertex->y.ToSchUnits() );
1500 poly->GetPolyShape().Append( arc, -1, -1,
ARC_ACCURACY );
1504 poly->AddPoint( pt );
1508 prev_curve = evertex->curve;
1511 poly->SetLayer(
kiCadLayer( aPolygon->layer ) );
1515 return poly.release();
1523 start.
x = aWire->x1.ToSchUnits();
1524 start.
y = -aWire->y1.ToSchUnits();
1525 end.x = aWire->x2.ToSchUnits();
1526 end.y = -aWire->y2.ToSchUnits();
1529 endpoints =
SEG( start,
end );
1533 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>(
SHAPE_T::ARC );
1536 arc->SetCenter(
center );
1537 arc->SetStart( start );
1544 return arc.release();
1548 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>();
1550 line->SetStartPoint( start );
1551 line->SetEndPoint(
end );
1552 line->SetLayer(
kiCadLayer( aWire->layer ) );
1555 return line.release();
1563 VECTOR2I center( aCircle->x.ToSchUnits(), -aCircle->y.ToSchUnits() );
1576 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>(
SHAPE_T::RECTANGLE );
1578 rectangle->SetLayer(
kiCadLayer( aRectangle->layer ) );
1579 rectangle->SetPosition(
VECTOR2I( aRectangle->x1.ToSchUnits(), -aRectangle->y1.ToSchUnits() ) );
1580 rectangle->SetEnd(
VECTOR2I( aRectangle->x2.ToSchUnits(), -aRectangle->y2.ToSchUnits() ) );
1582 if( aRectangle->rot )
1584 VECTOR2I pos( rectangle->GetPosition() );
1591 rectangle->SetPosition( pos );
1592 rectangle->SetEnd(
end );
1598 return rectangle.release();
1604 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
1606 VECTOR2I pos( aJunction->x.ToSchUnits(), -aJunction->y.ToSchUnits() );
1608 junction->SetPosition( pos );
1610 return junction.release();
1615 const wxString& aNetName )
1617 VECTOR2I elabelpos( aLabel->x.ToSchUnits(), -aLabel->y.ToSchUnits() );
1622 std::unique_ptr<SCH_LABEL_BASE> label;
1625 KiROUND( aLabel->size.ToSchUnits() * 0.7 ) );
1631 label = std::make_unique<SCH_HIERLABEL>();
1634 const auto it =
m_modules.back()->ports.find( aNetName );
1638 if( it->second->direction )
1640 wxString direction = *it->second->direction;
1642 if( direction ==
"in" )
1644 else if( direction ==
"out" )
1646 else if( direction ==
"io" )
1648 else if( direction ==
"hiz" )
1656 label->SetLabelShape( type );
1661 label = std::make_unique<SCH_LABEL>();
1667 label = std::make_unique<SCH_GLOBALLABEL>();
1672 label = std::make_unique<SCH_LABEL>();
1676 label->SetPosition( elabelpos );
1677 label->SetTextSize( textSize );
1682 for(
int i = 0; i <
KiROUND( aLabel->rot->degrees / 90.0 ) %4; ++i )
1683 label->Rotate90(
false );
1685 if( aLabel->rot->mirror )
1686 label->MirrorSpinStyle(
false );
1689 return label.release();
1693std::pair<VECTOR2I, const SEG*>
1695 const std::vector<SEG>& aLines )
const
1698 const SEG* nearestLine =
nullptr;
1700 double d, mindistance = std::numeric_limits<double>::max();
1703 for(
const SEG& line : aLines )
1708 if( d < mindistance )
1711 nearestPoint = testpoint;
1712 nearestLine = &line;
1715 testpoint = line.Center();
1718 if( d < mindistance )
1721 nearestPoint = testpoint;
1722 nearestLine = &line;
1728 if( d < mindistance )
1731 nearestPoint = testpoint;
1732 nearestLine = &line;
1736 return std::make_pair( nearestPoint, nearestLine );
1741 const std::map<wxString, std::unique_ptr<EPART>>& aParts )
1743 wxCHECK( aInstance, );
1749 const auto partIt = aParts.find( aInstance->part );
1751 if( partIt == aParts.end() )
1753 Report( wxString::Format(
_(
"Error parsing Eagle file. Could not find '%s' "
1754 "instance but it is referenced in the schematic." ),
1761 const std::unique_ptr<EPART>& epart = partIt->second;
1763 wxString libName = epart->library;
1766 if( epart->libraryUrn )
1767 libName += wxS(
"_" ) + epart->libraryUrn->assetId;
1769 wxString gatename = epart->deviceset + wxS(
"_" ) + epart->device + wxS(
"_" ) +
1771 wxString symbolname = wxString( epart->deviceset + epart->device );
1772 symbolname.Replace( wxT(
"*" ), wxEmptyString );
1780 wxString altSymbolName = libName + wxT(
"_" ) + symbolname;
1783 wxString libIdSymbolName = altSymbolName;
1789 Report( wxString::Format( wxS(
"Eagle library '%s' not found while looking up symbol for "
1790 "deviceset '%s', device '%s', and gate '%s." ),
1791 libName, epart->deviceset, epart->device, aInstance->gate ) );
1795 const auto gateIt = libIt->second.GateToUnitMap.find( gatename );
1797 if( gateIt == libIt->second.GateToUnitMap.end() )
1799 Report( wxString::Format( wxS(
"Symbol not found for deviceset '%s', device '%s', and "
1800 "gate '%s in library '%s'." ),
1801 epart->deviceset, epart->device, aInstance->gate, libName ) );
1805 int unit = gateIt->second;
1810 auto p = elib->
package.find( kisymbolname );
1812 if( p != elib->
package.end() )
1813 package = p->second;
1816 std::map<std::string, UTF8> properties;
1823 part =
m_pi->LoadSymbol(
getLibFileName().GetFullPath(), kisymbolname, &properties );
1824 libIdSymbolName = kisymbolname;
1829 Report( wxString::Format(
_(
"Could not find '%s' in the imported library." ),
1836 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
1837 symbol->SetLibId( libId );
1838 symbol->SetUnit( unit );
1839 symbol->SetPosition(
VECTOR2I( aInstance->x.ToSchUnits(), -aInstance->y.ToSchUnits() ) );
1842 if( !package.IsEmpty() )
1844 wxString footprint =
m_schematic->Project().GetProjectName() + wxT(
":" ) + package;
1848 if( aInstance->rot )
1852 if( aInstance->rot->mirror )
1853 symbol->MirrorHorizontally( aInstance->x.ToSchUnits() );
1856 std::vector<SCH_FIELD*> partFields;
1859 for(
const SCH_FIELD* partField : partFields )
1863 if( partField->IsMandatory() )
1864 symbolField = symbol->GetField( partField->GetId() );
1866 symbolField = symbol->GetField( partField->GetName() );
1868 wxCHECK2( symbolField,
continue );
1871 symbolField->
SetTextPos( symbol->GetPosition() + partField->GetTextPos() );
1876 wxString reference = package.IsEmpty() ?
'#' + aInstance->part : aInstance->part;
1879 if( reference.find_last_not_of( wxT(
"0123456789" ) ) == ( reference.Length()-1 ) )
1880 reference.Append( wxT(
"0" ) );
1885 if( reference.find_first_not_of( wxT(
"0123456789" ) ) != 0 )
1886 reference.Prepend( wxT(
"UNK" ) );
1890 if( aInstance->part.find_first_not_of( wxT(
"#" ) ) != 0 )
1891 reference.Prepend( wxT(
"UNK" ) );
1894 referenceField->
SetText( reference );
1897 bool userValue =
m_userValue.at( libIdSymbolName );
1905 if( epart->value && !epart->value.CGet().IsEmpty() )
1907 valueField->
SetText( *epart->value );
1911 valueField->
SetText( kisymbolname );
1917 for(
const auto& [ attrName, attr ] : epart->attributes )
1923 if( !symbol->GetFields().empty() )
1924 newField.
SetTextPos( symbol->GetFields().back().GetPosition() );
1927 newField.
SetText( *attr->value );
1931 symbol->AddField( newField );
1934 for(
const auto& [variantName, variant] : epart->variants )
1937 field->
SetName( wxT(
"VARIANT_" ) + variant->name );
1939 if( variant->value )
1940 field->
SetText( *variant->value );
1945 bool valueAttributeFound =
false;
1946 bool nameAttributeFound =
false;
1949 for(
auto& [
name, eattr] : aInstance->attributes )
1953 if( eattr->name.Lower() == wxT(
"name" ) )
1956 nameAttributeFound =
true;
1958 else if( eattr->name.Lower() == wxT(
"value" ) )
1961 valueAttributeFound =
true;
1965 field = symbol->GetField( eattr->name );
1975 int absdegrees = eattr->rot ? eattr->rot->degrees : 0;
1976 bool mirror = eattr->rot ? eattr->rot->mirror :
false;
1978 if( aInstance->rot && aInstance->rot->mirror )
1981 bool spin = eattr->rot ? eattr->rot->spin :
false;
1986 int rotation = aInstance->rot ? aInstance->rot->degrees : 0;
1987 int reldegrees = ( absdegrees - rotation + 360.0 );
1995 if( aInstance->smashed && aInstance->smashed.Get() )
1997 symbol->GetField(
FIELD_T::VALUE )->SetVisible( valueAttributeFound );
2009 wxCHECK2( emoduleInst,
continue );
2011 refPrefix += emoduleInst->name + wxS(
":" );
2014 symbol->AddHierarchicalReference(
m_sheetPath.Path(), refPrefix + reference, unit );
2020 wxCHECK( libSymbol, );
2022 symbol->SetLibSymbol(
new LIB_SYMBOL( *libSymbol ) );
2024 for(
const SCH_PIN*
pin : symbol->GetLibPins() )
2030 symbol->ClearFlags();
2032 screen->
Append( symbol.release() );
2038 wxCHECK( aLibrary && aEagleLibrary,
nullptr );
2044 wxString prefix = edeviceset->prefix ? edeviceset->prefix.Get() : wxString( wxT(
"" ) );
2045 wxString deviceSetDescr;
2047 if( edeviceset->description )
2051 for(
const std::unique_ptr<EDEVICE>& edevice : edeviceset->devices )
2054 wxString symbolName = edeviceset->name + edevice->name;
2055 symbolName.Replace( wxT(
"*" ), wxEmptyString );
2056 wxASSERT( !symbolName.IsEmpty() );
2059 if( edevice->package )
2060 aEagleLibrary->
package[symbolName] = edevice->package.Get();
2063 std::unique_ptr<LIB_SYMBOL> libSymbol = std::make_unique<LIB_SYMBOL>( symbolName );
2066 int gate_count =
static_cast<int>( edeviceset->gates.size() );
2067 libSymbol->SetUnitCount( gate_count,
true );
2068 libSymbol->LockUnits(
true );
2072 if( prefix.length() == 0 )
2080 reference->
SetText( edevice->package ? prefix :
'#' + prefix );
2083 libSymbol->GetValueField().SetVisible(
true );
2086 bool ispower =
false;
2088 for(
const auto& [gateName, egate] : edeviceset->gates )
2090 const auto it = aLibrary->
symbols.find( egate->symbol );
2092 if( it == aLibrary->
symbols.end() )
2094 Report( wxString::Format( wxS(
"Eagle symbol '%s' not found in library '%s'." ),
2095 egate->symbol, aLibrary->
GetName() ) );
2099 wxString gateMapName = edeviceset->name + wxS(
"_" ) + edevice->name +
2100 wxS(
"_" ) + egate->name;
2102 ispower =
loadSymbol( it->second, libSymbol, edevice, gateindex, egate->name );
2107 libSymbol->SetUnitCount( gate_count,
true );
2109 if( gate_count == 1 && ispower )
2110 libSymbol->SetGlobalPower();
2113 if( edevice->package )
2120 libName =
m_schematic->Project().GetProjectName();
2127 wxString packageString = libName + wxT(
":" ) + aEagleLibrary->
package[symbolName];
2129 libSymbol->GetFootprintField().SetText( packageString );
2132 wxString libName = libSymbol->GetName();
2133 libSymbol->SetName( libName );
2134 libSymbol->SetDescription( deviceSetDescr );
2144 libName = aEagleLibrary->
name + wxT(
"_" ) + libName;
2146 libSymbol->SetName( libName );
2150 std::map<std::string, UTF8> properties;
2164 aEagleLibrary->
KiCadSymbols[ libName ] = std::move( libSymbol );
2168 m_userValue.emplace( std::make_pair( libName, edeviceset->uservalue ==
true ) );
2172 return aEagleLibrary;
2177 std::unique_ptr<LIB_SYMBOL>& aSymbol,
2178 const std::unique_ptr<EDEVICE>& aDevice,
int aGateNumber,
2179 const wxString& aGateName )
2181 wxCHECK( aEsymbol && aSymbol && aDevice,
false );
2183 std::vector<SCH_ITEM*> items;
2185 bool showRefDes =
false;
2186 bool showValue =
false;
2187 bool ispower =
false;
2190 for(
const std::unique_ptr<ECIRCLE>& ecircle : aEsymbol->circles )
2193 for(
const std::unique_ptr<EPIN>& epin : aEsymbol->pins )
2195 std::unique_ptr<SCH_PIN>
pin(
loadPin( aSymbol, epin, aGateNumber ) );
2200 if( epin->direction )
2204 if( epin->direction->Lower() == pinDir.first )
2206 pin->SetType( pinDir.second );
2208 if( pinDir.first == wxT(
"sup" ) )
2217 if( aDevice->connects.size() != 0 )
2219 for(
const std::unique_ptr<ECONNECT>& connect : aDevice->connects )
2221 if( connect->gate == aGateName &&
pin->GetName() == connect->pin )
2223 wxArrayString pads = wxSplit( wxString( connect->pad ),
' ' );
2225 pin->SetUnit( aGateNumber );
2228 if( pads.GetCount() > 1 )
2230 pin->SetNumberTextSize( 0 );
2233 for(
unsigned i = 0; i < pads.GetCount(); i++ )
2237 wxString padname( pads[i] );
2239 aSymbol->AddDrawItem( apin );
2248 pin->SetUnit( aGateNumber );
2249 pin->SetNumber( wxString::Format( wxT(
"%i" ), pincount ) );
2250 aSymbol->AddDrawItem(
pin.release() );
2254 for(
const std::unique_ptr<EPOLYGON>& epolygon : aEsymbol->polygons )
2257 for(
const std::unique_ptr<ERECT>& erectangle : aEsymbol->rectangles )
2260 for(
const std::unique_ptr<ETEXT>& etext : aEsymbol->texts )
2262 std::unique_ptr<SCH_TEXT> libtext(
loadSymbolText( aSymbol, etext, aGateNumber ) );
2264 if( libtext->GetText() == wxT(
"${REFERENCE}" ) )
2270 showRefDes = etext->text == wxT(
">NAME" );
2272 else if( libtext->GetText() == wxT(
"${VALUE}" ) )
2278 showValue = etext->text == wxT(
">VALUE" );
2282 aSymbol->AddDrawItem( libtext.release() );
2286 for(
const std::unique_ptr<EWIRE>& ewire : aEsymbol->wires )
2287 aSymbol->AddDrawItem(
loadSymbolWire( aSymbol, ewire, aGateNumber ) );
2289 for(
const std::unique_ptr<EFRAME>& eframe : aEsymbol->frames )
2291 std::vector<SCH_ITEM*> frameItems;
2297 item->SetParent( aSymbol.get() );
2298 item->SetUnit( aGateNumber );
2299 aSymbol->AddDrawItem( item );
2303 aSymbol->GetReferenceField().SetVisible( showRefDes );
2304 aSymbol->GetValueField().SetVisible( showValue );
2306 return pincount == 1 ? ispower :
false;
2311 const std::unique_ptr<ECIRCLE>& aCircle,
2314 wxCHECK( aSymbol && aCircle,
nullptr );
2318 VECTOR2I center( aCircle->x.ToSchUnits(), -aCircle->y.ToSchUnits() );
2320 circle->SetParent( aSymbol.get() );
2324 circle->SetUnit( aGateNumber );
2331 const std::unique_ptr<ERECT>& aRectangle,
2334 wxCHECK( aSymbol && aRectangle,
nullptr );
2339 rectangle->
SetPosition(
VECTOR2I( aRectangle->x1.ToSchUnits(), -aRectangle->y1.ToSchUnits() ) );
2340 rectangle->
SetEnd(
VECTOR2I( aRectangle->x2.ToSchUnits(), -aRectangle->y2.ToSchUnits() ) );
2342 if( aRectangle->rot )
2355 rectangle->
SetUnit( aGateNumber );
2365 const std::unique_ptr<EWIRE>& aWire,
int aGateNumber )
2367 wxCHECK( aSymbol && aWire,
nullptr );
2371 begin.
x = aWire->x1.ToSchUnits();
2372 begin.
y = -aWire->y1.ToSchUnits();
2373 end.x = aWire->x2.ToSchUnits();
2374 end.y = -aWire->y2.ToSchUnits();
2393 ( aWire->width.ToSchUnits() /
radius );
2394 begin =
center + centerStartVector;
2428 const std::unique_ptr<EPOLYGON>& aPolygon,
2431 wxCHECK( aSymbol && aPolygon,
nullptr );
2439 for(
const std::unique_ptr<EVERTEX>& evertex : aPolygon->vertices )
2441 pt =
VECTOR2I( evertex->x.ToSchUnits(), evertex->y.ToSchUnits() );
2455 prev_curve = evertex->curve;
2467 const std::unique_ptr<EPIN>& aPin,
int aGateNumber )
2469 wxCHECK( aSymbol && aPin,
nullptr );
2471 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>( aSymbol.get() );
2472 pin->SetPosition(
VECTOR2I( aPin->x.ToSchUnits(), -aPin->y.ToSchUnits() ) );
2473 pin->SetName( aPin->name );
2474 pin->SetUnit( aGateNumber );
2476 int roti = aPin->rot ? aPin->rot->degrees : 0;
2484 default: wxFAIL_MSG( wxString::Format( wxT(
"Unhandled orientation (%d degrees)." ), roti ) );
2491 wxString length = aPin->length.Get();
2493 if( length == wxT(
"short" ) )
2495 else if( length == wxT(
"middle" ) )
2497 else if( length == wxT(
"long" ) )
2499 else if( length == wxT(
"point" ) )
2510 wxString visible = aPin->visible.Get();
2512 if( visible == wxT(
"off" ) )
2514 pin->SetNameTextSize( 0 );
2515 pin->SetNumberTextSize( 0 );
2517 else if( visible == wxT(
"pad" ) )
2519 pin->SetNameTextSize( 0 );
2521 else if( visible == wxT(
"pin" ) )
2523 pin->SetNumberTextSize( 0 );
2533 if( aPin->function )
2535 wxString function = aPin->function.Get();
2537 if( function == wxT(
"dot" ) )
2539 else if( function == wxT(
"clk" ) )
2541 else if( function == wxT(
"dotclk" ) )
2545 return pin.release();
2550 const std::unique_ptr<ETEXT>& aText,
int aGateNumber )
2552 wxCHECK( aSymbol && aText,
nullptr );
2554 std::unique_ptr<SCH_TEXT> libtext = std::make_unique<SCH_TEXT>();
2556 libtext->SetParent( aSymbol.get() );
2557 libtext->SetUnit( aGateNumber );
2558 libtext->SetPosition(
VECTOR2I( aText->x.ToSchUnits(), -aText->y.ToSchUnits() ) );
2560 const wxString& eagleText = aText->text;
2561 wxString adjustedText;
2562 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2565 while( tokenizer.HasMoreTokens() )
2567 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2569 if( tokenizer.HasMoreTokens() )
2572 adjustedText += tmp;
2575 libtext->SetText( adjustedText.IsEmpty() ? wxString( wxS(
"~" ) ) : adjustedText );
2579 return libtext.release();
2585 wxCHECK( aText,
nullptr );
2587 std::unique_ptr<SCH_TEXT> schtext = std::make_unique<SCH_TEXT>();
2589 const wxString& eagleText = aText->text;
2590 wxString adjustedText;
2591 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2594 while( tokenizer.HasMoreTokens() )
2596 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2598 if( tokenizer.HasMoreTokens() )
2601 adjustedText += tmp;
2604 schtext->SetText( adjustedText.IsEmpty() ? wxString( wxS(
"\" \"" ) )
2607 schtext->SetPosition(
VECTOR2I( aText->x.ToSchUnits(), -aText->y.ToSchUnits() ) );
2609 schtext->SetItalic(
false );
2611 return schtext.release();
2616 const std::unique_ptr<ETEXT>& aAttributes )
const
2618 wxCHECK( aText && aAttributes, );
2623 if( aAttributes->ratio && aAttributes->ratio.CGet() > 12 )
2627 int degrees = aAttributes->rot ? aAttributes->rot->degrees : 0;
2628 bool mirror = aAttributes->rot ? aAttributes->rot->mirror :
false;
2629 bool spin = aAttributes->rot ? aAttributes->rot->spin :
false;
2637 wxCHECK( aField && aText, );
2661 auto onIntersection =
2670 for(
SCH_TEXT* label : segDesc.labels )
2673 const SEG* segAttached = segDesc.LabelAttached( label );
2675 if( segAttached && !onIntersection( labelPos ) )
2689 VECTOR2I wireDirection( segAttached->
B - segAttached->
A );
2691 const VECTOR2I origPos( labelPos );
2694 bool checkPositive =
true, checkNegative =
true,
move =
false;
2698 while( ( !
move || onIntersection( labelPos ) ) && ( checkPositive || checkNegative ) )
2703 if( trial % 2 == 1 )
2705 labelPos =
VECTOR2I( origPos + wireDirection * trial / 2 );
2706 move = checkPositive = segAttached->
Contains( labelPos );
2710 labelPos =
VECTOR2I( origPos - wireDirection * trial / 2 );
2711 move = checkNegative = segAttached->
Contains( labelPos );
2747 wxFileInputStream input( aFileName );
2752 wxTextInputStream
text( input );
2754 for(
int i = 0; i < 8; i++ )
2759 if(
text.ReadLine().Contains( wxS(
"<eagle" ) ) )
2777 if( !item->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
2781 item->SetPosition( aNewEndPoint );
2794 std::vector<SCH_LINE*> buses;
2795 std::vector<SCH_LINE*> wires;
2806 buses.push_back( line );
2807 else if( line->
IsWire() )
2808 wires.push_back( line );
2813 VECTOR2I wireStart = wire->GetStartPoint();
2814 VECTOR2I wireEnd = wire->GetEndPoint();
2818 VECTOR2I busStart = bus->GetStartPoint();
2819 VECTOR2I busEnd = bus->GetEndPoint();
2822 [](
int signX,
int signY ) ->
VECTOR2I
2834 if( wireStart.
y == wireEnd.
y && busStart.
x == busEnd.
x )
2838 if( testBusHit( wireStart ) )
2842 if( wireEnd.
x < busStart.
x )
2849 VECTOR2I p = wireStart + entrySize( -1, 0 );
2851 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
2860 screen->
Append( busEntry );
2862 wire->SetStartPoint( p );
2864 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
2873 screen->
Append( busEntry );
2875 wire->SetStartPoint( p );
2890 VECTOR2I p = wireStart + entrySize( 1, 0 );
2892 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
2901 screen->
Append( busEntry );
2903 wire->SetStartPoint( p );
2905 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
2914 screen->
Append( busEntry );
2916 wire->SetStartPoint( p );
2927 else if( testBusHit( wireEnd ) )
2931 if( wireStart.
x < busStart.
x )
2938 VECTOR2I p = wireEnd + entrySize( -1, 0 );
2940 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2949 screen->
Append( busEntry );
2951 wire->SetEndPoint( p );
2953 else if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2962 screen->
Append( busEntry );
2963 moveLabels( wire, wireEnd + entrySize( -1, 0 ) );
2964 wire->SetEndPoint( wireEnd + entrySize( -1, 0 ) );
2979 VECTOR2I p = wireEnd + entrySize( 1, 0 );
2981 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2990 screen->
Append( busEntry );
2992 wire->SetEndPoint( p );
2994 else if( testBusHit( wireEnd + entrySize( 0, 1 ) ) )
3003 screen->
Append( busEntry );
3005 wire->SetEndPoint( p );
3017 else if( wireStart.
x == wireEnd.
x && busStart.
y == busEnd.
y )
3021 if( testBusHit( wireStart ) )
3025 if( wireEnd.
y < busStart.
y )
3033 VECTOR2I p = wireStart + entrySize( 0, -1 );
3035 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3045 screen->
Append( busEntry );
3047 wire->SetStartPoint( p );
3049 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3059 screen->
Append( busEntry );
3061 wire->SetStartPoint( p );
3077 VECTOR2I p = wireStart + entrySize( 0, 1 );
3079 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3089 screen->
Append( busEntry );
3091 wire->SetStartPoint( p );
3093 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3103 screen->
Append( busEntry );
3105 wire->SetStartPoint( p );
3116 else if( testBusHit( wireEnd ) )
3120 if( wireStart.
y < busStart.
y )
3128 VECTOR2I p = wireEnd + entrySize( 0, -1 );
3130 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3140 screen->
Append( busEntry );
3142 wire->SetEndPoint( p );
3144 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3154 screen->
Append( busEntry );
3156 wire->SetEndPoint( p );
3172 VECTOR2I p = wireEnd + entrySize( 0, 1 );
3174 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3184 screen->
Append( busEntry );
3186 wire->SetEndPoint( p );
3188 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3198 screen->
Append( busEntry );
3200 wire->SetEndPoint( p );
3216 if( testBusHit( wireStart ) )
3218 VECTOR2I wirevector = wireStart - wireEnd;
3220 if( wirevector.
x > 0 )
3222 if( wirevector.
y > 0 )
3224 VECTOR2I p = wireStart + entrySize( -1, -1 );
3227 screen->
Append( busEntry );
3230 wire->SetStartPoint( p );
3234 VECTOR2I p = wireStart + entrySize( -1, 1 );
3237 screen->
Append( busEntry );
3240 wire->SetStartPoint( p );
3245 if( wirevector.
y > 0 )
3247 VECTOR2I p = wireStart + entrySize( 1, -1 );
3250 screen->
Append( busEntry );
3253 wire->SetStartPoint( p );
3257 VECTOR2I p = wireStart + entrySize( 1, 1 );
3260 screen->
Append( busEntry );
3263 wire->SetStartPoint( p );
3269 else if( testBusHit( wireEnd ) )
3271 VECTOR2I wirevector = wireStart - wireEnd;
3273 if( wirevector.
x > 0 )
3275 if( wirevector.
y > 0 )
3277 VECTOR2I p = wireEnd + entrySize( 1, 1 );
3280 screen->
Append( busEntry );
3283 wire->SetEndPoint( p );
3287 VECTOR2I p = wireEnd + entrySize( 1, -1 );
3290 screen->
Append( busEntry );
3293 wire->SetEndPoint( p );
3298 if( wirevector.
y > 0 )
3300 VECTOR2I p = wireEnd + entrySize( -1, 1 );
3303 screen->
Append( busEntry );
3306 wire->SetEndPoint( p );
3310 VECTOR2I p = wireEnd + entrySize( -1, -1 );
3313 screen->
Append( busEntry );
3316 wire->SetEndPoint( p );
3330 wxCHECK( aLabel,
nullptr );
3336 if( seg.Contains( labelPos ) )
3348 wxCHECK( aSymbol && aPin,
false );
3356 const auto& items = pointIt->second;
3358 wxCHECK( items.find( aPin ) != items.end(),
false );
3360 return items.size() > 1;
3374 int unit = aSymbol->
GetUnit();
3377 std::set<int> missingUnits;
3384 bool pinInUnit = !unit ||
pin->GetUnit() == unit;
3398 switch(
pin->GetOrientation() )
3415 aScreen->
Append( netLabel );
3418 else if( aUpdateSet )
3423 wxASSERT(
pin->GetUnit() );
3424 missingUnits.insert(
pin->GetUnit() );
3437 entry.
cmp = aSymbol;
3438 entry.
units.emplace( unit,
false );
3443 cmpIt->second.units[unit] =
false;
3446 if( !missingUnits.empty() )
3449 entry.
cmp = aSymbol;
3452 for(
int i : missingUnits )
3454 if( entry.
units.find( i ) != entry.
units.end() )
3455 entry.
units.emplace( i,
true );
3467 wxString ret = wxT(
"{" );
3469 wxStringTokenizer tokenizer( aEagleName,
"," );
3471 while( tokenizer.HasMoreTokens() )
3473 wxString member = tokenizer.GetNextToken();
3480 if( member.Freq(
'!' ) % 2 > 0 )
3481 member << wxT(
"!" );
3483 ret << member << wxS(
" " );
3498 std::unique_ptr<EPART>& epart =
m_eagleDoc->drawing->schematic->parts[aInstance->part];
3500 if( !epart || epart->deviceset.IsEmpty() )
3503 std::unique_ptr<ELIBRARY>& elibrary =
m_eagleDoc->drawing->schematic->libraries[epart->library];
3508 std::unique_ptr<EDEVICE_SET>& edeviceset = elibrary->devicesets[epart->deviceset];
3513 std::unique_ptr<EGATE>& egate = edeviceset->gates[aInstance->gate];
3518 std::unique_ptr<ESYMBOL>& esymbol = elibrary->symbols[egate->symbol];
3521 return esymbol.get();
3528 const wxString& aEagleFieldName,
3531 wxCHECK( aField && !aEagleFieldName.
IsEmpty(), );
3537 for(
const std::unique_ptr<ETEXT>&
text : esymbol->
texts )
3539 if(
text->text == aEagleFieldName )
3542 VECTOR2I pos(
text->x.ToSchUnits() + aInstance->x.ToSchUnits(),
3543 -
text->y.ToSchUnits() - aInstance->y.ToSchUnits() );
3545 bool mirror =
text->rot ?
text->rot->mirror :
false;
3547 if( aInstance->rot && aInstance->rot->mirror )
3551 pos.
y = -aInstance->y.ToSchUnits() +
text->y.ToSchUnits();
constexpr EDA_IU_SCALE schIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
constexpr coord_type GetY() const
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 coord_type GetLeft() const
constexpr const SizeVec & GetSize() const
constexpr coord_type GetBottom() const
void SetFlags(EDA_ITEM_FLAGS aMask)
virtual void SetParent(EDA_ITEM *aParent)
void SetCenter(const VECTOR2I &aCenter)
SHAPE_POLY_SET & GetPolyShape()
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
void SetStart(const VECTOR2I &aStart)
void SetEnd(const VECTOR2I &aEnd)
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
void SetFillMode(FILL_T aFill)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
const EDA_ANGLE & GetTextAngle() const
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
virtual const wxString & GetText() const
Return the string associated with the text object.
void SetTextPos(const VECTOR2I &aPoint)
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
GR_TEXT_H_ALIGN_T GetHorizJustify() const
virtual void SetVisible(bool aVisible)
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.
VECTOR2I GetTextSize() const
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
EE_TYPE Overlapping(const BOX2I &aRect) const
iterator end()
Return a read/write iterator that points to one past the last element in the EE_RTREE.
iterator begin()
Return a read/write iterator that points to the first.
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.
REPORTER * m_reporter
Reporter to log errors/warnings to, may be nullptr.
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.
virtual void Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
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.
std::vector< SCH_PIN * > GetPins() const override
bool IsGlobalPower() const override
int GetUnitCount() const override
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.
void SetRoot(SCH_SHEET *aRootSheet)
Initialize the schematic with a new root sheet.
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
Class for a wire to bus entry.
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 loadModuleInstance(const std::unique_ptr< EMODULEINST > &aModuleInstance)
SCH_TEXT * loadLabel(const std::unique_ptr< ELABEL > &aLabel, const wxString &aNetName)
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)
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
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.
void loadSegments(const std::vector< std::unique_ptr< ESEGMENT > > &aSegments, const wxString &aNetName, const wxString &aNetClass)
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)
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.
virtual void SetUnit(int aUnit)
void SetShape(LABEL_FLAG_SHAPE aShape)
void SetPosition(const VECTOR2I &aPosition) override
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...
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
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)
void SetName(const wxString &aName)
SCH_SCREEN * GetScreen() const
void AutoplaceFields(SCH_SCREEN *aScreen, AUTOPLACE_ALGO aAlgo) override
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...
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
std::optional< LIB_STATUS > LoadOne(const wxString &aNickname)
Loads or reloads the given library, if it exists.
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.
static REPORTER & GetInstance()
static void SetReporter(REPORTER *aReporter)
Set the reporter to use for reporting font substitution warnings.
#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 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.
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
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)
Extract the net name part from a pin name (e.g. return 'GND' for pin named '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::vector< std::unique_ptr< ETEXT > > texts
Map references to missing symbol units data.
std::map< int, bool > units
Segments representing wires for intersection checking.
std::vector< SCH_TEXT * > labels
const SEG * LabelAttached(const SCH_TEXT *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".
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.