56#include <wx/xml/xml.h>
57#include <wx/filename.h>
59#include <wx/wfstream.h>
60#include <wx/txtstrm.h>
94 ECOORD coord( aDistance, unit );
105 T ret = std::max( aMin, aValue );
106 return std::min( aMax, ret );
112static wxString
makeKey(
const wxString& aFirst,
const wxString& aSecond )
114 wxString key = aFirst +
'\x02' + aSecond;
162 wxXmlNode* child = aRules->GetChildren();
168 if( child->GetName() == wxT(
"param" ) )
170 const wxString&
name = child->GetAttribute( wxT(
"name" ) );
171 const wxString& value = child->GetAttribute( wxT(
"value" ) );
173 if(
name == wxT(
"psElongationLong" ) )
175 else if(
name == wxT(
"psElongationOffset" ) )
177 else if(
name == wxT(
"mvStopFrame" ) )
179 else if(
name == wxT(
"mvCreamFrame" ) )
181 else if(
name == wxT(
"mlMinStopFrame" ) )
183 else if(
name == wxT(
"mlMaxStopFrame" ) )
185 else if(
name == wxT(
"mlMinCreamFrame" ) )
187 else if(
name == wxT(
"mlMaxCreamFrame" ) )
189 else if(
name == wxT(
"srRoundness" ) )
191 else if(
name == wxT(
"srMinRoundness" ) )
193 else if(
name == wxT(
"srMaxRoundness" ) )
195 else if(
name == wxT(
"psTop" ) )
196 psTop = wxAtoi( value );
197 else if(
name == wxT(
"psBottom" ) )
199 else if(
name == wxT(
"psFirst" ) )
201 else if(
name == wxT(
"rvPadTop" ) )
203 else if(
name == wxT(
"rlMinPadTop" ) )
205 else if(
name == wxT(
"rlMaxPadTop" ) )
207 else if(
name == wxT(
"rvViaOuter" ) )
209 else if(
name == wxT(
"rlMinViaOuter" ) )
211 else if(
name == wxT(
"rlMaxViaOuter" ) )
213 else if(
name == wxT(
"mdWireWire" ) )
217 child = child->GetNext();
224 m_xpath( new
XPATH() ),
225 m_progressReporter( nullptr ),
227 m_lastProgressCount( 0 ),
229 m_mod_time( wxDateTime::Now() )
231 using namespace std::placeholders;
274 wxFileInputStream input( aFileName );
279 wxTextInputStream
text( input );
281 for(
int i = 0; i < 3; i++ )
286 if(
text.ReadLine().Contains( wxS(
"<!DOCTYPE eagle" ) ) )
296 const unsigned PROGRESS_DELTA = 50;
318 return VECTOR2I( kz - aTextThickness, kz - aTextThickness );
339 unique_ptr<BOARD> deleter( aAppendToMe ?
nullptr :
m_board );
351 wxFileName fn = aFileName;
354 wxFFileInputStream stream( fn.GetFullPath() );
355 wxXmlDocument xmlDocument;
357 if( !stream.IsOk() || !xmlDocument.Load( stream ) )
360 fn.GetFullPath() ) );
363 doc = xmlDocument.GetRoot();
389 NETCLASS defaults( wxT(
"dummy" ) );
391 auto finishNetclass =
392 [&]( std::shared_ptr<NETCLASS> netclass )
398 if( netclass->GetTrackWidth() == INT_MAX )
401 if( netclass->GetViaDiameter() == INT_MAX )
404 if( netclass->GetViaDrill() == INT_MAX )
408 std::shared_ptr<NET_SETTINGS>& netSettings = bds.
m_NetSettings;
410 finishNetclass( netSettings->m_DefaultNetClass );
412 for(
const auto& [
name, netclass ] : netSettings->m_NetClasses )
413 finishNetclass( netclass );
418 fn.SetExt( wxT(
"kicad_dru" ) );
419 wxFile rulesFile( fn.GetFullPath(), wxFile::write );
427 wxString errmsg = exc.what();
429 errmsg += wxT(
"\n@ " );
447 std::vector<FOOTPRINT*> retval;
450 retval.push_back(
static_cast<FOOTPRINT*
>( footprint->Clone() ) );
486 wxXmlNode* drawing =
MapChildren( aDoc )[
"drawing"];
489 wxXmlNode* board = drawingChildren[
"board"];
492 auto count_children = [
this]( wxXmlNode* aNode )
496 wxXmlNode* child = aNode->GetChildren();
501 child = child->GetNext();
506 wxXmlNode* designrules = boardChildren[
"designrules"];
507 wxXmlNode* layers = drawingChildren[
"layers"];
508 wxXmlNode* plain = boardChildren[
"plain"];
509 wxXmlNode* classes = boardChildren[
"classes"];
510 wxXmlNode* signals = boardChildren[
"signals"];
511 wxXmlNode* libs = boardChildren[
"libraries"];
512 wxXmlNode* elems = boardChildren[
"elements"];
519 count_children( designrules );
520 count_children( layers );
521 count_children( plain );
522 count_children( signals );
523 count_children( elems );
528 libs = libs->GetNext();
532 libs = boardChildren[
"libraries"];
589 wxXmlNode* layerNode = aLayers->GetChildren();
596 ELAYER elayer( layerNode );
602 cu.push_back( elayer );
604 layerNode = layerNode->GetNext();
608 int ki_layer_count = 0;
610 for(
EITER it = cu.begin(); it != cu.end(); ++it, ++ki_layer_count )
612 if( ki_layer_count == 0 )
616 else if( ki_layer_count ==
int( cu.size()-1 ) )
623 m_cu_map[it->number] = ki_layer_count;
632 for(
EITER it = cu.begin(); it != cu.end(); ++it )
649#define DIMENSION_PRECISION DIM_PRECISION::X_XX
660 wxXmlNode* gr = aGraphics->GetChildren();
667 wxString grName = gr->GetName();
669 if( grName == wxT(
"wire" ) )
692 shape->
SetShape( SHAPE_T::SEGMENT );
712 else if( grName == wxT(
"text" ) )
743 if( degrees == 90 || t.
rot->
spin )
747 else if( degrees == 180 )
751 else if( degrees == 270 )
760 if( ( degrees > 0 ) && ( degrees < 90 ) )
764 else if( ( degrees > 90 ) && ( degrees < 180 ) )
769 else if( ( degrees > 180 ) && ( degrees < 270 ) )
774 else if( ( degrees > 270 ) && ( degrees < 360 ) )
833 else if( grName == wxT(
"circle" ) )
852 int outlineRadius = radius + ( width / 2 );
858 VECTOR2I rotatedPoint( outlineRadius, 0 );
866 int innerRadius = radius - ( width / 2 );
872 VECTOR2I rotatedPoint( innerRadius, 0 );
899 else if( grName == wxT(
"rectangle" ) )
919 const int outlineIdx = -1;
935 else if( grName == wxT(
"hole" ) )
951 else if( grName == wxT(
"frame" ) )
955 else if( grName == wxT(
"polygon" ) )
961 else if( grName == wxT(
"dimension" ) )
1000 dimension->
SetUnits( EDA_UNITS::MILLIMETRES );
1030 int newY = ( pt1.
y + pt2.
y ) / 2;
1036 int newX = ( pt1.
x + pt2.
x ) / 2;
1047 dimension->
SetEnd( pt2 );
1051 dimension->
SetUnits( EDA_UNITS::MILLIMETRES );
1057 if(
abs( pt1.
x - pt2.
x ) < 50000 )
1059 int offset = pt3.
x - pt1.
x;
1066 else if(
abs( pt1.
y - pt2.
y ) < 50000 )
1068 int offset = pt3.
y - pt1.
y;
1102 wxXmlNode* packages =
MapChildren( aLib )[
"packages"];
1114 wxXmlNode*
package = packages->GetChildren();
1120 m_xpath->push(
"package",
"name" );
1122 wxString pack_ref = package->GetAttribute(
"name" );
1125 m_xpath->Value( pack_ref.ToUTF8() );
1127 wxString key = aLibName ?
makeKey( *aLibName, pack_ref ) : pack_ref;
1129 FOOTPRINT* footprint = makeFootprint( package, pack_ref );
1132 auto r = m_templates.insert( { key, footprint } );
1136 wxString lib = aLibName ? *aLibName : m_lib_path;
1137 const wxString& pkg = pack_ref;
1139 wxString emsg = wxString::Format(
_(
"<package> '%s' duplicated in <library> '%s'" ),
1147 package = package->GetNext();
1159 m_xpath->push(
"libraries.library",
"name" );
1162 wxXmlNode*
library = aLibs->GetChildren();
1166 const wxString& lib_name =
library->GetAttribute(
"name" );
1168 m_xpath->Value( lib_name.c_str() );
1169 loadLibrary(
library, &lib_name );
1182 m_xpath->push(
"elements.element",
"name" );
1186 bool refanceNamePresetInPackageLayout;
1187 bool valueNamePresetInPackageLayout;
1190 wxXmlNode* element = aElements->GetChildren();
1196 if( element->GetName() != wxT(
"element" ) )
1199 element = element->GetNext();
1206 EATTR* nameAttr =
nullptr;
1207 EATTR* valueAttr =
nullptr;
1209 m_xpath->Value( e.
name.c_str() );
1212 auto it = m_templates.find( pkg_key );
1214 if( it == m_templates.end() )
1216 wxString emsg = wxString::Format(
_(
"No '%s' package in library '%s'." ),
1223 m_board->
Add( footprint, ADD_MODE::APPEND );
1231 if( ni != m_pads_to_nets.end() )
1233 const ENET* enet = &ni->second;
1238 refanceNamePresetInPackageLayout =
true;
1239 valueNamePresetInPackageLayout =
true;
1246 refanceNamePresetInPackageLayout =
false;
1250 if( footprint->
GetValue().size() == 0 )
1253 valueNamePresetInPackageLayout =
false;
1256 wxString reference = e.
name;
1262 if( reference.find_first_not_of(
"0123456789" ) != 0 )
1263 reference.Prepend(
"UNK" );
1267 if( reference.find_first_not_of(
"#" ) != 0 )
1268 reference.Prepend(
"UNK" );
1271 if( reference.find_last_not_of(
"0123456789" ) == (reference.Length()-1) )
1272 reference.Append(
"0" );
1280 if( valueNamePresetInPackageLayout )
1283 if( refanceNamePresetInPackageLayout )
1293 m_xpath->push(
"attribute",
"name" );
1303 wxXmlNode* attribute = element->GetChildren();
1307 if( attribute->GetName() != wxT(
"attribute" ) )
1309 attribute = attribute->GetNext();
1313 EATTR a( attribute );
1315 if( a.
name == wxT(
"NAME" ) )
1328 nameAttr->
name = reference;
1330 if( refanceNamePresetInPackageLayout )
1337 if( refanceNamePresetInPackageLayout )
1346 if( refanceNamePresetInPackageLayout )
1349 nameAttr->
name = nameAttr->
name + wxT(
" = " ) + e.
name;
1360 if( refanceNamePresetInPackageLayout )
1370 else if( a.
name == wxT(
"VALUE" ) )
1384 if( valueNamePresetInPackageLayout )
1390 if( valueNamePresetInPackageLayout )
1393 footprint->
SetValue( wxT(
"VALUE" ) );
1397 if( valueNamePresetInPackageLayout )
1411 if( valueNamePresetInPackageLayout )
1423 attribute = attribute->GetNext();
1429 orientFootprintAndText( footprint, e, nameAttr, valueAttr );
1432 element = element->GetNext();
1449 wxLogMessage( wxString::Format(
_(
"Ignoring a polygon since Eagle layer '%s' (%d) "
1459 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( m_board );
1462 zone->SetLayer( layer );
1464 setKeepoutSettingsToZone( zone.get(), p.
layer );
1467 wxXmlNode* vertex = aPolyNode->GetChildren();
1468 std::vector<EVERTEX> vertices;
1476 if( vertex->GetName() == wxT(
"vertex" ) )
1477 vertices.emplace_back( vertex );
1479 vertex = vertex->GetNext();
1485 zone->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::ALWAYS );
1487 zone->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::NEVER );
1489 vertices.push_back( vertices[0] );
1494 for(
size_t i = 0; i < vertices.size() - 1; i++ )
1508 double end_angle = atan2( kicad_y(
v2.
y ) - center.
y, kicad_x(
v2.
x ) - center.
x );
1509 double radius = sqrt( pow( center.
x - kicad_x(
v1.
x ), 2 )
1510 + pow( center.
y - kicad_y(
v1.
y ), 2 ) );
1514 double delta_angle = angle / segCount;
1516 for(
double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta_angle );
1520 KiROUND( radius * sin( a ) ) + center.
y );
1535 wxLogMessage( wxString::Format(
1536 _(
"Skipping a polygon on layer '%s' (%d): outline count is not 1" ),
1542 zone->AddPolygon( polygon.
COutline( 0 ) );
1547 zone->SetIsRuleArea(
true );
1548 zone->SetDoNotAllowVias(
false );
1549 zone->SetDoNotAllowTracks(
false );
1550 zone->SetDoNotAllowPads(
false );
1551 zone->SetDoNotAllowFootprints(
false );
1552 zone->SetDoNotAllowCopperPour(
true );
1553 zone->SetHatchStyle( ZONE_BORDER_DISPLAY_STYLE::NO_HATCH );
1559 zone->SetFillMode( ZONE_FILL_MODE::HATCH_PATTERN );
1562 zone->SetHatchOrientation(
ANGLE_0 );
1573 zone->SetLocalClearance( 1 );
1577 zone->SetPadConnection( thermals ? ZONE_CONNECTION::THERMAL : ZONE_CONNECTION::FULL );
1590 zone->SetAssignedPriority( rank );
1592 return zone.release();
1597 const EATTR* aNameAttr,
const EATTR* aValueAttr )
1612 orientFPText( aFootprint, e, &aFootprint->
Reference(), aNameAttr );
1613 orientFPText( aFootprint, e, &aFootprint->
Value(), aValueAttr );
1618 const EATTR* aAttr )
1624 const EATTR& a = *aAttr;
1633 VECTOR2I pos( kicad_x( *a.
x ), kicad_y( *a.
y ) );
1645 int textThickness =
KiROUND( fontz.
y * ratio / 100 );
1650 fontz = kicad_fontsize( *a.
size, textThickness );
1676 if( degrees == 90 || degrees == 0 || spin )
1680 else if( degrees == 180 )
1685 else if( degrees == 270 )
1754 if( ( !aFPText->
IsMirrored() && (
abs( degrees ) == 180 ||
abs( degrees ) == 270 ) )
1755 || ( aFPText->
IsMirrored() && ( degrees == 360 ) ) )
1767 std::unique_ptr<FOOTPRINT> m = std::make_unique<FOOTPRINT>( m_board );
1770 fpID.
Parse( aPkgName,
true );
1774 wxXmlNode* packageItem = aPackage->GetChildren();
1779 m.get()->Value().SetLayer( layer );
1781 while( packageItem )
1783 const wxString& itemName = packageItem->GetName();
1785 if( itemName == wxT(
"description" ) )
1786 m->SetLibDescription( packageItem->GetNodeContent() );
1787 else if( itemName == wxT(
"wire" ) )
1788 packageWire( m.get(), packageItem );
1789 else if( itemName == wxT(
"pad" ) )
1790 packagePad( m.get(), packageItem );
1791 else if( itemName == wxT(
"text" ) )
1792 packageText( m.get(), packageItem );
1793 else if( itemName == wxT(
"rectangle" ) )
1794 packageRectangle( m.get(), packageItem );
1795 else if( itemName == wxT(
"polygon" ) )
1796 packagePolygon( m.get(), packageItem );
1797 else if( itemName == wxT(
"circle" ) )
1798 packageCircle( m.get(), packageItem );
1799 else if( itemName == wxT(
"hole" ) )
1800 packageHole( m.get(), packageItem,
false );
1801 else if( itemName == wxT(
"smd" ) )
1802 packageSMD( m.get(), packageItem );
1804 packageItem = packageItem->GetNext();
1821 wxLogMessage( wxString::Format(
_(
"Ignoring a wire since Eagle layer '%s' (%d) "
1860 dwg =
new PCB_SHAPE( aFootprint, SHAPE_T::SEGMENT );
1867 dwg =
new PCB_SHAPE( aFootprint, SHAPE_T::ARC );
1880 aFootprint->
Add( dwg );
1891 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
1892 transferPad( e,
pad.get() );
1895 shape = m_rules->psFirst;
1897 shape = m_rules->psTop;
1899 shape = m_rules->psBottom;
1901 pad->SetDrillSize(
VECTOR2I( eagleDrillz, eagleDrillz ) );
1904 if( eagleDrillz < m_min_hole )
1905 m_min_hole = eagleDrillz;
1919 pad->SetShape( PAD_SHAPE::CIRCLE );
1923 pad->SetShape( PAD_SHAPE::CHAMFERED_RECT );
1925 pad->SetChamferRectRatio( 1 - M_SQRT1_2 );
1929 pad->SetShape( PAD_SHAPE::OVAL );
1933 pad->SetShape( PAD_SHAPE::RECTANGLE );
1937 pad->SetShape( PAD_SHAPE::OVAL );
1953 double drillz =
pad->GetDrillSize().x;
1954 double annulus = drillz * m_rules->rvPadTop;
1955 annulus =
eagleClamp( m_rules->rlMinPadTop, annulus, m_rules->rlMaxPadTop );
1956 int diameter =
KiROUND( drillz + 2 * annulus );
1960 if(
pad->GetShape() == PAD_SHAPE::OVAL )
1964 sz.
x = ( sz.
x * ( 100 + m_rules->psElongationLong ) ) / 100;
1969 int offset =
KiROUND( ( sz.
x - sz.
y ) / 2.0 );
1980 if(
pad->GetSizeX() > 0 &&
pad->GetSizeY() > 0 )
1982 aFootprint->
Add(
pad.release() );
1986 wxLogError(
_(
"Invalid zero-sized pad ignored in\nfile: %s" ), m_board->GetFileName() );
1998 wxLogMessage( wxString::Format(
_(
"Ignoring a text since Eagle layer '%s' (%d) "
2006 if( t.
text.Upper() == wxT(
">NAME" ) && aFootprint->
GetReference().IsEmpty() )
2010 textItem->
SetText( wxT(
"REF**" ) );
2012 else if( t.
text.Upper() == wxT(
">VALUE" ) && aFootprint->
GetValue().IsEmpty() )
2014 textItem = &aFootprint->
Value();
2020 textItem =
new PCB_TEXT( aFootprint );
2021 aFootprint->
Add( textItem );
2026 VECTOR2I pos( kicad_x( t.
x ), kicad_y( t.
y ) );
2049 if( degrees == 90 || t.
rot->
spin )
2053 else if( degrees == 180 )
2057 else if( degrees == 270 )
2121 ZONE* zone =
new ZONE( aFootprint );
2122 aFootprint->
Add( zone, ADD_MODE::APPEND );
2124 setKeepoutSettingsToZone( zone, r.
layer );
2126 const int outlineIdx = -1;
2134 VECTOR2I center( ( kicad_x( r.
x1 ) + kicad_x( r.
x2 ) ) / 2,
2135 ( kicad_y( r.
y1 ) + kicad_y( r.
y2 ) ) / 2 );
2148 wxLogMessage( wxString::Format(
_(
"Ignoring a rectangle since Eagle layer '%s' (%d) "
2156 aFootprint->
Add( dwg );
2162 std::vector<VECTOR2I> pts;
2167 pts.push_back( start );
2168 pts.emplace_back( kicad_x( r.
x2 ), kicad_y( r.
y1 ) );
2169 pts.emplace_back( kicad_x( r.
x2 ), kicad_y( r.
y2 ) );
2170 pts.push_back( end );
2187 std::vector<VECTOR2I> pts;
2190 wxXmlNode* vertex = aTree->GetChildren();
2191 std::vector<EVERTEX> vertices;
2199 if( vertex->GetName() == wxT(
"vertex" ) )
2200 vertices.emplace_back( vertex );
2202 vertex = vertex->GetNext();
2205 vertices.push_back( vertices[0] );
2207 for(
size_t i = 0; i < vertices.size() - 1; i++ )
2212 pts.emplace_back( kicad_x(
v1.
x ), kicad_y(
v1.
y ) );
2221 double end_angle = atan2( kicad_y(
v2.
y ) - center.
y, kicad_x(
v2.
x ) - center.
x );
2222 double radius = sqrt( pow( center.
x - kicad_x(
v1.
x ), 2 )
2223 + pow( center.
y - kicad_y(
v1.
y ), 2 ) );
2231 double delta = angle / segCount;
2233 for(
double a = end_angle + angle; fabs( a - end_angle ) > fabs(
delta ); a -=
delta )
2249 ZONE* zone =
new ZONE( aFootprint );
2250 aFootprint->
Add( zone, ADD_MODE::APPEND );
2252 setKeepoutSettingsToZone( zone, p.
layer );
2265 wxLogMessage( wxString::Format(
_(
"Ignoring a polygon since Eagle layer '%s' (%d) "
2273 aFootprint->
Add( dwg );
2299 ZONE* zone =
new ZONE( aFootprint );
2300 aFootprint->
Add( zone, ADD_MODE::APPEND );
2302 setKeepoutSettingsToZone( zone, e.
layer );
2305 VECTOR2I center( kicad_x( e.
x ), kicad_y( e.
y ) );
2306 int outlineRadius = radius + ( width / 2 );
2312 VECTOR2I rotatedPoint( outlineRadius, 0 );
2320 int innerRadius = radius - ( width / 2 );
2326 VECTOR2I rotatedPoint( innerRadius, 0 );
2341 wxLogMessage( wxString::Format(
_(
"Ignoring a circle since Eagle layer '%s' (%d) "
2353 radius = radius / 2;
2357 aFootprint->
Add( gr );
2360 switch( (
int) layer )
2389 pad->SetKeepTopBottom(
false );
2391 pad->SetShape( PAD_SHAPE::CIRCLE );
2392 pad->SetAttribute( PAD_ATTRIB::NPTH );
2399 VECTOR2I padpos( kicad_x( e.
x ), kicad_y( e.
y ) );
2404 pad->SetPosition( padpos );
2413 pad->SetDrillSize( sz );
2430 transferPad( e,
pad );
2432 pad->SetKeepTopBottom(
false );
2434 pad->SetShape( PAD_SHAPE::RECTANGLE );
2435 pad->SetAttribute( PAD_ATTRIB::SMD );
2438 pad->SetSize( padSize );
2439 pad->SetLayer( layer );
2445 pad->SetLayerSet( front );
2446 else if( layer ==
B_Cu )
2447 pad->SetLayerSet( back );
2449 int minPadSize = std::min( padSize.
x, padSize.
y );
2453 eagleClamp( m_rules->srMinRoundness * 2, (
int) ( minPadSize * m_rules->srRoundness ),
2454 m_rules->srMaxRoundness * 2 );
2458 double roundRatio = (double) roundRadius / minPadSize / 2.0;
2462 roundRatio = std::fmax( *e.
roundness / 200.0, roundRatio );
2464 pad->SetShape( PAD_SHAPE::ROUNDRECT );
2465 pad->SetRoundRectRadiusRatio( roundRatio );
2474 pad->SetLocalSolderPasteMargin( -
eagleClamp( m_rules->mlMinCreamFrame,
2475 (
int) ( m_rules->mvCreamFrame * minPadSize ),
2476 m_rules->mlMaxCreamFrame ) );
2482 pad->SetLayerSet(
pad->GetLayerSet().set(
F_Mask,
false ) );
2483 else if( layer ==
B_Cu )
2484 pad->SetLayerSet(
pad->GetLayerSet().set(
B_Mask,
false ) );
2491 pad->SetLayerSet(
pad->GetLayerSet().set(
F_Paste,
false ) );
2492 else if( layer ==
B_Cu )
2493 pad->SetLayerSet(
pad->GetLayerSet().set(
B_Paste,
false ) );
2502 VECTOR2I padPos( kicad_x( aEaglePad.
x ), kicad_y( aEaglePad.
y ) );
2509 (
int) ( m_rules->mvStopFrame * std::min( padSize.
x, padSize.
y ) ),
2510 m_rules->mlMaxStopFrame ) );
2517 wxCHECK( footprint, );
2525 for(
const auto& [
name, footprint ] : m_templates )
2527 footprint->SetParent(
nullptr );
2531 m_templates.clear();
2539 m_xpath->push(
"classes.class",
"number" );
2541 std::vector<ECLASS> eClasses;
2542 wxXmlNode* classNode = aClasses->GetChildren();
2548 ECLASS eClass( classNode );
2549 std::shared_ptr<NETCLASS> netclass;
2551 if( eClass.
name.CmpNoCase( wxT(
"default" ) ) == 0 )
2561 netclass->SetTrackWidth( INT_MAX );
2562 netclass->SetViaDiameter( INT_MAX );
2563 netclass->SetViaDrill( INT_MAX );
2565 eClasses.emplace_back( eClass );
2566 m_classMap[ eClass.
number ] = netclass;
2569 classNode = classNode->GetNext();
2572 m_customRules = wxT(
"(version 1)" );
2574 for(
ECLASS& eClass : eClasses )
2576 for( std::pair<const wxString&, ECOORD> entry : eClass.clearanceMap )
2578 if( m_classMap[ entry.first ] !=
nullptr )
2581 rule.Printf( wxT(
"(rule \"class %s:%s\"\n"
2582 " (condition \"A.NetClass == '%s' && B.NetClass == '%s'\")\n"
2583 " (constraint clearance (min %smm)))\n" ),
2587 m_classMap[ entry.first ]->GetName(),
2590 m_customRules += wxT(
"\n" ) + rule;
2604 m_xpath->push(
"signals.signal",
"name" );
2607 wxXmlNode* net = aSignals->GetChildren();
2613 bool sawPad =
false;
2617 const wxString& netName =
escapeName( net->GetAttribute(
"name" ) );
2619 std::shared_ptr<NETCLASS> netclass;
2621 if( net->HasAttribute(
"class" ) )
2623 auto netclassIt = m_classMap.find( net->GetAttribute(
"class" ) );
2625 if( netclassIt != m_classMap.end() )
2627 m_board->GetDesignSettings().m_NetSettings->m_NetClassPatternAssignments.push_back(
2628 { std::make_unique<EDA_COMBINED_MATCHER>( netName,
CTX_NETCLASS ),
2629 netclassIt->second->GetName() } );
2632 netclass = netclassIt->second;
2636 m_board->Add( netInfo );
2638 m_xpath->Value( netName.c_str() );
2641 wxXmlNode* netItem = net->GetChildren();
2646 const wxString& itemName = netItem->GetName();
2648 if( itemName == wxT(
"wire" ) )
2650 m_xpath->push(
"wire" );
2659 double end_angle = 0.0;
2660 double radius = 0.0;
2661 double delta_angle = 0.0;
2666 if( width < m_min_trace )
2667 m_min_trace = width;
2669 if( netclass && width < netclass->GetTrackWidth() )
2670 netclass->SetTrackWidth( width );
2680 end_angle = atan2( kicad_y( w.
y2 ) - center.
y,
2681 kicad_x( w.
x2 ) - center.
x );
2683 radius = sqrt( pow( center.
x - kicad_x( w.
x1 ), 2 ) +
2684 pow( center.
y - kicad_y( w.
y1 ), 2 ) );
2688 delta_angle = angle / segs;
2691 while( fabs( angle ) > fabs( delta_angle ) )
2693 wxASSERT( radius > 0.0 );
2695 KiROUND( radius * sin( end_angle + angle ) + center.
y ) );
2708 angle -= delta_angle;
2728 else if( itemName == wxT(
"via" ) )
2730 m_xpath->push(
"via" );
2740 && layer_front_most != layer_back_most )
2745 m_board->Add(
via );
2750 via->SetWidth( kidiam );
2754 double annulus = drillz * m_rules->rvViaOuter;
2755 annulus =
eagleClamp( m_rules->rlMinViaOuter, annulus,
2756 m_rules->rlMaxViaOuter );
2757 kidiam =
KiROUND( drillz + 2 * annulus );
2758 via->SetWidth( kidiam );
2761 via->SetDrill( drillz );
2765 if( !v.
diam ||
via->GetWidth() <=
via->GetDrill() )
2769 (
double) (
via->GetWidth() / 2 -
via->GetDrill() ),
2770 m_rules->rlMaxViaOuter );
2771 via->SetWidth( drillz + 2 * annulus );
2774 if( kidiam < m_min_via )
2777 if( netclass && kidiam < netclass->GetViaDiameter() )
2778 netclass->SetViaDiameter( kidiam );
2780 if( drillz < m_min_hole )
2781 m_min_hole = drillz;
2783 if( netclass && drillz < netclass->GetViaDrill() )
2784 netclass->SetViaDrill( drillz );
2786 if( ( kidiam - drillz ) / 2 < m_min_annulus )
2787 m_min_annulus = ( kidiam - drillz ) / 2;
2789 if( layer_front_most ==
F_Cu && layer_back_most ==
B_Cu )
2791 via->SetViaType( VIATYPE::THROUGH );
2798 via->SetViaType( VIATYPE::MICROVIA );
2802 via->SetViaType( VIATYPE::BLIND_BURIED );
2805 VECTOR2I pos( kicad_x( v.
x ), kicad_y( v.
y ) );
2807 via->SetLayerPair( layer_front_most, layer_back_most );
2808 via->SetPosition( pos );
2811 via->SetNetCode( netCode );
2817 else if( itemName == wxT(
"contactref" ) )
2819 m_xpath->push(
"contactref" );
2822 const wxString& reference = netItem->GetAttribute(
"element" );
2823 const wxString&
pad = netItem->GetAttribute(
"pad" );
2826 m_pads_to_nets[ key ] =
ENET( netCode, netName );
2833 else if( itemName == wxT(
"polygon" ) )
2835 m_xpath->push(
"polygon" );
2836 auto* zone = loadPolygon( netItem );
2840 zones.push_back( zone );
2842 if( !zone->GetIsRuleArea() )
2843 zone->SetNetCode( netCode );
2849 netItem = netItem->GetNext();
2852 if( zones.size() && !sawPad )
2856 for(
ZONE* zone : zones )
2867 net = net->GetNext();
2875 const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector )
2877 std::map<wxString, PCB_LAYER_ID> layer_map;
2881 PCB_LAYER_ID layerId = std::get<0>( defaultKicadLayer( eagle_layer_id( layer.Name ) ) );
2882 layer_map.emplace( layer.Name, layerId );
2891 std::vector<INPUT_LAYER_DESC> inputDescs;
2893 for (
const std::pair<const int, ELAYER>& layerPair : m_eagleLayers )
2895 const ELAYER& eLayer = layerPair.second;
2899 defaultKicadLayer( eLayer.
number, aIsLibraryCache );
2906 inputDescs.push_back( layerDesc );
2909 if( m_progressReporter &&
dynamic_cast<wxWindow*
>( m_progressReporter ) )
2910 dynamic_cast<wxWindow*
>( m_progressReporter )->Hide();
2912 m_layer_map = m_layer_mapping_handler( inputDescs );
2914 if( m_progressReporter &&
dynamic_cast<wxWindow*
>( m_progressReporter ))
2915 dynamic_cast<wxWindow*
>( m_progressReporter )->Show();
2921 auto result = m_layer_map.find( eagle_layer_name( aEagleLayer ) );
2922 return result == m_layer_map.end() ?
UNDEFINED_LAYER : result->second;
2927 bool aIsLibraryCache )
const
2930 if( aEagleLayer >= 1 && aEagleLayer <
int(
arrayDim( m_cu_map ) ) )
2934 for(
int copperLayer : m_cu_map )
2936 if( copperLayer >= 0 )
2937 copperLayers[copperLayer] =
true;
2940 return {
PCB_LAYER_ID( m_cu_map[aEagleLayer] ), copperLayers,
true };
2944 bool required =
false;
2945 LSET permittedLayers;
2947 permittedLayers.set();
2950 switch( aEagleLayer )
3048 if( aIsLibraryCache )
3056 return {
PCB_LAYER_ID( kiLayer ), permittedLayers, required };
3062 static const wxString
unknown(
"unknown" );
3063 auto it = m_eagleLayers.find( aLayer );
3064 return it == m_eagleLayers.end() ?
unknown : it->second.name;
3070 static const int unknown = -1;
3071 auto it = m_eagleLayersIds.find( aLayerName );
3072 return it == m_eagleLayersIds.end() ?
unknown : it->second;
3083 if( m_props->Value(
"page_width", &page_width ) &&
3084 m_props->Value(
"page_height", &page_height ) )
3086 BOX2I bbbox = m_board->GetBoardEdgesBoundingBox();
3088 int w = atoi( page_width.
c_str() );
3089 int h = atoi( page_height.
c_str() );
3091 int desired_x = ( w - bbbox.
GetWidth() ) / 2;
3092 int desired_y = ( h - bbbox.
GetHeight() ) / 2;
3094 m_board->Move(
VECTOR2I( desired_x - bbbox.
GetX(), desired_y - bbbox.
GetY() ) );
3103 if( aPath.IsEmpty() )
3104 return wxDateTime::Now();
3106 wxFileName fn( aPath );
3108 if( fn.IsFileReadable() )
3109 return fn.GetModificationTime();
3111 return wxDateTime( 0.0 );
3119 wxDateTime modtime = getModificationTime( aLibPath );
3124 bool load = !m_mod_time.IsValid() || !modtime.IsValid() || m_mod_time != modtime;
3126 if( aLibPath != m_lib_path || load )
3136 m_lib_path = aLibPath;
3141 string filename = (
const char*) aLibPath.char_str( wxConvFile );
3144 wxFileName fn( filename );
3145 wxFFileInputStream stream( fn.GetFullPath() );
3146 wxXmlDocument xmlDocument;
3148 if( !stream.IsOk() || !xmlDocument.Load( stream ) )
3151 fn.GetFullPath() ) );
3154 doc = xmlDocument.GetRoot();
3156 wxXmlNode* drawing =
MapChildren( doc )[
"drawing"];
3162 m_xpath->push(
"eagle.drawing.layers" );
3163 wxXmlNode* layers = drawingChildren[
"layers"];
3164 loadLayerDefs( layers );
3165 mapEagleLayersToKicad(
true );
3168 m_xpath->push(
"eagle.drawing.library" );
3169 wxXmlNode*
library = drawingChildren[
"library"];
3170 loadLibrary(
library,
nullptr );
3173 m_mod_time = modtime;
3204 init( aProperties );
3208 cacheLib( aLibraryPath );
3212 errorMsg = ioe.
What();
3218 for(
const auto& [
name, footprint ] : m_templates )
3219 aFootprintNames.Add(
name );
3221 if( !errorMsg.IsEmpty() && !aBestEfforts )
3227 const wxString& aFootprintName,
bool aKeepUUID,
3230 init( aProperties );
3231 cacheLib( aLibraryPath );
3232 auto it = m_templates.find( aFootprintName );
3234 if( it == m_templates.end() )
3239 copy->SetParent(
nullptr );
3251 int minLayerCount = 2;
3253 std::map<wxString, PCB_LAYER_ID>::const_iterator it;
3255 for( it = m_layer_map.begin(); it != m_layer_map.end(); ++it )
3260 && ( layerId + 2 ) > minLayerCount )
3261 minLayerCount = layerId + 2;
3267 if( ( minLayerCount % 2 ) != 0 )
3270 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
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
Container for design settings for a BOARD object.
std::shared_ptr< NET_SETTINGS > m_NetSettings
VECTOR2I GetTextSize(PCB_LAYER_ID aLayer) const
Return the default text size from the layer class for the given layer.
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
int m_ViasMinAnnularWidth
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
FOOTPRINT * GetParentFootprint() const
Information pertinent to a Pcbnew printed circuit board.
bool m_LegacyDesignSettingsLoaded
True if the legacy board design settings were loaded from a file.
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
void SetFileName(const wxString &aFileName)
bool SetLayerName(PCB_LAYER_ID aLayer, const wxString &aLayerName)
Changes the name of the layer given by aLayer.
bool m_LegacyNetclassesLoaded
True if netclasses were loaded from the file.
void SetCopperLayerCount(int aCount)
bool SetLayerType(PCB_LAYER_ID aLayer, LAYER_T aLayerType)
Change the type of the layer given by aLayer.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
coord_type GetHeight() const
coord_type GetWidth() const
void cacheLib(const wxString &aLibraryPath)
This PLUGIN only caches one footprint library, this determines which one.
void FootprintLibOptions(STRING_UTF8_MAP *aProperties) const override
Append supported PLUGIN options to aListToAppenTo along with internationalized descriptions.
int m_hole_count
generates unique footprint names from eagle "hole"s.
FOOTPRINT * makeFootprint(wxXmlNode *aPackage, const wxString &aPkgName)
Create a FOOTPRINT from an Eagle package.
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
void loadPlain(wxXmlNode *aPlain)
void packageCircle(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
void packageSMD(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
Handles common pad properties.
std::map< wxString, FOOTPRINT * > m_templates
is part of a FOOTPRINT factory that operates using copy construction.
static wxDateTime getModificationTime(const wxString &aPath)
get a file's or dir's modification time.
unsigned m_totalCount
for progress reporting
ERULES * m_rules
Eagle design rules.
void packagePolygon(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
void setKeepoutSettingsToZone(ZONE *aZone, int aLayer) const
int m_min_annulus
smallest via annulus we find on Load(), in BIU.
void loadAllSections(wxXmlNode *aDocument)
BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const STRING_UTF8_MAP *aProperties=nullptr, PROJECT *aProject=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr) override
Load information from some input file format that this PLUGIN implementation knows about into either ...
void orientFootprintAndText(FOOTPRINT *aFootprint, const EELEMENT &e, const EATTR *aNameAttr, const EATTR *aValueAttr)
std::map< wxString, PCB_LAYER_ID > DefaultLayerMappingCallback(const std::vector< INPUT_LAYER_DESC > &aInputLayerDescriptionVector)
Return the automapped layers.
std::vector< ELAYER > ELAYERS
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...
void mapEagleLayersToKicad(bool aIsLibraryCache=false)
Generate mapping between Eagle and KiCad layers.
void loadLibrary(wxXmlNode *aLib, const wxString *aLibName)
Load the Eagle "library" XML element, which can occur either under a "libraries" element (if a *....
int kicad_x(const ECOORD &x) const
NET_MAP m_pads_to_nets
net list
void loadLibraries(wxXmlNode *aLibs)
void init(const STRING_UTF8_MAP *aProperties)
initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
std::vector< FOOTPRINT * > GetImportedCachedLibraryFootprints() override
Return a container with the cached library footprints generated in the last call to Load.
const wxString & eagle_layer_name(int aLayer) const
Get Eagle layer name by its number.
void packageText(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
int m_min_trace
smallest trace we find on Load(), in BIU.
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
bool CanReadFootprint(const wxString &aFileName) const override
Checks if this PLUGIN can read a footprint from specified file or directory.
void packageHole(FOOTPRINT *aFootprint, wxXmlNode *aTree, bool aCenter) const
bool CanReadFootprintLib(const wxString &aFileName) const override
Checks if this PLUGIN can read footprint library from specified file or directory.
bool CanReadBoard(const wxString &aFileName) const override
Checks if this PLUGIN can read the specified board file.
int m_cu_map[17]
map eagle to KiCad, cu layers only.
void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aLibraryPath, bool aBestEfforts, const STRING_UTF8_MAP *aProperties=nullptr) override
Return a list of footprint names contained within the library at aLibraryPath.
void loadLayerDefs(wxXmlNode *aLayers)
FOOTPRINT * FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const STRING_UTF8_MAP *aProperties=nullptr) override
Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PL...
int m_min_via
smallest via we find on Load(), in BIU.
unsigned m_lastProgressCount
void centerBoard()
move the BOARD into the center of the page
void packagePad(FOOTPRINT *aFootprint, wxXmlNode *aTree)
ZONE * loadPolygon(wxXmlNode *aPolyNode)
Load a copper or keepout polygon and adds it to the board.
void transferPad(const EPAD_COMMON &aEaglePad, PAD *aPad) const
Deletes the footprint templates list.
void orientFPText(FOOTPRINT *aFootprint, const EELEMENT &e, PCB_TEXT *aFPText, const EATTR *aAttr)
void loadDesignRules(wxXmlNode *aDesignRules)
VECTOR2I kicad_fontsize(const ECOORD &d, int aTextThickness) const
create a font size (fontz) from an eagle font size scalar and KiCad font thickness
void loadSignals(wxXmlNode *aSignals)
const STRING_UTF8_MAP * m_props
passed via Save() or Load(), no ownership, may be NULL.
void packageWire(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
int getMinimumCopperLayerCount() const
Determines the minimum copper layer stackup count that includes all mapped layers.
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
std::map< int, ELAYER > m_eagleLayers
Eagle layer data stored by layer number.
ELAYERS::const_iterator EITER
std::map< wxString, int > m_eagleLayersIds
Eagle layer ids stored by layer name.
void packageRectangle(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
void loadClasses(wxXmlNode *aClasses)
int eagle_layer_id(const wxString &aLayerName) const
Get Eagle layer number by its name.
BOARD * m_board
which BOARD is being worked on, no ownership here
void loadElements(wxXmlNode *aElements)
bool checkHeader(const wxString &aFileName) const
int m_min_hole
smallest diameter hole we find on Load(), in BIU.
void SetCenter(const VECTOR2I &aCenter)
SHAPE_POLY_SET & GetPolyShape()
void SetFilled(bool aFlag)
void SetStart(const VECTOR2I &aStart)
void SetShape(SHAPE_T aShape)
void SetEnd(const VECTOR2I &aEnd)
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
void SetPolyPoints(const std::vector< VECTOR2I > &aPoints)
void SetTextSize(VECTOR2I aNewSize)
const EDA_ANGLE & GetTextAngle() const
void SetTextPos(const VECTOR2I &aPoint)
void SetMirrored(bool isMirrored)
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
VECTOR2I GetTextSize() const
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
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 RegisterLayerMappingCallback(LAYER_MAPPING_HANDLER aLayerMappingHandler)
Register a different handler to be called when mapping of input layers to KiCad layers occurs.
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
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
LSET is a set of PCB_LAYER_IDs.
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
A collection of nets and the parameters used to route or test these nets.
int GetViaDiameter() const
int GetTrackWidth() const
Handle the data for a net.
void SetNetClass(const std::shared_ptr< NETCLASS > &aNetClass)
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
T & Get()
Return a reference to the value of the attribute assuming it is available.
void SetNumber(const wxString &aNumber)
Set the pad number (note that it can be alphanumeric, such as the array reference "AA12").
void SetZoneConnection(ZONE_CONNECTION aType)
void SetPosition(const VECTOR2I &aPos) override
void SetLocalSolderMaskMargin(int aMargin)
const VECTOR2I & GetSize() const
void SetUnits(EDA_UNITS aUnits)
void SetLineThickness(int aWidth)
virtual void SetEnd(const VECTOR2I &aPoint)
void SetPrecision(DIM_PRECISION aPrecision)
virtual void SetStart(const VECTOR2I &aPoint)
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.
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
virtual void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
virtual void Move(const VECTOR2I &aMoveVector) override
Move this object.
void SetStroke(const STROKE_PARAMS &aStroke) override
virtual void SetPosition(const VECTOR2I &aPos) override
void SetWidth(int aWidth)
void SetEnd(const VECTOR2I &aEnd)
void SetPosition(const VECTOR2I &aPos) override
virtual bool CanReadFootprintLib(const wxString &aFileName) const
Checks if this PLUGIN can read footprint library from specified file or directory.
virtual bool CanReadBoard(const wxString &aFileName) const
Checks if this PLUGIN can read the specified board file.
virtual void FootprintLibOptions(STRING_UTF8_MAP *aListToAppendTo) const
Append supported PLUGIN options to aListToAppenTo along with internationalized descriptions.
A progress reporter interface for use in multi-threaded environments.
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
virtual void Report(const wxString &aMessage)=0
Display aMessage in the progress bar dialog.
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).
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.
@ ALLOW_ACUTE_CORNERS
just inflate the polygon. Acute angles create spikes
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
A name/value tuple with unique names and optional values.
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
Keep track of what we are working on within a PTREE.
void push(const char *aPathSegment, const char *aAttribute="")
wxString Contents()
return the contents of the XPATH as a single string
Handle a list of polygons defining a copper zone.
void SetDoNotAllowPads(bool aEnable)
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aBorderHatchStyle, int aBorderHatchPitch, bool aRebuilBorderdHatch)
Set all hatch parameters for the zone.
void SetDoNotAllowCopperPour(bool aEnable)
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.
void SetIsRuleArea(bool aEnable)
void SetDoNotAllowTracks(bool aEnable)
void Rotate(const VECTOR2I &aCentre, const EDA_ANGLE &aAngle) override
Rotate the outlines.
void SetDoNotAllowVias(bool aEnable)
VECTOR2I GetPosition() const override
void SetLayerSet(LSET aLayerSet) override
void SetDoNotAllowFootprints(bool aEnable)
bool AppendCorner(VECTOR2I aPosition, int aHoleIdx, bool aAllowDuplication=false)
Add a new corner to the zone outline (to the main outline or a hole)
static int GetDefaultHatchPitch()
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Provide an easy access to the children of an XML node via their names.
wxString escapeName(const wxString &aNetName)
Interprets special characters in Eagle text and converts them to KiCAD notation.
wxString interpretText(const wxString &aText)
Translates Eagle special text reference to a KiCad variable reference.
VECTOR2I ConvertArcCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, double aAngle)
OPTIONAL_XML_ATTRIBUTE< wxString > opt_wxString
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
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
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)
std::vector< ZONE * > ZONES
NET_MAP::const_iterator NET_MAP_CITER
static constexpr EDA_ANGLE & ANGLE_360
static constexpr EDA_ANGLE & FULL_CIRCLE
static constexpr EDA_ANGLE & ANGLE_0
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)
#define THROW_IO_ERROR(msg)
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
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)
Returns the string from aValue according to aUnits (inch, mm ...) for display.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
bool ReplaceIllegalFileNameChars(std::string *aName, int aReplaceChar)
Checks aName for illegal file name characters.
Parse an Eagle "attribute" XML element.
long long int value
Unit used for the value field.
constexpr int mmToIU(double mm) const
opt_wxString dimensionType
Structure holding common properties for through-hole and SMD pads.
Eagle polygon, without vertices which are parsed as needed.
static const int max_priority
Eagle XML rectangle in binary.
subset of eagle.drawing.board.designrules in the XML document
int psBottom
Shape of the bottom pads.
double mvStopFrame
solderpaste mask, expressed as percentage of the smaller pad/via dimension
double srRoundness
corner rounding ratio for SMD pads (percentage)
double rlMinViaOuter
minimum copper annulus on via
int mlMaxCreamFrame
solder paste mask, maximum size (Eagle mils, here nanometers)
int mlMinCreamFrame
solder paste mask, minimum size (Eagle mils, here nanometers)
int psTop
Shape of the top pads.
double rlMaxViaOuter
maximum copper annulus on via
void parse(wxXmlNode *aRules, std::function< void()> aCheckpoint)
percent over 100%.
double mdWireWire
wire to wire spacing I presume.
double rvPadTop
top pad size as percent of drill size
double rvViaOuter
copper annulus is this percent of via hole
double rlMinPadTop
minimum copper annulus on through hole pads
int psElongationOffset
the offset of the hole within the "long" pad.
int mlMinStopFrame
solder mask, minimum size (Eagle mils, here nanometers)
int srMinRoundness
corner rounding radius, maximum size (Eagle mils, here nanometers)
int mlMaxStopFrame
solder mask, maximum size (Eagle mils, here nanometers)
double rlMaxPadTop
maximum copper annulus on through hole pads
int psFirst
Shape of the first pads.
int layer_back_most
< extent
opt_double curve
range is -359.9..359.9
Implement a simple wrapper around runtime_error to isolate the errors thrown by the Eagle XML parser.
VECTOR2I v2(1, 0)
Test suite for KiCad math code.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
double DEG2RAD(double deg)
double GetLineLength(const VECTOR2I &aPointA, const VECTOR2I &aPointB)
Return the length of a line segment defined by aPointA and aPointB.
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
ZONE_BORDER_DISPLAY_STYLE
Zone border styles.
#define ZONE_THICKNESS_MIN_VALUE_MM