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(
"rlMinPadInner" ) )
210 else if(
name == wxT(
"rlMaxPadInner" ) )
212 else if(
name == wxT(
"rlMinPadBottom" ) )
214 else if(
name == wxT(
"rlMaxPadBottom" ) )
216 else if(
name == wxT(
"rvViaOuter" ) )
218 else if(
name == wxT(
"rlMinViaOuter" ) )
220 else if(
name == wxT(
"rlMaxViaOuter" ) )
222 else if(
name == wxT(
"mdWireWire" ) )
226 child = child->GetNext();
239 m_timestamp( wxDateTime::Now().GetValue().GetValue() )
241 using namespace std::placeholders;
283 wxFileInputStream input( aFileName );
292 wxTextInputStream
text( input );
294 for(
int i = 0; i < 8; i++ )
299 if(
text.ReadLine().Contains( wxS(
"<eagle" ) ) )
309 const unsigned PROGRESS_DELTA = 50;
330 return VECTOR2I( kz - aTextThickness, kz - aTextThickness );
335 const std::map<std::string, UTF8>* aProperties,
PROJECT* aProject )
356 wxFileName fn = aFileName;
359 wxFFileInputStream stream( fn.GetFullPath() );
367 wxXmlDocument xmlDocument;
368 std::unique_ptr<wxXmlDocument> binDocument;
374 std::vector<uint8_t> bytes;
375 bytes.resize(
static_cast<size_t>( stream.GetLength() ) );
376 stream.Read( bytes.data(), bytes.size() );
378 if( stream.LastRead() != bytes.size() )
382 binDocument = binParser.
Parse( bytes );
383 doc = binDocument->GetRoot();
387 if( !xmlDocument.Load( stream ) )
390 doc = xmlDocument.GetRoot();
417 NETCLASS defaults( wxT(
"dummy" ) );
419 auto finishNetclass =
420 [&](
const std::shared_ptr<NETCLASS>& netclass )
424 if( !netclass->HasClearance() )
429 if( netclass->GetTrackWidth() == INT_MAX )
432 if( netclass->GetViaDiameter() == INT_MAX )
435 if( netclass->GetViaDrill() == INT_MAX )
439 std::shared_ptr<NET_SETTINGS>& netSettings = bds.
m_NetSettings;
441 finishNetclass( netSettings->GetDefaultNetclass() );
443 for(
const auto& [
name, netclass] : netSettings->GetNetclasses() )
444 finishNetclass( netclass );
446 m_board->m_LegacyNetclassesLoaded =
true;
447 m_board->m_LegacyDesignSettingsLoaded =
true;
453 fn.SetExt( wxT(
"kicad_dru" ) );
455 wxFile rulesFile( fn.GetFullPath(), wxFile::write );
460 wxASSERT(
m_xpath->Contents().size() == 0 );
471 LSET enabledLayers =
m_board->GetDesignSettings().GetEnabledLayers();
473 for(
const auto& [eagleLayerName, layer] :
m_layer_map )
476 enabledLayers.
set( layer );
479 m_board->GetDesignSettings().SetEnabledLayers( enabledLayers );
487 std::vector<FOOTPRINT*> retval;
490 retval.push_back(
static_cast<FOOTPRINT*
>( footprint->Clone() ) );
526 wxXmlNode* drawing =
MapChildren( aDoc )[
"drawing"];
529 wxXmlNode* board = drawingChildren[
"board"];
532 auto count_children =
533 [
this]( wxXmlNode* aNode )
537 wxXmlNode* child = aNode->GetChildren();
542 child = child->GetNext();
547 wxXmlNode* designrules = boardChildren[
"designrules"];
548 wxXmlNode* layers = drawingChildren[
"layers"];
549 wxXmlNode* plain = boardChildren[
"plain"];
550 wxXmlNode* classes = boardChildren[
"classes"];
551 wxXmlNode* signals = boardChildren[
"signals"];
552 wxXmlNode* libs = boardChildren[
"libraries"];
553 wxXmlNode* elems = boardChildren[
"elements"];
560 count_children( designrules );
561 count_children( layers );
562 count_children( plain );
563 count_children( signals );
564 count_children( elems );
569 libs = libs->GetNext();
573 libs = boardChildren[
"libraries"];
576 m_xpath->push(
"eagle.drawing" );
615 m_xpath->push(
"designrules" );
634 wxXmlNode* layerNode = aLayers->GetChildren();
641 ELAYER elayer( layerNode );
647 cu.push_back( elayer );
649 layerNode = layerNode->GetNext();
653 int ki_layer_count = 0;
655 for(
EITER it = cu.begin(); it != cu.end(); ++it, ++ki_layer_count )
657 if( ki_layer_count == 0 )
661 else if( ki_layer_count ==
int( cu.size()-1 ) )
675 m_board->SetCopperLayerCount( cu.size() );
677 for(
EITER it = cu.begin(); it != cu.end(); ++it )
684 m_board->SetLayerName( layer, it->name );
694#define DIMENSION_PRECISION DIM_PRECISION::X_XX
699 std::map<int, std::tuple<GR_TEXT_V_ALIGN_T, GR_TEXT_H_ALIGN_T>> alignmentmap{
710 return alignmentmap[aAlign];
716 std::map<std::tuple<GR_TEXT_V_ALIGN_T, GR_TEXT_H_ALIGN_T>,
int> alignmentmap{
727 return alignmentmap[aAlign];
732 double aElementDegrees = 0.0,
bool aElementMirror =
false,
733 bool aElementSpin =
false )
737 int align{ aTxtAlign };
739 bool spin = aTxtSpin != aElementSpin;
740 bool mirror = aTxtMirror != aElementMirror;
743 double degrees = ( aTxtMirror ? -1.0 : 1.0 ) * textDefDegrees + elementDegrees;
748 if( ( !aTxtMirror && degrees > 90 && degrees <= 270 ) || ( aTxtMirror && degrees >= 90 && degrees < 270 ) )
751 degrees = degrees - 180;
776 wxXmlNode* gr = aGraphics->GetChildren();
783 wxString grName = gr->GetName();
785 if( grName == wxT(
"wire" ) )
802 width =
m_board->GetDesignSettings().GetLineThickness( layer );
806 if( w.
curve.has_value() )
829 else if( grName == wxT(
"text" ) )
845 double ratio = t.
ratio.value_or( 8 );
855 double degrees = t.
rot.has_value() ? t.
rot.value().degrees : 0.0;
856 bool mirror = t.
rot.has_value() ? t.
rot.value().mirror :
false;
857 bool spin = t.
rot.has_value() ? t.
rot.value().spin :
false;
864 else if( grName == wxT(
"circle" ) )
883 int outlineRadius =
radius + ( width / 2 );
889 VECTOR2I rotatedPoint( outlineRadius, 0 );
897 int innerRadius =
radius - ( width / 2 );
903 VECTOR2I rotatedPoint( innerRadius, 0 );
930 else if( grName == wxT(
"rectangle" ) )
963 const int outlineIdx = -1;
969 if( r.
rot.has_value() )
982 else if( grName == wxT(
"hole" ) )
992 footprint->
SetReference( wxString::Format( wxT(
"UNK_HOLE_%d" ), hole_count ) );
995 LIB_ID fpid( wxEmptyString, wxString::Format( wxT(
"dummyfp%d" ), hole_count ) );
1002 else if( grName == wxT(
"frame" ) )
1006 else if( grName == wxT(
"polygon" ) )
1012 else if( grName == wxT(
"dimension" ) )
1027 textThickness =
KiROUND( d.
textsize.value().ToPcbUnits() * ratio / 100.0 );
1033 if( d.
dimensionType.value_or( wxEmptyString ) == wxT(
"angle" ) )
1037 else if( d.
dimensionType.value_or( wxEmptyString ) == wxT(
"radius" ) )
1046 dimension->
SetEnd( pt2 );
1053 else if( d.
dimensionType.value_or( wxEmptyString ) == wxT(
"leader" ) )
1077 if( d.
dimensionType.value_or( wxEmptyString ) == wxT(
"horizontal" ) )
1079 int newY = ( pt1.
y + pt2.
y ) / 2;
1083 else if( d.
dimensionType.value_or( wxEmptyString ) == wxT(
"vertical" ) )
1085 int newX = ( pt1.
x + pt2.
x ) / 2;
1095 dimension->
SetEnd( pt2 );
1105 if(
abs( pt1.
x - pt2.
x ) < 50000 )
1107 int offset = pt3.
x - pt1.
x;
1114 else if(
abs( pt1.
y - pt2.
y ) < 50000 )
1116 int offset = pt3.
y - pt1.
y;
1149 wxString urn = aLib->GetAttribute(
"urn" );
1158 if( !urn.IsEmpty() )
1159 libraryUrn.
Parse( urn );
1162 wxXmlNode* packages =
MapChildren( aLib )[
"packages"];
1181 libKey += wxS(
"_" ) + libraryUrn.
assetId;
1189 wxXmlNode*
package = packages->GetChildren();
1195 m_xpath->push(
"package",
"name" );
1197 wxString pack_ref = package->GetAttribute(
"name" );
1201 m_xpath->Value( pack_ref.ToUTF8() );
1203 wxString key = aLibName ?
makeKey( libKey, pack_ref ) : pack_ref;
1208 auto r =
m_templates.insert( { key, footprint } );
1219 package = package->GetNext();
1231 m_xpath->push(
"libraries.library",
"name" );
1234 wxXmlNode*
library = aLibs->GetChildren();
1238 const wxString& lib_name =
library->GetAttribute(
"name" );
1240 m_xpath->Value( lib_name.c_str() );
1254 m_xpath->push(
"elements.element",
"name" );
1258 bool refanceNamePresetInPackageLayout;
1259 bool valueNamePresetInPackageLayout;
1262 wxXmlNode* element = aElements->GetChildren();
1268 if( element->GetName() != wxT(
"element" ) )
1271 element = element->GetNext();
1278 EATTR* nameAttr =
nullptr;
1279 EATTR* valueAttr =
nullptr;
1289 libKey += wxS(
"_" ) + e.
library_urn.value().assetId;
1309 const ENET* enet = &ni->second;
1314 refanceNamePresetInPackageLayout =
true;
1315 valueNamePresetInPackageLayout =
true;
1322 refanceNamePresetInPackageLayout =
false;
1326 if( footprint->
GetValue().size() == 0 )
1329 valueNamePresetInPackageLayout =
false;
1332 wxString reference = e.
name;
1338 if( reference.find_first_not_of(
"0123456789" ) != 0 )
1339 reference.Prepend(
"UNK" );
1343 if( reference.find_first_not_of(
"#" ) != 0 )
1344 reference.Prepend(
"UNK" );
1347 if( reference.find_last_not_of(
"0123456789" ) == (reference.Length()-1) )
1348 reference.Append(
"0" );
1356 if( valueNamePresetInPackageLayout )
1359 if( refanceNamePresetInPackageLayout )
1362 else if( e.
smashed.value() ==
true )
1369 m_xpath->push(
"attribute",
"name" );
1379 wxXmlNode* attribute = element->GetChildren();
1383 if( attribute->GetName() != wxT(
"attribute" ) )
1385 attribute = attribute->GetNext();
1389 EATTR a( attribute );
1391 if( a.
name == wxT(
"NAME" ) )
1404 nameAttr->
name = reference;
1406 if( refanceNamePresetInPackageLayout )
1413 if( refanceNamePresetInPackageLayout )
1422 if( refanceNamePresetInPackageLayout )
1425 nameAttr->
name = nameAttr->
name + wxT(
" = " ) + e.
name;
1436 if( refanceNamePresetInPackageLayout )
1446 else if( a.
name == wxT(
"VALUE" ) )
1460 if( valueNamePresetInPackageLayout )
1466 if( valueNamePresetInPackageLayout )
1469 footprint->
SetValue( wxT(
"VALUE" ) );
1473 if( valueNamePresetInPackageLayout )
1476 valueAttr->
value = wxT(
"VALUE = " ) + e.
value;
1487 if( valueNamePresetInPackageLayout )
1499 attribute = attribute->GetNext();
1509 element = element->GetNext();
1529 Report( wxString::Format(
_(
"Ignoring a polygon since Eagle layer '%s' (%d) was not mapped" ),
1536 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board );
1539 zone->SetLayer( layer );
1544 wxXmlNode* vertex = aPolyNode->GetChildren();
1545 std::vector<EVERTEX> vertices;
1553 if( vertex->GetName() == wxT(
"vertex" ) )
1554 vertices.emplace_back( vertex );
1556 vertex = vertex->GetNext();
1561 if( p.
orphans.value_or(
false ) )
1566 if( vertices.size() < 3 )
1568 Report( wxString::Format(
_(
"Skipping a polygon on layer '%s' (%d): less than 3 vertices" ),
1575 vertices.push_back( vertices[0] );
1580 for(
size_t i = 0; i < vertices.size() - 1; i++ )
1587 if(
v1.curve.has_value() )
1592 double angle =
DEG2RAD(
v1.curve.value() );
1598 double delta_angle = angle / segCount;
1600 for(
double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta_angle ); a -= delta_angle )
1615 Report( wxString::Format(
_(
"Skipping a polygon on layer '%s' (%d): outline count is not 1" ),
1623 zone->AddPolygon( polygon.
COutline( 0 ) );
1628 zone->SetIsRuleArea(
true );
1629 zone->SetDoNotAllowVias(
false );
1630 zone->SetDoNotAllowTracks(
false );
1631 zone->SetDoNotAllowPads(
false );
1632 zone->SetDoNotAllowFootprints(
false );
1633 zone->SetDoNotAllowZoneFills(
true );
1643 zone->SetHatchOrientation(
ANGLE_0 );
1652 zone->SetLocalClearance( p.
isolate.value().ToPcbUnits() );
1654 zone->SetLocalClearance( 1 );
1657 bool thermals = p.
thermals.value_or(
true );
1671 zone->SetAssignedPriority( rank );
1673 ZONE* zonePtr = zone.release();
1681 const EATTR* aNameAttr,
const EATTR* aValueAttr )
1683 std::vector<std::tuple<PCB_FIELD*, double, bool, bool, const EATTR*>> textRotDefs{};
1685 std::vector<PCB_FIELD*> fields{};
1690 double defDegrees = field->GetLibTextAngle().AsDegrees();
1691 bool defMirror = field->IsMirrored();
1692 bool defSpin = !field->IsKeepUpright();
1693 const EATTR* attr =
nullptr;
1697 else if( field == &aFootprint->
Value() )
1700 textRotDefs.push_back( std::tuple<PCB_FIELD*, double, bool, bool, const EATTR*>( field, defDegrees, defMirror,
1704 if( e.
rot.has_value() )
1706 if( e.
rot.value().mirror )
1717 for(
auto textRotDef : textRotDefs )
1720 double defDegrees{};
1723 const EATTR* attr{};
1724 std::tie( field, defDegrees, defMirror, defSpin, attr ) = textRotDef;
1725 orientFPText( aFootprint, e, field, attr, defDegrees, defMirror, defSpin );
1731 double aTextDefAngle,
bool aTextDefMirror,
bool aTextDefSpin )
1737 const EATTR& a = *aAttr;
1739 if( a.
value.has_value() )
1742 if( a.
x.has_value() && a.
y.has_value() )
1750 double ratio = a.
ratio.value_or( 8 );
1752 int textThickness =
KiROUND( fontSize.
y * ratio / 100.0 );
1756 if( a.
size.has_value() )
1768 double degrees = a.
rot.has_value() ? a.
rot.value().degrees : 0.0;
1769 bool mirror = a.
rot.has_value() ? a.
rot.value().mirror :
false;
1770 bool spin = a.
rot.has_value() ? a.
rot.value().spin :
false;
1781 double elementAngle = e.
rot.has_value() ? e.
rot.value().degrees : 0.0;
1782 bool elementMirror = e.
rot.has_value() ? e.
rot.value().mirror :
false;
1783 bool elementSpin = e.
rot.has_value() ? e.
rot.value().spin :
false;
1789 elementMirror, elementSpin );
1806 int adjustedPadDiameter = 0.0;
1813 if( ( padstack.
Size(
F_Cu ).
x < adjustedPadDiameter ) )
1823 adjustedPadDiameter = padstack.
Drill().
size.
x + (
m_rules->rlMinPadBottom * 2 );
1825 if( padstack.
Size(
B_Cu ).
x < adjustedPadDiameter )
1829 if(
m_rules->rlMinPadInner != 0.0 )
1835 if( !padstack.
LayerSet().test( layerId ) )
1840 if( padstack.
Size( layerId ).
x < adjustedPadDiameter )
1841 padstack.
SetSize(
VECTOR2I( adjustedPadDiameter, adjustedPadDiameter ), layerId );
1851 std::unique_ptr<FOOTPRINT> m = std::make_unique<FOOTPRINT>(
m_board );
1854 fpID.
Parse( aPkgName,
true );
1858 wxXmlNode* packageItem = aPackage->GetChildren();
1863 m.get()->Value().SetLayer( layer );
1865 while( packageItem )
1867 const wxString& itemName = packageItem->GetName();
1869 if( itemName == wxT(
"description" ) )
1872 m->SetLibDescription( descr );
1874 else if( itemName == wxT(
"wire" ) )
1876 else if( itemName == wxT(
"pad" ) )
1878 else if( itemName == wxT(
"text" ) )
1880 else if( itemName == wxT(
"rectangle" ) )
1882 else if( itemName == wxT(
"polygon" ) )
1884 else if( itemName == wxT(
"circle" ) )
1886 else if( itemName == wxT(
"hole" ) )
1888 else if( itemName == wxT(
"smd" ) )
1891 packageItem = packageItem->GetNext();
1908 Report( wxString::Format(
_(
"Ignoring a wire since Eagle layer '%s' (%d) was not mapped" ),
1945 if( w.
curve.has_value() )
1967 aFootprint->
Add( dwg );
1976 int drillSize = e.
drill.has_value() ? e.
drill.value().ToPcbUnits() : 0;
1978 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
1988 pad->SetDrillSize(
VECTOR2I( drillSize, drillSize ) );
1991 if( drillSize > 0 && drillSize <
m_min_hole )
1995 if( e.
stop.value_or(
true ) )
2001 if( e.
shape.has_value() )
2003 switch( e.
shape.value() )
2035 int diameter = e.
diameter.value().ToPcbUnits();
2040 double drillz =
pad->GetDrillSize().x;
2041 double annulus = drillz *
m_rules->rvPadTop;
2043 int diameter =
KiROUND( drillz + 2 * annulus );
2051 sz.
x = ( sz.
x * ( 100 +
m_rules->psElongationLong ) ) / 100;
2056 int offset =
KiROUND( ( sz.
x - sz.
y ) / 2.0 );
2061 if( e.
rot.has_value() )
2067 if(
pad->GetSizeX() > 0 &&
pad->GetSizeY() > 0 &&
pad->HasHole() )
2069 aFootprint->
Add(
pad.release() );
2076 Report( wxString::Format(
_(
"Invalid zero-sized pad ignored in\nfile: %s" ),
2079 Report( wxString::Format(
_(
"Invalid zero-sized pad ignored in\nfile: %s" ),
2092 Report( wxString::Format(
_(
"Ignoring a text since Eagle layer '%s' (%d) was not mapped" ),
2100 if( t.
text.Upper() == wxT(
">NAME" ) && aFootprint->
GetReference().IsEmpty() )
2104 textItem->
SetText( wxT(
"REF**" ) );
2106 else if( t.
text.Upper() == wxT(
">VALUE" ) && aFootprint->
GetValue().IsEmpty() )
2108 textItem = &aFootprint->
Value();
2114 textItem =
new PCB_TEXT( aFootprint );
2115 aFootprint->
Add( textItem );
2125 double ratio = t.
ratio.value_or( 8 );
2136 double degrees = t.
rot.has_value() ? t.
rot.value().degrees : 0.0;
2137 bool mirror = t.
rot.has_value() ? t.
rot.value().mirror :
false;
2138 bool spin = t.
rot.has_value() ? t.
rot.value().spin :
false;
2164 ZONE* zone =
new ZONE( aFootprint );
2169 const int outlineIdx = -1;
2175 if( r.
rot.has_value() )
2191 Report( wxString::Format(
_(
"Ignoring a rectangle since Eagle layer '%s' (%d) was not mapped" ),
2199 aFootprint->
Add( dwg );
2205 std::vector<VECTOR2I> pts;
2210 pts.push_back( start );
2213 pts.push_back(
end );
2217 if( r.
rot.has_value() )
2230 std::vector<VECTOR2I> pts;
2233 wxXmlNode* vertex = aTree->GetChildren();
2234 std::vector<EVERTEX> vertices;
2242 if( vertex->GetName() == wxT(
"vertex" ) )
2243 vertices.emplace_back( vertex );
2245 vertex = vertex->GetNext();
2251 if( vertices.size() < 3 )
2253 Report( wxString::Format(
_(
"Skipping a polygon on layer '%s' (%d): less than 3 vertices" ),
2260 vertices.push_back( vertices[0] );
2262 for(
size_t i = 0; i < vertices.size() - 1; i++ )
2269 if(
v1.curve.has_value() )
2274 double angle =
DEG2RAD(
v1.curve.value() );
2284 double delta = angle / segCount;
2286 for(
double a = end_angle + angle; fabs( a - end_angle ) > fabs(
delta ); a -=
delta )
2301 ZONE* zone =
new ZONE( aFootprint );
2317 Report( wxString::Format(
_(
"Ignoring a polygon since Eagle layer '%s' (%d) was not mapped" ),
2325 aFootprint->
Add( dwg );
2351 ZONE* zone =
new ZONE( aFootprint );
2358 int outlineRadius =
radius + ( width / 2 );
2364 VECTOR2I rotatedPoint( outlineRadius, 0 );
2372 int innerRadius =
radius - ( width / 2 );
2378 VECTOR2I rotatedPoint( innerRadius, 0 );
2393 Report( wxString::Format(
_(
"Ignoring a circle since Eagle layer '%s' (%d) was not mapped" ),
2409 aFootprint->
Add( gr );
2412 switch( (
int) layer )
2454 pad->SetPosition( padpos );
2463 pad->SetDrillSize( sz );
2487 pad->SetLayer( layer );
2493 pad->SetLayerSet( front );
2494 else if( layer ==
B_Cu )
2495 pad->SetLayerSet( back );
2497 int minPadSize = std::min( padSize.
x, padSize.
y );
2501 (
int) ( minPadSize *
m_rules->srRoundness ),
2502 m_rules->srMaxRoundness * 2 );
2504 if( e.
roundness.has_value() || roundRadius > 0 )
2506 double roundRatio = (double) roundRadius / minPadSize / 2.0;
2510 roundRatio = std::fmax( e.
roundness.value() / 200.0, roundRatio );
2516 if( e.
rot.has_value() )
2523 (
int) (
m_rules->mvCreamFrame * minPadSize ),
2527 if( e.
stop.has_value() && e.
stop.value() ==
false )
2530 pad->SetLayerSet(
pad->GetLayerSet().set(
F_Mask,
false ) );
2531 else if( layer ==
B_Cu )
2532 pad->SetLayerSet(
pad->GetLayerSet().set(
B_Mask,
false ) );
2536 if( e.
cream.has_value() && e.
cream.value() ==
false )
2539 pad->SetLayerSet(
pad->GetLayerSet().set(
F_Paste,
false ) );
2540 else if( layer ==
B_Cu )
2541 pad->SetLayerSet(
pad->GetLayerSet().set(
B_Paste,
false ) );
2556 (
int) (
m_rules->mvStopFrame * std::min( padSize.
x, padSize.
y ) ),
2560 if( aEaglePad.
thermals.has_value() && aEaglePad.
thermals.value() ==
false )
2564 wxCHECK( footprint, );
2574 footprint->SetParent(
nullptr );
2590 m_xpath->push(
"classes.class",
"number" );
2592 std::vector<ECLASS> eClasses;
2593 wxXmlNode* classNode = aClasses->GetChildren();
2599 ECLASS eClass( classNode );
2600 std::shared_ptr<NETCLASS> netclass;
2602 if( eClass.
name.CmpNoCase( wxT(
"default" ) ) == 0 )
2612 netclass->SetTrackWidth( INT_MAX );
2613 netclass->SetViaDiameter( INT_MAX );
2614 netclass->SetViaDrill( INT_MAX );
2616 eClasses.emplace_back( eClass );
2620 auto clearanceToDefaultIt = eClass.
clearanceMap.find( wxT(
"0" ) );
2622 if( clearanceToDefaultIt != eClass.
clearanceMap.end() )
2624 netclass->SetClearance( clearanceToDefaultIt->second.ToPcbUnits() );
2628 classNode = classNode->GetNext();
2633 for(
ECLASS& eClass : eClasses )
2635 for(
const auto& [className, pt] : eClass.clearanceMap )
2638 if( className == wxT(
"0" ) )
2644 rule.Printf( wxT(
"(rule \"class %s:%s\"\n"
2645 " (condition \"A.NetClass == '%s' && B.NetClass == '%s'\")\n"
2646 " (constraint clearance (min %smm)))\n" ),
2675 std::set<wxString> usedNetNames;
2677 for( wxXmlNode* signal = aSignals->GetChildren(); signal; signal = signal->GetNext() )
2679 wxString explicitName =
escapeName( signal->GetAttribute(
"name" ) );
2681 if( !explicitName.IsEmpty() )
2682 usedNetNames.insert( explicitName );
2685 m_xpath->push(
"signals.signal",
"name" );
2688 wxXmlNode* net = aSignals->GetChildren();
2694 wxString netName =
escapeName( net->GetAttribute(
"name" ) );
2701 if( netName.IsEmpty() )
2703 int candidate = netCode;
2707 netName = wxString::Format( wxT(
"N$%d" ), candidate++ );
2708 }
while( usedNetNames.count( netName ) );
2710 usedNetNames.insert( netName );
2714 std::shared_ptr<NETCLASS> netclass;
2716 if( net->HasAttribute(
"class" ) )
2718 auto netclassIt =
m_classMap.find( net->GetAttribute(
"class" ) );
2724 netclass = netclassIt->second;
2735 m_xpath->Value( netName.c_str() );
2738 wxXmlNode* netItem = net->GetChildren();
2743 const wxString& itemName = netItem->GetName();
2745 if( itemName == wxT(
"wire" ) )
2762 if( netclass && width < netclass->GetTrackWidth() )
2763 netclass->SetTrackWidth( width );
2765 if( w.
curve.has_value() )
2773 double radiusA = ( mid -
center ).EuclideanNorm();
2774 double radiusB = ( otherMid -
center ).EuclideanNorm();
2777 std::swap( mid, otherMid );
2810 else if( itemName == wxT(
"via" ) )
2822 && layer_front_most != layer_back_most )
2829 if( v.
diam.has_value() )
2831 kidiam = v.
diam.value().ToPcbUnits();
2836 double annulus = drillSize *
m_rules->rvViaOuter;
2838 kidiam =
KiROUND( drillSize + 2 * annulus );
2842 via->SetDrill( drillSize );
2848 if( !v.
diam.has_value() || via_width <= via->GetDrill() )
2850 double annular_width = ( via_width -
via->GetDrill() ) / 2.0;
2860 if( netclass && kidiam < netclass->GetViaDiameter() )
2861 netclass->SetViaDiameter( kidiam );
2863 if( ( drillSize > 0 ) && ( drillSize <
m_min_hole ) )
2866 if( netclass && ( drillSize > 0 ) && ( drillSize < netclass->GetViaDrill() ) )
2867 netclass->SetViaDrill( drillSize );
2872 if( layer_front_most ==
F_Cu && layer_back_most ==
B_Cu )
2876 else if( layer_front_most ==
F_Cu || layer_back_most ==
B_Cu )
2887 via->SetLayerPair( layer_front_most, layer_back_most );
2888 via->SetPosition( pos );
2891 via->SetNetCode( netCode );
2897 else if( itemName == wxT(
"contactref" ) )
2899 m_xpath->push(
"contactref" );
2902 const wxString& reference = netItem->GetAttribute(
"element" );
2903 const wxString&
pad = netItem->GetAttribute(
"pad" );
2911 else if( itemName == wxT(
"polygon" ) )
2916 if( zone && !zone->GetIsRuleArea() )
2917 zone->SetNetCode( netCode );
2922 netItem = netItem->GetNext();
2929 net = net->GetNext();
2937 const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector )
2939 std::map<wxString, PCB_LAYER_ID> layer_map;
2944 layer_map.emplace( layer.Name, layerId );
2953 std::vector<INPUT_LAYER_DESC> inputDescs;
2955 for (
const std::pair<const int, ELAYER>& layerPair :
m_eagleLayers )
2957 const ELAYER& eLayer = layerPair.second;
2968 inputDescs.push_back( layerDesc );
2999 bool aIsLibraryCache )
const
3008 if( copperLayer >= 0 )
3009 copperLayers[copperLayer] =
true;
3016 bool required =
false;
3017 LSET permittedLayers;
3019 permittedLayers.
set();
3022 switch( aEagleLayer )
3155 if( aIsLibraryCache )
3163 return {
PCB_LAYER_ID( kiLayer ), permittedLayers, required };
3169 static const wxString
unknown(
"unknown" );
3177 static const int unknown = -1;
3190 if(
auto it =
m_props->find(
"page_width" ); it !=
m_props->end() )
3191 page_width = it->second;
3193 if(
auto it =
m_props->find(
"page_height" ); it !=
m_props->end() )
3194 page_height = it->second;
3196 if( !page_width.
empty() && !page_height.
empty() )
3200 int w = atoi( page_width.
c_str() );
3201 int h = atoi( page_height.
c_str() );
3203 int desired_x = ( w - bbbox.
GetWidth() ) / 2;
3204 int desired_y = ( h - bbbox.
GetHeight() ) / 2;
3206 VECTOR2I movementVector{ desired_x - bbbox.
GetX(), desired_y - bbbox.
GetY() };
3207 m_board->Move( movementVector );
3222 if( aPath.IsEmpty() )
3223 return wxDateTime::Now().GetValue().GetValue();
3225 wxFileName fn( aPath );
3227 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
3228 return fn.GetModificationTime().GetValue().GetValue();
3257 string filename = (
const char*) aLibPath.char_str( wxConvFile );
3260 wxFileName fn( filename );
3261 wxFFileInputStream stream( fn.GetFullPath() );
3262 wxXmlDocument xmlDocument;
3264 if( !stream.IsOk() || !xmlDocument.Load( stream ) )
3267 doc = xmlDocument.GetRoot();
3269 wxXmlNode* drawing =
MapChildren( doc )[
"drawing"];
3275 m_xpath->push(
"eagle.drawing.layers" );
3276 wxXmlNode* layers = drawingChildren[
"layers"];
3281 m_xpath->push(
"eagle.drawing.library" );
3282 wxXmlNode*
library = drawingChildren[
"library"];
3316 bool aBestEfforts,
const std::map<std::string, UTF8>* aProperties )
3320 init( aProperties );
3328 errorMsg = ioe.
What();
3335 aFootprintNames.Add(
name );
3337 if( !errorMsg.IsEmpty() && !aBestEfforts )
3343 bool aKeepUUID,
const std::map<std::string, UTF8>* aProperties )
3345 init( aProperties );
3354 copy->SetParent(
nullptr );
3361 int minLayerCount = 2;
3363 std::map<wxString, PCB_LAYER_ID>::const_iterator it;
3374 if( ( ordinal + 2 ) > minLayerCount )
3375 minLayerCount = ordinal + 2;
3381 if( ( minLayerCount % 2 ) != 0 )
3384 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
void SetGridOrigin(const VECTOR2I &aOrigin)
const VECTOR2I & GetGridOrigin() const
void SetAuxOrigin(const VECTOR2I &aOrigin)
const VECTOR2I & GetAuxOrigin() const
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 without changing the stream position.
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)
GR_TEXT_H_ALIGN_T GetHorizJustify() const
virtual void SetVisible(bool aVisible)
void SetKeepUpright(bool aKeepUpright)
GR_TEXT_V_ALIGN_T GetVertJustify() const
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 void Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) const
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.
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
static const LSET & InternalCuMask()
Return a complete set of internal copper layers which is all Cu layers except F_Cu and B_Cu.
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 ...
A PADSTACK defines the characteristics of a single or multi-layer pad, in the IPC sense of the word.
const LSET & LayerSet() const
const VECTOR2I & Size(PCB_LAYER_ID aLayer) const
@ NORMAL
Shape is the same on all layers.
void SetSize(const VECTOR2I &aSize, PCB_LAYER_ID aLayer)
static constexpr PCB_LAYER_ID TEMP_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.
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...
std::unique_ptr< 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...
void adjustFootprintForDesignRules(FOOTPRINT *aFootprint)
Reconcile all required footprint design rule adjustments.
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.
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.
void loadBoard(const wxString &aFileName, BOARD &aBoard, bool aIsNewLoad, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr) override
Parse aFileName into aBoard.
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)
void orientFPText(FOOTPRINT *aFootprint, const EELEMENT &e, PCB_TEXT *aFPText, const EATTR *aAttr, double aTextDefAngle=0.0, bool aTextDefMirror=false, bool aTextDefSpin=false)
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.
void SetLibTextAngle(const EDA_ANGLE &aAngle)
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true) override
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)
bool AppendCorner(const VECTOR2I &aPosition, int aHoleIdx, bool aAllowDuplication=false)
Add a new corner to the zone outline (to the main outline or a hole)
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)
void SetDoNotAllowZoneFills(bool aEnable)
static int GetDefaultHatchPitch()
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aBorderHatchStyle, int aBorderHatchPitch, bool aRebuilBorderHatch)
Set all hatch parameters for the zone.
@ 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.
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
#define THROW_IO_ERRORF(msg,...)
#define THROW_IO_CANCELLED()
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:
static bool loadLibrary(SYMBOL_LIBRARY_ADAPTER &aAdapter, const wxString &aNickname, std::vector< KI_ERROR > &aErrors)
@ 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)
void EaglePcbTextToKiCadAlignment(EDA_TEXT *aTxt, int aTxtAlign, double aTxtDegrees, bool aTxtMirror, bool aTxtSpin, double aElementDegrees=0.0, bool aElementMirror=false, bool aElementSpin=false)
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)
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::optional< ECOORD > y
std::optional< wxString > value
std::optional< ECOORD > size
std::optional< int > align
std::optional< EROT > rot
std::optional< double > ratio
std::optional< int > display
std::optional< ECOORD > x
std::map< wxString, ECOORD > clearanceMap
long long int value
Value expressed in nanometers.
std::optional< wxString > dimensionType
std::optional< ECOORD > textsize
std::optional< bool > smashed
std::optional< EROT > rot
std::optional< EURN > library_urn
std::optional< bool > active
Structure holding common properties for through-hole and SMD pads.
std::optional< bool > thermals
std::optional< EROT > rot
std::optional< bool > stop
std::optional< bool > first
std::optional< ECOORD > diameter
std::optional< int > shape
std::optional< ECOORD > drill
Eagle polygon, without vertices which are parsed as needed.
std::optional< ECOORD > isolate
static const int max_priority
std::optional< int > rank
std::optional< ECOORD > spacing
std::optional< bool > thermals
std::optional< bool > orphans
Eagle XML rectangle in binary.
std::optional< EROT > rot
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 rlMaxPadBottom
Maximum bottom layer copper annulus on through hole pads.
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 top layer copper annulus on through hole pads.
double rlMinPadInner
Minimum inner layer copper annulus on through hole pads.
int psElongationOffset
the offset of the hole within the "long" pad.
double rlMaxPadInner
Maximum inner layer copper annulus on through hole pads.
int mlMinStopFrame
solder mask, minimum size (Eagle mils, here nanometers)
int srMinRoundness
corner rounding radius, maximum size (Eagle mils, here nanometers)
double rlMinPadBottom
Minimum bottom layer copper annulus on through hole pads.
int mlMaxStopFrame
solder mask, maximum size (Eagle mils, here nanometers)
double rlMaxPadTop
Maximum top layer copper annulus on through hole pads.
int psFirst
Shape of the first pads.
std::optional< bool > cream
std::optional< int > roundness
std::optional< EROT > rot
std::optional< int > align
std::optional< double > ratio
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.
std::optional< ECOORD > diam
int layer_back_most
< extent
std::optional< double > curve
range is -359.9..359.9
VECTOR2I size
Drill diameter (x == y) or slot dimensions (x != y)
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)
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