53#include <wx/xml/xml.h>
54#include <wx/filename.h>
56#include <wx/wfstream.h>
57#include <wx/txtstrm.h>
95 ECOORD coord( aDistance, unit );
106 T ret = std::max( aMin, aValue );
107 return std::min( aMax, ret );
113static wxString
makeKey(
const wxString& aFirst,
const wxString& aSecond )
115 wxString key = aFirst +
'\x02' + aSecond;
163 wxXmlNode* child = aRules->GetChildren();
169 if( child->GetName() == wxT(
"param" ) )
171 const wxString&
name = child->GetAttribute( wxT(
"name" ) );
172 const wxString& value = child->GetAttribute( wxT(
"value" ) );
174 if(
name == wxT(
"psElongationLong" ) )
176 else if(
name == wxT(
"psElongationOffset" ) )
178 else if(
name == wxT(
"mvStopFrame" ) )
180 else if(
name == wxT(
"mvCreamFrame" ) )
182 else if(
name == wxT(
"mlMinStopFrame" ) )
184 else if(
name == wxT(
"mlMaxStopFrame" ) )
186 else if(
name == wxT(
"mlMinCreamFrame" ) )
188 else if(
name == wxT(
"mlMaxCreamFrame" ) )
190 else if(
name == wxT(
"srRoundness" ) )
192 else if(
name == wxT(
"srMinRoundness" ) )
194 else if(
name == wxT(
"srMaxRoundness" ) )
196 else if(
name == wxT(
"psTop" ) )
197 psTop = wxAtoi( value );
198 else if(
name == wxT(
"psBottom" ) )
200 else if(
name == wxT(
"psFirst" ) )
202 else if(
name == wxT(
"rvPadTop" ) )
204 else if(
name == wxT(
"rlMinPadTop" ) )
206 else if(
name == wxT(
"rlMaxPadTop" ) )
208 else if(
name == wxT(
"rvViaOuter" ) )
210 else if(
name == wxT(
"rlMinViaOuter" ) )
212 else if(
name == wxT(
"rlMaxViaOuter" ) )
214 else if(
name == wxT(
"mdWireWire" ) )
218 child = child->GetNext();
231 m_timestamp( wxDateTime::Now().GetValue().GetValue() )
233 using namespace std::placeholders;
275 wxFileInputStream input( aFileName );
286 wxTextInputStream
text( input );
288 for(
int i = 0; i < 8; i++ )
293 if(
text.ReadLine().Contains( wxS(
"<eagle" ) ) )
303 const unsigned PROGRESS_DELTA = 50;
324 return VECTOR2I( kz - aTextThickness, kz - aTextThickness );
329 const std::map<std::string, UTF8>* aProperties,
PROJECT* aProject )
342 m_board->SetFileName( aFileName );
345 unique_ptr<BOARD> deleter( aAppendToMe ?
nullptr :
m_board );
357 wxFileName fn = aFileName;
360 wxFFileInputStream stream( fn.GetFullPath() );
365 fn.GetFullPath() ) );
371 wxXmlDocument xmlDocument;
372 std::unique_ptr<wxXmlDocument> binDocument;
380 std::vector<uint8_t> bytes;
381 bytes.resize(
static_cast<size_t>( stream.GetLength() ) );
382 stream.Read( bytes.data(), bytes.size() );
384 if( stream.LastRead() != bytes.size() )
387 fn.GetFullPath() ) );
391 binDocument = binParser.
Parse( bytes );
392 doc = binDocument->GetRoot();
396 if( !xmlDocument.Load( stream ) )
399 fn.GetFullPath() ) );
402 doc = xmlDocument.GetRoot();
429 NETCLASS defaults( wxT(
"dummy" ) );
431 auto finishNetclass =
432 [&](
const std::shared_ptr<NETCLASS>& netclass )
436 if( !netclass->HasClearance() )
441 if( netclass->GetTrackWidth() == INT_MAX )
444 if( netclass->GetViaDiameter() == INT_MAX )
447 if( netclass->GetViaDrill() == INT_MAX )
451 std::shared_ptr<NET_SETTINGS>& netSettings = bds.
m_NetSettings;
453 finishNetclass( netSettings->GetDefaultNetclass() );
455 for(
const auto& [
name, netclass] : netSettings->GetNetclasses() )
456 finishNetclass( netclass );
458 m_board->m_LegacyNetclassesLoaded =
true;
459 m_board->m_LegacyDesignSettingsLoaded =
true;
465 fn.SetExt( wxT(
"kicad_dru" ) );
467 wxFile rulesFile( fn.GetFullPath(), wxFile::write );
472 wxASSERT(
m_xpath->Contents().size() == 0 );
476 wxString errmsg = exc.what();
478 errmsg += wxT(
"\n@ " );
488 LSET enabledLayers =
m_board->GetDesignSettings().GetEnabledLayers();
490 for(
const auto& [eagleLayerName, layer] :
m_layer_map )
493 enabledLayers.
set( layer );
496 m_board->GetDesignSettings().SetEnabledLayers( enabledLayers );
507 std::vector<FOOTPRINT*> retval;
510 retval.push_back(
static_cast<FOOTPRINT*
>( footprint->Clone() ) );
546 wxXmlNode* drawing =
MapChildren( aDoc )[
"drawing"];
549 wxXmlNode* board = drawingChildren[
"board"];
552 auto count_children =
553 [
this]( wxXmlNode* aNode )
557 wxXmlNode* child = aNode->GetChildren();
562 child = child->GetNext();
567 wxXmlNode* designrules = boardChildren[
"designrules"];
568 wxXmlNode* layers = drawingChildren[
"layers"];
569 wxXmlNode* plain = boardChildren[
"plain"];
570 wxXmlNode* classes = boardChildren[
"classes"];
571 wxXmlNode* signals = boardChildren[
"signals"];
572 wxXmlNode* libs = boardChildren[
"libraries"];
573 wxXmlNode* elems = boardChildren[
"elements"];
580 count_children( designrules );
581 count_children( layers );
582 count_children( plain );
583 count_children( signals );
584 count_children( elems );
589 libs = libs->GetNext();
593 libs = boardChildren[
"libraries"];
596 m_xpath->push(
"eagle.drawing" );
635 m_xpath->push(
"designrules" );
654 wxXmlNode* layerNode = aLayers->GetChildren();
661 ELAYER elayer( layerNode );
667 cu.push_back( elayer );
669 layerNode = layerNode->GetNext();
673 int ki_layer_count = 0;
675 for(
EITER it = cu.begin(); it != cu.end(); ++it, ++ki_layer_count )
677 if( ki_layer_count == 0 )
681 else if( ki_layer_count ==
int( cu.size()-1 ) )
695 m_board->SetCopperLayerCount( cu.size() );
697 for(
EITER it = cu.begin(); it != cu.end(); ++it )
704 m_board->SetLayerName( layer, it->name );
714#define DIMENSION_PRECISION DIM_PRECISION::X_XX
719 std::map<int, std::tuple<GR_TEXT_V_ALIGN_T, GR_TEXT_H_ALIGN_T>> alignmentmap{
730 return alignmentmap[aAlign];
736 std::map<std::tuple<GR_TEXT_V_ALIGN_T, GR_TEXT_H_ALIGN_T>,
int> alignmentmap{
747 return alignmentmap[aAlign];
755 double degrees{ aDegrees };
765 if( degrees > 90 && degrees <= 270 )
794 wxXmlNode* gr = aGraphics->GetChildren();
801 wxString grName = gr->GetName();
803 if( grName == wxT(
"wire" ) )
820 width =
m_board->GetDesignSettings().GetLineThickness( layer );
846 else if( grName == wxT(
"text" ) )
881 else if( grName == wxT(
"circle" ) )
900 int outlineRadius =
radius + ( width / 2 );
906 VECTOR2I rotatedPoint( outlineRadius, 0 );
914 int innerRadius =
radius - ( width / 2 );
920 VECTOR2I rotatedPoint( innerRadius, 0 );
947 else if( grName == wxT(
"rectangle" ) )
980 const int outlineIdx = -1;
999 else if( grName == wxT(
"hole" ) )
1009 footprint->
SetReference( wxString::Format( wxT(
"UNK_HOLE_%d" ), hole_count ) );
1012 LIB_ID fpid( wxEmptyString, wxString::Format( wxT(
"dummyfp%d" ), hole_count ) );
1019 else if( grName == wxT(
"frame" ) )
1023 else if( grName == wxT(
"polygon" ) )
1029 else if( grName == wxT(
"dimension" ) )
1063 dimension->
SetEnd( pt2 );
1098 int newY = ( pt1.
y + pt2.
y ) / 2;
1104 int newX = ( pt1.
x + pt2.
x ) / 2;
1115 dimension->
SetEnd( pt2 );
1125 if(
abs( pt1.
x - pt2.
x ) < 50000 )
1127 int offset = pt3.
x - pt1.
x;
1134 else if(
abs( pt1.
y - pt2.
y ) < 50000 )
1136 int offset = pt3.
y - pt1.
y;
1169 wxString urn = aLib->GetAttribute(
"urn" );
1178 if( !urn.IsEmpty() )
1179 libraryUrn.
Parse( urn );
1182 wxXmlNode* packages =
MapChildren( aLib )[
"packages"];
1201 libKey += wxS(
"_" ) + libraryUrn.
assetId;
1209 wxXmlNode*
package = packages->GetChildren();
1215 m_xpath->push(
"package",
"name" );
1217 wxString pack_ref = package->GetAttribute(
"name" );
1221 m_xpath->Value( pack_ref.ToUTF8() );
1223 wxString key = aLibName ?
makeKey( libKey, pack_ref ) : pack_ref;
1228 auto r =
m_templates.insert( { key, footprint } );
1232 wxString lib = aLibName ? *aLibName :
m_lib_path;
1233 const wxString& pkg = pack_ref;
1235 wxString emsg = wxString::Format(
_(
"<package> '%s' duplicated in <library> '%s'" ),
1243 package = package->GetNext();
1255 m_xpath->push(
"libraries.library",
"name" );
1258 wxXmlNode*
library = aLibs->GetChildren();
1262 const wxString& lib_name =
library->GetAttribute(
"name" );
1264 m_xpath->Value( lib_name.c_str() );
1278 m_xpath->push(
"elements.element",
"name" );
1282 bool refanceNamePresetInPackageLayout;
1283 bool valueNamePresetInPackageLayout;
1286 wxXmlNode* element = aElements->GetChildren();
1292 if( element->GetName() != wxT(
"element" ) )
1295 element = element->GetNext();
1302 EATTR* nameAttr =
nullptr;
1303 EATTR* valueAttr =
nullptr;
1320 wxString emsg = wxString::Format(
_(
"No '%s' package in library '%s'." ),
1337 const ENET* enet = &ni->second;
1342 refanceNamePresetInPackageLayout =
true;
1343 valueNamePresetInPackageLayout =
true;
1350 refanceNamePresetInPackageLayout =
false;
1354 if( footprint->
GetValue().size() == 0 )
1357 valueNamePresetInPackageLayout =
false;
1360 wxString reference = e.
name;
1366 if( reference.find_first_not_of(
"0123456789" ) != 0 )
1367 reference.Prepend(
"UNK" );
1371 if( reference.find_first_not_of(
"#" ) != 0 )
1372 reference.Prepend(
"UNK" );
1375 if( reference.find_last_not_of(
"0123456789" ) == (reference.Length()-1) )
1376 reference.Append(
"0" );
1384 if( valueNamePresetInPackageLayout )
1387 if( refanceNamePresetInPackageLayout )
1397 m_xpath->push(
"attribute",
"name" );
1407 wxXmlNode* attribute = element->GetChildren();
1411 if( attribute->GetName() != wxT(
"attribute" ) )
1413 attribute = attribute->GetNext();
1417 EATTR a( attribute );
1419 if( a.
name == wxT(
"NAME" ) )
1432 nameAttr->
name = reference;
1434 if( refanceNamePresetInPackageLayout )
1441 if( refanceNamePresetInPackageLayout )
1450 if( refanceNamePresetInPackageLayout )
1453 nameAttr->
name = nameAttr->
name + wxT(
" = " ) + e.
name;
1464 if( refanceNamePresetInPackageLayout )
1474 else if( a.
name == wxT(
"VALUE" ) )
1488 if( valueNamePresetInPackageLayout )
1494 if( valueNamePresetInPackageLayout )
1497 footprint->
SetValue( wxT(
"VALUE" ) );
1501 if( valueNamePresetInPackageLayout )
1515 if( valueNamePresetInPackageLayout )
1527 attribute = attribute->GetNext();
1536 element = element->GetNext();
1556 wxLogMessage( wxString::Format(
_(
"Ignoring a polygon since Eagle layer '%s' (%d) was not mapped" ),
1563 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board );
1566 zone->SetLayer( layer );
1571 wxXmlNode* vertex = aPolyNode->GetChildren();
1572 std::vector<EVERTEX> vertices;
1580 if( vertex->GetName() == wxT(
"vertex" ) )
1581 vertices.emplace_back( vertex );
1583 vertex = vertex->GetNext();
1593 if( vertices.size() < 3 )
1595 wxLogMessage( wxString::Format(
_(
"Skipping a polygon on layer '%s' (%d): less than 3 vertices" ),
1601 vertices.push_back( vertices[0] );
1606 for(
size_t i = 0; i < vertices.size() - 1; i++ )
1624 double delta_angle = angle / segCount;
1626 for(
double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta_angle ); a -= delta_angle )
1641 wxLogMessage( wxString::Format(
_(
"Skipping a polygon on layer '%s' (%d): outline count is not 1" ),
1648 zone->AddPolygon( polygon.
COutline( 0 ) );
1653 zone->SetIsRuleArea(
true );
1654 zone->SetDoNotAllowVias(
false );
1655 zone->SetDoNotAllowTracks(
false );
1656 zone->SetDoNotAllowPads(
false );
1657 zone->SetDoNotAllowFootprints(
false );
1658 zone->SetDoNotAllowZoneFills(
true );
1668 zone->SetHatchOrientation(
ANGLE_0 );
1679 zone->SetLocalClearance( 1 );
1696 zone->SetAssignedPriority( rank );
1698 ZONE* zonePtr = zone.release();
1706 const EATTR* aNameAttr,
const EATTR* aValueAttr )
1727 const EATTR* aAttr )
1733 const EATTR& a = *aAttr;
1752 int textThickness =
KiROUND( fontz.
y * ratio / 100.0 );
1799 std::unique_ptr<FOOTPRINT> m = std::make_unique<FOOTPRINT>(
m_board );
1802 fpID.
Parse( aPkgName,
true );
1806 wxXmlNode* packageItem = aPackage->GetChildren();
1811 m.get()->Value().SetLayer( layer );
1813 while( packageItem )
1815 const wxString& itemName = packageItem->GetName();
1817 if( itemName == wxT(
"description" ) )
1820 m->SetLibDescription( descr );
1822 else if( itemName == wxT(
"wire" ) )
1824 else if( itemName == wxT(
"pad" ) )
1826 else if( itemName == wxT(
"text" ) )
1828 else if( itemName == wxT(
"rectangle" ) )
1830 else if( itemName == wxT(
"polygon" ) )
1832 else if( itemName == wxT(
"circle" ) )
1834 else if( itemName == wxT(
"hole" ) )
1836 else if( itemName == wxT(
"smd" ) )
1839 packageItem = packageItem->GetNext();
1856 wxLogMessage( wxString::Format(
_(
"Ignoring a wire since Eagle layer '%s' (%d) was not mapped" ),
1915 aFootprint->
Add( dwg );
1926 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
1936 pad->SetDrillSize(
VECTOR2I( eagleDrillz, eagleDrillz ) );
1988 double drillz =
pad->GetDrillSize().x;
1989 double annulus = drillz *
m_rules->rvPadTop;
1991 int diameter =
KiROUND( drillz + 2 * annulus );
1999 sz.
x = ( sz.
x * ( 100 +
m_rules->psElongationLong ) ) / 100;
2004 int offset =
KiROUND( ( sz.
x - sz.
y ) / 2.0 );
2015 if(
pad->GetSizeX() > 0 &&
pad->GetSizeY() > 0 &&
pad->HasHole() )
2017 aFootprint->
Add(
pad.release() );
2024 wxLogError(
_(
"Invalid zero-sized pad ignored in\nfile: %s" ),
m_board->GetFileName() );
2026 wxLogError(
_(
"Invalid zero-sized pad ignored in\nfile: %s" ), fileName.GetFullName() );
2038 wxLogMessage( wxString::Format(
_(
"Ignoring a text since Eagle layer '%s' (%d) was not mapped" ),
2046 if( t.
text.Upper() == wxT(
">NAME" ) && aFootprint->
GetReference().IsEmpty() )
2050 textItem->
SetText( wxT(
"REF**" ) );
2052 else if( t.
text.Upper() == wxT(
">VALUE" ) && aFootprint->
GetValue().IsEmpty() )
2054 textItem = &aFootprint->
Value();
2060 textItem =
new PCB_TEXT( aFootprint );
2061 aFootprint->
Add( textItem );
2149 ZONE* zone =
new ZONE( aFootprint );
2154 const int outlineIdx = -1;
2176 wxLogMessage( wxString::Format(
_(
"Ignoring a rectangle since Eagle layer '%s' (%d) was not mapped" ),
2184 aFootprint->
Add( dwg );
2190 std::vector<VECTOR2I> pts;
2195 pts.push_back( start );
2198 pts.push_back(
end );
2215 std::vector<VECTOR2I> pts;
2218 wxXmlNode* vertex = aTree->GetChildren();
2219 std::vector<EVERTEX> vertices;
2227 if( vertex->GetName() == wxT(
"vertex" ) )
2228 vertices.emplace_back( vertex );
2230 vertex = vertex->GetNext();
2236 if( vertices.size() < 3 )
2238 wxLogMessage( wxString::Format(
_(
"Skipping a polygon on layer '%s' (%d): less than 3 vertices" ),
2244 vertices.push_back( vertices[0] );
2246 for(
size_t i = 0; i < vertices.size() - 1; i++ )
2269 double delta = angle / segCount;
2271 for(
double a = end_angle + angle; fabs( a - end_angle ) > fabs(
delta ); a -=
delta )
2286 ZONE* zone =
new ZONE( aFootprint );
2302 wxLogMessage( wxString::Format(
_(
"Ignoring a polygon since Eagle layer '%s' (%d) was not mapped" ),
2310 aFootprint->
Add( dwg );
2336 ZONE* zone =
new ZONE( aFootprint );
2343 int outlineRadius =
radius + ( width / 2 );
2349 VECTOR2I rotatedPoint( outlineRadius, 0 );
2357 int innerRadius =
radius - ( width / 2 );
2363 VECTOR2I rotatedPoint( innerRadius, 0 );
2378 wxLogMessage( wxString::Format(
_(
"Ignoring a circle since Eagle layer '%s' (%d) was not mapped" ),
2394 aFootprint->
Add( gr );
2397 switch( (
int) layer )
2439 pad->SetPosition( padpos );
2448 pad->SetDrillSize( sz );
2472 pad->SetLayer( layer );
2478 pad->SetLayerSet( front );
2479 else if( layer ==
B_Cu )
2480 pad->SetLayerSet( back );
2482 int minPadSize = std::min( padSize.
x, padSize.
y );
2486 (
int) ( minPadSize *
m_rules->srRoundness ),
2487 m_rules->srMaxRoundness * 2 );
2491 double roundRatio = (double) roundRadius / minPadSize / 2.0;
2495 roundRatio = std::fmax( *e.
roundness / 200.0, roundRatio );
2508 (
int) (
m_rules->mvCreamFrame * minPadSize ),
2515 pad->SetLayerSet(
pad->GetLayerSet().set(
F_Mask,
false ) );
2516 else if( layer ==
B_Cu )
2517 pad->SetLayerSet(
pad->GetLayerSet().set(
B_Mask,
false ) );
2524 pad->SetLayerSet(
pad->GetLayerSet().set(
F_Paste,
false ) );
2525 else if( layer ==
B_Cu )
2526 pad->SetLayerSet(
pad->GetLayerSet().set(
B_Paste,
false ) );
2541 (
int) (
m_rules->mvStopFrame * std::min( padSize.
x, padSize.
y ) ),
2549 wxCHECK( footprint, );
2559 footprint->SetParent(
nullptr );
2575 m_xpath->push(
"classes.class",
"number" );
2577 std::vector<ECLASS> eClasses;
2578 wxXmlNode* classNode = aClasses->GetChildren();
2584 ECLASS eClass( classNode );
2585 std::shared_ptr<NETCLASS> netclass;
2587 if( eClass.
name.CmpNoCase( wxT(
"default" ) ) == 0 )
2597 netclass->SetTrackWidth( INT_MAX );
2598 netclass->SetViaDiameter( INT_MAX );
2599 netclass->SetViaDrill( INT_MAX );
2601 eClasses.emplace_back( eClass );
2605 auto clearanceToDefaultIt = eClass.
clearanceMap.find( wxT(
"0" ) );
2607 if( clearanceToDefaultIt != eClass.
clearanceMap.end() )
2609 netclass->SetClearance( clearanceToDefaultIt->second.ToPcbUnits() );
2613 classNode = classNode->GetNext();
2618 for(
ECLASS& eClass : eClasses )
2620 for(
const auto& [className, pt] : eClass.clearanceMap )
2623 if( className == wxT(
"0" ) )
2629 rule.Printf( wxT(
"(rule \"class %s:%s\"\n"
2630 " (condition \"A.NetClass == '%s' && B.NetClass == '%s'\")\n"
2631 " (constraint clearance (min %smm)))\n" ),
2661 std::set<wxString> usedNetNames;
2663 for( wxXmlNode* signal = aSignals->GetChildren(); signal; signal = signal->GetNext() )
2665 wxString explicitName =
escapeName( signal->GetAttribute(
"name" ) );
2667 if( !explicitName.IsEmpty() )
2668 usedNetNames.insert( explicitName );
2671 m_xpath->push(
"signals.signal",
"name" );
2674 wxXmlNode* net = aSignals->GetChildren();
2680 bool sawPad =
false;
2684 wxString netName =
escapeName( net->GetAttribute(
"name" ) );
2691 if( netName.IsEmpty() )
2693 int candidate = netCode;
2697 netName = wxString::Format( wxT(
"N$%d" ), candidate++ );
2698 }
while( usedNetNames.count( netName ) );
2700 usedNetNames.insert( netName );
2704 std::shared_ptr<NETCLASS> netclass;
2706 if( net->HasAttribute(
"class" ) )
2708 auto netclassIt =
m_classMap.find( net->GetAttribute(
"class" ) );
2714 netclass = netclassIt->second;
2725 m_xpath->Value( netName.c_str() );
2728 wxXmlNode* netItem = net->GetChildren();
2733 const wxString& itemName = netItem->GetName();
2735 if( itemName == wxT(
"wire" ) )
2752 if( netclass && width < netclass->GetTrackWidth() )
2753 netclass->SetTrackWidth( width );
2763 double radiusA = ( mid -
center ).EuclideanNorm();
2764 double radiusB = ( otherMid -
center ).EuclideanNorm();
2767 std::swap( mid, otherMid );
2800 else if( itemName == wxT(
"via" ) )
2812 && layer_front_most != layer_back_most )
2826 double annulus = drillz *
m_rules->rvViaOuter;
2828 kidiam =
KiROUND( drillz + 2 * annulus );
2832 via->SetDrill( drillz );
2838 if( !v.
diam || via_width <= via->GetDrill() )
2840 double annular_width = ( via_width -
via->GetDrill() ) / 2.0;
2850 if( netclass && kidiam < netclass->GetViaDiameter() )
2851 netclass->SetViaDiameter( kidiam );
2856 if( netclass && drillz < netclass->GetViaDrill() )
2857 netclass->SetViaDrill( drillz );
2862 if( layer_front_most ==
F_Cu && layer_back_most ==
B_Cu )
2866 else if( layer_front_most ==
F_Cu || layer_back_most ==
B_Cu )
2877 via->SetLayerPair( layer_front_most, layer_back_most );
2878 via->SetPosition( pos );
2881 via->SetNetCode( netCode );
2887 else if( itemName == wxT(
"contactref" ) )
2889 m_xpath->push(
"contactref" );
2892 const wxString& reference = netItem->GetAttribute(
"element" );
2893 const wxString&
pad = netItem->GetAttribute(
"pad" );
2903 else if( itemName == wxT(
"polygon" ) )
2910 zones.push_back( zone );
2912 if( !zone->GetIsRuleArea() )
2913 zone->SetNetCode( netCode );
2919 netItem = netItem->GetNext();
2922 if( zones.size() && !sawPad )
2926 for(
ZONE* zone : zones )
2936 net = net->GetNext();
2944 const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector )
2946 std::map<wxString, PCB_LAYER_ID> layer_map;
2951 layer_map.emplace( layer.Name, layerId );
2960 std::vector<INPUT_LAYER_DESC> inputDescs;
2962 for (
const std::pair<const int, ELAYER>& layerPair :
m_eagleLayers )
2964 const ELAYER& eLayer = layerPair.second;
2975 inputDescs.push_back( layerDesc );
3006 bool aIsLibraryCache )
const
3015 if( copperLayer >= 0 )
3016 copperLayers[copperLayer] =
true;
3023 bool required =
false;
3024 LSET permittedLayers;
3026 permittedLayers.
set();
3029 switch( aEagleLayer )
3127 if( aIsLibraryCache )
3135 return {
PCB_LAYER_ID( kiLayer ), permittedLayers, required };
3141 static const wxString
unknown(
"unknown" );
3149 static const int unknown = -1;
3162 if(
auto it =
m_props->find(
"page_width" ); it !=
m_props->end() )
3163 page_width = it->second;
3165 if(
auto it =
m_props->find(
"page_height" ); it !=
m_props->end() )
3166 page_height = it->second;
3168 if( !page_width.
empty() && !page_height.
empty() )
3172 int w = atoi( page_width.
c_str() );
3173 int h = atoi( page_height.
c_str() );
3175 int desired_x = ( w - bbbox.
GetWidth() ) / 2;
3176 int desired_y = ( h - bbbox.
GetHeight() ) / 2;
3187 if( aPath.IsEmpty() )
3188 return wxDateTime::Now().GetValue().GetValue();
3190 wxFileName fn( aPath );
3192 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
3193 return fn.GetModificationTime().GetValue().GetValue();
3222 string filename = (
const char*) aLibPath.char_str( wxConvFile );
3225 wxFileName fn( filename );
3226 wxFFileInputStream stream( fn.GetFullPath() );
3227 wxXmlDocument xmlDocument;
3229 if( !stream.IsOk() || !xmlDocument.Load( stream ) )
3230 THROW_IO_ERROR( wxString::Format(
_(
"Unable to read file '%s'." ), fn.GetFullPath() ) );
3232 doc = xmlDocument.GetRoot();
3234 wxXmlNode* drawing =
MapChildren( doc )[
"drawing"];
3240 m_xpath->push(
"eagle.drawing.layers" );
3241 wxXmlNode* layers = drawingChildren[
"layers"];
3246 m_xpath->push(
"eagle.drawing.library" );
3247 wxXmlNode*
library = drawingChildren[
"library"];
3281 bool aBestEfforts,
const std::map<std::string, UTF8>* aProperties )
3285 init( aProperties );
3293 errorMsg = ioe.
What();
3300 aFootprintNames.Add(
name );
3302 if( !errorMsg.IsEmpty() && !aBestEfforts )
3308 bool aKeepUUID,
const std::map<std::string, UTF8>* aProperties )
3310 init( aProperties );
3319 copy->SetParent(
nullptr );
3326 int minLayerCount = 2;
3328 std::map<wxString, PCB_LAYER_ID>::const_iterator it;
3339 if( ( ordinal + 2 ) > minLayerCount )
3340 minLayerCount = ordinal + 2;
3346 if( ( minLayerCount % 2 ) != 0 )
3349 return minLayerCount;
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
constexpr int ARC_HIGH_DEF
constexpr EDA_IU_SCALE pcbIUScale
#define DEFAULT_SILK_LINE_WIDTH
#define DEFAULT_EDGE_WIDTH
#define DEFAULT_LINE_WIDTH
#define DEFAULT_COURTYARD_WIDTH
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
BASE_SET & set(size_t pos)
virtual bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Container for design settings for a BOARD object.
std::shared_ptr< NET_SETTINGS > m_NetSettings
VECTOR2I GetTextSize(PCB_LAYER_ID aLayer) const
Return the default text size from the layer class for the given layer.
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
int m_ViasMinAnnularWidth
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
FOOTPRINT * GetParentFootprint() const
Information pertinent to a Pcbnew printed circuit board.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
constexpr coord_type GetY() const
constexpr size_type GetWidth() const
constexpr coord_type GetX() const
constexpr size_type GetHeight() 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 SetCenter(const VECTOR2I &aCenter)
SHAPE_POLY_SET & GetPolyShape()
virtual void SetFilled(bool aFlag)
void SetPolyPoints(const std::vector< VECTOR2I > &aPoints)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual void SetTextPos(const VECTOR2I &aPoint)
void SetMirrored(bool isMirrored)
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
void SetKeepUpright(bool aKeepUpright)
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
RAII class to set and restore the fontconfig reporter.
virtual bool CanReadLibrary(const wxString &aFileName) const
Checks if this IO object can read the specified library file/directory.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
virtual void RegisterCallback(LAYER_MAPPING_HANDLER aLayerMappingHandler)
Register a different handler to be called when mapping of input layers to KiCad layers occurs.
LAYER_MAPPING_HANDLER m_layer_mapping_handler
Callback to get layer mapping.
A logical library item identifier and consists of various portions much like a URI.
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
const UTF8 & GetLibItemName() const
static LOAD_INFO_REPORTER & GetInstance()
LSET is a set of PCB_LAYER_IDs.
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
A collection of nets and the parameters used to route or test these nets.
int GetViaDiameter() const
int GetTrackWidth() const
Handle the data for a net.
void SetNetClass(const std::shared_ptr< NETCLASS > &aNetClass)
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
void SetNetclassPatternAssignment(const wxString &pattern, const wxString &netclass)
Sets a netclass pattern assignment Calling this method will reset the effective netclass calculation ...
std::shared_ptr< NETCLASS > GetDefaultNetclass() const
Gets the default netclass for the project.
void SetNetclass(const wxString &netclassName, std::shared_ptr< NETCLASS > &netclass)
Sets the given netclass Calling user is responsible for resetting the effective netclass calculation ...
T & Get()
Return a reference to the value of the attribute assuming it is available.
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
void SetNumber(const wxString &aNumber)
Set the pad number (note that it can be alphanumeric, such as the array reference "AA12").
void SetLocalSolderMaskMargin(std::optional< int > aMargin)
void SetLocalZoneConnection(ZONE_CONNECTION aType)
VECTOR2I GetSize(PCB_LAYER_ID aLayer) const
void SetPosition(const VECTOR2I &aPos) override
void SetPosition(const VECTOR2I &aPos) override
void SetMid(const VECTOR2I &aMid)
virtual void SetEnd(const VECTOR2I &aPoint)
void SetUnits(EDA_UNITS aUnits)
virtual void SetStart(const VECTOR2I &aPoint)
void SetLineThickness(int aWidth)
void SetPrecision(DIM_PRECISION aPrecision)
void SetOverrideText(const wxString &aValue)
For better understanding of the points that make a dimension:
void SetHeight(int aHeight)
Set the distance from the feature points to the crossbar line.
A leader is a dimension-like object pointing to a specific point.
A radial dimension indicates either the radius or diameter of an arc or circle.
std::vector< ELAYER > ELAYERS
void packageSMD(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
Handles common pad properties.
void loadPlain(wxXmlNode *aPlain)
int m_min_trace
smallest trace we find on Load(), in BIU.
std::map< wxString, PCB_LAYER_ID > m_layer_map
Map of Eagle layers to KiCad layers.
void orientFPText(FOOTPRINT *aFootprint, const EELEMENT &e, PCB_TEXT *aFPText, const EATTR *aAttr)
VECTOR2I kicad_fontsize(const ECOORD &d, int aTextThickness) const
create a font size (fontz) from an eagle font size scalar and KiCad font thickness
std::map< wxString, PCB_LAYER_ID > DefaultLayerMappingCallback(const std::vector< INPUT_LAYER_DESC > &aInputLayerDescriptionVector)
Return the automapped layers.
bool checkHeader(const wxString &aFileName) const
void loadElements(wxXmlNode *aElements)
FOOTPRINT * makeFootprint(wxXmlNode *aPackage, const wxString &aPkgName)
Create a FOOTPRINT from an Eagle package.
int m_min_hole
smallest diameter hole we find on Load(), in BIU.
std::vector< FOOTPRINT * > GetImportedCachedLibraryFootprints() override
Return a container with the cached library footprints generated in the last call to Load.
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
unsigned m_totalCount
for progress reporting
void cacheLib(const wxString &aLibraryPath)
This PLUGIN only caches one footprint library, this determines which one.
int m_hole_count
generates unique footprint names from eagle "hole"s.
std::map< wxString, FOOTPRINT * > m_templates
is part of a FOOTPRINT factory that operates using copy construction.
std::map< wxString, int > m_eagleLayersIds
Eagle layer ids stored by layer name.
void mapEagleLayersToKicad(bool aIsLibraryCache=false)
Generate mapping between Eagle and KiCad layers.
std::map< wxString, std::shared_ptr< NETCLASS > > m_classMap
std::tuple< PCB_LAYER_ID, LSET, bool > defaultKicadLayer(int aEagleLayer, bool aIsLibraryCache=false) const
Get the default KiCad layer corresponding to an Eagle layer of the board, a set of sensible layer map...
BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr) override
Load information from some input file format that this PCB_IO implementation knows about into either ...
void loadLibraries(wxXmlNode *aLibs)
void init(const std::map< std::string, UTF8 > *aProperties)
initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
FOOTPRINT * FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PC...
int eagle_layer_id(const wxString &aLayerName) const
Get Eagle layer number by its name.
void loadAllSections(wxXmlNode *aDocument)
bool CanReadFootprint(const wxString &aFileName) const override
Checks if this PCB_IO can read a footprint from specified file or directory.
void packageWire(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
bool CanReadBoard(const wxString &aFileName) const override
Checks if this PCB_IO can read the specified board file.
const wxString & eagle_layer_name(int aLayer) const
Get Eagle layer name by its number.
ELAYERS::const_iterator EITER
void packageRectangle(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
void loadClasses(wxXmlNode *aClasses)
std::map< int, ELAYER > m_eagleLayers
Eagle layer data stored by layer number.
NET_MAP m_pads_to_nets
net list
void packageText(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
int getMinimumCopperLayerCount() const
Determines the minimum copper layer stackup count that includes all mapped layers.
void packageHole(FOOTPRINT *aFootprint, wxXmlNode *aTree, bool aCenter) const
void packagePolygon(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
void centerBoard()
move the BOARD into the center of the page
unsigned m_lastProgressCount
int m_cu_map[17]
map eagle to KiCad, cu layers only.
ZONE * loadPolygon(wxXmlNode *aPolyNode)
Load a copper or keepout polygon and adds it to the board.
int m_min_via
smallest via we find on Load(), in BIU.
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this IO object can read the specified library file/directory.
void packageCircle(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
void loadLibrary(wxXmlNode *aLib, const wxString *aLibName)
Load the Eagle "library" XML element, which can occur either under a "libraries" element (if a *....
void packagePad(FOOTPRINT *aFootprint, wxXmlNode *aTree)
void loadSignals(wxXmlNode *aSignals)
ERULES * m_rules
Eagle design rules.
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
void orientFootprintAndText(FOOTPRINT *aFootprint, const EELEMENT &e, const EATTR *aNameAttr, const EATTR *aValueAttr)
long long GetLibraryTimestamp(const wxString &aLibraryPath) const override
Generate a timestamp representing all the files in the library (including the library directory).
int m_min_annulus
smallest via annulus we find on Load(), in BIU.
void loadLayerDefs(wxXmlNode *aLayers)
void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aLibraryPath, bool aBestEfforts, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Return a list of footprint names contained within the library at aLibraryPath.
void setKeepoutSettingsToZone(ZONE *aZone, int aLayer) const
void transferPad(const EPAD_COMMON &aEaglePad, PAD *aPad) const
Deletes the footprint templates list.
int kicad_x(const ECOORD &x) const
void loadDesignRules(wxXmlNode *aDesignRules)
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
BOARD * m_board
The board BOARD being worked on, no ownership here.
virtual bool CanReadBoard(const wxString &aFileName) const
Checks if this PCB_IO can read the specified board file.
PCB_IO(const wxString &aName)
const std::map< std::string, UTF8 > * m_props
Properties passed via Save() or Load(), no ownership, may be NULL.
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
void SetShape(SHAPE_T aShape) override
void SetEnd(const VECTOR2I &aEnd) override
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void Move(const VECTOR2I &aMoveVector) override
Move this object.
void SetStart(const VECTOR2I &aStart) override
void SetStroke(const STROKE_PARAMS &aStroke) override
void SetTextThickness(int aWidth) override
The TextThickness is that set by the user.
EDA_ANGLE GetTextAngle() const override
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true) override
virtual void SetPosition(const VECTOR2I &aPos) override
void SetTextAngle(const EDA_ANGLE &aAngle) override
VECTOR2I GetTextSize() const override
void SetEnd(const VECTOR2I &aEnd)
void SetPosition(const VECTOR2I &aPos) override
virtual void SetWidth(int aWidth)
Container for project specific data.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
Represent a set of closed polygons.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
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)
int NewOutline()
Creates a new empty polygon in the set and returns its index.
int OutlineCount() const
Return the number of outlines in the set.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
Simple container to manage line stroke parameters.
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
const char * c_str() const
double Distance(const VECTOR2< extended_type > &aVector) const
Compute the distance between two vectors.
Keep track of what we are working on within a PTREE.
Handle a list of polygons defining a copper zone.
void SetDoNotAllowPads(bool aEnable)
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aBorderHatchStyle, int aBorderHatchPitch, bool aRebuilBorderdHatch)
Set all hatch parameters for the zone.
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
SHAPE_POLY_SET * Outline()
void NewHole()
Create a new hole on the zone; i.e., a new contour on the zone's outline.
bool SetNetCode(int aNetCode, bool aNoAssert) override
Override that clamps the netcode to 0 when this zone is in copper-thieving fill mode.
void SetIsRuleArea(bool aEnable)
void SetDoNotAllowTracks(bool aEnable)
void Rotate(const VECTOR2I &aCentre, const EDA_ANGLE &aAngle) override
Rotate the outlines.
void SetLayerSet(const LSET &aLayerSet) override
void SetDoNotAllowVias(bool aEnable)
void SetDoNotAllowFootprints(bool aEnable)
bool AppendCorner(VECTOR2I aPosition, int aHoleIdx, bool aAllowDuplication=false)
Add a new corner to the zone outline (to the main outline or a hole)
void SetDoNotAllowZoneFills(bool aEnable)
static int GetDefaultHatchPitch()
@ ALLOW_ACUTE_CORNERS
just inflate the polygon. Acute angles create spikes
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Provide an easy access to the children of an XML node via their names.
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.
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< wxString > opt_wxString
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE FULL_CIRCLE
static constexpr EDA_ANGLE ANGLE_360
#define IGNORE_PARENT_GROUP
a few functions useful in geometry calculations.
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
PCB_LAYER_ID BoardLayerFromLegacyId(int aLegacyId)
Retrieve a layer ID from an integer converted from a legacy (pre-V9) enum value.
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
size_t CopperLayerToOrdinal(PCB_LAYER_ID aLayer)
Converts KiCad copper layer enum to an ordinal between the front and back layers.
PCB_LAYER_ID
A quick note on layer IDs:
@ TOP_BOTTOM
Flip top to bottom (around the X axis)
KICOMMON_API wxString StringFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Return the string from aValue according to aUnits (inch, mm ...) for display.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
@ SMD
Smd pad, appears on the solder paste layer (default)
static wxString makeKey(const wxString &aFirst, const wxString &aSecond)
Assemble a two part key as a simple concatenation of aFirst and aSecond parts, using a separator.
#define DIMENSION_PRECISION
std::tuple< GR_TEXT_V_ALIGN_T, GR_TEXT_H_ALIGN_T > KiCadAlignmentFromEagle(int aAlign)
int EagleAlignmentFromKiCad(std::tuple< GR_TEXT_V_ALIGN_T, GR_TEXT_H_ALIGN_T > aAlign)
static int parseEagle(const wxString &aDistance)
Parse an eagle distance which is either mm, or mils if there is "mil" suffix.
static T eagleClamp(T aMin, T aValue, T aMax)
void EaglePcbTextToKiCadAlignment(EDA_TEXT *aTxt, int aAlign, double aDegrees, bool aMirror, bool aSpin)
std::vector< ZONE * > ZONES
NET_MAP::const_iterator NET_MAP_CITER
bool ReplaceIllegalFileNameChars(std::string &aName, int aReplaceChar)
Checks aName for illegal file name characters.
wxString UnescapeHTML(const wxString &aString)
Return a new wxString unescaped from HTML format.
Parse an Eagle "attribute" XML element.
std::map< wxString, ECOORD > clearanceMap
long long int value
Value expressed in nanometers.
opt_wxString dimensionType
Structure holding common properties for through-hole and SMD pads.
Eagle polygon, without vertices which are parsed as needed.
static const int max_priority
Eagle XML rectangle in binary.
subset of eagle.drawing.board.designrules in the XML document
int psBottom
Shape of the bottom pads.
double mvStopFrame
solderpaste mask, expressed as percentage of the smaller pad/via dimension
double srRoundness
corner rounding ratio for SMD pads (percentage)
double rlMinViaOuter
minimum copper annulus on via
int mlMaxCreamFrame
solder paste mask, maximum size (Eagle mils, here nanometers)
int mlMinCreamFrame
solder paste mask, minimum size (Eagle mils, here nanometers)
int psTop
Shape of the top pads.
double rlMaxViaOuter
maximum copper annulus on via
void parse(wxXmlNode *aRules, std::function< void()> aCheckpoint)
percent over 100%.
double mdWireWire
wire to wire spacing I presume.
double rvPadTop
top pad size as percent of drill size
double rvViaOuter
copper annulus is this percent of via hole
double rlMinPadTop
minimum copper annulus on through hole pads
int psElongationOffset
the offset of the hole within the "long" pad.
int mlMinStopFrame
solder mask, minimum size (Eagle mils, here nanometers)
int srMinRoundness
corner rounding radius, maximum size (Eagle mils, here nanometers)
int mlMaxStopFrame
solder mask, maximum size (Eagle mils, here nanometers)
double rlMaxPadTop
maximum copper annulus on through hole pads
int psFirst
Shape of the first pads.
Container that parses Eagle library file "urn" definitions.
bool IsValid() const
Check if the string passed to the ctor was a valid Eagle urn.
void Parse(const wxString &aUrn)
wxString assetId
The unique asset identifier for the asset type.
int layer_back_most
< extent
opt_double curve
range is -359.9..359.9
Implement a simple wrapper around runtime_error to isolate the errors thrown by the Eagle XML parser.
wxString result
Test unit parsing edge cases and error handling.
GR_TEXT_H_ALIGN_T
This is API surface mapped to common.types.HorizontalAlignment.
@ GR_TEXT_H_ALIGN_INDETERMINATE
GR_TEXT_V_ALIGN_T
This is API surface mapped to common.types.VertialAlignment.
@ GR_TEXT_V_ALIGN_INDETERMINATE
const VECTOR2I CalcArcMid(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aMinArcAngle=true)
Return the middle point of an arc, half-way between 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.
double DEG2RAD(double deg)
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
constexpr int sign(T val)
VECTOR2< int32_t > VECTOR2I
ZONE_BORDER_DISPLAY_STYLE
Zone border styles.
@ THERMAL
Use thermal relief for pads.
@ FULL
pads are covered by copper
#define ZONE_THICKNESS_MIN_VALUE_MM