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>
91 bbox.
Merge( item->GetBoundingBox() );
100 return aPinName.BeforeFirst(
'@' );
113 wxCHECK( currentSheet,
nullptr );
158 for(
const std::unique_ptr<ELAYER>& elayer : aLayers )
177 switch ( elayer->number)
207 int roti = int( eagleDegrees );
217 wxASSERT_MSG(
false, wxString::Format( wxT(
"Unhandled orientation (%d degrees)" ),
226 bool aMirror,
bool aSpin,
int aAbsDegress )
228 int align = aEagleAlignment;
230 if( aRelDegress == 90 )
234 else if( aRelDegress == 180 )
238 else if( aRelDegress == 270 )
244 if( aMirror ==
true )
246 if( aAbsDegress == 90 || aAbsDegress == 270 )
257 else if( aAbsDegress == 0 || aAbsDegress == 180 )
351 const std::map<std::string, UTF8>* aProperties )
353 wxASSERT( !aFileName || aSchematic !=
nullptr );
373 wxXmlNode* currentNode = xmlDocument.GetRoot();
383 unique_ptr<SCH_SHEET> tempVROwner;
387 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
388 wxT(
"Can't append to a schematic with no root!" ) );
399 if( sheetPath.Last() == aAppendToMe )
411 tempVROwner = std::make_unique<SCH_SHEET>( aSchematic );
431 wxCHECK_MSG(
table,
nullptr,
"Could not load symbol lib table." );
433 m_pi.reset( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
441 wxString libTableUri = wxT(
"${KIPRJMOD}/" ) +
getLibFileName().GetFullName();
446 row.
SetURI( libTableUri );
454 m_eagleDoc = std::make_unique<EAGLE_DOC>( currentNode,
this );
476 const wxString& aLibraryPath,
477 const std::map<std::string, UTF8>* aProperties )
488 for(
const auto& [symName, libSymbol] : it->second.KiCadSymbols )
489 aSymbolNameList.push_back( symName );
495 const wxString& aLibraryPath,
496 const std::map<std::string, UTF8>* aProperties )
507 for(
const auto& [symName, libSymbol] : it->second.KiCadSymbols )
508 aSymbolList.push_back( libSymbol.get() );
514 const std::map<std::string, UTF8>* aProperties )
525 auto it2 = it->second.KiCadSymbols.find( aAliasName );
527 if( it2 != it->second.KiCadSymbols.end() )
528 return it2->second.get();
537 wxFileName fn( aLibraryPath );
539 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
540 return fn.GetModificationTime().GetValue().GetValue();
571 std::unique_ptr<EAGLE_DOC> doc = std::make_unique<EAGLE_DOC>( xmlDocument.GetRoot(),
this );
575 m_version = ( doc->version.IsEmpty() ) ? wxString( wxS(
"0.0" ) ) : doc->version;
587 wxXmlDocument xmlDocument;
588 wxFFileInputStream stream(
m_filename.GetFullPath() );
593 wxString::Format(
_(
"Unable to read file '%s'." ),
m_filename.GetFullPath() ) );
597 wxTextInputStream
text( stream );
598 wxString line =
text.ReadLine();
600 if( !line.StartsWith( wxT(
"<?xml" ) ) && !line.StartsWith( wxT(
"<!--" ) )
601 && !line.StartsWith( wxT(
"<eagle " ) ) )
603 THROW_IO_ERROR( wxString::Format(
_(
"'%s' is an Eagle binary-format file; "
604 "only Eagle XML-format files can be imported." ),
608#if wxCHECK_VERSION( 3, 3, 0 )
611 if( !xmlDocument.Load( stream, wxXMLDOC_NONE, &err ) )
613 if( err.message == wxS(
"no element found" ) )
617 wxMemoryOutputStream memOutput;
620 header <<
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
621 header <<
"<!DOCTYPE eagle SYSTEM \"eagle.dtd\">\n";
623 wxScopedCharBuffer headerBuf =
header.utf8_str();
624 memOutput.Write( headerBuf.data(), headerBuf.length() );
626 wxFFileInputStream stream2(
m_filename.GetFullPath() );
627 memOutput.Write( stream2 );
629 wxMemoryInputStream memInput( memOutput );
631 if( !xmlDocument.Load( memInput, wxXMLDOC_NONE, &err ) )
638 THROW_IO_ERROR( wxString::Format(
_(
"Unable to read file '%s'.\n'%s' at line %d, column %d, offset %d" ),
639 m_filename.GetFullPath(), err.message, err.line, err.column,
644 if( !xmlDocument.Load( stream ) )
648 wxMemoryOutputStream memOutput;
651 header <<
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
652 header <<
"<!DOCTYPE eagle SYSTEM \"eagle.dtd\">\n";
654 wxScopedCharBuffer headerBuf =
header.utf8_str();
655 memOutput.Write( headerBuf.data(), headerBuf.length() );
657 wxFFileInputStream stream2(
m_filename.GetFullPath() );
658 memOutput.Write( stream2 );
660 wxMemoryInputStream memInput( memOutput );
662 if( !xmlDocument.Load( memInput ) )
675 wxCHECK( aDrawing, );
679 if( aDrawing->library )
687 if( aDrawing->schematic )
694 for(
const std::unique_ptr<ESHEET>& esheet : aSchematic.
sheets )
696 for(
const std::unique_ptr<ENET>& enet : esheet->nets )
698 wxString netName = enet->netname;
707 for(
const auto& [modname, emodule] : aSchematic.
modules )
709 for(
const std::unique_ptr<ESHEET>& esheet : emodule->sheets )
711 for(
const std::unique_ptr<ENET>& enet : esheet->nets )
713 wxString netName = enet->netname;
728 if( aSchematic.
sheets.empty() )
732 for(
const auto& [
name, epart] : aSchematic.
parts )
735 for(
const auto& [modName, emodule] : aSchematic.
modules )
737 for(
const auto& [partName, epart] : emodule->parts )
743 for(
const auto& [libName, elibrary] : aSchematic.
libraries )
746 elib->
name = elibrary->GetName();
761 std::vector<SCH_SHEET*> eaglePages;
762 eaglePages.reserve( aSchematic.
sheets.size() );
764 for(
const std::unique_ptr<ESHEET>& esheet : aSchematic.
sheets )
768 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>(
m_rootSheet );
770 sheet->SetScreen( screen );
772 wxCHECK2( sheet && screen,
continue );
774 wxString pageNo = wxString::Format( wxT(
"%d" ),
m_sheetIndex );
782 eaglePages.push_back( sheet.release() );
787 if( !eaglePages.empty() )
812 struct MISSING_UNIT_PLACEMENT
822 std::map<SCH_SCREEN*, MISSING_UNIT_PLACEMENT> placements;
826 const SCH_SYMBOL* origSymbol = cmp.second.cmp;
828 for(
auto& unitEntry : cmp.second.units )
830 if( unitEntry.second ==
false )
834 int unit = unitEntry.first;
845 targetScreen = fallbackSheet->
GetScreen();
847 targetScreen = schematicRoot->
GetScreen();
850 auto placementIt = placements.find( targetScreen );
852 if( placementIt == placements.end() )
854 MISSING_UNIT_PLACEMENT placement;
855 placement.screen = targetScreen;
859 SCH_SHEET* targetSheet = placement.sheetpath.Last();
864 placement.newCmpPosition =
VECTOR2I( placement.sheetBbox.GetLeft(),
865 placement.sheetBbox.GetBottom() );
866 placement.maxY = placement.sheetBbox.GetY();
867 placementIt = placements.emplace( targetScreen, placement ).first;
870 MISSING_UNIT_PLACEMENT& placement = placementIt->second;
872 symbol->SetUnitSelection( &placement.sheetpath, unit );
873 symbol->SetUnit( unit );
874 symbol->SetOrientation( 0 );
875 symbol->AddHierarchicalReference( placement.sheetpath.Path(), reference, unit );
878 BOX2I cmpBbox = symbol->GetBoundingBox();
879 int posY = placement.newCmpPosition.y + cmpBbox.
GetHeight();
880 symbol->SetPosition(
VECTOR2I( placement.newCmpPosition.x, posY ) );
881 placement.newCmpPosition.x += cmpBbox.
GetWidth();
882 placement.maxY = std::max( placement.maxY, posY );
884 if( placement.newCmpPosition.x >= placement.pageSizeIU.x )
885 placement.newCmpPosition =
VECTOR2I( placement.sheetBbox.GetLeft(),
890 placement.screen->Append( symbol.release() );
903 wxCHECK( sheet && screen, );
907 std::string filename;
911 if( aSheet->description )
912 sheet->
SetName( aSheet->description.value().text );
917 replace( filename.begin(), filename.end(),
' ',
'_' );
922 fn.SetPath(
m_schematic->Project().GetProjectPath() );
923 fn.SetName( filename );
930 for(
const auto& [
name, moduleinst] : aSheet->moduleinsts )
937 for(
const std::unique_ptr<EPOLYGON>& epoly : aSheet->plain->polygons )
940 for(
const std::unique_ptr<EWIRE>& ewire : aSheet->plain->wires )
946 for(
const std::unique_ptr<ETEXT>& etext : aSheet->plain->texts )
949 for(
const std::unique_ptr<ECIRCLE>& ecircle : aSheet->plain->circles )
952 for(
const std::unique_ptr<ERECT>& erectangle : aSheet->plain->rectangles )
955 for(
const std::unique_ptr<EFRAME>& eframe : aSheet->plain->frames )
957 std::vector<SCH_ITEM*> frameItems;
968 for(
const std::unique_ptr<EINSTANCE>& einstance : aSheet->instances )
976 for(
const std::unique_ptr<EBUS>& ebus : aSheet->busses )
985 for(
const std::unique_ptr<ENET>& enet : aSheet->nets )
988 wxString netName = enet->netname;
989 wxString netClass = wxString::Format( wxS(
"%i" ), enet->netcode );
1008 if( pageSizeIU.
x < targetSheetSize.
x )
1011 if( pageSizeIU.
y < targetSheetSize.
y )
1018 VECTOR2I sheetcentre( pageSizeIU.
x / 2, pageSizeIU.
y / 2 );
1022 VECTOR2I translation = sheetcentre - itemsCentre;
1023 translation.
x = translation.
x - translation.
x %
schIUScale.MilsToIU( 100 );
1024 translation.
y = translation.
y - translation.
y %
schIUScale.MilsToIU( 100 );
1036 std::vector<SCH_ITEM*> allItems;
1038 std::copy( screen->
Items().
begin(), screen->
Items().
end(), std::back_inserter( allItems ) );
1042 item->SetPosition( item->GetPosition() + translation );
1060 wxCHECK( currentSheet &¤tScreen, );
1066 auto it =
m_eagleDoc->drawing->schematic->modules.find( aModuleInstance->moduleinst );
1069 if( it ==
m_eagleDoc->drawing->schematic->modules.end() )
1071 THROW_IO_ERROR( wxString::Format(
_(
"No module instance '%s' found in schematic "
1073 aModuleInstance->name,
m_filename.GetFullPath() ) );
1077 fn.SetName( aModuleInstance->moduleinst );
1081 VECTOR2I size( it->second->dx.ToSchUnits(), it->second->dy.ToSchUnits() );
1083 int halfX =
KiROUND( size.
x / 2.0 );
1084 int halfY =
KiROUND( size.
y / 2.0 );
1085 int portExtWireLength =
schIUScale.mmToIU( 5.08 );
1086 VECTOR2I pos( aModuleInstance->x.ToSchUnits() - halfX,
1087 -aModuleInstance->y.ToSchUnits() - halfY );
1089 std::unique_ptr<SCH_SHEET> newSheet = std::make_unique<SCH_SHEET>( currentSheet, pos, size );
1097 if( schFile->GetFileName() == fn.GetFullPath() )
1099 newScreen = schFile;
1104 bool isNewSchFile = ( newScreen == nullptr );
1112 wxCHECK( newSheet && newScreen, );
1114 newSheet->SetScreen( newScreen );
1115 newSheet->SetFileName( fn.GetFullName() );
1116 newSheet->SetName( aModuleInstance->name );
1118 for(
const auto& [portName, port] : it->second->ports )
1121 int pinOffset = port->coord.ToSchUnits();
1124 if( port->side ==
"left" )
1128 pinPos.
y = pos.
y + halfY - pinOffset;
1129 portExtWireEndpoint = pinPos;
1130 portExtWireEndpoint.
x -= portExtWireLength;
1132 else if( port->side ==
"right" )
1135 pinPos.
x = pos.
x + size.
x;
1136 pinPos.
y = pos.
y + halfY - pinOffset;
1137 portExtWireEndpoint = pinPos;
1138 portExtWireEndpoint.
x += portExtWireLength;
1140 else if( port->side ==
"top" )
1143 pinPos.
x = pos.
x + halfX + pinOffset;
1145 portExtWireEndpoint = pinPos;
1146 portExtWireEndpoint.
y -= portExtWireLength;
1148 else if( port->side ==
"bottom" )
1151 pinPos.
x = pos.
x + halfX + pinOffset;
1152 pinPos.
y = pos.
y + size.
y;
1153 portExtWireEndpoint = pinPos;
1154 portExtWireEndpoint.
y += portExtWireLength;
1159 currentScreen->
Append( portExtWire );
1163 if( port->direction )
1165 if( *port->direction ==
"in" )
1167 else if( *port->direction ==
"out" )
1169 else if( *port->direction ==
"io" )
1171 else if( *port->direction ==
"hiz" )
1186 newSheet->AddPin( sheetPin );
1189 wxString pageNo = wxString::Format( wxT(
"%d" ),
m_sheetIndex );
1191 newSheet->SetParent( currentSheet );
1194 currentScreen->
Append( newSheet.release() );
1196 m_modules.push_back( it->second.get() );
1202 for(
const std::unique_ptr<ESHEET>& esheet : it->second->sheets )
1212 wxCHECK2( emoduleInst,
continue );
1214 refPrefix += emoduleInst->name + wxS(
":" );
1225 wxCHECK2( symbol && !symbol->
GetInstances().empty(),
continue );
1228 wxString newReference = refPrefix + inst.
m_Reference.AfterLast(
':' );
1242 std::vector<SCH_ITEM*>& aItems )
1244 int xMin = aFrame->x1.ToSchUnits();
1245 int xMax = aFrame->x2.ToSchUnits();
1246 int yMin = -aFrame->y1.ToSchUnits();
1247 int yMax = -aFrame->y2.ToSchUnits();
1250 std::swap( xMin, xMax );
1253 std::swap( yMin, yMax );
1261 aItems.push_back( lines );
1263 if( !( aFrame->border_left ==
false ) )
1270 aItems.push_back( lines );
1273 int height = yMax - yMin;
1276 int legendPosX = xMin +
schIUScale.MilsToIU( 75 );
1277 double rowSpacing = height / double( aFrame->rows );
1278 double legendPosY = yMin + ( rowSpacing / 2 );
1280 for( i = 1; i < aFrame->rows; i++ )
1282 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1286 aItems.push_back( lines );
1289 char legendChar =
'A';
1291 for( i = 0; i < aFrame->rows; i++ )
1297 legendText->
SetText( wxString( legendChar ) );
1300 aItems.push_back( legendText );
1302 legendPosY += rowSpacing;
1306 if( !( aFrame->border_right ==
false ) )
1313 aItems.push_back( lines );
1316 int height = yMax - yMin;
1319 int legendPosX = xMax -
schIUScale.MilsToIU( 75 );
1320 double rowSpacing = height / double( aFrame->rows );
1321 double legendPosY = yMin + ( rowSpacing / 2 );
1323 for( i = 1; i < aFrame->rows; i++ )
1325 int newY =
KiROUND( yMin + ( rowSpacing * (
double) i ) );
1329 aItems.push_back( lines );
1332 char legendChar =
'A';
1334 for( i = 0; i < aFrame->rows; i++ )
1340 legendText->
SetText( wxString( legendChar ) );
1343 aItems.push_back( legendText );
1345 legendPosY += rowSpacing;
1349 if( !( aFrame->border_top ==
false ) )
1356 aItems.push_back( lines );
1359 int width = xMax - xMin;
1362 int legendPosY = yMin +
schIUScale.MilsToIU( 75 );
1363 double columnSpacing = width / double( aFrame->columns );
1364 double legendPosX = xMin + ( columnSpacing / 2 );
1366 for( i = 1; i < aFrame->columns; i++ )
1368 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1372 aItems.push_back( lines );
1375 char legendChar =
'1';
1377 for( i = 0; i < aFrame->columns; i++ )
1383 legendText->
SetText( wxString( legendChar ) );
1386 aItems.push_back( legendText );
1388 legendPosX += columnSpacing;
1392 if( !( aFrame->border_bottom ==
false ) )
1399 aItems.push_back( lines );
1402 int width = xMax - xMin;
1405 int legendPosY = yMax -
schIUScale.MilsToIU( 75 );
1406 double columnSpacing = width / double( aFrame->columns );
1407 double legendPosX = xMin + ( columnSpacing / 2 );
1409 for( i = 1; i < aFrame->columns; i++ )
1411 int newX =
KiROUND( xMin + ( columnSpacing * (
double) i ) );
1415 aItems.push_back( lines );
1418 char legendChar =
'1';
1420 for( i = 0; i < aFrame->columns; i++ )
1426 legendText->
SetText( wxString( legendChar ) );
1429 aItems.push_back( legendText );
1431 legendPosX += columnSpacing;
1438 const wxString& netName,
1439 const wxString& aNetClass )
1446 size_t segmentCount = aSegments.size();
1448 for(
const std::unique_ptr<ESEGMENT>& esegment : aSegments )
1450 bool labelled =
false;
1451 bool firstWireFound =
false;
1457 for(
const std::unique_ptr<EWIRE>& ewire : esegment->wires )
1466 if( !firstWireFound )
1468 firstWire = thisWire;
1469 firstWireFound =
true;
1475 if( !desc.labels.empty() && desc.labels.front()->GetText() == netName )
1478 for(
const SEG& seg : desc.segs )
1487 segDesc.
segs.push_back( thisWire );
1491 for(
const std::unique_ptr<EJUNCTION>& ejunction : esegment->junctions )
1494 for(
const std::unique_ptr<ELABEL>& elabel : esegment->labels )
1499 wxASSERT( segDesc.
labels.empty()
1502 segDesc.
labels.push_back( label );
1506 for(
const std::unique_ptr<EPINREF>& epinref : esegment->pinRefs )
1508 wxString part = epinref->part;
1509 wxString
pin = epinref->pin;
1511 auto powerPort =
m_powerPorts.find( wxT(
"#" ) + part );
1523 if( !labelled && firstWireFound )
1525 std::unique_ptr<SCH_LABEL_BASE> label;
1530 else if( segmentCount > 1 )
1535 label->SetPosition( firstWire.
A );
1540 if( firstWire.
A.
y == firstWire.
B.
y )
1542 if( firstWire.
B.
x > firstWire.
A.
x )
1547 else if( firstWire.
A.
x == firstWire.
B.
x )
1549 if( firstWire.
B.
y > firstWire.
A.
y )
1555 screen->
Append( label.release() );
1564 std::unique_ptr<SCH_SHAPE> poly = std::make_unique<SCH_SHAPE>(
SHAPE_T::POLY );
1568 for(
const std::unique_ptr<EVERTEX>& evertex : aPolygon->vertices )
1570 pt =
VECTOR2I( evertex->x.ToSchUnits(), -evertex->y.ToSchUnits() );
1576 poly->GetPolyShape().Append( arc, -1, -1,
ARC_ACCURACY );
1580 poly->AddPoint( pt );
1584 prev_curve = evertex->curve;
1587 poly->SetLayer(
kiCadLayer( aPolygon->layer ) );
1591 return poly.release();
1599 start.
x = aWire->x1.ToSchUnits();
1600 start.
y = -aWire->y1.ToSchUnits();
1601 end.x = aWire->x2.ToSchUnits();
1602 end.y = -aWire->y2.ToSchUnits();
1605 endpoints =
SEG( start,
end );
1614 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>(
SHAPE_T::ARC );
1617 arc->SetCenter(
center );
1618 arc->SetStart( start );
1625 return arc.release();
1629 std::unique_ptr<SCH_LINE> line = std::make_unique<SCH_LINE>();
1631 line->SetStartPoint( start );
1632 line->SetEndPoint(
end );
1633 line->SetLayer(
kiCadLayer( aWire->layer ) );
1636 return line.release();
1644 VECTOR2I center( aCircle->x.ToSchUnits(), -aCircle->y.ToSchUnits() );
1657 std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>(
SHAPE_T::RECTANGLE );
1659 rectangle->SetLayer(
kiCadLayer( aRectangle->layer ) );
1660 rectangle->SetPosition(
VECTOR2I( aRectangle->x1.ToSchUnits(), -aRectangle->y1.ToSchUnits() ) );
1661 rectangle->SetEnd(
VECTOR2I( aRectangle->x2.ToSchUnits(), -aRectangle->y2.ToSchUnits() ) );
1663 if( aRectangle->rot )
1665 VECTOR2I pos( rectangle->GetPosition() );
1672 rectangle->SetPosition( pos );
1673 rectangle->SetEnd(
end );
1679 return rectangle.release();
1685 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
1687 VECTOR2I pos( aJunction->x.ToSchUnits(), -aJunction->y.ToSchUnits() );
1689 junction->SetPosition( pos );
1691 return junction.release();
1697 VECTOR2I elabelpos( aLabel->x.ToSchUnits(), -aLabel->y.ToSchUnits() );
1702 std::unique_ptr<SCH_LABEL_BASE> label;
1704 VECTOR2I textSize =
KiROUND( aLabel->size.ToSchUnits() * 0.7, aLabel->size.ToSchUnits() * 0.7 );
1710 label = std::make_unique<SCH_HIERLABEL>();
1713 const auto it =
m_modules.back()->ports.find( aNetName );
1717 if( it->second->direction )
1719 wxString direction = *it->second->direction;
1721 if( direction ==
"in" )
1723 else if( direction ==
"out" )
1725 else if( direction ==
"io" )
1727 else if( direction ==
"hiz" )
1735 label->SetLabelShape( type );
1740 label = std::make_unique<SCH_LABEL>();
1746 label = std::make_unique<SCH_GLOBALLABEL>();
1751 label = std::make_unique<SCH_LABEL>();
1755 label->SetPosition( elabelpos );
1756 label->SetTextSize( textSize );
1762 int angle =
KiROUND( aLabel->rot->degrees );
1781 return label.release();
1785std::pair<VECTOR2I, const SEG*>
1787 const std::vector<SEG>& aLines )
const
1790 const SEG* nearestLine =
nullptr;
1792 double d, mindistance = std::numeric_limits<double>::max();
1795 for(
const SEG& line : aLines )
1800 if( d < mindistance )
1803 nearestPoint = testpoint;
1804 nearestLine = &line;
1807 testpoint = line.Center();
1810 if( d < mindistance )
1813 nearestPoint = testpoint;
1814 nearestLine = &line;
1820 if( d < mindistance )
1823 nearestPoint = testpoint;
1824 nearestLine = &line;
1828 return std::make_pair( nearestPoint, nearestLine );
1833 const std::map<wxString, std::unique_ptr<EPART>>& aParts )
1835 wxCHECK( aInstance, );
1841 const auto partIt = aParts.find( aInstance->part );
1843 if( partIt == aParts.end() )
1845 Report( wxString::Format(
_(
"Error parsing Eagle file. Could not find '%s' "
1846 "instance but it is referenced in the schematic." ),
1853 const std::unique_ptr<EPART>& epart = partIt->second;
1855 wxString libName = epart->library;
1858 if( epart->libraryUrn )
1859 libName += wxS(
"_" ) + epart->libraryUrn->assetId;
1861 wxString gatename = epart->deviceset + wxS(
"_" ) + epart->device + wxS(
"_" ) +
1863 wxString symbolname = wxString( epart->deviceset + epart->device );
1864 symbolname.Replace( wxT(
"*" ), wxEmptyString );
1872 wxString altSymbolName = libName + wxT(
"_" ) + symbolname;
1875 wxString libIdSymbolName = altSymbolName;
1881 Report( wxString::Format( wxS(
"Eagle library '%s' not found while looking up symbol for "
1882 "deviceset '%s', device '%s', and gate '%s." ),
1883 libName, epart->deviceset, epart->device, aInstance->gate ) );
1887 const auto gateIt = libIt->second.GateToUnitMap.find( gatename );
1889 if( gateIt == libIt->second.GateToUnitMap.end() )
1891 Report( wxString::Format( wxS(
"Symbol not found for deviceset '%s', device '%s', and "
1892 "gate '%s in library '%s'." ),
1893 epart->deviceset, epart->device, aInstance->gate, libName ) );
1897 int unit = gateIt->second;
1902 auto p = elib->
package.find( kisymbolname );
1904 if( p != elib->
package.end() )
1905 package = p->second;
1908 std::map<std::string, UTF8> properties;
1915 part =
m_pi->LoadSymbol(
getLibFileName().GetFullPath(), kisymbolname, &properties );
1916 libIdSymbolName = kisymbolname;
1921 Report( wxString::Format(
_(
"Could not find '%s' in the imported library." ),
1928 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
1929 symbol->SetLibId( libId );
1930 symbol->SetUnit( unit );
1931 symbol->SetPosition(
VECTOR2I( aInstance->x.ToSchUnits(), -aInstance->y.ToSchUnits() ) );
1934 if( !package.IsEmpty() )
1936 wxString footprint =
m_schematic->Project().GetProjectName() + wxT(
":" ) + package;
1940 if( aInstance->rot )
1944 if( aInstance->rot->mirror )
1945 symbol->MirrorHorizontally( aInstance->x.ToSchUnits() );
1948 std::vector<SCH_FIELD*> partFields;
1951 for(
const SCH_FIELD* partField : partFields )
1955 if( partField->IsMandatory() )
1956 symbolField = symbol->GetField( partField->GetId() );
1958 symbolField = symbol->GetField( partField->GetName() );
1960 wxCHECK2( symbolField,
continue );
1963 symbolField->
SetTextPos( symbol->GetPosition() + partField->GetTextPos() );
1968 wxString reference = package.IsEmpty() ?
'#' + aInstance->part : aInstance->part;
1971 if( reference.find_last_not_of( wxT(
"0123456789" ) ) == ( reference.Length()-1 ) )
1972 reference.Append( wxT(
"0" ) );
1977 if( reference.find_first_not_of( wxT(
"0123456789" ) ) != 0 )
1978 reference.Prepend( wxT(
"UNK" ) );
1982 if( aInstance->part.find_first_not_of( wxT(
"#" ) ) != 0 )
1983 reference.Prepend( wxT(
"UNK" ) );
1986 referenceField->
SetText( reference );
1989 bool userValue =
m_userValue.at( libIdSymbolName );
1997 if( epart->value && !epart->value.CGet().IsEmpty() )
1999 valueField->
SetText( *epart->value );
2003 valueField->
SetText( kisymbolname );
2009 for(
const auto& [ attrName, attr ] : epart->attributes )
2015 if( !symbol->GetFields().empty() )
2016 newField.
SetTextPos( symbol->GetFields().back().GetPosition() );
2019 newField.
SetText( *attr->value );
2023 symbol->AddField( newField );
2026 for(
const auto& [variantName, variant] : epart->variants )
2029 field->
SetName( wxT(
"VARIANT_" ) + variant->name );
2031 if( variant->value )
2032 field->
SetText( *variant->value );
2037 bool valueAttributeFound =
false;
2038 bool nameAttributeFound =
false;
2041 for(
auto& [
name, eattr] : aInstance->attributes )
2045 if( eattr->name.Lower() == wxT(
"name" ) )
2048 nameAttributeFound =
true;
2050 else if( eattr->name.Lower() == wxT(
"value" ) )
2053 valueAttributeFound =
true;
2057 field = symbol->GetField( eattr->name );
2067 int absdegrees = eattr->rot ? eattr->rot->degrees : 0;
2068 bool mirror = eattr->rot ? eattr->rot->mirror :
false;
2070 if( aInstance->rot && aInstance->rot->mirror )
2073 bool spin = eattr->rot ? eattr->rot->spin :
false;
2078 int rotation = aInstance->rot ? aInstance->rot->degrees : 0;
2079 int reldegrees = ( absdegrees - rotation + 360.0 );
2087 if( aInstance->smashed && aInstance->smashed.Get() )
2089 symbol->GetField(
FIELD_T::VALUE )->SetVisible( valueAttributeFound );
2101 wxCHECK2( emoduleInst,
continue );
2103 refPrefix += emoduleInst->name + wxS(
":" );
2106 symbol->AddHierarchicalReference(
m_sheetPath.Path(), refPrefix + reference, unit );
2112 symbol->SetLibSymbol(
new LIB_SYMBOL( *part ) );
2114 for(
const SCH_PIN*
pin : symbol->GetLibPins() )
2120 symbol->ClearFlags();
2122 screen->
Append( symbol.release() );
2128 wxCHECK( aLibrary && aEagleLibrary,
nullptr );
2134 wxString prefix = edeviceset->prefix ? edeviceset->prefix.Get() : wxString( wxT(
"" ) );
2135 wxString deviceSetDescr;
2137 if( edeviceset->description )
2141 for(
const std::unique_ptr<EDEVICE>& edevice : edeviceset->devices )
2144 wxString symbolName = edeviceset->name + edevice->name;
2145 symbolName.Replace( wxT(
"*" ), wxEmptyString );
2146 wxASSERT( !symbolName.IsEmpty() );
2149 if( edevice->package )
2150 aEagleLibrary->
package[symbolName] = edevice->package.Get();
2153 std::unique_ptr<LIB_SYMBOL> libSymbol = std::make_unique<LIB_SYMBOL>( symbolName );
2156 int gate_count =
static_cast<int>( edeviceset->gates.size() );
2157 libSymbol->SetUnitCount( gate_count,
true );
2158 libSymbol->LockUnits(
true );
2162 if( prefix.length() == 0 )
2170 reference->
SetText( edevice->package ? prefix :
'#' + prefix );
2173 libSymbol->GetValueField().SetVisible(
true );
2176 bool ispower =
false;
2178 for(
const auto& [gateName, egate] : edeviceset->gates )
2180 const auto it = aLibrary->
symbols.find( egate->symbol );
2182 if( it == aLibrary->
symbols.end() )
2184 Report( wxString::Format( wxS(
"Eagle symbol '%s' not found in library '%s'." ),
2185 egate->symbol, aLibrary->
GetName() ) );
2189 wxString gateMapName = edeviceset->name + wxS(
"_" ) + edevice->name +
2190 wxS(
"_" ) + egate->name;
2192 ispower =
loadSymbol( it->second, libSymbol, edevice, gateindex, egate->name );
2197 libSymbol->SetUnitCount( gate_count,
true );
2199 if( gate_count == 1 && ispower )
2200 libSymbol->SetGlobalPower();
2203 if( edevice->package )
2210 libName =
m_schematic->Project().GetProjectName();
2217 wxString packageString = libName + wxT(
":" ) + aEagleLibrary->
package[symbolName];
2219 libSymbol->GetFootprintField().SetText( packageString );
2222 wxString libName = libSymbol->GetName();
2223 libSymbol->SetName( libName );
2224 libSymbol->SetDescription( deviceSetDescr );
2234 libName = aEagleLibrary->
name + wxT(
"_" ) + libName;
2236 libSymbol->SetName( libName );
2240 std::map<std::string, UTF8> properties;
2254 aEagleLibrary->
KiCadSymbols[ libName ] = std::move( libSymbol );
2258 m_userValue.emplace( std::make_pair( libName, edeviceset->uservalue ==
true ) );
2262 return aEagleLibrary;
2267 std::unique_ptr<LIB_SYMBOL>& aSymbol,
2268 const std::unique_ptr<EDEVICE>& aDevice,
int aGateNumber,
2269 const wxString& aGateName )
2271 wxCHECK( aEsymbol && aSymbol && aDevice,
false );
2273 std::vector<SCH_ITEM*> items;
2275 bool showRefDes =
false;
2276 bool showValue =
false;
2277 bool ispower =
false;
2280 for(
const std::unique_ptr<ECIRCLE>& ecircle : aEsymbol->circles )
2283 for(
const std::unique_ptr<EPIN>& epin : aEsymbol->pins )
2285 std::unique_ptr<SCH_PIN>
pin(
loadPin( aSymbol, epin, aGateNumber ) );
2290 if( epin->direction )
2294 if( epin->direction->Lower() == pinDir.first )
2296 pin->SetType( pinDir.second );
2298 if( pinDir.first == wxT(
"sup" ) )
2307 if( aDevice->connects.size() != 0 )
2309 for(
const std::unique_ptr<ECONNECT>& connect : aDevice->connects )
2311 if( connect->gate == aGateName &&
pin->GetName() == connect->pin )
2313 wxArrayString pads = wxSplit( wxString( connect->pad ),
' ' );
2315 pin->SetUnit( aGateNumber );
2318 if( pads.GetCount() > 1 )
2320 pin->SetNumberTextSize( 0 );
2323 for(
unsigned i = 0; i < pads.GetCount(); i++ )
2327 wxString padname( pads[i] );
2329 aSymbol->AddDrawItem( apin );
2338 pin->SetUnit( aGateNumber );
2339 pin->SetNumber( wxString::Format( wxT(
"%i" ), pincount ) );
2340 aSymbol->AddDrawItem(
pin.release() );
2344 for(
const std::unique_ptr<EPOLYGON>& epolygon : aEsymbol->polygons )
2347 for(
const std::unique_ptr<ERECT>& erectangle : aEsymbol->rectangles )
2350 for(
const std::unique_ptr<ETEXT>& etext : aEsymbol->texts )
2352 std::unique_ptr<SCH_TEXT> libtext(
loadSymbolText( aSymbol, etext, aGateNumber ) );
2354 if( libtext->GetText() == wxT(
"${REFERENCE}" ) )
2360 showRefDes = etext->text == wxT(
">NAME" );
2362 else if( libtext->GetText() == wxT(
"${VALUE}" ) )
2368 showValue = etext->text == wxT(
">VALUE" );
2372 aSymbol->AddDrawItem( libtext.release() );
2376 for(
const std::unique_ptr<EWIRE>& ewire : aEsymbol->wires )
2377 aSymbol->AddDrawItem(
loadSymbolWire( aSymbol, ewire, aGateNumber ) );
2379 for(
const std::unique_ptr<EFRAME>& eframe : aEsymbol->frames )
2381 std::vector<SCH_ITEM*> frameItems;
2387 item->SetParent( aSymbol.get() );
2388 item->SetUnit( aGateNumber );
2389 aSymbol->AddDrawItem( item );
2393 aSymbol->GetReferenceField().SetVisible( showRefDes );
2394 aSymbol->GetValueField().SetVisible( showValue );
2396 return pincount == 1 ? ispower :
false;
2401 const std::unique_ptr<ECIRCLE>& aCircle,
2404 wxCHECK( aSymbol && aCircle,
nullptr );
2408 VECTOR2I center( aCircle->x.ToSchUnits(), -aCircle->y.ToSchUnits() );
2410 circle->SetParent( aSymbol.get() );
2414 circle->SetUnit( aGateNumber );
2421 const std::unique_ptr<ERECT>& aRectangle,
2424 wxCHECK( aSymbol && aRectangle,
nullptr );
2429 rectangle->
SetPosition(
VECTOR2I( aRectangle->x1.ToSchUnits(), -aRectangle->y1.ToSchUnits() ) );
2430 rectangle->
SetEnd(
VECTOR2I( aRectangle->x2.ToSchUnits(), -aRectangle->y2.ToSchUnits() ) );
2432 if( aRectangle->rot )
2445 rectangle->
SetUnit( aGateNumber );
2455 const std::unique_ptr<EWIRE>& aWire,
int aGateNumber )
2457 wxCHECK( aSymbol && aWire,
nullptr );
2461 begin.
x = aWire->x1.ToSchUnits();
2462 begin.
y = -aWire->y1.ToSchUnits();
2463 end.x = aWire->x2.ToSchUnits();
2464 end.y = -aWire->y2.ToSchUnits();
2483 ( aWire->width.ToSchUnits() /
radius );
2484 begin =
center + centerStartVector;
2518 const std::unique_ptr<EPOLYGON>& aPolygon,
2521 wxCHECK( aSymbol && aPolygon,
nullptr );
2529 for(
const std::unique_ptr<EVERTEX>& evertex : aPolygon->vertices )
2531 pt =
VECTOR2I( evertex->x.ToSchUnits(), evertex->y.ToSchUnits() );
2545 prev_curve = evertex->curve;
2557 const std::unique_ptr<EPIN>& aPin,
int aGateNumber )
2559 wxCHECK( aSymbol && aPin,
nullptr );
2561 std::unique_ptr<SCH_PIN>
pin = std::make_unique<SCH_PIN>( aSymbol.get() );
2562 pin->SetPosition(
VECTOR2I( aPin->x.ToSchUnits(), -aPin->y.ToSchUnits() ) );
2563 pin->SetName( aPin->name );
2564 pin->SetUnit( aGateNumber );
2566 int roti = aPin->rot ? aPin->rot->degrees : 0;
2574 default: wxFAIL_MSG( wxString::Format( wxT(
"Unhandled orientation (%d degrees)." ), roti ) );
2581 wxString length = aPin->length.Get();
2583 if( length == wxT(
"short" ) )
2585 else if( length == wxT(
"middle" ) )
2587 else if( length == wxT(
"long" ) )
2589 else if( length == wxT(
"point" ) )
2600 wxString visible = aPin->visible.Get();
2602 if( visible == wxT(
"off" ) )
2604 pin->SetNameTextSize( 0 );
2605 pin->SetNumberTextSize( 0 );
2607 else if( visible == wxT(
"pad" ) )
2609 pin->SetNameTextSize( 0 );
2611 else if( visible == wxT(
"pin" ) )
2613 pin->SetNumberTextSize( 0 );
2623 if( aPin->function )
2625 wxString function = aPin->function.Get();
2627 if( function == wxT(
"dot" ) )
2629 else if( function == wxT(
"clk" ) )
2631 else if( function == wxT(
"dotclk" ) )
2635 return pin.release();
2640 const std::unique_ptr<ETEXT>& aText,
int aGateNumber )
2642 wxCHECK( aSymbol && aText,
nullptr );
2644 std::unique_ptr<SCH_TEXT> libtext = std::make_unique<SCH_TEXT>();
2646 libtext->SetParent( aSymbol.get() );
2647 libtext->SetUnit( aGateNumber );
2648 libtext->SetPosition(
VECTOR2I( aText->x.ToSchUnits(), -aText->y.ToSchUnits() ) );
2650 const wxString& eagleText = aText->text;
2651 wxString adjustedText;
2652 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2655 while( tokenizer.HasMoreTokens() )
2657 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2659 if( tokenizer.HasMoreTokens() )
2662 adjustedText += tmp;
2665 libtext->SetText( adjustedText.IsEmpty() ? wxString( wxS(
"~" ) ) : adjustedText );
2669 return libtext.release();
2675 wxCHECK( aText,
nullptr );
2677 std::unique_ptr<SCH_TEXT> schtext = std::make_unique<SCH_TEXT>();
2679 const wxString& eagleText = aText->text;
2680 wxString adjustedText;
2681 wxStringTokenizer tokenizer( eagleText,
"\r\n" );
2684 while( tokenizer.HasMoreTokens() )
2686 wxString tmp =
interpretText( tokenizer.GetNextToken().Trim(
true ).Trim(
false ) );
2688 if( tokenizer.HasMoreTokens() )
2691 adjustedText += tmp;
2694 schtext->SetText( adjustedText.IsEmpty() ? wxString( wxS(
"\" \"" ) )
2697 schtext->SetPosition(
VECTOR2I( aText->x.ToSchUnits(), -aText->y.ToSchUnits() ) );
2699 schtext->SetItalic(
false );
2701 return schtext.release();
2706 const std::unique_ptr<ETEXT>& aAttributes )
const
2708 wxCHECK( aText && aAttributes, );
2713 if( aAttributes->ratio && aAttributes->ratio.CGet() > 12 )
2717 int degrees = aAttributes->rot ? aAttributes->rot->degrees : 0;
2718 bool mirror = aAttributes->rot ? aAttributes->rot->mirror :
false;
2719 bool spin = aAttributes->rot ? aAttributes->rot->spin :
false;
2727 wxCHECK( aField && aText, );
2751 auto onIntersection =
2763 const SEG* segAttached = segDesc.LabelAttached( label );
2765 if( segAttached && !onIntersection( labelPos ) )
2779 VECTOR2I wireDirection( segAttached->
B - segAttached->
A );
2781 if( ( wireDirection.
x == 0 ) && (wireDirection.
y == 0 ) )
2785 const VECTOR2I origPos( labelPos );
2788 bool checkPositive =
true;
2789 bool checkNegative =
true;
2794 while( ( !
move || onIntersection( labelPos ) ) && ( checkPositive || checkNegative ) )
2799 if( trial % 2 == 1 )
2801 labelPos =
VECTOR2I( origPos + wireDirection * trial / 2 );
2802 move = checkPositive = segAttached->
Contains( labelPos );
2806 labelPos =
VECTOR2I( origPos - wireDirection * trial / 2 );
2807 move = checkNegative = segAttached->
Contains( labelPos );
2817 if( wireDirection.
x == 0 )
2819 if( wireDirection.
y < 0 )
2824 else if( wireDirection.
y == 0 )
2826 if( wireDirection.
x < 0 )
2860 wxFileInputStream input( aFileName );
2865 wxTextInputStream
text( input );
2867 for(
int i = 0; i < 8; i++ )
2872 if(
text.ReadLine().Contains( wxS(
"<eagle" ) ) )
2890 if( !item->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
2894 item->SetPosition( aNewEndPoint );
2907 std::vector<SCH_LINE*> buses;
2908 std::vector<SCH_LINE*> wires;
2919 buses.push_back( line );
2920 else if( line->
IsWire() )
2921 wires.push_back( line );
2926 VECTOR2I wireStart = wire->GetStartPoint();
2927 VECTOR2I wireEnd = wire->GetEndPoint();
2931 VECTOR2I busStart = bus->GetStartPoint();
2932 VECTOR2I busEnd = bus->GetEndPoint();
2935 [](
int signX,
int signY ) ->
VECTOR2I
2947 if( wireStart.
y == wireEnd.
y && busStart.
x == busEnd.
x )
2951 if( testBusHit( wireStart ) )
2955 if( wireEnd.
x < busStart.
x )
2962 VECTOR2I p = wireStart + entrySize( -1, 0 );
2964 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
2973 screen->
Append( busEntry );
2975 wire->SetStartPoint( p );
2977 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
2986 screen->
Append( busEntry );
2988 wire->SetStartPoint( p );
3003 VECTOR2I p = wireStart + entrySize( 1, 0 );
3005 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
3014 screen->
Append( busEntry );
3016 wire->SetStartPoint( p );
3018 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
3027 screen->
Append( busEntry );
3029 wire->SetStartPoint( p );
3040 else if( testBusHit( wireEnd ) )
3044 if( wireStart.
x < busStart.
x )
3051 VECTOR2I p = wireEnd + entrySize( -1, 0 );
3053 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3062 screen->
Append( busEntry );
3064 wire->SetEndPoint( p );
3066 else if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3075 screen->
Append( busEntry );
3076 moveLabels( wire, wireEnd + entrySize( -1, 0 ) );
3077 wire->SetEndPoint( wireEnd + entrySize( -1, 0 ) );
3092 VECTOR2I p = wireEnd + entrySize( 1, 0 );
3094 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
3103 screen->
Append( busEntry );
3105 wire->SetEndPoint( p );
3107 else if( testBusHit( wireEnd + entrySize( 0, 1 ) ) )
3116 screen->
Append( busEntry );
3118 wire->SetEndPoint( p );
3130 else if( wireStart.
x == wireEnd.
x && busStart.
y == busEnd.
y )
3134 if( testBusHit( wireStart ) )
3138 if( wireEnd.
y < busStart.
y )
3146 VECTOR2I p = wireStart + entrySize( 0, -1 );
3148 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3158 screen->
Append( busEntry );
3160 wire->SetStartPoint( p );
3162 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3172 screen->
Append( busEntry );
3174 wire->SetStartPoint( p );
3190 VECTOR2I p = wireStart + entrySize( 0, 1 );
3192 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
3202 screen->
Append( busEntry );
3204 wire->SetStartPoint( p );
3206 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
3216 screen->
Append( busEntry );
3218 wire->SetStartPoint( p );
3229 else if( testBusHit( wireEnd ) )
3233 if( wireStart.
y < busStart.
y )
3241 VECTOR2I p = wireEnd + entrySize( 0, -1 );
3243 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3253 screen->
Append( busEntry );
3255 wire->SetEndPoint( p );
3257 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3267 screen->
Append( busEntry );
3269 wire->SetEndPoint( p );
3285 VECTOR2I p = wireEnd + entrySize( 0, 1 );
3287 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
3297 screen->
Append( busEntry );
3299 wire->SetEndPoint( p );
3301 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
3311 screen->
Append( busEntry );
3313 wire->SetEndPoint( p );
3329 if( testBusHit( wireStart ) )
3331 VECTOR2I wirevector = wireStart - wireEnd;
3333 if( wirevector.
x > 0 )
3335 if( wirevector.
y > 0 )
3337 VECTOR2I p = wireStart + entrySize( -1, -1 );
3340 screen->
Append( busEntry );
3343 wire->SetStartPoint( p );
3347 VECTOR2I p = wireStart + entrySize( -1, 1 );
3350 screen->
Append( busEntry );
3353 wire->SetStartPoint( p );
3358 if( wirevector.
y > 0 )
3360 VECTOR2I p = wireStart + entrySize( 1, -1 );
3363 screen->
Append( busEntry );
3366 wire->SetStartPoint( p );
3370 VECTOR2I p = wireStart + entrySize( 1, 1 );
3373 screen->
Append( busEntry );
3376 wire->SetStartPoint( p );
3382 else if( testBusHit( wireEnd ) )
3384 VECTOR2I wirevector = wireStart - wireEnd;
3386 if( wirevector.
x > 0 )
3388 if( wirevector.
y > 0 )
3390 VECTOR2I p = wireEnd + entrySize( 1, 1 );
3393 screen->
Append( busEntry );
3396 wire->SetEndPoint( p );
3400 VECTOR2I p = wireEnd + entrySize( 1, -1 );
3403 screen->
Append( busEntry );
3406 wire->SetEndPoint( p );
3411 if( wirevector.
y > 0 )
3413 VECTOR2I p = wireEnd + entrySize( -1, 1 );
3416 screen->
Append( busEntry );
3419 wire->SetEndPoint( p );
3423 VECTOR2I p = wireEnd + entrySize( -1, -1 );
3426 screen->
Append( busEntry );
3429 wire->SetEndPoint( p );
3443 wxCHECK( aLabel,
nullptr );
3449 if( seg.Contains( labelPos ) )
3461 wxCHECK( aSymbol && aPin,
false );
3469 const auto& items = pointIt->second;
3471 wxCHECK( items.find( aPin ) != items.end(),
false );
3473 return items.size() > 1;
3487 int unit = aSymbol->
GetUnit();
3490 std::set<int> missingUnits;
3497 bool pinInUnit = !unit ||
pin->GetUnit() == unit;
3511 switch(
pin->GetOrientation() )
3528 aScreen->
Append( netLabel );
3531 else if( aUpdateSet )
3536 wxASSERT(
pin->GetUnit() );
3537 missingUnits.insert(
pin->GetUnit() );
3550 entry.
cmp = aSymbol;
3552 entry.
units.emplace( unit,
false );
3557 cmpIt->second.units[unit] =
false;
3560 if( !missingUnits.empty() )
3563 entry.
cmp = aSymbol;
3567 for(
int i : missingUnits )
3569 if( entry.
units.find( i ) != entry.
units.end() )
3570 entry.
units.emplace( i,
true );
3582 wxString ret = wxT(
"{" );
3584 wxStringTokenizer tokenizer( aEagleName,
"," );
3586 while( tokenizer.HasMoreTokens() )
3588 wxString member = tokenizer.GetNextToken();
3595 if( member.Freq(
'!' ) % 2 > 0 )
3596 member << wxT(
"!" );
3598 ret << member << wxS(
" " );
3613 std::unique_ptr<EPART>& epart =
m_eagleDoc->drawing->schematic->parts[aInstance->part];
3615 if( !epart || epart->deviceset.IsEmpty() )
3618 std::unique_ptr<ELIBRARY>& elibrary =
m_eagleDoc->drawing->schematic->libraries[epart->library];
3623 std::unique_ptr<EDEVICE_SET>& edeviceset = elibrary->devicesets[epart->deviceset];
3628 std::unique_ptr<EGATE>& egate = edeviceset->gates[aInstance->gate];
3633 std::unique_ptr<ESYMBOL>& esymbol = elibrary->symbols[egate->symbol];
3636 return esymbol.get();
3643 const wxString& aEagleFieldName,
3646 wxCHECK( aField && !aEagleFieldName.
IsEmpty(), );
3652 for(
const std::unique_ptr<ETEXT>&
text : esymbol->
texts )
3654 if(
text->text == aEagleFieldName )
3657 VECTOR2I pos(
text->x.ToSchUnits() + aInstance->x.ToSchUnits(),
3658 -
text->y.ToSchUnits() - aInstance->y.ToSchUnits() );
3660 bool mirror =
text->rot ?
text->rot->mirror :
false;
3662 if( aInstance->rot && aInstance->rot->mirror )
3666 pos.
y = -aInstance->y.ToSchUnits() +
text->y.ToSchUnits();
constexpr EDA_IU_SCALE schIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
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
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
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)
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.
bool IsGlobalPower() const override
int GetUnitCount() const override
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 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)
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_LABEL_BASE * loadLabel(const std::unique_ptr< ELABEL > &aLabel, const wxString &aNetName)
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
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
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.
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 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.
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".
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.