56#include <wx/xml/xml.h>
57#include <wx/filename.h>
59#include <wx/wfstream.h>
60#include <wx/txtstrm.h>
97 ECOORD coord( aDistance, unit );
108 T ret = std::max( aMin, aValue );
109 return std::min( aMax, ret );
115static wxString
makeKey(
const wxString& aFirst,
const wxString& aSecond )
117 wxString key = aFirst +
'\x02' + aSecond;
165 wxXmlNode* child = aRules->GetChildren();
171 if( child->GetName() == wxT(
"param" ) )
173 const wxString&
name = child->GetAttribute( wxT(
"name" ) );
174 const wxString& value = child->GetAttribute( wxT(
"value" ) );
176 if(
name == wxT(
"psElongationLong" ) )
178 else if(
name == wxT(
"psElongationOffset" ) )
180 else if(
name == wxT(
"mvStopFrame" ) )
182 else if(
name == wxT(
"mvCreamFrame" ) )
184 else if(
name == wxT(
"mlMinStopFrame" ) )
186 else if(
name == wxT(
"mlMaxStopFrame" ) )
188 else if(
name == wxT(
"mlMinCreamFrame" ) )
190 else if(
name == wxT(
"mlMaxCreamFrame" ) )
192 else if(
name == wxT(
"srRoundness" ) )
194 else if(
name == wxT(
"srMinRoundness" ) )
196 else if(
name == wxT(
"srMaxRoundness" ) )
198 else if(
name == wxT(
"psTop" ) )
199 psTop = wxAtoi( value );
200 else if(
name == wxT(
"psBottom" ) )
202 else if(
name == wxT(
"psFirst" ) )
204 else if(
name == wxT(
"rvPadTop" ) )
206 else if(
name == wxT(
"rlMinPadTop" ) )
208 else if(
name == wxT(
"rlMaxPadTop" ) )
210 else if(
name == wxT(
"rvViaOuter" ) )
212 else if(
name == wxT(
"rlMinViaOuter" ) )
214 else if(
name == wxT(
"rlMaxViaOuter" ) )
216 else if(
name == wxT(
"mdWireWire" ) )
220 child = child->GetNext();
228 m_xpath( new
XPATH() ),
229 m_progressReporter( nullptr ),
231 m_lastProgressCount( 0 ),
233 m_mod_time( wxDateTime::Now() )
235 using namespace std::placeholders;
277 wxFileInputStream input( aFileName );
282 wxTextInputStream
text( input );
284 for(
int i = 0; i < 4; i++ )
289 if(
text.ReadLine().Contains( wxS(
"<eagle" ) ) )
299 const unsigned PROGRESS_DELTA = 50;
321 return VECTOR2I( kz - aTextThickness, kz - aTextThickness );
342 unique_ptr<BOARD> deleter( aAppendToMe ?
nullptr :
m_board );
354 wxFileName fn = aFileName;
357 wxFFileInputStream stream( fn.GetFullPath() );
358 wxXmlDocument xmlDocument;
360 if( !stream.IsOk() || !xmlDocument.Load( stream ) )
363 fn.GetFullPath() ) );
366 doc = xmlDocument.GetRoot();
392 NETCLASS defaults( wxT(
"dummy" ) );
394 auto finishNetclass =
395 [&]( std::shared_ptr<NETCLASS> netclass )
401 if( netclass->GetTrackWidth() == INT_MAX )
404 if( netclass->GetViaDiameter() == INT_MAX )
407 if( netclass->GetViaDrill() == INT_MAX )
411 std::shared_ptr<NET_SETTINGS>& netSettings = bds.
m_NetSettings;
413 finishNetclass( netSettings->m_DefaultNetClass );
415 for(
const auto& [
name, netclass ] : netSettings->m_NetClasses )
416 finishNetclass( netclass );
421 fn.SetExt( wxT(
"kicad_dru" ) );
422 wxFile rulesFile( fn.GetFullPath(), wxFile::write );
430 wxString errmsg = exc.what();
432 errmsg += wxT(
"\n@ " );
450 std::vector<FOOTPRINT*> retval;
453 retval.push_back(
static_cast<FOOTPRINT*
>( footprint->Clone() ) );
489 wxXmlNode* drawing =
MapChildren( aDoc )[
"drawing"];
492 wxXmlNode* board = drawingChildren[
"board"];
495 auto count_children = [
this]( wxXmlNode* aNode )
499 wxXmlNode* child = aNode->GetChildren();
504 child = child->GetNext();
509 wxXmlNode* designrules = boardChildren[
"designrules"];
510 wxXmlNode* layers = drawingChildren[
"layers"];
511 wxXmlNode* plain = boardChildren[
"plain"];
512 wxXmlNode* classes = boardChildren[
"classes"];
513 wxXmlNode* signals = boardChildren[
"signals"];
514 wxXmlNode* libs = boardChildren[
"libraries"];
515 wxXmlNode* elems = boardChildren[
"elements"];
522 count_children( designrules );
523 count_children( layers );
524 count_children( plain );
525 count_children( signals );
526 count_children( elems );
531 libs = libs->GetNext();
535 libs = boardChildren[
"libraries"];
592 wxXmlNode* layerNode = aLayers->GetChildren();
599 ELAYER elayer( layerNode );
605 cu.push_back( elayer );
607 layerNode = layerNode->GetNext();
611 int ki_layer_count = 0;
613 for(
EITER it = cu.begin(); it != cu.end(); ++it, ++ki_layer_count )
615 if( ki_layer_count == 0 )
619 else if( ki_layer_count ==
int( cu.size()-1 ) )
626 m_cu_map[it->number] = ki_layer_count;
635 for(
EITER it = cu.begin(); it != cu.end(); ++it )
652#define DIMENSION_PRECISION DIM_PRECISION::X_XX
663 wxXmlNode* gr = aGraphics->GetChildren();
670 wxString grName = gr->GetName();
672 if( grName == wxT(
"wire" ) )
695 shape->
SetShape( SHAPE_T::SEGMENT );
715 else if( grName == wxT(
"text" ) )
754 if( degrees > 90 && degrees <= 270 )
779 offset.
y = -signY * (int) textbox.
GetHeight();
791 offset.
x = signX * (int) textbox.
GetWidth();
797 offset.
x = -signX * (int) textbox.
GetWidth();
858 else if( grName == wxT(
"circle" ) )
877 int outlineRadius = radius + ( width / 2 );
883 VECTOR2I rotatedPoint( outlineRadius, 0 );
891 int innerRadius = radius - ( width / 2 );
897 VECTOR2I rotatedPoint( innerRadius, 0 );
924 else if( grName == wxT(
"rectangle" ) )
944 const int outlineIdx = -1;
963 else if( grName == wxT(
"hole" ) )
979 else if( grName == wxT(
"frame" ) )
983 else if( grName == wxT(
"polygon" ) )
989 else if( grName == wxT(
"dimension" ) )
1023 dimension->
SetEnd( pt2 );
1028 dimension->
SetUnits( EDA_UNITS::MILLIMETRES );
1058 int newY = ( pt1.
y + pt2.
y ) / 2;
1064 int newX = ( pt1.
x + pt2.
x ) / 2;
1075 dimension->
SetEnd( pt2 );
1079 dimension->
SetUnits( EDA_UNITS::MILLIMETRES );
1085 if(
abs( pt1.
x - pt2.
x ) < 50000 )
1087 int offset = pt3.
x - pt1.
x;
1094 else if(
abs( pt1.
y - pt2.
y ) < 50000 )
1096 int offset = pt3.
y - pt1.
y;
1129 wxString urn = aLib->GetAttribute(
"urn" );
1131 wxString urnOrdinal;
1133 if( !urn.IsEmpty() )
1135 urnOrdinal = urn.AfterLast(
':' );
1139 wxXmlNode* packages =
MapChildren( aLib )[
"packages"];
1151 wxXmlNode*
package = packages->GetChildren();
1157 m_xpath->push(
"package",
"name" );
1159 wxString pack_ref = package->GetAttribute(
"name" );
1161 if( !urnOrdinal.IsEmpty() )
1162 pack_ref += wxS(
"_" ) + urnOrdinal;
1166 m_xpath->Value( pack_ref.ToUTF8() );
1168 wxString key = aLibName ?
makeKey( *aLibName, pack_ref ) : pack_ref;
1170 FOOTPRINT* footprint = makeFootprint( package, pack_ref );
1173 auto r = m_templates.insert( { key, footprint } );
1177 wxString lib = aLibName ? *aLibName : m_lib_path;
1178 const wxString& pkg = pack_ref;
1180 wxString emsg = wxString::Format(
_(
"<package> '%s' duplicated in <library> '%s'" ),
1188 package = package->GetNext();
1200 m_xpath->push(
"libraries.library",
"name" );
1203 wxXmlNode*
library = aLibs->GetChildren();
1207 const wxString& lib_name =
library->GetAttribute(
"name" );
1209 m_xpath->Value( lib_name.c_str() );
1210 loadLibrary(
library, &lib_name );
1223 m_xpath->push(
"elements.element",
"name" );
1227 bool refanceNamePresetInPackageLayout;
1228 bool valueNamePresetInPackageLayout;
1231 wxXmlNode* element = aElements->GetChildren();
1237 if( element->GetName() != wxT(
"element" ) )
1240 element = element->GetNext();
1247 EATTR* nameAttr =
nullptr;
1248 EATTR* valueAttr =
nullptr;
1250 m_xpath->Value( e.
name.c_str() );
1252 wxString packageName = e.
package;
1257 packageName = e.
package + wxS(
"_" ) + libOrdinal.AfterLast(
':' );
1261 auto it = m_templates.find( pkg_key );
1263 if( it == m_templates.end() )
1265 wxString emsg = wxString::Format(
_(
"No '%s' package in library '%s'." ),
1272 m_board->
Add( footprint, ADD_MODE::APPEND );
1280 if( ni != m_pads_to_nets.end() )
1282 const ENET* enet = &ni->second;
1287 refanceNamePresetInPackageLayout =
true;
1288 valueNamePresetInPackageLayout =
true;
1295 refanceNamePresetInPackageLayout =
false;
1299 if( footprint->
GetValue().size() == 0 )
1302 valueNamePresetInPackageLayout =
false;
1305 wxString reference = e.
name;
1311 if( reference.find_first_not_of(
"0123456789" ) != 0 )
1312 reference.Prepend(
"UNK" );
1316 if( reference.find_first_not_of(
"#" ) != 0 )
1317 reference.Prepend(
"UNK" );
1320 if( reference.find_last_not_of(
"0123456789" ) == (reference.Length()-1) )
1321 reference.Append(
"0" );
1329 if( valueNamePresetInPackageLayout )
1332 if( refanceNamePresetInPackageLayout )
1342 m_xpath->push(
"attribute",
"name" );
1352 wxXmlNode* attribute = element->GetChildren();
1356 if( attribute->GetName() != wxT(
"attribute" ) )
1358 attribute = attribute->GetNext();
1362 EATTR a( attribute );
1364 if( a.
name == wxT(
"NAME" ) )
1377 nameAttr->
name = reference;
1379 if( refanceNamePresetInPackageLayout )
1386 if( refanceNamePresetInPackageLayout )
1395 if( refanceNamePresetInPackageLayout )
1398 nameAttr->
name = nameAttr->
name + wxT(
" = " ) + e.
name;
1409 if( refanceNamePresetInPackageLayout )
1419 else if( a.
name == wxT(
"VALUE" ) )
1433 if( valueNamePresetInPackageLayout )
1439 if( valueNamePresetInPackageLayout )
1442 footprint->
SetValue( wxT(
"VALUE" ) );
1446 if( valueNamePresetInPackageLayout )
1460 if( valueNamePresetInPackageLayout )
1472 attribute = attribute->GetNext();
1478 orientFootprintAndText( footprint, e, nameAttr, valueAttr );
1481 element = element->GetNext();
1498 wxLogMessage( wxString::Format(
_(
"Ignoring a polygon since Eagle layer '%s' (%d) "
1505 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( m_board );
1508 zone->SetLayer( layer );
1510 setKeepoutSettingsToZone( zone.get(), p.
layer );
1513 wxXmlNode* vertex = aPolyNode->GetChildren();
1514 std::vector<EVERTEX> vertices;
1522 if( vertex->GetName() == wxT(
"vertex" ) )
1523 vertices.emplace_back( vertex );
1525 vertex = vertex->GetNext();
1531 zone->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::ALWAYS );
1533 zone->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::NEVER );
1535 vertices.push_back( vertices[0] );
1540 for(
size_t i = 0; i < vertices.size() - 1; i++ )
1554 double end_angle = atan2( kicad_y(
v2.
y ) - center.
y, kicad_x(
v2.
x ) - center.
x );
1555 double radius = sqrt( pow( center.
x - kicad_x(
v1.
x ), 2 )
1556 + pow( center.
y - kicad_y(
v1.
y ), 2 ) );
1560 double delta_angle = angle / segCount;
1562 for(
double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta_angle );
1566 KiROUND( radius * sin( a ) ) + center.
y );
1581 wxLogMessage( wxString::Format(
1582 _(
"Skipping a polygon on layer '%s' (%d): outline count is not 1" ),
1588 zone->AddPolygon( polygon.
COutline( 0 ) );
1593 zone->SetIsRuleArea(
true );
1594 zone->SetDoNotAllowVias(
false );
1595 zone->SetDoNotAllowTracks(
false );
1596 zone->SetDoNotAllowPads(
false );
1597 zone->SetDoNotAllowFootprints(
false );
1598 zone->SetDoNotAllowCopperPour(
true );
1599 zone->SetHatchStyle( ZONE_BORDER_DISPLAY_STYLE::NO_HATCH );
1605 zone->SetFillMode( ZONE_FILL_MODE::HATCH_PATTERN );
1608 zone->SetHatchOrientation(
ANGLE_0 );
1619 zone->SetLocalClearance( 1 );
1623 zone->SetPadConnection( thermals ? ZONE_CONNECTION::THERMAL : ZONE_CONNECTION::FULL );
1636 zone->SetAssignedPriority( rank );
1638 ZONE* zonePtr = zone.release();
1639 m_board->Add( zonePtr, ADD_MODE::APPEND );
1646 const EATTR* aNameAttr,
const EATTR* aValueAttr )
1661 orientFPText( aFootprint, e, &aFootprint->
Reference(), aNameAttr );
1662 orientFPText( aFootprint, e, &aFootprint->
Value(), aValueAttr );
1667 const EATTR* aAttr )
1673 const EATTR& a = *aAttr;
1682 VECTOR2I pos( kicad_x( *a.
x ), kicad_y( *a.
y ) );
1694 int textThickness =
KiROUND( fontz.
y * ratio / 100 );
1699 fontz = kicad_fontsize( *a.
size, textThickness );
1725 if( degrees == 90 || degrees == 0 || spin )
1729 else if( degrees == 180 )
1734 else if( degrees == 270 )
1803 if( ( !aFPText->
IsMirrored() && (
abs( degrees ) == 180 ||
abs( degrees ) == 270 ) )
1804 || ( aFPText->
IsMirrored() && ( degrees == 360 ) ) )
1816 std::unique_ptr<FOOTPRINT> m = std::make_unique<FOOTPRINT>( m_board );
1819 fpID.
Parse( aPkgName,
true );
1823 wxXmlNode* packageItem = aPackage->GetChildren();
1828 m.get()->Value().SetLayer( layer );
1830 while( packageItem )
1832 const wxString& itemName = packageItem->GetName();
1834 if( itemName == wxT(
"description" ) )
1837 m->SetLibDescription( descr );
1839 else if( itemName == wxT(
"wire" ) )
1840 packageWire( m.get(), packageItem );
1841 else if( itemName == wxT(
"pad" ) )
1842 packagePad( m.get(), packageItem );
1843 else if( itemName == wxT(
"text" ) )
1844 packageText( m.get(), packageItem );
1845 else if( itemName == wxT(
"rectangle" ) )
1846 packageRectangle( m.get(), packageItem );
1847 else if( itemName == wxT(
"polygon" ) )
1848 packagePolygon( m.get(), packageItem );
1849 else if( itemName == wxT(
"circle" ) )
1850 packageCircle( m.get(), packageItem );
1851 else if( itemName == wxT(
"hole" ) )
1852 packageHole( m.get(), packageItem,
false );
1853 else if( itemName == wxT(
"smd" ) )
1854 packageSMD( m.get(), packageItem );
1856 packageItem = packageItem->GetNext();
1873 wxLogMessage( wxString::Format(
_(
"Ignoring a wire since Eagle layer '%s' (%d) "
1912 dwg =
new PCB_SHAPE( aFootprint, SHAPE_T::SEGMENT );
1919 dwg =
new PCB_SHAPE( aFootprint, SHAPE_T::ARC );
1932 aFootprint->
Add( dwg );
1943 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
1944 transferPad( e,
pad.get() );
1947 shape = m_rules->psFirst;
1949 shape = m_rules->psTop;
1951 shape = m_rules->psBottom;
1953 pad->SetDrillSize(
VECTOR2I( eagleDrillz, eagleDrillz ) );
1956 if( eagleDrillz < m_min_hole )
1957 m_min_hole = eagleDrillz;
1971 pad->SetShape( PAD_SHAPE::CIRCLE );
1975 pad->SetShape( PAD_SHAPE::CHAMFERED_RECT );
1977 pad->SetChamferRectRatio( 1 - M_SQRT1_2 );
1981 pad->SetShape( PAD_SHAPE::OVAL );
1985 pad->SetShape( PAD_SHAPE::RECTANGLE );
1989 pad->SetShape( PAD_SHAPE::OVAL );
2005 double drillz =
pad->GetDrillSize().x;
2006 double annulus = drillz * m_rules->rvPadTop;
2007 annulus =
eagleClamp( m_rules->rlMinPadTop, annulus, m_rules->rlMaxPadTop );
2008 int diameter =
KiROUND( drillz + 2 * annulus );
2012 if(
pad->GetShape() == PAD_SHAPE::OVAL )
2016 sz.
x = ( sz.
x * ( 100 + m_rules->psElongationLong ) ) / 100;
2021 int offset =
KiROUND( ( sz.
x - sz.
y ) / 2.0 );
2032 if(
pad->GetSizeX() > 0 &&
pad->GetSizeY() > 0 )
2034 aFootprint->
Add(
pad.release() );
2038 wxLogError(
_(
"Invalid zero-sized pad ignored in\nfile: %s" ), m_board->GetFileName() );
2050 wxLogMessage( wxString::Format(
_(
"Ignoring a text since Eagle layer '%s' (%d) "
2058 if( t.
text.Upper() == wxT(
">NAME" ) && aFootprint->
GetReference().IsEmpty() )
2062 textItem->
SetText( wxT(
"REF**" ) );
2064 else if( t.
text.Upper() == wxT(
">VALUE" ) && aFootprint->
GetValue().IsEmpty() )
2066 textItem = &aFootprint->
Value();
2072 textItem =
new PCB_TEXT( aFootprint );
2073 aFootprint->
Add( textItem );
2078 VECTOR2I pos( kicad_x( t.
x ), kicad_y( t.
y ) );
2102 if( degrees == 90 || t.
rot->
spin )
2106 else if( degrees == 180 )
2110 else if( degrees == 270 )
2174 ZONE* zone =
new ZONE( aFootprint );
2175 aFootprint->
Add( zone, ADD_MODE::APPEND );
2177 setKeepoutSettingsToZone( zone, r.
layer );
2179 const int outlineIdx = -1;
2187 VECTOR2I center( ( kicad_x( r.
x1 ) + kicad_x( r.
x2 ) ) / 2,
2188 ( kicad_y( r.
y1 ) + kicad_y( r.
y2 ) ) / 2 );
2201 wxLogMessage( wxString::Format(
_(
"Ignoring a rectangle since Eagle layer '%s' (%d) "
2209 aFootprint->
Add( dwg );
2215 std::vector<VECTOR2I> pts;
2220 pts.push_back( start );
2221 pts.emplace_back( kicad_x( r.
x2 ), kicad_y( r.
y1 ) );
2222 pts.emplace_back( kicad_x( r.
x2 ), kicad_y( r.
y2 ) );
2223 pts.push_back( end );
2240 std::vector<VECTOR2I> pts;
2243 wxXmlNode* vertex = aTree->GetChildren();
2244 std::vector<EVERTEX> vertices;
2252 if( vertex->GetName() == wxT(
"vertex" ) )
2253 vertices.emplace_back( vertex );
2255 vertex = vertex->GetNext();
2258 vertices.push_back( vertices[0] );
2260 for(
size_t i = 0; i < vertices.size() - 1; i++ )
2265 pts.emplace_back( kicad_x(
v1.
x ), kicad_y(
v1.
y ) );
2274 double end_angle = atan2( kicad_y(
v2.
y ) - center.
y, kicad_x(
v2.
x ) - center.
x );
2275 double radius = sqrt( pow( center.
x - kicad_x(
v1.
x ), 2 )
2276 + pow( center.
y - kicad_y(
v1.
y ), 2 ) );
2284 double delta = angle / segCount;
2286 for(
double a = end_angle + angle; fabs( a - end_angle ) > fabs(
delta ); a -=
delta )
2302 ZONE* zone =
new ZONE( aFootprint );
2303 aFootprint->
Add( zone, ADD_MODE::APPEND );
2305 setKeepoutSettingsToZone( zone, p.
layer );
2318 wxLogMessage( wxString::Format(
_(
"Ignoring a polygon since Eagle layer '%s' (%d) "
2326 aFootprint->
Add( dwg );
2352 ZONE* zone =
new ZONE( aFootprint );
2353 aFootprint->
Add( zone, ADD_MODE::APPEND );
2355 setKeepoutSettingsToZone( zone, e.
layer );
2358 VECTOR2I center( kicad_x( e.
x ), kicad_y( e.
y ) );
2359 int outlineRadius = radius + ( width / 2 );
2365 VECTOR2I rotatedPoint( outlineRadius, 0 );
2373 int innerRadius = radius - ( width / 2 );
2379 VECTOR2I rotatedPoint( innerRadius, 0 );
2394 wxLogMessage( wxString::Format(
_(
"Ignoring a circle since Eagle layer '%s' (%d) "
2406 radius = radius / 2;
2410 aFootprint->
Add( gr );
2413 switch( (
int) layer )
2442 pad->SetShape( PAD_SHAPE::CIRCLE );
2443 pad->SetAttribute( PAD_ATTRIB::NPTH );
2450 VECTOR2I padpos( kicad_x( e.
x ), kicad_y( e.
y ) );
2455 pad->SetPosition( padpos );
2464 pad->SetDrillSize( sz );
2481 transferPad( e,
pad );
2483 pad->SetShape( PAD_SHAPE::RECTANGLE );
2484 pad->SetAttribute( PAD_ATTRIB::SMD );
2487 pad->SetSize( padSize );
2488 pad->SetLayer( layer );
2494 pad->SetLayerSet( front );
2495 else if( layer ==
B_Cu )
2496 pad->SetLayerSet( back );
2498 int minPadSize = std::min( padSize.
x, padSize.
y );
2502 eagleClamp( m_rules->srMinRoundness * 2, (
int) ( minPadSize * m_rules->srRoundness ),
2503 m_rules->srMaxRoundness * 2 );
2507 double roundRatio = (double) roundRadius / minPadSize / 2.0;
2511 roundRatio = std::fmax( *e.
roundness / 200.0, roundRatio );
2513 pad->SetShape( PAD_SHAPE::ROUNDRECT );
2514 pad->SetRoundRectRadiusRatio( roundRatio );
2523 pad->SetLocalSolderPasteMargin( -
eagleClamp( m_rules->mlMinCreamFrame,
2524 (
int) ( m_rules->mvCreamFrame * minPadSize ),
2525 m_rules->mlMaxCreamFrame ) );
2531 pad->SetLayerSet(
pad->GetLayerSet().set(
F_Mask,
false ) );
2532 else if( layer ==
B_Cu )
2533 pad->SetLayerSet(
pad->GetLayerSet().set(
B_Mask,
false ) );
2540 pad->SetLayerSet(
pad->GetLayerSet().set(
F_Paste,
false ) );
2541 else if( layer ==
B_Cu )
2542 pad->SetLayerSet(
pad->GetLayerSet().set(
B_Paste,
false ) );
2551 VECTOR2I padPos( kicad_x( aEaglePad.
x ), kicad_y( aEaglePad.
y ) );
2558 (
int) ( m_rules->mvStopFrame * std::min( padSize.
x, padSize.
y ) ),
2559 m_rules->mlMaxStopFrame ) );
2566 wxCHECK( footprint, );
2574 for(
const auto& [
name, footprint ] : m_templates )
2576 footprint->SetParent(
nullptr );
2580 m_templates.clear();
2592 m_xpath->push(
"classes.class",
"number" );
2594 std::vector<ECLASS> eClasses;
2595 wxXmlNode* classNode = aClasses->GetChildren();
2601 ECLASS eClass( classNode );
2602 std::shared_ptr<NETCLASS> netclass;
2604 if( eClass.
name.CmpNoCase( wxT(
"default" ) ) == 0 )
2614 netclass->SetTrackWidth( INT_MAX );
2615 netclass->SetViaDiameter( INT_MAX );
2616 netclass->SetViaDrill( INT_MAX );
2618 eClasses.emplace_back( eClass );
2619 m_classMap[ eClass.
number ] = netclass;
2622 classNode = classNode->GetNext();
2625 m_customRules = wxT(
"(version 1)" );
2627 for(
ECLASS& eClass : eClasses )
2629 for( std::pair<const wxString&, ECOORD> entry : eClass.clearanceMap )
2631 if( m_classMap[ entry.first ] !=
nullptr )
2634 rule.Printf( wxT(
"(rule \"class %s:%s\"\n"
2635 " (condition \"A.NetClass == '%s' && B.NetClass == '%s'\")\n"
2636 " (constraint clearance (min %smm)))\n" ),
2640 m_classMap[ entry.first ]->GetName(),
2643 m_customRules += wxT(
"\n" ) + rule;
2661 m_xpath->push(
"signals.signal",
"name" );
2664 wxXmlNode* net = aSignals->GetChildren();
2670 bool sawPad =
false;
2674 const wxString& netName =
escapeName( net->GetAttribute(
"name" ) );
2676 std::shared_ptr<NETCLASS> netclass;
2678 if( net->HasAttribute(
"class" ) )
2680 auto netclassIt = m_classMap.find( net->GetAttribute(
"class" ) );
2682 if( netclassIt != m_classMap.end() )
2684 m_board->GetDesignSettings().m_NetSettings->m_NetClassPatternAssignments.push_back(
2685 { std::make_unique<EDA_COMBINED_MATCHER>( netName,
CTX_NETCLASS ),
2686 netclassIt->second->GetName() } );
2689 netclass = netclassIt->second;
2693 m_board->Add( netInfo );
2695 m_xpath->Value( netName.c_str() );
2698 wxXmlNode* netItem = net->GetChildren();
2703 const wxString& itemName = netItem->GetName();
2705 if( itemName == wxT(
"wire" ) )
2707 m_xpath->push(
"wire" );
2719 if( width < m_min_trace )
2720 m_min_trace = width;
2722 if( netclass && width < netclass->GetTrackWidth() )
2723 netclass->SetTrackWidth( width );
2728 double radius = sqrt( pow( center.
x - kicad_x( w.
x1 ), 2 ) +
2729 pow( center.
y - kicad_y( w.
y1 ), 2 ) );
2733 double radiusA = ( mid - center ).EuclideanNorm();
2734 double radiusB = ( otherMid - center ).EuclideanNorm();
2736 if(
abs( radiusA - radius ) >
abs( radiusB - radius ) )
2737 std::swap( mid, otherMid );
2748 m_board->Add( arc );
2760 m_board->Add( track );
2770 else if( itemName == wxT(
"via" ) )
2772 m_xpath->push(
"via" );
2782 && layer_front_most != layer_back_most )
2787 m_board->Add(
via );
2792 via->SetWidth( kidiam );
2796 double annulus = drillz * m_rules->rvViaOuter;
2797 annulus =
eagleClamp( m_rules->rlMinViaOuter, annulus,
2798 m_rules->rlMaxViaOuter );
2799 kidiam =
KiROUND( drillz + 2 * annulus );
2800 via->SetWidth( kidiam );
2803 via->SetDrill( drillz );
2807 if( !v.
diam ||
via->GetWidth() <=
via->GetDrill() )
2811 (
double) (
via->GetWidth() / 2 -
via->GetDrill() ),
2812 m_rules->rlMaxViaOuter );
2813 via->SetWidth( drillz + 2 * annulus );
2816 if( kidiam < m_min_via )
2819 if( netclass && kidiam < netclass->GetViaDiameter() )
2820 netclass->SetViaDiameter( kidiam );
2822 if( drillz < m_min_hole )
2823 m_min_hole = drillz;
2825 if( netclass && drillz < netclass->GetViaDrill() )
2826 netclass->SetViaDrill( drillz );
2828 if( ( kidiam - drillz ) / 2 < m_min_annulus )
2829 m_min_annulus = ( kidiam - drillz ) / 2;
2831 if( layer_front_most ==
F_Cu && layer_back_most ==
B_Cu )
2833 via->SetViaType( VIATYPE::THROUGH );
2840 via->SetViaType( VIATYPE::MICROVIA );
2844 via->SetViaType( VIATYPE::BLIND_BURIED );
2847 VECTOR2I pos( kicad_x( v.
x ), kicad_y( v.
y ) );
2849 via->SetLayerPair( layer_front_most, layer_back_most );
2850 via->SetPosition( pos );
2853 via->SetNetCode( netCode );
2859 else if( itemName == wxT(
"contactref" ) )
2861 m_xpath->push(
"contactref" );
2864 const wxString& reference = netItem->GetAttribute(
"element" );
2865 const wxString&
pad = netItem->GetAttribute(
"pad" );
2868 m_pads_to_nets[ key ] =
ENET( netCode, netName );
2875 else if( itemName == wxT(
"polygon" ) )
2877 m_xpath->push(
"polygon" );
2878 auto* zone = loadPolygon( netItem );
2882 zones.push_back( zone );
2884 if( !zone->GetIsRuleArea() )
2885 zone->SetNetCode( netCode );
2891 netItem = netItem->GetNext();
2894 if( zones.size() && !sawPad )
2898 for(
ZONE* zone : zones )
2909 net = net->GetNext();
2917 const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector )
2919 std::map<wxString, PCB_LAYER_ID> layer_map;
2923 PCB_LAYER_ID layerId = std::get<0>( defaultKicadLayer( eagle_layer_id( layer.Name ) ) );
2924 layer_map.emplace( layer.Name, layerId );
2933 std::vector<INPUT_LAYER_DESC> inputDescs;
2935 for (
const std::pair<const int, ELAYER>& layerPair : m_eagleLayers )
2937 const ELAYER& eLayer = layerPair.second;
2941 defaultKicadLayer( eLayer.
number, aIsLibraryCache );
2948 inputDescs.push_back( layerDesc );
2951 if( m_progressReporter &&
dynamic_cast<wxWindow*
>( m_progressReporter ) )
2952 dynamic_cast<wxWindow*
>( m_progressReporter )->Hide();
2954 m_layer_map = m_layer_mapping_handler( inputDescs );
2956 if( m_progressReporter &&
dynamic_cast<wxWindow*
>( m_progressReporter ))
2957 dynamic_cast<wxWindow*
>( m_progressReporter )->Show();
2963 auto result = m_layer_map.find( eagle_layer_name( aEagleLayer ) );
2964 return result == m_layer_map.end() ?
UNDEFINED_LAYER : result->second;
2969 bool aIsLibraryCache )
const
2972 if( aEagleLayer >= 1 && aEagleLayer <
int(
arrayDim( m_cu_map ) ) )
2976 for(
int copperLayer : m_cu_map )
2978 if( copperLayer >= 0 )
2979 copperLayers[copperLayer] =
true;
2982 return {
PCB_LAYER_ID( m_cu_map[aEagleLayer] ), copperLayers,
true };
2986 bool required =
false;
2987 LSET permittedLayers;
2989 permittedLayers.
set();
2992 switch( aEagleLayer )
3090 if( aIsLibraryCache )
3098 return {
PCB_LAYER_ID( kiLayer ), permittedLayers, required };
3104 static const wxString
unknown(
"unknown" );
3105 auto it = m_eagleLayers.find( aLayer );
3106 return it == m_eagleLayers.end() ?
unknown : it->second.name;
3112 static const int unknown = -1;
3113 auto it = m_eagleLayersIds.find( aLayerName );
3114 return it == m_eagleLayersIds.end() ?
unknown : it->second;
3125 if( m_props->Value(
"page_width", &page_width ) &&
3126 m_props->Value(
"page_height", &page_height ) )
3128 BOX2I bbbox = m_board->GetBoardEdgesBoundingBox();
3130 int w = atoi( page_width.
c_str() );
3131 int h = atoi( page_height.
c_str() );
3133 int desired_x = ( w - bbbox.
GetWidth() ) / 2;
3134 int desired_y = ( h - bbbox.
GetHeight() ) / 2;
3136 m_board->Move(
VECTOR2I( desired_x - bbbox.
GetX(), desired_y - bbbox.
GetY() ) );
3145 if( aPath.IsEmpty() )
3146 return wxDateTime::Now();
3148 wxFileName fn( aPath );
3150 if( fn.IsFileReadable() )
3151 return fn.GetModificationTime();
3153 return wxDateTime( 0.0 );
3163 wxDateTime modtime = getModificationTime( aLibPath );
3168 bool load = !m_mod_time.IsValid() || !modtime.IsValid() || m_mod_time != modtime;
3170 if( aLibPath != m_lib_path || load )
3180 m_lib_path = aLibPath;
3185 string filename = (
const char*) aLibPath.char_str( wxConvFile );
3188 wxFileName fn( filename );
3189 wxFFileInputStream stream( fn.GetFullPath() );
3190 wxXmlDocument xmlDocument;
3192 if( !stream.IsOk() || !xmlDocument.Load( stream ) )
3195 fn.GetFullPath() ) );
3198 doc = xmlDocument.GetRoot();
3200 wxXmlNode* drawing =
MapChildren( doc )[
"drawing"];
3206 m_xpath->push(
"eagle.drawing.layers" );
3207 wxXmlNode* layers = drawingChildren[
"layers"];
3208 loadLayerDefs( layers );
3209 mapEagleLayersToKicad(
true );
3212 m_xpath->push(
"eagle.drawing.library" );
3213 wxXmlNode*
library = drawingChildren[
"library"];
3215 loadLibrary(
library,
nullptr );
3218 m_mod_time = modtime;
3249 init( aProperties );
3253 cacheLib( aLibraryPath );
3257 errorMsg = ioe.
What();
3263 for(
const auto& [
name, footprint ] : m_templates )
3264 aFootprintNames.Add(
name );
3266 if( !errorMsg.IsEmpty() && !aBestEfforts )
3272 const wxString& aFootprintName,
bool aKeepUUID,
3275 init( aProperties );
3276 cacheLib( aLibraryPath );
3277 auto it = m_templates.find( aFootprintName );
3279 if( it == m_templates.end() )
3284 copy->SetParent(
nullptr );
3291 int minLayerCount = 2;
3293 std::map<wxString, PCB_LAYER_ID>::const_iterator it;
3295 for( it = m_layer_map.begin(); it != m_layer_map.end(); ++it )
3300 && ( layerId + 2 ) > minLayerCount )
3301 minLayerCount = layerId + 2;
3307 if( ( minLayerCount % 2 ) != 0 )
3310 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
BASE_SET & set(size_t pos=std::numeric_limits< size_t >::max(), bool value=true)
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
size_type GetHeight() const
size_type GetWidth() const
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)
const EDA_ANGLE & GetTextAngle() const
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
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.
void SetKeepUpright(bool aKeepUpright)
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
VECTOR2I GetTextSize() const
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
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.
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 SetLocalSolderMaskMargin(std::optional< int > aMargin)
void SetLocalZoneConnection(ZONE_CONNECTION aType)
void SetPosition(const VECTOR2I &aPos) override
const VECTOR2I & GetSize() const
void SetPosition(const VECTOR2I &aPos) override
void SetMid(const VECTOR2I &aMid)
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.
std::vector< ELAYER > ELAYERS
void packageSMD(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
Handles common pad properties.
void loadPlain(wxXmlNode *aPlain)
int m_min_trace
smallest trace we find on Load(), in BIU.
void orientFPText(FOOTPRINT *aFootprint, const EELEMENT &e, PCB_TEXT *aFPText, const EATTR *aAttr)
VECTOR2I kicad_fontsize(const ECOORD &d, int aTextThickness) const
create a font size (fontz) from an eagle font size scalar and KiCad font thickness
std::map< wxString, PCB_LAYER_ID > DefaultLayerMappingCallback(const std::vector< INPUT_LAYER_DESC > &aInputLayerDescriptionVector)
Return the automapped layers.
bool checkHeader(const wxString &aFileName) const
void loadElements(wxXmlNode *aElements)
FOOTPRINT * makeFootprint(wxXmlNode *aPackage, const wxString &aPkgName)
Create a FOOTPRINT from an Eagle package.
int m_min_hole
smallest diameter hole we find on Load(), in BIU.
std::vector< FOOTPRINT * > GetImportedCachedLibraryFootprints() override
Return a container with the cached library footprints generated in the last call to Load.
XPATH * m_xpath
keeps track of what we are working on within XML document during a Load().
unsigned m_totalCount
for progress reporting
void 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 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::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 loadLibraries(wxXmlNode *aLibs)
int eagle_layer_id(const wxString &aLayerName) const
Get Eagle layer number by its name.
void loadAllSections(wxXmlNode *aDocument)
bool CanReadFootprint(const wxString &aFileName) const override
Checks if this PCB_IO can read a footprint from specified file or directory.
void packageWire(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
bool CanReadBoard(const wxString &aFileName) const override
Checks if this PCB_IO can read the specified board file.
const wxString & eagle_layer_name(int aLayer) const
Get Eagle layer name by its number.
ELAYERS::const_iterator EITER
void packageRectangle(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
void loadClasses(wxXmlNode *aClasses)
std::map< int, ELAYER > m_eagleLayers
Eagle layer data stored by layer number.
NET_MAP m_pads_to_nets
net list
void packageText(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
int getMinimumCopperLayerCount() const
Determines the minimum copper layer stackup count that includes all mapped layers.
void packageHole(FOOTPRINT *aFootprint, wxXmlNode *aTree, bool aCenter) const
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 PC...
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)
static wxDateTime getModificationTime(const wxString &aPath)
get a file's or dir's modification time.
int m_min_annulus
smallest via annulus we find on Load(), in BIU.
void loadLayerDefs(wxXmlNode *aLayers)
void init(const STRING_UTF8_MAP *aProperties)
initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const STRING_UTF8_MAP *aProperties=nullptr, PROJECT *aProject=nullptr) override
Load information from some input file format that this PCB_IO implementation knows about into either ...
void setKeepoutSettingsToZone(ZONE *aZone, int aLayer) const
void transferPad(const EPAD_COMMON &aEaglePad, PAD *aPad) const
Deletes the footprint templates list.
int kicad_x(const ECOORD &x) const
void loadDesignRules(wxXmlNode *aDesignRules)
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
A base class that BOARD loading and saving plugins should derive from.
BOARD * m_board
The board BOARD being worked on, no ownership here.
const STRING_UTF8_MAP * m_props
Properties passed via Save() or Load(), no ownership, may be NULL.
virtual bool CanReadBoard(const wxString &aFileName) const
Checks if this PCB_IO can read the specified board file.
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 SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void Move(const VECTOR2I &aMoveVector) override
Move this object.
void SetStroke(const STROKE_PARAMS &aStroke) override
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
virtual void SetPosition(const VECTOR2I &aPos) override
void SetWidth(int aWidth)
void SetEnd(const VECTOR2I &aEnd)
void SetPosition(const VECTOR2I &aPos) override
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.
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
double Distance(const VECTOR2< extended_type > &aVector) const
Compute the distance between two vectors.
static REPORTER & GetInstance()
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)
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()
static void SetReporter(REPORTER *aReporter)
Set the reporter to use for reporting font substitution warnings.
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)
wxString convertDescription(wxString aDescr)
OPTIONAL_XML_ATTRIBUTE< wxString > opt_wxString
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE FULL_CIRCLE
static constexpr EDA_ANGLE ANGLE_360
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)
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
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.
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.
const VECTOR2I CalcArcMid(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aMinArcAngle=true)
Return the middle point of an arc, half-way between aStart and aEnd.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
double DEG2RAD(double deg)
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
VECTOR2< int32_t > VECTOR2I
ZONE_BORDER_DISPLAY_STYLE
Zone border styles.
#define ZONE_THICKNESS_MIN_VALUE_MM