52#include <wx/xml/xml.h>
53#include <wx/filename.h>
55#include <wx/wfstream.h>
56#include <wx/txtstrm.h>
96 ECOORD coord( aDistance, unit );
107 T ret = std::max( aMin, aValue );
108 return std::min( aMax, ret );
114static wxString
makeKey(
const wxString& aFirst,
const wxString& aSecond )
116 wxString key = aFirst +
'\x02' + aSecond;
164 wxXmlNode* child = aRules->GetChildren();
170 if( child->GetName() == wxT(
"param" ) )
172 const wxString&
name = child->GetAttribute( wxT(
"name" ) );
173 const wxString& value = child->GetAttribute( wxT(
"value" ) );
175 if(
name == wxT(
"psElongationLong" ) )
177 else if(
name == wxT(
"psElongationOffset" ) )
179 else if(
name == wxT(
"mvStopFrame" ) )
181 else if(
name == wxT(
"mvCreamFrame" ) )
183 else if(
name == wxT(
"mlMinStopFrame" ) )
185 else if(
name == wxT(
"mlMaxStopFrame" ) )
187 else if(
name == wxT(
"mlMinCreamFrame" ) )
189 else if(
name == wxT(
"mlMaxCreamFrame" ) )
191 else if(
name == wxT(
"srRoundness" ) )
193 else if(
name == wxT(
"srMinRoundness" ) )
195 else if(
name == wxT(
"srMaxRoundness" ) )
197 else if(
name == wxT(
"psTop" ) )
198 psTop = wxAtoi( value );
199 else if(
name == wxT(
"psBottom" ) )
201 else if(
name == wxT(
"psFirst" ) )
203 else if(
name == wxT(
"rvPadTop" ) )
205 else if(
name == wxT(
"rlMinPadTop" ) )
207 else if(
name == wxT(
"rlMaxPadTop" ) )
209 else if(
name == wxT(
"rlMinPadInner" ) )
211 else if(
name == wxT(
"rlMaxPadInner" ) )
213 else if(
name == wxT(
"rlMinPadBottom" ) )
215 else if(
name == wxT(
"rlMaxPadBottom" ) )
217 else if(
name == wxT(
"rvViaOuter" ) )
219 else if(
name == wxT(
"rlMinViaOuter" ) )
221 else if(
name == wxT(
"rlMaxViaOuter" ) )
223 else if(
name == wxT(
"mdWireWire" ) )
227 child = child->GetNext();
240 m_timestamp( wxDateTime::Now().GetValue().GetValue() )
242 using namespace std::placeholders;
284 wxFileInputStream input( aFileName );
293 wxTextInputStream
text( input );
295 for(
int i = 0; i < 8; i++ )
300 if(
text.ReadLine().Contains( wxS(
"<eagle" ) ) )
310 const unsigned PROGRESS_DELTA = 50;
331 return VECTOR2I( kz - aTextThickness, kz - aTextThickness );
336 const std::map<std::string, UTF8>* aProperties,
PROJECT* aProject )
358 wxFileName fn = aFileName;
361 wxFFileInputStream stream( fn.GetFullPath() );
369 wxXmlDocument xmlDocument;
370 std::unique_ptr<wxXmlDocument> binDocument;
376 std::vector<uint8_t>
bytes;
377 bytes.resize(
static_cast<size_t>( stream.GetLength() ) );
380 if( stream.LastRead() !=
bytes.size() )
385 doc = binDocument->GetRoot();
389 if( !xmlDocument.Load( stream ) )
392 doc = xmlDocument.GetRoot();
419 NETCLASS defaults( wxT(
"dummy" ) );
421 auto finishNetclass =
422 [&](
const std::shared_ptr<NETCLASS>& netclass )
426 if( !netclass->HasClearance() )
431 if( netclass->GetTrackWidth() == INT_MAX )
434 if( netclass->GetViaDiameter() == INT_MAX )
437 if( netclass->GetViaDrill() == INT_MAX )
441 std::shared_ptr<NET_SETTINGS>& netSettings = bds.
m_NetSettings;
443 finishNetclass( netSettings->GetDefaultNetclass() );
445 for(
const auto& [
name, netclass] : netSettings->GetNetclasses() )
446 finishNetclass( netclass );
448 m_board->m_LegacyNetclassesLoaded =
true;
449 m_board->m_LegacyDesignSettingsLoaded =
true;
457 wxASSERT(
m_xpath->Contents().size() == 0 );
468 LSET enabledLayers =
m_board->GetDesignSettings().GetEnabledLayers();
470 for(
const auto& [eagleLayerName, layer] :
m_layer_map )
473 enabledLayers.
set( layer );
476 m_board->GetDesignSettings().SetEnabledLayers( enabledLayers );
484 std::vector<FOOTPRINT*> retval;
487 retval.push_back(
static_cast<FOOTPRINT*
>( footprint->Clone() ) );
523 wxXmlNode* drawing =
MapChildren( aDoc )[
"drawing"];
526 wxXmlNode* board = drawingChildren[
"board"];
529 auto count_children =
530 [
this]( wxXmlNode* aNode )
534 wxXmlNode* child = aNode->GetChildren();
539 child = child->GetNext();
544 wxXmlNode* designrules = boardChildren[
"designrules"];
545 wxXmlNode* layers = drawingChildren[
"layers"];
546 wxXmlNode* plain = boardChildren[
"plain"];
547 wxXmlNode* classes = boardChildren[
"classes"];
548 wxXmlNode* signals = boardChildren[
"signals"];
549 wxXmlNode* libs = boardChildren[
"libraries"];
550 wxXmlNode* elems = boardChildren[
"elements"];
555 if( wxXmlNode* attributes = boardChildren[
"attributes"] )
557 for( wxXmlNode* attribute = attributes->GetChildren(); attribute; attribute = attribute->GetNext() )
559 if( attribute->GetName() == wxT(
"attribute" ) )
560 m_boardAttributes[attribute->GetAttribute( wxT(
"name" ) )] = attribute->GetAttribute( wxT(
"value" ) );
569 count_children( designrules );
570 count_children( layers );
571 count_children( plain );
572 count_children( signals );
573 count_children( elems );
578 libs = libs->GetNext();
582 libs = boardChildren[
"libraries"];
585 m_xpath->push(
"eagle.drawing" );
624 m_xpath->push(
"designrules" );
643 wxXmlNode* layerNode = aLayers->GetChildren();
650 ELAYER elayer( layerNode );
656 cu.push_back( elayer );
658 layerNode = layerNode->GetNext();
662 int ki_layer_count = 0;
664 for(
EITER it = cu.begin(); it != cu.end(); ++it, ++ki_layer_count )
666 if( ki_layer_count == 0 )
670 else if( ki_layer_count ==
int( cu.size()-1 ) )
684 m_board->SetCopperLayerCount( cu.size() );
686 for(
EITER it = cu.begin(); it != cu.end(); ++it )
693 m_board->SetLayerName( layer, it->name );
703#define DIMENSION_PRECISION DIM_PRECISION::X_XX
708 std::map<int, std::tuple<GR_TEXT_V_ALIGN_T, GR_TEXT_H_ALIGN_T>> alignmentmap{
719 return alignmentmap[aAlign];
725 std::map<std::tuple<GR_TEXT_V_ALIGN_T, GR_TEXT_H_ALIGN_T>,
int> alignmentmap{
736 return alignmentmap[aAlign];
741 double aElementDegrees = 0.0,
bool aElementMirror =
false,
742 bool aElementSpin =
false )
746 int align{ aTxtAlign };
748 bool spin = aTxtSpin != aElementSpin;
749 bool mirror = aTxtMirror != aElementMirror;
752 double degrees = ( aTxtMirror ? -1.0 : 1.0 ) * textDefDegrees + elementDegrees;
757 if( ( !aTxtMirror && degrees > 90 && degrees <= 270 ) || ( aTxtMirror && degrees >= 90 && degrees < 270 ) )
760 degrees = degrees - 180;
785 wxXmlNode* gr = aGraphics->GetChildren();
792 wxString grName = gr->GetName();
794 if( grName == wxT(
"wire" ) )
811 width =
m_board->GetDesignSettings().GetLineThickness( layer );
815 if( w.
curve.has_value() )
838 else if( grName == wxT(
"text" ) )
854 double ratio = t.
ratio.value_or( 8 );
864 double degrees = t.
rot.has_value() ? t.
rot.value().degrees : 0.0;
865 bool mirror = t.
rot.has_value() ? t.
rot.value().mirror :
false;
866 bool spin = t.
rot.has_value() ? t.
rot.value().spin :
false;
873 else if( grName == wxT(
"circle" ) )
892 int outlineRadius =
radius + ( width / 2 );
898 VECTOR2I rotatedPoint( outlineRadius, 0 );
906 int innerRadius =
radius - ( width / 2 );
912 VECTOR2I rotatedPoint( innerRadius, 0 );
939 else if( grName == wxT(
"rectangle" ) )
972 const int outlineIdx = -1;
978 if( r.
rot.has_value() )
991 else if( grName == wxT(
"hole" ) )
1001 footprint->
SetReference( wxString::Format( wxT(
"UNK_HOLE_%d" ), hole_count ) );
1004 LIB_ID fpid( wxEmptyString, wxString::Format( wxT(
"dummyfp%d" ), hole_count ) );
1011 else if( grName == wxT(
"frame" ) )
1015 else if( grName == wxT(
"polygon" ) )
1021 else if( grName == wxT(
"dimension" ) )
1036 textThickness =
KiROUND( d.
textsize.value().ToPcbUnits() * ratio / 100.0 );
1042 if( d.
dimensionType.value_or( wxEmptyString ) == wxT(
"angle" ) )
1046 else if( d.
dimensionType.value_or( wxEmptyString ) == wxT(
"radius" ) )
1055 dimension->
SetEnd( pt2 );
1062 else if( d.
dimensionType.value_or( wxEmptyString ) == wxT(
"leader" ) )
1086 if( d.
dimensionType.value_or( wxEmptyString ) == wxT(
"horizontal" ) )
1088 int newY = ( pt1.
y + pt2.
y ) / 2;
1092 else if( d.
dimensionType.value_or( wxEmptyString ) == wxT(
"vertical" ) )
1094 int newX = ( pt1.
x + pt2.
x ) / 2;
1104 dimension->
SetEnd( pt2 );
1114 if(
abs( pt1.
x - pt2.
x ) < 50000 )
1116 int offset = pt3.
x - pt1.
x;
1123 else if(
abs( pt1.
y - pt2.
y ) < 50000 )
1125 int offset = pt3.
y - pt1.
y;
1158 wxString urn = aLib->GetAttribute(
"urn" );
1167 if( !urn.IsEmpty() )
1168 libraryUrn.
Parse( urn );
1171 wxXmlNode* packages =
MapChildren( aLib )[
"packages"];
1190 libKey += wxS(
"_" ) + libraryUrn.
assetId;
1198 wxXmlNode*
package = packages->GetChildren();
1204 m_xpath->push(
"package",
"name" );
1206 wxString pack_ref = package->GetAttribute(
"name" );
1210 m_xpath->Value( pack_ref.ToUTF8() );
1212 wxString key = aLibName ?
makeKey( libKey, pack_ref ) : pack_ref;
1217 auto r =
m_templates.insert( { key, footprint } );
1228 package = package->GetNext();
1240 m_xpath->push(
"libraries.library",
"name" );
1243 wxXmlNode*
library = aLibs->GetChildren();
1247 const wxString& lib_name =
library->GetAttribute(
"name" );
1249 m_xpath->Value( lib_name.c_str() );
1263 m_xpath->push(
"elements.element",
"name" );
1267 bool refanceNamePresetInPackageLayout;
1268 bool valueNamePresetInPackageLayout;
1271 wxXmlNode* element = aElements->GetChildren();
1277 if( element->GetName() != wxT(
"element" ) )
1280 element = element->GetNext();
1287 EATTR* nameAttr =
nullptr;
1288 EATTR* valueAttr =
nullptr;
1298 libKey += wxS(
"_" ) + e.
library_urn.value().assetId;
1318 const ENET* enet = &ni->second;
1328 if( !
text || !
text->GetText().StartsWith( wxS(
"${" ) ) || !
text->GetText().EndsWith( wxS(
"}" ) ) )
1331 wxString varName =
text->GetText().Mid( 2,
text->GetText().length() - 3 );
1332 wxString token = varName;
1338 wxString fieldValue;
1341 fieldValue = boardValue->second;
1343 for( wxXmlNode* attribute = element->GetChildren(); attribute; attribute = attribute->GetNext() )
1345 if( attribute->GetName() == wxT(
"attribute" ) && attribute->GetAttribute( wxT(
"name" ) ) == varName
1346 && attribute->HasAttribute( wxT(
"value" ) ) )
1348 fieldValue = attribute->GetAttribute( wxT(
"value" ) );
1357 footprint->
Add( field );
1360 refanceNamePresetInPackageLayout =
true;
1361 valueNamePresetInPackageLayout =
true;
1368 refanceNamePresetInPackageLayout =
false;
1372 if( footprint->
GetValue().size() == 0 )
1375 valueNamePresetInPackageLayout =
false;
1378 wxString reference = e.
name;
1384 if( reference.find_first_not_of(
"0123456789" ) != 0 )
1385 reference.Prepend(
"UNK" );
1389 if( reference.find_first_not_of(
"#" ) != 0 )
1390 reference.Prepend(
"UNK" );
1393 if( reference.find_last_not_of(
"0123456789" ) == (reference.Length()-1) )
1394 reference.Append(
"0" );
1402 if( valueNamePresetInPackageLayout )
1405 if( refanceNamePresetInPackageLayout )
1408 else if( e.
smashed.value() ==
true )
1415 m_xpath->push(
"attribute",
"name" );
1425 wxXmlNode* attribute = element->GetChildren();
1429 if( attribute->GetName() != wxT(
"attribute" ) )
1431 attribute = attribute->GetNext();
1435 EATTR a( attribute );
1437 if( a.
name == wxT(
"NAME" ) )
1450 nameAttr->
name = reference;
1452 if( refanceNamePresetInPackageLayout )
1459 if( refanceNamePresetInPackageLayout )
1468 if( refanceNamePresetInPackageLayout )
1471 nameAttr->
name = nameAttr->
name + wxT(
" = " ) + e.
name;
1482 if( refanceNamePresetInPackageLayout )
1492 else if( a.
name == wxT(
"VALUE" ) )
1506 if( valueNamePresetInPackageLayout )
1512 if( valueNamePresetInPackageLayout )
1515 footprint->
SetValue( wxT(
"VALUE" ) );
1519 if( valueNamePresetInPackageLayout )
1522 valueAttr->
value = wxT(
"VALUE = " ) + e.
value;
1533 if( valueNamePresetInPackageLayout )
1545 attribute = attribute->GetNext();
1555 element = element->GetNext();
1575 Report( wxString::Format(
_(
"Ignoring a polygon since Eagle layer '%s' (%d) was not mapped" ),
1582 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>(
m_board );
1585 zone->SetLayer( layer );
1590 wxXmlNode* vertex = aPolyNode->GetChildren();
1591 std::vector<EVERTEX> vertices;
1599 if( vertex->GetName() == wxT(
"vertex" ) )
1600 vertices.emplace_back( vertex );
1602 vertex = vertex->GetNext();
1607 if( p.
orphans.value_or(
false ) )
1612 if( vertices.size() < 3 )
1614 Report( wxString::Format(
_(
"Skipping a polygon on layer '%s' (%d): less than 3 vertices" ),
1621 vertices.push_back( vertices[0] );
1626 for(
size_t i = 0; i < vertices.size() - 1; i++ )
1633 if(
v1.curve.has_value() )
1638 double angle =
DEG2RAD(
v1.curve.value() );
1644 double delta_angle = angle / segCount;
1646 for(
double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta_angle ); a -= delta_angle )
1661 Report( wxString::Format(
_(
"Skipping a polygon on layer '%s' (%d): outline count is not 1" ),
1669 zone->AddPolygon( polygon.
COutline( 0 ) );
1674 zone->SetIsRuleArea(
true );
1675 zone->SetDoNotAllowVias(
false );
1676 zone->SetDoNotAllowTracks(
false );
1677 zone->SetDoNotAllowPads(
false );
1678 zone->SetDoNotAllowFootprints(
false );
1679 zone->SetDoNotAllowZoneFills(
true );
1689 zone->SetHatchOrientation(
ANGLE_0 );
1698 zone->SetLocalClearance( p.
isolate.value().ToPcbUnits() );
1700 zone->SetLocalClearance( 1 );
1703 bool thermals = p.
thermals.value_or(
true );
1717 zone->SetAssignedPriority( rank );
1719 ZONE* zonePtr = zone.release();
1727 const EATTR* aNameAttr,
const EATTR* aValueAttr )
1729 std::vector<std::tuple<PCB_FIELD*, double, bool, bool, const EATTR*>> textRotDefs{};
1731 std::vector<PCB_FIELD*> fields{};
1736 double defDegrees = field->GetLibTextAngle().AsDegrees();
1737 bool defMirror = field->IsMirrored();
1738 bool defSpin = !field->IsKeepUpright();
1739 const EATTR* attr =
nullptr;
1743 else if( field == &aFootprint->
Value() )
1746 textRotDefs.push_back( std::tuple<PCB_FIELD*, double, bool, bool, const EATTR*>( field, defDegrees, defMirror,
1750 if( e.
rot.has_value() )
1752 if( e.
rot.value().mirror )
1763 for(
auto textRotDef : textRotDefs )
1766 double defDegrees{};
1769 const EATTR* attr{};
1770 std::tie( field, defDegrees, defMirror, defSpin, attr ) = textRotDef;
1771 orientFPText( aFootprint, e, field, attr, defDegrees, defMirror, defSpin );
1777 double aTextDefAngle,
bool aTextDefMirror,
bool aTextDefSpin )
1783 const EATTR& a = *aAttr;
1785 if( a.
value.has_value() )
1788 if( a.
x.has_value() && a.
y.has_value() )
1796 double ratio = a.
ratio.value_or( 8 );
1798 int textThickness =
KiROUND( fontSize.
y * ratio / 100.0 );
1802 if( a.
size.has_value() )
1814 double degrees = a.
rot.has_value() ? a.
rot.value().degrees : 0.0;
1815 bool mirror = a.
rot.has_value() ? a.
rot.value().mirror :
false;
1816 bool spin = a.
rot.has_value() ? a.
rot.value().spin :
false;
1827 double elementAngle = e.
rot.has_value() ? e.
rot.value().degrees : 0.0;
1828 bool elementMirror = e.
rot.has_value() ? e.
rot.value().mirror :
false;
1829 bool elementSpin = e.
rot.has_value() ? e.
rot.value().spin :
false;
1835 elementMirror, elementSpin );
1852 int adjustedPadDiameter = 0.0;
1859 if( ( padstack.
Size(
F_Cu ).
x < adjustedPadDiameter ) )
1869 adjustedPadDiameter = padstack.
Drill().
size.
x + (
m_rules->rlMinPadBottom * 2 );
1871 if( padstack.
Size(
B_Cu ).
x < adjustedPadDiameter )
1875 if(
m_rules->rlMinPadInner != 0.0 )
1881 if( !padstack.
LayerSet().test( layerId ) )
1886 if( padstack.
Size( layerId ).
x < adjustedPadDiameter )
1887 padstack.
SetSize(
VECTOR2I( adjustedPadDiameter, adjustedPadDiameter ), layerId );
1897 std::unique_ptr<FOOTPRINT> m = std::make_unique<FOOTPRINT>(
m_board );
1900 fpID.
Parse( aPkgName,
true );
1904 wxXmlNode* packageItem = aPackage->GetChildren();
1909 m.get()->Value().SetLayer( layer );
1911 while( packageItem )
1913 const wxString& itemName = packageItem->GetName();
1915 if( itemName == wxT(
"description" ) )
1918 m->SetLibDescription( descr );
1920 else if( itemName == wxT(
"wire" ) )
1922 else if( itemName == wxT(
"pad" ) )
1924 else if( itemName == wxT(
"text" ) )
1926 else if( itemName == wxT(
"rectangle" ) )
1928 else if( itemName == wxT(
"polygon" ) )
1930 else if( itemName == wxT(
"circle" ) )
1932 else if( itemName == wxT(
"hole" ) )
1934 else if( itemName == wxT(
"smd" ) )
1937 packageItem = packageItem->GetNext();
1954 Report( wxString::Format(
_(
"Ignoring a wire since Eagle layer '%s' (%d) was not mapped" ),
1991 if( w.
curve.has_value() )
2013 aFootprint->
Add( dwg );
2022 int drillSize = e.
drill.has_value() ? e.
drill.value().ToPcbUnits() : 0;
2024 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
2034 pad->SetDrillSize(
VECTOR2I( drillSize, drillSize ) );
2037 if( drillSize > 0 && drillSize <
m_min_hole )
2041 if( e.
stop.value_or(
true ) )
2047 if( e.
shape.has_value() )
2049 switch( e.
shape.value() )
2081 int diameter = e.
diameter.value().ToPcbUnits();
2086 double drillz =
pad->GetDrillSize().x;
2087 double annulus = drillz *
m_rules->rvPadTop;
2089 int diameter =
KiROUND( drillz + 2 * annulus );
2097 sz.
x = ( sz.
x * ( 100 +
m_rules->psElongationLong ) ) / 100;
2102 int offset =
KiROUND( ( sz.
x - sz.
y ) / 2.0 );
2107 if( e.
rot.has_value() )
2113 bool badPad =
false;
2115 pad->Padstack().ForEachUniqueLayer(
2120 if( padSize.
x <= 0 || padSize.
y <= 0 )
2130 Report( wxString::Format(
_(
"Invalid zero-sized pad ignored in\nfile: %s" ),
2136 Report( wxString::Format(
_(
"Invalid zero-sized pad ignored in\nfile: %s" ),
2137 fileName.GetFullName() ),
2143 aFootprint->
Add(
pad.release() );
2155 Report( wxString::Format(
_(
"Ignoring a text since Eagle layer '%s' (%d) was not mapped" ),
2163 if( t.
text.Upper() == wxT(
">NAME" ) && aFootprint->
GetReference().IsEmpty() )
2167 textItem->
SetText( wxT(
"REF**" ) );
2169 else if( t.
text.Upper() == wxT(
">VALUE" ) && aFootprint->
GetValue().IsEmpty() )
2171 textItem = &aFootprint->
Value();
2177 textItem =
new PCB_TEXT( aFootprint );
2178 aFootprint->
Add( textItem );
2188 double ratio = t.
ratio.value_or( 8 );
2199 double degrees = t.
rot.has_value() ? t.
rot.value().degrees : 0.0;
2200 bool mirror = t.
rot.has_value() ? t.
rot.value().mirror :
false;
2201 bool spin = t.
rot.has_value() ? t.
rot.value().spin :
false;
2227 ZONE* zone =
new ZONE( aFootprint );
2232 const int outlineIdx = -1;
2238 if( r.
rot.has_value() )
2254 Report( wxString::Format(
_(
"Ignoring a rectangle since Eagle layer '%s' (%d) was not mapped" ),
2262 aFootprint->
Add( dwg );
2268 std::vector<VECTOR2I> pts;
2273 pts.push_back( start );
2276 pts.push_back(
end );
2280 if( r.
rot.has_value() )
2293 std::vector<VECTOR2I> pts;
2296 wxXmlNode* vertex = aTree->GetChildren();
2297 std::vector<EVERTEX> vertices;
2305 if( vertex->GetName() == wxT(
"vertex" ) )
2306 vertices.emplace_back( vertex );
2308 vertex = vertex->GetNext();
2314 if( vertices.size() < 3 )
2316 Report( wxString::Format(
_(
"Skipping a polygon on layer '%s' (%d): less than 3 vertices" ),
2323 vertices.push_back( vertices[0] );
2325 for(
size_t i = 0; i < vertices.size() - 1; i++ )
2332 if(
v1.curve.has_value() )
2337 double angle =
DEG2RAD(
v1.curve.value() );
2347 double delta = angle / segCount;
2349 for(
double a = end_angle + angle; fabs( a - end_angle ) > fabs(
delta ); a -=
delta )
2364 ZONE* zone =
new ZONE( aFootprint );
2380 Report( wxString::Format(
_(
"Ignoring a polygon since Eagle layer '%s' (%d) was not mapped" ),
2388 aFootprint->
Add( dwg );
2414 ZONE* zone =
new ZONE( aFootprint );
2421 int outlineRadius =
radius + ( width / 2 );
2427 VECTOR2I rotatedPoint( outlineRadius, 0 );
2435 int innerRadius =
radius - ( width / 2 );
2441 VECTOR2I rotatedPoint( innerRadius, 0 );
2456 Report( wxString::Format(
_(
"Ignoring a circle since Eagle layer '%s' (%d) was not mapped" ),
2472 aFootprint->
Add( gr );
2475 switch( (
int) layer )
2517 pad->SetPosition( padpos );
2526 pad->SetDrillSize( sz );
2550 pad->SetLayer( layer );
2556 pad->SetLayerSet( front );
2557 else if( layer ==
B_Cu )
2558 pad->SetLayerSet( back );
2560 int minPadSize = std::min( padSize.
x, padSize.
y );
2564 (
int) ( minPadSize *
m_rules->srRoundness ),
2565 m_rules->srMaxRoundness * 2 );
2567 if( e.
roundness.has_value() || roundRadius > 0 )
2569 double roundRatio = (double) roundRadius / minPadSize / 2.0;
2573 roundRatio = std::fmax( e.
roundness.value() / 200.0, roundRatio );
2579 if( e.
rot.has_value() )
2586 (
int) (
m_rules->mvCreamFrame * minPadSize ),
2590 if( e.
stop.has_value() && e.
stop.value() ==
false )
2593 pad->SetLayerSet(
pad->GetLayerSet().set(
F_Mask,
false ) );
2594 else if( layer ==
B_Cu )
2595 pad->SetLayerSet(
pad->GetLayerSet().set(
B_Mask,
false ) );
2599 if( e.
cream.has_value() && e.
cream.value() ==
false )
2602 pad->SetLayerSet(
pad->GetLayerSet().set(
F_Paste,
false ) );
2603 else if( layer ==
B_Cu )
2604 pad->SetLayerSet(
pad->GetLayerSet().set(
B_Paste,
false ) );
2619 (
int) (
m_rules->mvStopFrame * std::min( padSize.
x, padSize.
y ) ),
2623 if( aEaglePad.
thermals.has_value() && aEaglePad.
thermals.value() ==
false )
2627 wxCHECK( footprint, );
2637 footprint->SetParent(
nullptr );
2653 m_xpath->push(
"classes.class",
"number" );
2655 std::vector<ECLASS> eClasses;
2656 wxXmlNode* classNode = aClasses->GetChildren();
2662 ECLASS eClass( classNode );
2663 std::shared_ptr<NETCLASS> netclass;
2665 if( eClass.
name.CmpNoCase( wxT(
"default" ) ) == 0 )
2675 netclass->SetTrackWidth( INT_MAX );
2676 netclass->SetViaDiameter( INT_MAX );
2677 netclass->SetViaDrill( INT_MAX );
2679 eClasses.emplace_back( eClass );
2683 auto clearanceToDefaultIt = eClass.
clearanceMap.find( wxT(
"0" ) );
2685 if( clearanceToDefaultIt != eClass.
clearanceMap.end() )
2687 netclass->SetClearance( clearanceToDefaultIt->second.ToPcbUnits() );
2691 classNode = classNode->GetNext();
2696 for(
ECLASS& eClass : eClasses )
2698 for(
const auto& [className, pt] : eClass.clearanceMap )
2701 if( className == wxT(
"0" ) )
2707 rule.Printf( wxT(
"(rule \"class %s:%s\"\n"
2708 " (condition \"A.NetClass == '%s' && B.NetClass == '%s'\")\n"
2709 " (constraint clearance (min %smm)))\n" ),
2738 std::set<wxString> usedNetNames;
2740 for( wxXmlNode* signal = aSignals->GetChildren(); signal; signal = signal->GetNext() )
2742 wxString explicitName =
escapeName( signal->GetAttribute(
"name" ) );
2744 if( !explicitName.IsEmpty() )
2745 usedNetNames.insert( explicitName );
2748 m_xpath->push(
"signals.signal",
"name" );
2751 wxXmlNode* net = aSignals->GetChildren();
2757 wxString netName =
escapeName( net->GetAttribute(
"name" ) );
2764 if( netName.IsEmpty() )
2766 int candidate = netCode;
2770 netName = wxString::Format( wxT(
"N$%d" ), candidate++ );
2771 }
while( usedNetNames.count( netName ) );
2773 usedNetNames.insert( netName );
2777 std::shared_ptr<NETCLASS> netclass;
2779 if( net->HasAttribute(
"class" ) )
2781 auto netclassIt =
m_classMap.find( net->GetAttribute(
"class" ) );
2787 netclass = netclassIt->second;
2798 m_xpath->Value( netName.c_str() );
2801 wxXmlNode* netItem = net->GetChildren();
2806 const wxString& itemName = netItem->GetName();
2808 if( itemName == wxT(
"wire" ) )
2825 if( netclass && width < netclass->GetTrackWidth() )
2826 netclass->SetTrackWidth( width );
2828 if( w.
curve.has_value() )
2836 double radiusA = ( mid -
center ).EuclideanNorm();
2837 double radiusB = ( otherMid -
center ).EuclideanNorm();
2840 std::swap( mid, otherMid );
2873 else if( itemName == wxT(
"via" ) )
2885 && layer_front_most != layer_back_most )
2892 if( v.
diam.has_value() )
2894 kidiam = v.
diam.value().ToPcbUnits();
2899 double annulus = drillSize *
m_rules->rvViaOuter;
2901 kidiam =
KiROUND( drillSize + 2 * annulus );
2905 via->SetDrill( drillSize );
2911 if( !v.
diam.has_value() || via_width <= via->GetDrill() )
2913 double annular_width = ( via_width -
via->GetDrill() ) / 2.0;
2923 if( netclass && kidiam < netclass->GetViaDiameter() )
2924 netclass->SetViaDiameter( kidiam );
2926 if( ( drillSize > 0 ) && ( drillSize <
m_min_hole ) )
2929 if( netclass && ( drillSize > 0 ) && ( drillSize < netclass->GetViaDrill() ) )
2930 netclass->SetViaDrill( drillSize );
2935 if( layer_front_most ==
F_Cu && layer_back_most ==
B_Cu )
2939 else if( layer_front_most ==
F_Cu || layer_back_most ==
B_Cu )
2950 via->SetLayerPair( layer_front_most, layer_back_most );
2951 via->SetPosition( pos );
2954 via->SetNetCode( netCode );
2960 else if( itemName == wxT(
"contactref" ) )
2962 m_xpath->push(
"contactref" );
2965 const wxString& reference = netItem->GetAttribute(
"element" );
2966 const wxString&
pad = netItem->GetAttribute(
"pad" );
2974 else if( itemName == wxT(
"polygon" ) )
2979 if( zone && !zone->GetIsRuleArea() )
2980 zone->SetNetCode( netCode );
2985 netItem = netItem->GetNext();
2992 net = net->GetNext();
3000 const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector )
3002 std::map<wxString, PCB_LAYER_ID> layer_map;
3007 layer_map.emplace( layer.Name, layerId );
3016 std::vector<INPUT_LAYER_DESC> inputDescs;
3018 for (
const std::pair<const int, ELAYER>& layerPair :
m_eagleLayers )
3020 const ELAYER& eLayer = layerPair.second;
3031 inputDescs.push_back( layerDesc );
3062 bool aIsLibraryCache )
const
3071 if( copperLayer >= 0 )
3072 copperLayers[copperLayer] =
true;
3079 bool required =
false;
3080 LSET permittedLayers;
3082 permittedLayers.
set();
3085 switch( aEagleLayer )
3218 if( aIsLibraryCache )
3226 return {
PCB_LAYER_ID( kiLayer ), permittedLayers, required };
3232 static const wxString
unknown(
"unknown" );
3240 static const int unknown = -1;
3253 if(
auto it =
m_props->find(
"page_width" ); it !=
m_props->end() )
3254 page_width = it->second;
3256 if(
auto it =
m_props->find(
"page_height" ); it !=
m_props->end() )
3257 page_height = it->second;
3259 if( !page_width.
empty() && !page_height.
empty() )
3263 int w = atoi( page_width.
c_str() );
3264 int h = atoi( page_height.
c_str() );
3266 int desired_x = ( w - bbbox.
GetWidth() ) / 2;
3267 int desired_y = ( h - bbbox.
GetHeight() ) / 2;
3269 VECTOR2I movementVector{ desired_x - bbbox.
GetX(), desired_y - bbbox.
GetY() };
3270 m_board->Move( movementVector );
3285 if( aPath.IsEmpty() )
3286 return wxDateTime::Now().GetValue().GetValue();
3288 wxFileName fn( aPath );
3290 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
3291 return fn.GetModificationTime().GetValue().GetValue();
3320 string filename = (
const char*) aLibPath.char_str( wxConvFile );
3323 wxFileName fn( filename );
3324 wxFFileInputStream stream( fn.GetFullPath() );
3325 wxXmlDocument xmlDocument;
3327 if( !stream.IsOk() || !xmlDocument.Load( stream ) )
3330 doc = xmlDocument.GetRoot();
3332 wxXmlNode* drawing =
MapChildren( doc )[
"drawing"];
3338 m_xpath->push(
"eagle.drawing.layers" );
3339 wxXmlNode* layers = drawingChildren[
"layers"];
3344 m_xpath->push(
"eagle.drawing.library" );
3345 wxXmlNode*
library = drawingChildren[
"library"];
3379 bool aBestEfforts,
const std::map<std::string, UTF8>* aProperties )
3383 init( aProperties );
3391 errorMsg = ioe.
What();
3398 aFootprintNames.Add(
name );
3400 if( !errorMsg.IsEmpty() && !aBestEfforts )
3406 bool aKeepUUID,
const std::map<std::string, UTF8>* aProperties )
3408 init( aProperties );
3417 copy->SetParent(
nullptr );
3424 int minLayerCount = 2;
3426 std::map<wxString, PCB_LAYER_ID>::const_iterator it;
3437 if( ( ordinal + 2 ) > minLayerCount )
3438 minLayerCount = ordinal + 2;
3444 if( ( minLayerCount % 2 ) != 0 )
3447 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
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
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()
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.
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
void loadPlain(wxXmlNode *aPlain)
int m_min_trace
smallest trace we find on Load(), in BIU.
wxString m_importedDesignRules
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().
std::map< wxString, wxString > m_boardAttributes
Board attribute values by name.
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
Eagle class number to KiCad netclass.
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
Check 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
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
Handles common pad properties.
void deleteTemplates()
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
PCB_IO(const wxString &aName)
const std::map< std::string, UTF8 > * m_props
Properties passed via Save() or Load(), no ownership, may be NULL.
void SetCenter(const VECTOR2I &aCenter) override
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)
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aBorderHatchStyle, int aBorderHatchPitch, bool aRebuildBorderHatch)
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)
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.
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.
int psElongationLong
percent over 100%.
double mvStopFrame
solder 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)
double mdWireWire
wire to wire spacing I presume.
double rvPadTop
top pad size as percent of drill size
int srMaxRoundness
corner rounding radius, maximum size (Eagle mils, here nanometers)
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.
double mvCreamFrame
solderpaste mask, expressed as percentage of the smaller pad/via dimension
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, minimum 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.
@ USER
The field ID hasn't been set yet; field is invalid.
static std::vector< uint8_t > bytes(const std::string &aText)
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