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 )
353 const std::map<std::string, UTF8>* aProperties )
355 wxASSERT( !aFileName || aSchematic !=
nullptr );
375 wxXmlNode* currentNode = xmlDocument.GetRoot();
385 unique_ptr<SCH_SHEET> tempVROwner;
389 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
390 wxT(
"Can't append to a schematic with no root!" ) );
401 if( sheetPath.Last() == aAppendToMe )
413 tempVROwner = std::make_unique<SCH_SHEET>( aSchematic );
433 wxCHECK_MSG(
table,
nullptr,
"Could not load symbol lib table." );
435 m_pi.reset( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
443 wxString libTableUri = wxT(
"${KIPRJMOD}/" ) +
getLibFileName().GetFullName();
448 row.
SetURI( libTableUri );
456 m_eagleDoc = std::make_unique<EAGLE_DOC>( currentNode,
this );
484 const wxString& aLibraryPath,
485 const std::map<std::string, UTF8>* aProperties )
496 for(
const auto& [symName, libSymbol] : it->second.KiCadSymbols )
497 aSymbolNameList.push_back( symName );
503 const wxString& aLibraryPath,
504 const std::map<std::string, UTF8>* aProperties )
515 for(
const auto& [symName, libSymbol] : it->second.KiCadSymbols )
516 aSymbolList.push_back( libSymbol.get() );
522 const std::map<std::string, UTF8>* aProperties )
533 auto it2 = it->second.KiCadSymbols.find( aAliasName );
535 if( it2 != it->second.KiCadSymbols.end() )
536 return it2->second.get();
545 wxFileName fn( aLibraryPath );
547 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
548 return fn.GetModificationTime().GetValue().GetValue();
579 std::unique_ptr<EAGLE_DOC> doc = std::make_unique<EAGLE_DOC>( xmlDocument.GetRoot(),
this );
583 m_version = ( doc->version.IsEmpty() ) ? wxString( wxS(
"0.0" ) ) : doc->version;
595 wxXmlDocument xmlDocument;
596 wxFFileInputStream stream(
m_filename.GetFullPath() );
601 wxString::Format(
_(
"Unable to read file '%s'." ),
m_filename.GetFullPath() ) );
612 std::vector<uint8_t> bytes;
613 bytes.resize(
static_cast<size_t>( stream.GetLength() ) );
614 stream.Read( bytes.data(), bytes.size() );
616 if( stream.LastRead() != bytes.size() )
619 wxString::Format(
_(
"Unable to read file '%s'." ),
m_filename.GetFullPath() ) );
623 std::unique_ptr<wxXmlDocument> binDocument = binParser.
Parse( bytes );
625 xmlDocument.SetRoot( binDocument->DetachRoot() );
630 wxTextInputStream
text( stream );
631 wxString line =
text.ReadLine();
633 if( !line.StartsWith( wxT(
"<?xml" ) ) && !line.StartsWith( wxT(
"<!--" ) )
634 && !line.StartsWith( wxT(
"<eagle " ) ) )
636 THROW_IO_ERROR( wxString::Format(
_(
"'%s' is an Eagle binary-format file; "
637 "only Eagle XML-format files can be imported." ),
641#if wxCHECK_VERSION( 3, 3, 0 )
644 if( !xmlDocument.Load( stream, wxXMLDOC_NONE, &err ) )
646 if( err.message == wxS(
"no element found" ) )
650 wxMemoryOutputStream memOutput;
653 header <<
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
654 header <<
"<!DOCTYPE eagle SYSTEM \"eagle.dtd\">\n";
656 wxScopedCharBuffer headerBuf =
header.utf8_str();
657 memOutput.Write( headerBuf.data(), headerBuf.length() );
659 wxFFileInputStream stream2(
m_filename.GetFullPath() );
660 memOutput.Write( stream2 );
662 wxMemoryInputStream memInput( memOutput );
664 if( !xmlDocument.Load( memInput, wxXMLDOC_NONE, &err ) )
671 THROW_IO_ERROR( wxString::Format(
_(
"Unable to read file '%s'.\n'%s' at line %d, column %d, offset %d" ),
672 m_filename.GetFullPath(), err.message, err.line, err.column,
677 if( !xmlDocument.Load( stream ) )
681 wxMemoryOutputStream memOutput;
684 header <<
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
685 header <<
"<!DOCTYPE eagle SYSTEM \"eagle.dtd\">\n";
687 wxScopedCharBuffer headerBuf =
header.utf8_str();
688 memOutput.Write( headerBuf.data(), headerBuf.length() );
690 wxFFileInputStream stream2(
m_filename.GetFullPath() );
691 memOutput.Write( stream2 );
693 wxMemoryInputStream memInput( memOutput );
695 if( !xmlDocument.Load( memInput ) )
708 wxCHECK( aDrawing, );
712 if( aDrawing->library )
720 if( aDrawing->schematic )
727 for(
const std::unique_ptr<ESHEET>& esheet : aSchematic.
sheets )
729 for(
const std::unique_ptr<ENET>& enet : esheet->nets )
731 wxString netName = enet->netname;
740 for(
const auto& [modname, emodule] : aSchematic.
modules )
742 for(
const std::unique_ptr<ESHEET>& esheet : emodule->sheets )
744 for(
const std::unique_ptr<ENET>& enet : esheet->nets )
746 wxString netName = enet->netname;
761 if( aSchematic.
sheets.empty() )
768 if( variantDef->current && *variantDef->current )
773 for(
const auto& [
name, epart] : aSchematic.
parts )
776 for(
const auto& [modName, emodule] : aSchematic.
modules )
778 for(
const auto& [partName, epart] : emodule->parts )
784 for(
const auto& [libName, elibrary] : aSchematic.
libraries )
787 elib->
name = elibrary->GetName();
803 std::vector<SCH_SHEET*> eaglePages;
804 eaglePages.reserve( aSchematic.
sheets.size() );
806 for(
const std::unique_ptr<ESHEET>& esheet : aSchematic.
sheets )
810 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>(
m_rootSheet );
812 sheet->SetScreen( screen );
814 wxCHECK2( sheet && screen,
continue );
816 wxString pageNo = wxString::Format( wxT(
"%d" ),
m_sheetIndex );
824 eaglePages.push_back( sheet.release() );
829 if( !eaglePages.empty() )
854 struct MISSING_UNIT_PLACEMENT
864 std::map<SCH_SCREEN*, MISSING_UNIT_PLACEMENT> placements;
868 const SCH_SYMBOL* origSymbol = cmp.second.cmp;
870 for(
auto& unitEntry : cmp.second.units )
872 if( unitEntry.second ==
false )
876 int unit = unitEntry.first;
887 targetScreen = fallbackSheet->
GetScreen();
889 targetScreen = schematicRoot->
GetScreen();
892 auto placementIt = placements.find( targetScreen );
894 if( placementIt == placements.end() )
896 MISSING_UNIT_PLACEMENT placement;
897 placement.screen = targetScreen;
901 SCH_SHEET* targetSheet = placement.sheetpath.Last();
906 placement.newCmpPosition =
VECTOR2I( placement.sheetBbox.GetLeft(),
907 placement.sheetBbox.GetBottom() );
908 placement.maxY = placement.sheetBbox.GetY();
909 placementIt = placements.emplace( targetScreen, placement ).first;
912 MISSING_UNIT_PLACEMENT& placement = placementIt->second;
914 symbol->SetUnitSelection( &placement.sheetpath, unit );
915 symbol->SetUnit( unit );
916 symbol->SetOrientation( 0 );
917 symbol->AddHierarchicalReference( placement.sheetpath.Path(), reference, unit );
920 BOX2I cmpBbox = symbol->GetBoundingBox();
921 int posY = placement.newCmpPosition.y + cmpBbox.
GetHeight();
922 symbol->SetPosition(
VECTOR2I( placement.newCmpPosition.x, posY ) );
923 placement.newCmpPosition.x += cmpBbox.
GetWidth();
924 placement.maxY = std::max( placement.maxY, posY );
926 if( placement.newCmpPosition.x >= placement.pageSizeIU.x )
927 placement.newCmpPosition =
VECTOR2I( placement.sheetBbox.GetLeft(),
932 placement.screen->Append( symbol.release() );
945 wxCHECK( sheet && screen, );
949 std::string filename;
953 if( aSheet->description )
954 sheet->
SetName( aSheet->description.value().text );
959 replace( filename.begin(), filename.end(),
' ',
'_' );
964 fn.SetPath(
m_schematic->Project().GetProjectPath() );
965 fn.SetName( filename );
972 for(
const auto& [
name, moduleinst] : aSheet->moduleinsts )
979 for(
const std::unique_ptr<EPOLYGON>& epoly : aSheet->plain->polygons )
985 for(
const std::unique_ptr<EWIRE>& ewire : aSheet->plain->wires )
991 for(
const std::unique_ptr<ETEXT>& etext : aSheet->plain->texts )
994 for(
const std::unique_ptr<ECIRCLE>& ecircle : aSheet->plain->circles )
997 for(
const std::unique_ptr<ERECT>& erectangle : aSheet->plain->rectangles )
1000 for(
const std::unique_ptr<EFRAME>& eframe : aSheet->plain->frames )
1002 std::vector<SCH_ITEM*> frameItems;
1013 for(
const std::unique_ptr<EINSTANCE>& einstance : aSheet->instances )
1021 for(
const std::unique_ptr<EBUS>& ebus : aSheet->busses )
1027 loadSegments( ebus->segments, busName, wxString(),
true );
1030 for(
const std::unique_ptr<ENET>& enet : aSheet->nets )
1033 wxString netName = enet->netname;
1034 wxString netClass = wxString::Format( wxS(
"%i" ), enet->netcode );
1053 if( pageSizeIU.
x < targetSheetSize.
x )
1056 if( pageSizeIU.
y < targetSheetSize.
y )
1063 VECTOR2I sheetcentre( pageSizeIU.
x / 2, pageSizeIU.
y / 2 );
1067 VECTOR2I translation = sheetcentre - itemsCentre;
1068 translation.
x = translation.
x - translation.
x %
schIUScale.MilsToIU( 100 );
1069 translation.
y = translation.
y - translation.
y %
schIUScale.MilsToIU( 100 );
1081 std::vector<SCH_ITEM*> allItems;
1083 std::copy( screen->
Items().
begin(), screen->
Items().
end(), std::back_inserter( allItems ) );
1087 item->SetPosition( item->GetPosition() + translation );
1105 wxCHECK( currentSheet &¤tScreen, );
1111 auto it =
m_eagleDoc->drawing->schematic->modules.find( aModuleInstance->moduleinst );
1114 if( it ==
m_eagleDoc->drawing->schematic->modules.end() )
1116 THROW_IO_ERROR( wxString::Format(
_(
"No module instance '%s' found in schematic "
1118 aModuleInstance->name,
m_filename.GetFullPath() ) );
1122 fn.SetName( aModuleInstance->moduleinst );
1126 VECTOR2I size( it->second->dx.ToSchUnits(), it->second->dy.ToSchUnits() );
1128 int halfX =
KiROUND( size.
x / 2.0 );
1129 int halfY =
KiROUND( size.
y / 2.0 );
1130 int portExtWireLength =
schIUScale.mmToIU( 5.08 );
1131 VECTOR2I pos( aModuleInstance->x.ToSchUnits() - halfX,
1132 -aModuleInstance->y.ToSchUnits() - halfY );
1134 std::unique_ptr<SCH_SHEET> newSheet = std::make_unique<SCH_SHEET>( currentSheet, pos, size );
1142 if( schFile->GetFileName() == fn.GetFullPath() )
1144 newScreen = schFile;
1149 bool isNewSchFile = ( newScreen == nullptr );
1157 wxCHECK( newSheet && newScreen, );
1159 newSheet->SetScreen( newScreen );
1160 newSheet->SetFileName( fn.GetFullName() );
1161 newSheet->SetName( aModuleInstance->name );
1163 for(
const auto& [portName, port] : it->second->ports )
1166 int pinOffset = port->coord.ToSchUnits();
1169 if( port->side ==
"left" )
1173 pinPos.
y = pos.
y + halfY - pinOffset;
1174 portExtWireEndpoint = pinPos;
1175 portExtWireEndpoint.
x -= portExtWireLength;
1177 else if( port->side ==
"right" )
1180 pinPos.
x = pos.
x + size.
x;
1181 pinPos.
y = pos.
y + halfY - pinOffset;
1182 portExtWireEndpoint = pinPos;
1183 portExtWireEndpoint.
x += portExtWireLength;
1185 else if( port->side ==
"top" )
1188 pinPos.
x = pos.
x + halfX + pinOffset;
1190 portExtWireEndpoint = pinPos;
1191 portExtWireEndpoint.
y -= portExtWireLength;
1193 else if( port->side ==
"bottom" )
1196 pinPos.
x = pos.
x + halfX + pinOffset;
1197 pinPos.
y = pos.
y + size.
y;
1198 portExtWireEndpoint = pinPos;
1199 portExtWireEndpoint.
y += portExtWireLength;
1204 currentScreen->
Append( portExtWire );
1208 if( port->direction )
1210 if( *port->direction ==
"in" )
1212 else if( *port->direction ==
"out" )
1214 else if( *port->direction ==
"io" )
1216 else if( *port->direction ==
"hiz" )
1231 newSheet->AddPin( sheetPin );
1234 wxString pageNo = wxString::Format( wxT(
"%d" ),
m_sheetIndex );
1236 newSheet->SetParent( currentSheet );
1239 currentScreen->
Append( newSheet.release() );
1241 m_modules.push_back( it->second.get() );
1247 for(
const std::unique_ptr<ESHEET>& esheet : it->second->sheets )
1257 wxCHECK2( emoduleInst,
continue );
1259 refPrefix += emoduleInst->name + wxS(
":" );
1270 wxCHECK2( symbol && !symbol->
GetInstances().empty(),
continue );
1273 wxString newReference = refPrefix + inst.
m_Reference.AfterLast(
':' );
1287 std::vector<SCH_ITEM*>& aItems )
1289 int xMin = aFrame->x1.ToSchUnits();
1290 int xMax = aFrame->x2.ToSchUnits();
1291 int yMin = -aFrame->y1.ToSchUnits();
1292 int yMax = -aFrame->y2.ToSchUnits();
1295 std::swap( xMin, xMax );
1298 std::swap( yMin, yMax );
1306 aItems.push_back( lines );
1308 if( !( aFrame->border_left ==
false ) )
1315 aItems.push_back( lines );
1318 int height = yMax - yMin;
1321 int legendPosX = xMin +
schIUScale.MilsToIU( 75 );
1322 double rowSpacing = height / double( aFrame->rows );
1323 double legendPosY = yMin + ( rowSpacing / 2 );
1325 for( i = 1; i < aFrame->rows; i++ )
1327 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1331 aItems.push_back( lines );
1334 char legendChar =
'A';
1336 for( i = 0; i < aFrame->rows; i++ )
1342 legendText->
SetText( wxString( legendChar ) );
1345 aItems.push_back( legendText );
1347 legendPosY += rowSpacing;
1351 if( !( aFrame->border_right ==
false ) )
1358 aItems.push_back( lines );
1361 int height = yMax - yMin;
1364 int legendPosX = xMax -
schIUScale.MilsToIU( 75 );
1365 double rowSpacing = height / double( aFrame->rows );
1366 double legendPosY = yMin + ( rowSpacing / 2 );
1368 for( i = 1; i < aFrame->rows; i++ )
1370 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1374 aItems.push_back( lines );
1377 char legendChar =
'A';
1379 for( i = 0; i < aFrame->rows; i++ )
1385 legendText->
SetText( wxString( legendChar ) );
1388 aItems.push_back( legendText );
1390 legendPosY += rowSpacing;
1394 if( !( aFrame->border_top ==
false ) )
1401 aItems.push_back( lines );
1404 int width = xMax - xMin;
1407 int legendPosY = yMin +
schIUScale.MilsToIU( 75 );
1408 double columnSpacing = width / double( aFrame->columns );
1409 double legendPosX = xMin + ( columnSpacing / 2 );
1411 for( i = 1; i < aFrame->columns; i++ )
1413 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1417 aItems.push_back( lines );
1420 char legendChar =
'1';
1422 for( i = 0; i < aFrame->columns; i++ )
1428 legendText->
SetText( wxString( legendChar ) );
1431 aItems.push_back( legendText );
1433 legendPosX += columnSpacing;
1437 if( !( aFrame->border_bottom ==
false ) )
1444 aItems.push_back( lines );
1447 int width = xMax - xMin;
1450 int legendPosY = yMax -
schIUScale.MilsToIU( 75 );
1451 double columnSpacing = width / double( aFrame->columns );
1452 double legendPosX = xMin + ( columnSpacing / 2 );
1454 for( i = 1; i < aFrame->columns; i++ )
1456 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1460 aItems.push_back( lines );
1463 char legendChar =
'1';
1465 for( i = 0; i < aFrame->columns; i++ )
1471 legendText->
SetText( wxString( legendChar ) );
1474 aItems.push_back( legendText );
1476 legendPosX += columnSpacing;
1483 const wxString& netName,
1484 const wxString& aNetClass,
1492 size_t segmentCount = aSegments.size();
1494 for(
const std::unique_ptr<ESEGMENT>& esegment : aSegments )
1496 bool labelled =
false;
1497 bool firstWireFound =
false;
1503 for(
const std::unique_ptr<EWIRE>& ewire : esegment->wires )
1512 if( !firstWireFound )
1514 firstWire = thisWire;
1515 firstWireFound =
true;
1521 if( !desc.labels.empty() && desc.labels.front()->GetText() == netName )
1524 for(
const SEG& seg : desc.segs )
1533 segDesc.
segs.push_back( thisWire );
1537 for(
const std::unique_ptr<EJUNCTION>& ejunction : esegment->junctions )
1540 for(
const std::unique_ptr<ELABEL>& elabel : esegment->labels )
1545 wxASSERT( segDesc.
labels.empty()
1548 segDesc.
labels.push_back( label );
1552 for(
const std::unique_ptr<EPINREF>& epinref : esegment->pinRefs )
1554 wxString part = epinref->part;
1555 wxString
pin = epinref->pin;
1557 auto powerPort =
m_powerPorts.find( wxT(
"#" ) + part );
1569 if( !labelled && firstWireFound )
1571 std::unique_ptr<SCH_LABEL_BASE> label;
1583 if( segmentCount > 1 ||
m_netCounts[netName] > 1 )
1593 label->SetPosition( firstWire.
A );
1598 if( firstWire.
A.
y == firstWire.
B.
y )
1600 if( firstWire.
B.
x > firstWire.
A.
x )
1605 else if( firstWire.
A.
x == firstWire.
B.
x )
1607 if( firstWire.
B.
y > firstWire.
A.
y )
1613 screen->
Append( label.release() );
1622 if( !aPolygon->IsValidOutline() )
1625 std::unique_ptr<SCH_SHAPE> poly = std::make_unique<SCH_SHAPE>(
SHAPE_T::POLY );
1629 for(
const std::unique_ptr<EVERTEX>& evertex : aPolygon->vertices )
1631 pt =
VECTOR2I( evertex->x.ToSchUnits(), -evertex->y.ToSchUnits() );
1637 poly->GetPolyShape().Append( arc, -1, -1,
ARC_ACCURACY );
1641 poly->AddPoint( pt );
1645 prev_curve = evertex->curve;
1648 poly->SetLayer(
kiCadLayer( aPolygon->layer ) );
1652 return poly.release();
1660 start.
x = aWire->x1.ToSchUnits();
1661 start.
y = -aWire->y1.ToSchUnits();
1662 end.x = aWire->x2.ToSchUnits();
1663 end.y = -aWire->y2.ToSchUnits();
1666 endpoints =
SEG( start,
end );
1675 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>(
SHAPE_T::ARC );
1678 arc->SetCenter(
center );
1679 arc->SetStart( start );
1686 return arc.release();
1690 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>();
1692 line->SetStartPoint( start );
1693 line->SetEndPoint(
end );
1694 line->SetLayer(
kiCadLayer( aWire->layer ) );
1697 return line.release();
1705 VECTOR2I center( aCircle->x.ToSchUnits(), -aCircle->y.ToSchUnits() );
1718 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>(
SHAPE_T::RECTANGLE );
1720 rectangle->SetLayer(
kiCadLayer( aRectangle->layer ) );
1721 rectangle->SetPosition(
VECTOR2I( aRectangle->x1.ToSchUnits(), -aRectangle->y1.ToSchUnits() ) );
1722 rectangle->SetEnd(
VECTOR2I( aRectangle->x2.ToSchUnits(), -aRectangle->y2.ToSchUnits() ) );
1724 if( aRectangle->rot )
1726 VECTOR2I pos( rectangle->GetPosition() );
1733 rectangle->SetPosition( pos );
1734 rectangle->SetEnd(
end );
1740 return rectangle.release();
1746 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
1748 VECTOR2I pos( aJunction->x.ToSchUnits(), -aJunction->y.ToSchUnits() );
1750 junction->SetPosition( pos );
1752 return junction.release();
1757 const wxString& aNetName,
bool aIsBus )
1759 VECTOR2I elabelpos( aLabel->x.ToSchUnits(), -aLabel->y.ToSchUnits() );
1764 std::unique_ptr<SCH_LABEL_BASE> label;
1766 VECTOR2I textSize =
KiROUND( aLabel->size.ToSchUnits() * 0.7, aLabel->size.ToSchUnits() * 0.7 );
1768 auto findModulePort =
1769 [&]() ->
const EPORT*
1774 const auto& ports =
m_modules.back()->ports;
1775 const auto it = ports.find( aNetName );
1776 return it == ports.end() ? nullptr : it->second.get();
1779 const EPORT* port = findModulePort();
1783 auto hierLabel = std::make_unique<SCH_HIERLABEL>();
1790 if( direction ==
"in" )
1792 else if( direction ==
"out" )
1794 else if( direction ==
"io" )
1796 else if( direction ==
"hiz" )
1804 hierLabel->SetLabelShape( type );
1807 label = std::move( hierLabel );
1811 label = std::make_unique<SCH_LABEL>();
1815 label = std::make_unique<SCH_GLOBALLABEL>();
1819 label->SetPosition( elabelpos );
1820 label->SetTextSize( textSize );
1826 int angle =
KiROUND( aLabel->rot->degrees );
1845 return label.release();
1849std::pair<VECTOR2I, const SEG*>
1851 const std::vector<SEG>& aLines )
const
1854 const SEG* nearestLine =
nullptr;
1856 double d, mindistance = std::numeric_limits<double>::max();
1859 for(
const SEG& line : aLines )
1864 if( d < mindistance )
1867 nearestPoint = testpoint;
1868 nearestLine = &line;
1871 testpoint = line.Center();
1874 if( d < mindistance )
1877 nearestPoint = testpoint;
1878 nearestLine = &line;
1884 if( d < mindistance )
1887 nearestPoint = testpoint;
1888 nearestLine = &line;
1892 return std::make_pair( nearestPoint, nearestLine );
1897 const std::map<wxString, std::unique_ptr<EPART>>& aParts )
1899 wxCHECK( aInstance, );
1905 const auto partIt = aParts.find( aInstance->part );
1907 if( partIt == aParts.end() )
1909 Report( wxString::Format(
_(
"Error parsing Eagle file. Could not find '%s' "
1910 "instance but it is referenced in the schematic." ),
1917 const std::unique_ptr<EPART>& epart = partIt->second;
1919 wxString libName = epart->library;
1922 if( epart->libraryUrn )
1923 libName += wxS(
"_" ) + epart->libraryUrn->assetId;
1925 wxString gatename = epart->deviceset + wxS(
"_" ) + epart->device + wxS(
"_" ) +
1927 wxString symbolname = wxString( epart->deviceset + epart->device );
1928 wxString kiPackageName = epart->deviceset + epart->device;
1930 if( epart->technology )
1931 symbolname += *epart->technology;
1933 symbolname.Replace( wxT(
"*" ), wxEmptyString );
1934 kiPackageName.Replace( wxT(
"*" ), wxEmptyString );
1943 wxString altSymbolName = libName + wxT(
"_" ) + symbolname;
1946 wxString libIdSymbolName = altSymbolName;
1952 Report( wxString::Format( wxS(
"Eagle library '%s' not found while looking up symbol for "
1953 "deviceset '%s', device '%s', and gate '%s." ),
1954 libName, epart->deviceset, epart->device, aInstance->gate ) );
1958 const auto gateIt = libIt->second.GateToUnitMap.find( gatename );
1960 if( gateIt == libIt->second.GateToUnitMap.end() )
1962 Report( wxString::Format( wxS(
"Symbol not found for deviceset '%s', device '%s', and "
1963 "gate '%s in library '%s'." ),
1964 epart->deviceset, epart->device, aInstance->gate, libName ) );
1968 int unit = gateIt->second;
1973 auto p = elib->
package.find( kisymbolname );
1975 if( p != elib->
package.end() )
1977 package = p->second;
1981 p = elib->
package.find( kiPackageName );
1983 if( p != elib->
package.end() )
1984 package = p->second;
1988 std::map<std::string, UTF8> properties;
1995 part =
m_pi->LoadSymbol(
getLibFileName().GetFullPath(), kisymbolname, &properties );
1996 libIdSymbolName = kisymbolname;
2001 Report( wxString::Format(
_(
"Could not find '%s' in the imported library." ),
2008 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
2009 symbol->SetLibId( libId );
2010 symbol->SetUnit( unit );
2011 symbol->SetPosition(
VECTOR2I( aInstance->x.ToSchUnits(), -aInstance->y.ToSchUnits() ) );
2014 if( !package.IsEmpty() )
2016 wxString footprint =
m_schematic->Project().GetProjectName() + wxT(
":" ) + package;
2020 if( aInstance->rot )
2024 if( aInstance->rot->mirror )
2025 symbol->MirrorHorizontally( aInstance->x.ToSchUnits() );
2028 std::vector<SCH_FIELD*> partFields;
2033 for(
const SCH_FIELD* partField : partFields )
2037 if( partField->IsMandatory() )
2038 symbolField = symbol->GetField( partField->GetId() );
2040 symbolField = symbol->GetField( partField->GetName() );
2047 newField.
SetText( partField->GetText() );
2051 symbol->AddField( newField );
2056 symbolField->
SetTextPos( symbol->GetPosition() + partField->GetTextPos() );
2062 wxString reference = package.IsEmpty() ?
'#' + aInstance->part : aInstance->part;
2065 if( reference.find_last_not_of( wxT(
"0123456789" ) ) == ( reference.Length()-1 ) )
2066 reference.Append( wxT(
"0" ) );
2071 if( reference.find_first_not_of( wxT(
"0123456789" ) ) != 0 )
2072 reference.Prepend( wxT(
"UNK" ) );
2076 if( aInstance->part.find_first_not_of( wxT(
"#" ) ) != 0 )
2077 reference.Prepend( wxT(
"UNK" ) );
2080 referenceField->
SetText( reference );
2083 bool userValue =
m_userValue.at( libIdSymbolName );
2091 if( epart->value && !epart->value.CGet().IsEmpty() )
2093 valueField->
SetText( *epart->value );
2097 valueField->
SetText( kisymbolname );
2103 for(
const auto& [ attrName, attr ] : epart->attributes )
2109 if( !symbol->GetFields().empty() )
2110 newField.
SetTextPos( symbol->GetFields().back().GetPosition() );
2113 newField.
SetText( *attr->value );
2117 symbol->AddField( newField );
2120 bool valueAttributeFound =
false;
2121 bool nameAttributeFound =
false;
2124 for(
auto& [
name, eattr] : aInstance->attributes )
2128 if( eattr->name.Lower() == wxT(
"name" ) )
2131 nameAttributeFound =
true;
2133 else if( eattr->name.Lower() == wxT(
"value" ) )
2136 valueAttributeFound =
true;
2140 field = symbol->GetField( eattr->name );
2152 int absdegrees = eattr->rot ? eattr->rot->degrees : 0;
2153 bool mirror = eattr->rot ? eattr->rot->mirror :
false;
2155 if( aInstance->rot && aInstance->rot->mirror )
2158 bool spin = eattr->rot ? eattr->rot->spin :
false;
2163 int rotation = aInstance->rot ? aInstance->rot->degrees : 0;
2164 int reldegrees = ( absdegrees - rotation + 360.0 );
2172 if( aInstance->smashed && aInstance->smashed.Get() )
2174 symbol->GetField(
FIELD_T::VALUE )->SetVisible( valueAttributeFound );
2186 wxCHECK2( emoduleInst,
continue );
2188 refPrefix += emoduleInst->name + wxS(
":" );
2191 symbol->AddHierarchicalReference(
m_sheetPath.Path(), refPrefix + reference, unit );
2197 symbol->SetLibSymbol( part->
Flatten().release() );
2199 for(
const auto& [
name, variant] : epart->variants )
2203 if( variant->populate && !*variant->populate )
2204 symbolVariant.
m_DNP =
true;
2206 if( variant->value )
2209 if( variant->technology )
2211 auto eLibIt =
m_eagleDoc->drawing->schematic->libraries.find( epart->library );
2213 if( eLibIt ==
m_eagleDoc->drawing->schematic->libraries.end() )
2215 Report( wxString::Format( wxS(
"Library '%s' not found in schematic." ), epart->library ) );
2219 auto eDeviceSetIt = eLibIt->second->devicesets.find( epart->deviceset );
2221 if( eDeviceSetIt == eLibIt->second->devicesets.end() )
2223 Report( wxString::Format( wxS(
"Device set '%s' not found in library '%s'." ),
2224 epart->deviceset, epart->library ) );
2228 auto eDeviceIt = eDeviceSetIt->second->devices.find( epart->device );
2230 if( eDeviceIt == eDeviceSetIt->second->devices.end() )
2232 Report( wxString::Format( wxS(
"Device '%s' not found in device set '%s' in library '%s'." ),
2233 epart->device, epart->deviceset, epart->library ) );
2237 auto eTechnologyIt = eDeviceIt->second->technologies.find( *variant->technology );
2239 if( eTechnologyIt == eDeviceIt->second->technologies.end() )
2241 Report( wxString::Format( wxS(
"Technology '%s' not found in device '%s' in device set '%s' "
2242 "in library '%s'." ),
2243 *variant->technology, epart->device, epart->deviceset, epart->library ) );
2247 for(
const auto& attr : eTechnologyIt->second->attributes )
2252 attrValue = *attr->value;
2254 symbolVariant.
m_Fields[attr->name] = attrValue;
2261 for(
const SCH_PIN*
pin : symbol->GetLibPins() )
2267 symbol->ClearFlags();
2269 screen->
Append( symbol.release() );
2275 wxCHECK( aLibrary && aEagleLibrary,
nullptr );
2282 wxString prefix = edeviceset->prefix ? edeviceset->prefix.Get() : wxString( wxT(
"" ) );
2283 wxString deviceSetDescr;
2285 if( edeviceset->description )
2289 for(
const auto& [devname, edevice] : edeviceset->devices )
2291 std::vector<std::unique_ptr<LIB_SYMBOL>> derivedSymbols;
2294 wxString symbolName = edeviceset->name + edevice->name;
2295 symbolName.Replace( wxT(
"*" ), wxEmptyString );
2296 wxASSERT( !symbolName.IsEmpty() );
2299 if( edevice->package )
2300 aEagleLibrary->
package[symbolName] = edevice->package.Get();
2303 std::unique_ptr<LIB_SYMBOL> libSymbol = std::make_unique<LIB_SYMBOL>( symbolName );
2306 int gate_count =
static_cast<int>( edeviceset->gates.size() );
2308 if( gate_count > 1 )
2309 libSymbol->SetUnitCount( gate_count,
true );
2311 libSymbol->LockUnits(
true );
2315 if( prefix.length() == 0 )
2323 reference->
SetText( edevice->package ? prefix :
'#' + prefix );
2326 libSymbol->GetValueField().SetVisible(
true );
2329 bool ispower =
false;
2331 for(
const auto& [gateName, egate] : edeviceset->gates )
2333 const auto it = aLibrary->
symbols.find( egate->symbol );
2335 if( it == aLibrary->
symbols.end() )
2337 Report( wxString::Format( wxS(
"Eagle symbol '%s' not found in library '%s'." ),
2338 egate->symbol, aLibrary->
GetName() ) );
2342 wxString gateMapName = edeviceset->name + wxS(
"_" ) + edevice->name +
2343 wxS(
"_" ) + egate->name;
2345 ispower =
loadSymbol( it->second, libSymbol, edevice, gateindex, egate->name );
2350 std::vector<SCH_FIELD*> fields;
2351 libSymbol->GetFields( fields );
2354 field->SetCanAutoplace( canAutoplace );
2356 for(
const auto& [techname, technology ] : edevice->technologies )
2358 std::unique_ptr<LIB_SYMBOL> derivedSymbol;
2361 if( !technology->name.IsEmpty() )
2363 derivedSymbol = std::make_unique<LIB_SYMBOL>( symbolName + technology->name, libSymbol.get() );
2367 SCH_FIELD* childField = derivedSymbol->GetField( parentField->GetName() );
2377 for(
const std::unique_ptr<EATTR>& attr : technology->attributes )
2384 if( !derivedSymbol )
2385 field = libSymbol->FindFieldCaseInsensitive( attr->name );
2387 field = derivedSymbol->FindFieldCaseInsensitive( attr->name );
2391 field->
SetText( *attr->value );
2395 SCH_FIELD* newField =
new SCH_FIELD( derivedSymbol ? derivedSymbol.get() : libSymbol.get(),
2400 SCH_FIELD* parentField = libSymbol->FindFieldCaseInsensitive( attr->name );
2407 newField->
SetText( *attr->value );
2412 if( !derivedSymbol )
2413 libSymbol->AddField( newField );
2415 derivedSymbol->AddField( newField );
2420 derivedSymbols.push_back( std::move( derivedSymbol ) );
2423 if( gate_count > 1 )
2424 libSymbol->SetUnitCount( gate_count,
true );
2426 if( gate_count == 1 && ispower )
2427 libSymbol->SetGlobalPower();
2430 if( edevice->package )
2437 libName =
m_schematic->Project().GetProjectName();
2444 wxString packageString = libName + wxT(
":" ) + aEagleLibrary->
package[symbolName];
2446 libSymbol->GetFootprintField().SetText( packageString );
2449 wxString libName = libSymbol->GetName();
2450 libSymbol->SetName( libName );
2451 libSymbol->SetDescription( deviceSetDescr );
2461 libName = aEagleLibrary->
name + wxT(
"_" ) + libName;
2463 libSymbol->SetName( libName );
2467 std::map<std::string, UTF8> properties;
2473 for( std::unique_ptr<LIB_SYMBOL>& symbol : derivedSymbols )
2477 wxString tmp = aEagleLibrary->
name + wxT(
"_" ) + symbol->GetName();
2479 symbol->SetName( tmp );
2484 derivedSymbol->
SetParent( parentSymbol );
2496 aEagleLibrary->
KiCadSymbols[ libName ] = std::move( libSymbol );
2500 m_userValue.emplace( std::make_pair( libName, edeviceset->uservalue ==
true ) );
2502 for( std::unique_ptr<LIB_SYMBOL>& symbol : derivedSymbols )
2504 m_userValue.emplace( std::make_pair( symbol->GetName(), edeviceset->uservalue ==
true ) );
2505 aEagleLibrary->
KiCadSymbols[symbol->GetName()] = std::move( symbol );
2510 return aEagleLibrary;
2515 std::unique_ptr<LIB_SYMBOL>& aSymbol,
2516 const std::unique_ptr<EDEVICE>& aDevice,
int aGateNumber,
2517 const wxString& aGateName )
2519 wxCHECK( aEsymbol && aSymbol && aDevice,
false );
2521 std::vector<SCH_ITEM*> items;
2523 bool showRefDes =
false;
2524 bool showValue =
false;
2525 bool ispower =
false;
2528 for(
const std::unique_ptr<ECIRCLE>& ecircle : aEsymbol->circles )
2531 for(
const std::unique_ptr<EPIN>& epin : aEsymbol->pins )
2533 std::unique_ptr<SCH_PIN>
pin(
loadPin( aSymbol, epin, aGateNumber ) );
2538 if( epin->direction )
2542 if( epin->direction->Lower() == pinDir.first )
2544 pin->SetType( pinDir.second );
2546 if( pinDir.first == wxT(
"sup" ) )
2555 if( aDevice->connects.size() != 0 )
2557 for(
const std::unique_ptr<ECONNECT>& connect : aDevice->connects )
2562 if( connect->gate == aGateName && epin->name == connect->pin )
2564 wxArrayString pads = wxSplit( wxString( connect->pad ),
' ' );
2566 pin->SetUnit( aGateNumber );
2569 if( pads.GetCount() > 1 )
2571 pin->SetNumberTextSize( 0 );
2574 for(
unsigned i = 0; i < pads.GetCount(); i++ )
2578 wxString padname( pads[i] );
2580 aSymbol->AddDrawItem( apin );
2589 pin->SetUnit( aGateNumber );
2590 pin->SetNumber( wxString::Format( wxT(
"%i" ), pincount ) );
2591 aSymbol->AddDrawItem(
pin.release() );
2595 for(
const std::unique_ptr<EPOLYGON>& epolygon : aEsymbol->polygons )
2597 aSymbol->AddDrawItem( shape );
2599 for(
const std::unique_ptr<ERECT>& erectangle : aEsymbol->rectangles )
2602 for(
const std::unique_ptr<ETEXT>& etext : aEsymbol->texts )
2604 std::unique_ptr<SCH_TEXT> libtext(
loadSymbolText( aSymbol, etext, aGateNumber ) );
2606 if( libtext->GetText() == wxT(
"${REFERENCE}" ) )
2612 showRefDes = etext->text == wxT(
">NAME" );
2614 else if( libtext->GetText() == wxT(
"${VALUE}" ) )
2620 showValue = etext->text == wxT(
">VALUE" );
2622 else if( etext->text.StartsWith(
">" ) )
2626 wxString fieldName = etext->text.Mid( 1 );
2628 if( !fieldName.IsEmpty() )
2636 aSymbol->AddField( field );
2641 aSymbol->AddDrawItem( libtext.release() );
2645 for(
const std::unique_ptr<EWIRE>& ewire : aEsymbol->wires )
2646 aSymbol->AddDrawItem(
loadSymbolWire( aSymbol, ewire, aGateNumber ) );
2648 for(
const std::unique_ptr<EFRAME>& eframe : aEsymbol->frames )
2650 std::vector<SCH_ITEM*> frameItems;
2656 item->SetParent( aSymbol.get() );
2657 item->SetUnit( aGateNumber );
2658 aSymbol->AddDrawItem( item );
2662 aSymbol->GetReferenceField().SetVisible( showRefDes );
2663 aSymbol->GetValueField().SetVisible( showValue );
2665 return pincount == 1 ? ispower :
false;
2670 const std::unique_ptr<ECIRCLE>& aCircle,
2673 wxCHECK( aSymbol && aCircle,
nullptr );
2677 VECTOR2I center( aCircle->x.ToSchUnits(), -aCircle->y.ToSchUnits() );
2679 circle->SetParent( aSymbol.get() );
2683 if( aCircle->width.ToSchUnits() == 0 )
2693 circle->SetUnit( aGateNumber );
2700 const std::unique_ptr<ERECT>& aRectangle,
2703 wxCHECK( aSymbol && aRectangle,
nullptr );
2708 rectangle->
SetPosition(
VECTOR2I( aRectangle->x1.ToSchUnits(), -aRectangle->y1.ToSchUnits() ) );
2709 rectangle->
SetEnd(
VECTOR2I( aRectangle->x2.ToSchUnits(), -aRectangle->y2.ToSchUnits() ) );
2711 if( aRectangle->rot )
2724 rectangle->
SetUnit( aGateNumber );
2735 const std::unique_ptr<EWIRE>& aWire,
int aGateNumber )
2737 wxCHECK( aSymbol && aWire,
nullptr );
2741 begin.
x = aWire->x1.ToSchUnits();
2742 begin.
y = -aWire->y1.ToSchUnits();
2743 end.x = aWire->x2.ToSchUnits();
2744 end.y = -aWire->y2.ToSchUnits();
2763 ( aWire->width.ToSchUnits() /
radius );
2764 begin =
center + centerStartVector;
2798 const std::unique_ptr<EPOLYGON>& aPolygon,
2801 wxCHECK( aSymbol && aPolygon,
nullptr );
2803 if( !aPolygon->IsValidOutline() )
2809 std::optional<VECTOR2I> first_pt;
2813 for(
const std::unique_ptr<EVERTEX>& evertex : aPolygon->vertices )
2815 pt =
VECTOR2I( evertex->x.ToSchUnits(), -evertex->y.ToSchUnits() );
2817 if( !first_pt.has_value() )
2832 prev_curve = evertex->curve;
2835 if( first_pt.has_value() )
2836 poly->
AddPoint( first_pt.value() );
2847 const std::unique_ptr<EPIN>& aPin,
int aGateNumber )
2849 wxCHECK( aSymbol && aPin,
nullptr );
2851 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>( aSymbol.get() );
2852 pin->SetPosition(
VECTOR2I( aPin->x.ToSchUnits(), -aPin->y.ToSchUnits() ) );
2858 pin->SetUnit( aGateNumber );
2860 int roti = aPin->rot ? aPin->rot->degrees : 0;
2868 default: wxFAIL_MSG( wxString::Format( wxT(
"Unhandled orientation (%d degrees)." ), roti ) );
2875 wxString length = aPin->length.Get();
2877 if( length == wxT(
"short" ) )
2879 else if( length == wxT(
"middle" ) )
2881 else if( length == wxT(
"long" ) )
2883 else if( length == wxT(
"point" ) )
2894 wxString visible = aPin->visible.Get();
2896 if( visible == wxT(
"off" ) )
2898 pin->SetNameTextSize( 0 );
2899 pin->SetNumberTextSize( 0 );
2901 else if( visible == wxT(
"pad" ) )
2903 pin->SetNameTextSize( 0 );
2905 else if( visible == wxT(
"pin" ) )
2907 pin->SetNumberTextSize( 0 );
2917 if( aPin->function )
2919 wxString function = aPin->function.Get();
2921 if( function == wxT(
"dot" ) )
2923 else if( function == wxT(
"clk" ) )
2925 else if( function == wxT(
"dotclk" ) )
2929 return pin.release();
2934 const std::unique_ptr<ETEXT>& aText,
int aGateNumber )
2936 wxCHECK( aSymbol && aText,
nullptr );
2938 std::unique_ptr<SCH_TEXT> libtext = std::make_unique<SCH_TEXT>();
2940 libtext->SetParent( aSymbol.get() );
2941 libtext->SetUnit( aGateNumber );
2942 libtext->SetPosition(
VECTOR2I( aText->x.ToSchUnits(), -aText->y.ToSchUnits() ) );
2944 const wxString& eagleText = aText->text;
2945 wxString adjustedText;
2946 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2949 while( tokenizer.HasMoreTokens() )
2951 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2953 if( tokenizer.HasMoreTokens() )
2956 adjustedText += tmp;
2959 libtext->SetText( adjustedText.IsEmpty() ? wxString( wxS(
"~" ) ) : adjustedText );
2963 return libtext.release();
2969 wxCHECK( aText,
nullptr );
2971 std::unique_ptr<SCH_TEXT> schtext = std::make_unique<SCH_TEXT>();
2973 const wxString& eagleText = aText->text;
2974 wxString adjustedText;
2975 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2978 while( tokenizer.HasMoreTokens() )
2980 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2982 if( tokenizer.HasMoreTokens() )
2985 adjustedText += tmp;
2988 schtext->SetText( adjustedText.IsEmpty() ? wxString( wxS(
"\" \"" ) )
2991 schtext->SetPosition(
VECTOR2I( aText->x.ToSchUnits(), -aText->y.ToSchUnits() ) );
2993 schtext->SetItalic(
false );
2995 return schtext.release();
3000 const std::unique_ptr<ETEXT>& aAttributes )
const
3002 wxCHECK( aText && aAttributes, );
3007 if( aAttributes->ratio && aAttributes->ratio.CGet() > 12 )
3011 int degrees = aAttributes->rot ? aAttributes->rot->degrees : 0;
3012 bool mirror = aAttributes->rot ? aAttributes->rot->mirror :
false;
3013 bool spin = aAttributes->rot ? aAttributes->rot->spin :
false;
3021 wxCHECK( aField && aText, );
3045 auto onIntersection =
3057 const SEG* segAttached = segDesc.LabelAttached( label );
3059 if( segAttached && !onIntersection( labelPos ) )
3073 VECTOR2I wireDirection( segAttached->
B - segAttached->
A );
3075 if( ( wireDirection.
x == 0 ) && (wireDirection.
y == 0 ) )
3079 const VECTOR2I origPos( labelPos );
3082 bool checkPositive =
true;
3083 bool checkNegative =
true;
3088 while( ( !
move || onIntersection( labelPos ) ) && ( checkPositive || checkNegative ) )
3093 if( trial % 2 == 1 )
3095 labelPos =
VECTOR2I( origPos + wireDirection * trial / 2 );
3096 move = checkPositive = segAttached->
Contains( labelPos );
3100 labelPos =
VECTOR2I( origPos - wireDirection * trial / 2 );
3101 move = checkNegative = segAttached->
Contains( labelPos );
3111 if( wireDirection.
x == 0 )
3113 if( wireDirection.
y < 0 )
3118 else if( wireDirection.
y == 0 )
3120 if( wireDirection.
x < 0 )
3154 wxFileInputStream input( aFileName );
3159 wxTextInputStream
text( input );
3161 for(
int i = 0; i < 8; i++ )
3166 if(
text.ReadLine().Contains( wxS(
"<eagle" ) ) )
3184 if( !item->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
3188 item->SetPosition( aNewEndPoint );
3201 std::vector<SCH_LINE*> buses;
3202 std::vector<SCH_LINE*> wires;
3213 buses.push_back( line );
3214 else if( line->
IsWire() )
3215 wires.push_back( line );
3220 VECTOR2I wireStart = wire->GetStartPoint();
3221 VECTOR2I wireEnd = wire->GetEndPoint();
3225 VECTOR2I busStart = bus->GetStartPoint();
3226 VECTOR2I busEnd = bus->GetEndPoint();
3229 [](
int signX,
int signY ) ->
VECTOR2I
3241 if( wireStart.
y == wireEnd.
y && busStart.
x == busEnd.
x )
3245 if( testBusHit( wireStart ) )
3249 if( wireEnd.
x < busStart.
x )
3256 VECTOR2I p = wireStart + entrySize( -1, 0 );
3258 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
3267 screen->
Append( busEntry );
3269 wire->SetStartPoint( p );
3271 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
3280 screen->
Append( busEntry );
3282 wire->SetStartPoint( p );
3297 VECTOR2I p = wireStart + entrySize( 1, 0 );
3299 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
3308 screen->
Append( busEntry );
3310 wire->SetStartPoint( p );
3312 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
3321 screen->
Append( busEntry );
3323 wire->SetStartPoint( p );
3334 else if( testBusHit( wireEnd ) )
3338 if( wireStart.
x < busStart.
x )
3345 VECTOR2I p = wireEnd + entrySize( -1, 0 );
3347 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3356 screen->
Append( busEntry );
3358 wire->SetEndPoint( p );
3360 else if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3369 screen->
Append( busEntry );
3370 moveLabels( wire, wireEnd + entrySize( -1, 0 ) );
3371 wire->SetEndPoint( wireEnd + entrySize( -1, 0 ) );
3386 VECTOR2I p = wireEnd + entrySize( 1, 0 );
3388 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3397 screen->
Append( busEntry );
3399 wire->SetEndPoint( p );
3401 else if( testBusHit( wireEnd + entrySize( 0, 1 ) ) )
3410 screen->
Append( busEntry );
3412 wire->SetEndPoint( p );
3424 else if( wireStart.
x == wireEnd.
x && busStart.
y == busEnd.
y )
3428 if( testBusHit( wireStart ) )
3432 if( wireEnd.
y < busStart.
y )
3440 VECTOR2I p = wireStart + entrySize( 0, -1 );
3442 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3452 screen->
Append( busEntry );
3454 wire->SetStartPoint( p );
3456 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3466 screen->
Append( busEntry );
3468 wire->SetStartPoint( p );
3484 VECTOR2I p = wireStart + entrySize( 0, 1 );
3486 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3496 screen->
Append( busEntry );
3498 wire->SetStartPoint( p );
3500 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3510 screen->
Append( busEntry );
3512 wire->SetStartPoint( p );
3523 else if( testBusHit( wireEnd ) )
3527 if( wireStart.
y < busStart.
y )
3535 VECTOR2I p = wireEnd + entrySize( 0, -1 );
3537 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3547 screen->
Append( busEntry );
3549 wire->SetEndPoint( p );
3551 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3561 screen->
Append( busEntry );
3563 wire->SetEndPoint( p );
3579 VECTOR2I p = wireEnd + entrySize( 0, 1 );
3581 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3591 screen->
Append( busEntry );
3593 wire->SetEndPoint( p );
3595 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3605 screen->
Append( busEntry );
3607 wire->SetEndPoint( p );
3623 if( testBusHit( wireStart ) )
3625 VECTOR2I wirevector = wireStart - wireEnd;
3627 if( wirevector.
x > 0 )
3629 if( wirevector.
y > 0 )
3631 VECTOR2I p = wireStart + entrySize( -1, -1 );
3634 screen->
Append( busEntry );
3637 wire->SetStartPoint( p );
3641 VECTOR2I p = wireStart + entrySize( -1, 1 );
3644 screen->
Append( busEntry );
3647 wire->SetStartPoint( p );
3652 if( wirevector.
y > 0 )
3654 VECTOR2I p = wireStart + entrySize( 1, -1 );
3657 screen->
Append( busEntry );
3660 wire->SetStartPoint( p );
3664 VECTOR2I p = wireStart + entrySize( 1, 1 );
3667 screen->
Append( busEntry );
3670 wire->SetStartPoint( p );
3676 else if( testBusHit( wireEnd ) )
3678 VECTOR2I wirevector = wireStart - wireEnd;
3680 if( wirevector.
x > 0 )
3682 if( wirevector.
y > 0 )
3684 VECTOR2I p = wireEnd + entrySize( 1, 1 );
3687 screen->
Append( busEntry );
3690 wire->SetEndPoint( p );
3694 VECTOR2I p = wireEnd + entrySize( 1, -1 );
3697 screen->
Append( busEntry );
3700 wire->SetEndPoint( p );
3705 if( wirevector.
y > 0 )
3707 VECTOR2I p = wireEnd + entrySize( -1, 1 );
3710 screen->
Append( busEntry );
3713 wire->SetEndPoint( p );
3717 VECTOR2I p = wireEnd + entrySize( -1, -1 );
3720 screen->
Append( busEntry );
3723 wire->SetEndPoint( p );
3737 wxCHECK( aLabel,
nullptr );
3743 if( seg.Contains( labelPos ) )
3755 wxCHECK( aSymbol && aPin,
false );
3763 const auto& items = pointIt->second;
3765 wxCHECK( items.find( aPin ) != items.end(),
false );
3767 return items.size() > 1;
3781 int unit = aSymbol->
GetUnit();
3784 std::set<int> missingUnits;
3791 bool pinInUnit = !unit ||
pin->GetUnit() == unit;
3805 switch(
pin->GetOrientation() )
3822 aScreen->
Append( netLabel );
3825 else if( aUpdateSet )
3830 wxASSERT(
pin->GetUnit() );
3831 missingUnits.insert(
pin->GetUnit() );
3844 entry.
cmp = aSymbol;
3846 entry.
units.emplace( unit,
false );
3851 cmpIt->second.units[unit] =
false;
3854 if( !missingUnits.empty() )
3857 entry.
cmp = aSymbol;
3861 for(
int i : missingUnits )
3863 if( entry.
units.find( i ) != entry.
units.end() )
3864 entry.
units.emplace( i,
true );
3876 wxString ret = wxT(
"{" );
3878 wxStringTokenizer tokenizer( aEagleName,
"," );
3880 while( tokenizer.HasMoreTokens() )
3882 wxString member = tokenizer.GetNextToken();
3889 if( member.Freq(
'!' ) % 2 > 0 )
3890 member << wxT(
"!" );
3892 ret << member << wxS(
" " );
3907 std::unique_ptr<EPART>& epart =
m_eagleDoc->drawing->schematic->parts[aInstance->part];
3909 if( !epart || epart->deviceset.IsEmpty() )
3912 std::unique_ptr<ELIBRARY>& elibrary =
m_eagleDoc->drawing->schematic->libraries[epart->library];
3917 std::unique_ptr<EDEVICE_SET>& edeviceset = elibrary->devicesets[epart->deviceset];
3922 std::unique_ptr<EGATE>& egate = edeviceset->gates[aInstance->gate];
3927 std::unique_ptr<ESYMBOL>& esymbol = elibrary->symbols[egate->symbol];
3930 return esymbol.get();
3937 const wxString& aEagleFieldName,
3940 wxCHECK( aField && !aEagleFieldName.
IsEmpty(), );
3946 for(
const std::unique_ptr<ETEXT>&
text : esymbol->
texts )
3948 if(
text->text == aEagleFieldName )
3951 VECTOR2I pos(
text->x.ToSchUnits() + aInstance->x.ToSchUnits(),
3952 -
text->y.ToSchUnits() - aInstance->y.ToSchUnits() );
3954 bool mirror =
text->rot ?
text->rot->mirror :
false;
3956 if( aInstance->rot && aInstance->rot->mirror )
3960 pos.
y = -aInstance->y.ToSchUnits() +
text->y.ToSchUnits();
3973 std::vector<SCH_FIELD*> fields;
3978 retv = fields[0]->GetPosition();
3980 for(
size_t i = 1; i < fields.size(); i++ )
3982 if( fields[i]->GetPosition().x > retv.
x )
3983 retv.
x = fields[i]->GetPosition().x;
3985 if( fields[i]->GetPosition().y > retv.
y )
3986 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.
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)
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)
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
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.
static REPORTER & GetInstance()
#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
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)
std::vector< std::string > header
std::vector< std::vector< std::string > > table
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.