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 );
326 const std::map<std::string, UTF8>* aProperties,
PROJECT* aProject )
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->GetDefaultNetclass() );
415 for(
const auto& [
name, netclass] : netSettings->GetNetclasses() )
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();
856 if( pcbtxt->
IsMirrored() && degrees < -90 && degrees >= -270 )
874 else if( grName == wxT(
"circle" ) )
893 int outlineRadius = radius + ( width / 2 );
899 VECTOR2I rotatedPoint( outlineRadius, 0 );
907 int innerRadius = radius - ( width / 2 );
913 VECTOR2I rotatedPoint( innerRadius, 0 );
940 else if( grName == wxT(
"rectangle" ) )
960 const int outlineIdx = -1;
979 else if( grName == wxT(
"hole" ) )
989 footprint->
SetReference( wxString::Format( wxT(
"UNK_HOLE_%d" ), hole_count ) );
992 LIB_ID fpid( wxEmptyString, wxString::Format( wxT(
"dummyfp%d" ), hole_count ) );
999 else if( grName == wxT(
"frame" ) )
1003 else if( grName == wxT(
"polygon" ) )
1009 else if( grName == wxT(
"dimension" ) )
1043 dimension->
SetEnd( pt2 );
1048 dimension->
SetUnits( EDA_UNITS::MILLIMETRES );
1078 int newY = ( pt1.
y + pt2.
y ) / 2;
1084 int newX = ( pt1.
x + pt2.
x ) / 2;
1095 dimension->
SetEnd( pt2 );
1099 dimension->
SetUnits( EDA_UNITS::MILLIMETRES );
1105 if(
abs( pt1.
x - pt2.
x ) < 50000 )
1107 int offset = pt3.
x - pt1.
x;
1114 else if(
abs( pt1.
y - pt2.
y ) < 50000 )
1116 int offset = pt3.
y - pt1.
y;
1149 wxString urn = aLib->GetAttribute(
"urn" );
1151 wxString urnOrdinal;
1153 if( !urn.IsEmpty() )
1155 urnOrdinal = urn.AfterLast(
':' );
1159 wxXmlNode* packages =
MapChildren( aLib )[
"packages"];
1171 wxXmlNode*
package = packages->GetChildren();
1177 m_xpath->push(
"package",
"name" );
1179 wxString pack_ref = package->GetAttribute(
"name" );
1181 if( !urnOrdinal.IsEmpty() )
1182 pack_ref += wxS(
"_" ) + urnOrdinal;
1186 m_xpath->Value( pack_ref.ToUTF8() );
1188 wxString key = aLibName ?
makeKey( *aLibName, pack_ref ) : pack_ref;
1190 FOOTPRINT* footprint = makeFootprint( package, pack_ref );
1193 auto r = m_templates.insert( { key, footprint } );
1197 wxString lib = aLibName ? *aLibName : m_lib_path;
1198 const wxString& pkg = pack_ref;
1200 wxString emsg = wxString::Format(
_(
"<package> '%s' duplicated in <library> '%s'" ),
1208 package = package->GetNext();
1220 m_xpath->push(
"libraries.library",
"name" );
1223 wxXmlNode*
library = aLibs->GetChildren();
1227 const wxString& lib_name =
library->GetAttribute(
"name" );
1229 m_xpath->Value( lib_name.c_str() );
1230 loadLibrary(
library, &lib_name );
1243 m_xpath->push(
"elements.element",
"name" );
1247 bool refanceNamePresetInPackageLayout;
1248 bool valueNamePresetInPackageLayout;
1251 wxXmlNode* element = aElements->GetChildren();
1257 if( element->GetName() != wxT(
"element" ) )
1260 element = element->GetNext();
1267 EATTR* nameAttr =
nullptr;
1268 EATTR* valueAttr =
nullptr;
1270 m_xpath->Value( e.
name.c_str() );
1272 wxString packageName = e.
package;
1277 packageName = e.
package + wxS(
"_" ) + libOrdinal.AfterLast(
':' );
1281 auto it = m_templates.find( pkg_key );
1283 if( it == m_templates.end() )
1285 wxString emsg = wxString::Format(
_(
"No '%s' package in library '%s'." ),
1292 m_board->
Add( footprint, ADD_MODE::APPEND );
1300 if( ni != m_pads_to_nets.end() )
1302 const ENET* enet = &ni->second;
1307 refanceNamePresetInPackageLayout =
true;
1308 valueNamePresetInPackageLayout =
true;
1315 refanceNamePresetInPackageLayout =
false;
1319 if( footprint->
GetValue().size() == 0 )
1322 valueNamePresetInPackageLayout =
false;
1325 wxString reference = e.
name;
1331 if( reference.find_first_not_of(
"0123456789" ) != 0 )
1332 reference.Prepend(
"UNK" );
1336 if( reference.find_first_not_of(
"#" ) != 0 )
1337 reference.Prepend(
"UNK" );
1340 if( reference.find_last_not_of(
"0123456789" ) == (reference.Length()-1) )
1341 reference.Append(
"0" );
1349 if( valueNamePresetInPackageLayout )
1352 if( refanceNamePresetInPackageLayout )
1362 m_xpath->push(
"attribute",
"name" );
1372 wxXmlNode* attribute = element->GetChildren();
1376 if( attribute->GetName() != wxT(
"attribute" ) )
1378 attribute = attribute->GetNext();
1382 EATTR a( attribute );
1384 if( a.
name == wxT(
"NAME" ) )
1397 nameAttr->
name = reference;
1399 if( refanceNamePresetInPackageLayout )
1406 if( refanceNamePresetInPackageLayout )
1415 if( refanceNamePresetInPackageLayout )
1418 nameAttr->
name = nameAttr->
name + wxT(
" = " ) + e.
name;
1429 if( refanceNamePresetInPackageLayout )
1439 else if( a.
name == wxT(
"VALUE" ) )
1453 if( valueNamePresetInPackageLayout )
1459 if( valueNamePresetInPackageLayout )
1462 footprint->
SetValue( wxT(
"VALUE" ) );
1466 if( valueNamePresetInPackageLayout )
1480 if( valueNamePresetInPackageLayout )
1492 attribute = attribute->GetNext();
1498 orientFootprintAndText( footprint, e, nameAttr, valueAttr );
1501 element = element->GetNext();
1518 wxLogMessage( wxString::Format(
_(
"Ignoring a polygon since Eagle layer '%s' (%d) "
1525 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( m_board );
1528 zone->SetLayer( layer );
1530 setKeepoutSettingsToZone( zone.get(), p.
layer );
1533 wxXmlNode* vertex = aPolyNode->GetChildren();
1534 std::vector<EVERTEX> vertices;
1542 if( vertex->GetName() == wxT(
"vertex" ) )
1543 vertices.emplace_back( vertex );
1545 vertex = vertex->GetNext();
1551 zone->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::ALWAYS );
1553 zone->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::NEVER );
1555 vertices.push_back( vertices[0] );
1560 for(
size_t i = 0; i < vertices.size() - 1; i++ )
1574 double end_angle = atan2( kicad_y(
v2.
y ) - center.
y, kicad_x(
v2.
x ) - center.
x );
1575 double radius = sqrt( pow( center.
x - kicad_x(
v1.
x ), 2 )
1576 + pow( center.
y - kicad_y(
v1.
y ), 2 ) );
1580 double delta_angle = angle / segCount;
1582 for(
double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta_angle );
1586 KiROUND( radius * sin( a ) ) + center.
y );
1601 wxLogMessage( wxString::Format(
1602 _(
"Skipping a polygon on layer '%s' (%d): outline count is not 1" ),
1608 zone->AddPolygon( polygon.
COutline( 0 ) );
1613 zone->SetIsRuleArea(
true );
1614 zone->SetDoNotAllowVias(
false );
1615 zone->SetDoNotAllowTracks(
false );
1616 zone->SetDoNotAllowPads(
false );
1617 zone->SetDoNotAllowFootprints(
false );
1618 zone->SetDoNotAllowCopperPour(
true );
1619 zone->SetHatchStyle( ZONE_BORDER_DISPLAY_STYLE::NO_HATCH );
1625 zone->SetFillMode( ZONE_FILL_MODE::HATCH_PATTERN );
1628 zone->SetHatchOrientation(
ANGLE_0 );
1639 zone->SetLocalClearance( 1 );
1643 zone->SetPadConnection( thermals ? ZONE_CONNECTION::THERMAL : ZONE_CONNECTION::FULL );
1656 zone->SetAssignedPriority( rank );
1658 ZONE* zonePtr = zone.release();
1659 m_board->Add( zonePtr, ADD_MODE::APPEND );
1666 const EATTR* aNameAttr,
const EATTR* aValueAttr )
1673 aFootprint->
Flip( aFootprint->
GetPosition(), FLIP_DIRECTION::TOP_BOTTOM );
1681 orientFPText( aFootprint, e, &aFootprint->
Reference(), aNameAttr );
1682 orientFPText( aFootprint, e, &aFootprint->
Value(), aValueAttr );
1687 const EATTR* aAttr )
1693 const EATTR& a = *aAttr;
1702 VECTOR2I pos( kicad_x( *a.
x ), kicad_y( *a.
y ) );
1714 int textThickness =
KiROUND( fontz.
y * ratio / 100 );
1719 fontz = kicad_fontsize( *a.
size, textThickness );
1745 if( degrees == 90 || degrees == 0 || spin )
1749 else if( degrees == 180 )
1754 else if( degrees == 270 )
1823 if( ( !aFPText->
IsMirrored() && (
abs( degrees ) == 180 ||
abs( degrees ) == 270 ) )
1824 || ( aFPText->
IsMirrored() && ( degrees == 360 ) ) )
1836 std::unique_ptr<FOOTPRINT> m = std::make_unique<FOOTPRINT>( m_board );
1839 fpID.
Parse( aPkgName,
true );
1843 wxXmlNode* packageItem = aPackage->GetChildren();
1848 m.get()->Value().SetLayer( layer );
1850 while( packageItem )
1852 const wxString& itemName = packageItem->GetName();
1854 if( itemName == wxT(
"description" ) )
1857 m->SetLibDescription( descr );
1859 else if( itemName == wxT(
"wire" ) )
1860 packageWire( m.get(), packageItem );
1861 else if( itemName == wxT(
"pad" ) )
1862 packagePad( m.get(), packageItem );
1863 else if( itemName == wxT(
"text" ) )
1864 packageText( m.get(), packageItem );
1865 else if( itemName == wxT(
"rectangle" ) )
1866 packageRectangle( m.get(), packageItem );
1867 else if( itemName == wxT(
"polygon" ) )
1868 packagePolygon( m.get(), packageItem );
1869 else if( itemName == wxT(
"circle" ) )
1870 packageCircle( m.get(), packageItem );
1871 else if( itemName == wxT(
"hole" ) )
1872 packageHole( m.get(), packageItem,
false );
1873 else if( itemName == wxT(
"smd" ) )
1874 packageSMD( m.get(), packageItem );
1876 packageItem = packageItem->GetNext();
1893 wxLogMessage( wxString::Format(
_(
"Ignoring a wire since Eagle layer '%s' (%d) "
1932 dwg =
new PCB_SHAPE( aFootprint, SHAPE_T::SEGMENT );
1939 dwg =
new PCB_SHAPE( aFootprint, SHAPE_T::ARC );
1952 aFootprint->
Add( dwg );
1963 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
1964 transferPad( e,
pad.get() );
1967 shape = m_rules->psFirst;
1969 shape = m_rules->psTop;
1971 shape = m_rules->psBottom;
1973 pad->SetDrillSize(
VECTOR2I( eagleDrillz, eagleDrillz ) );
1976 if( eagleDrillz < m_min_hole )
1977 m_min_hole = eagleDrillz;
2025 double drillz =
pad->GetDrillSize().x;
2026 double annulus = drillz * m_rules->rvPadTop;
2027 annulus =
eagleClamp( m_rules->rlMinPadTop, annulus, m_rules->rlMaxPadTop );
2028 int diameter =
KiROUND( drillz + 2 * annulus );
2036 sz.
x = ( sz.
x * ( 100 + m_rules->psElongationLong ) ) / 100;
2041 int offset =
KiROUND( ( sz.
x - sz.
y ) / 2.0 );
2052 if(
pad->GetSizeX() > 0 &&
pad->GetSizeY() > 0 )
2054 aFootprint->
Add(
pad.release() );
2058 wxFileName fileName( m_lib_path );
2061 wxLogError(
_(
"Invalid zero-sized pad ignored in\nfile: %s" ), m_board->GetFileName() );
2063 wxLogError(
_(
"Invalid zero-sized pad ignored in\nfile: %s" ), fileName.GetFullName() );
2075 wxLogMessage( wxString::Format(
_(
"Ignoring a text since Eagle layer '%s' (%d) "
2083 if( t.
text.Upper() == wxT(
">NAME" ) && aFootprint->
GetReference().IsEmpty() )
2087 textItem->
SetText( wxT(
"REF**" ) );
2089 else if( t.
text.Upper() == wxT(
">VALUE" ) && aFootprint->
GetValue().IsEmpty() )
2091 textItem = &aFootprint->
Value();
2097 textItem =
new PCB_TEXT( aFootprint );
2098 aFootprint->
Add( textItem );
2103 VECTOR2I pos( kicad_x( t.
x ), kicad_y( t.
y ) );
2127 if( degrees == 90 || t.
rot->
spin )
2131 else if( degrees == 180 )
2135 else if( degrees == 270 )
2199 ZONE* zone =
new ZONE( aFootprint );
2200 aFootprint->
Add( zone, ADD_MODE::APPEND );
2202 setKeepoutSettingsToZone( zone, r.
layer );
2204 const int outlineIdx = -1;
2212 VECTOR2I center( ( kicad_x( r.
x1 ) + kicad_x( r.
x2 ) ) / 2,
2213 ( kicad_y( r.
y1 ) + kicad_y( r.
y2 ) ) / 2 );
2226 wxLogMessage( wxString::Format(
_(
"Ignoring a rectangle since Eagle layer '%s' (%d) "
2234 aFootprint->
Add( dwg );
2240 std::vector<VECTOR2I> pts;
2245 pts.push_back( start );
2246 pts.emplace_back( kicad_x( r.
x2 ), kicad_y( r.
y1 ) );
2247 pts.emplace_back( kicad_x( r.
x2 ), kicad_y( r.
y2 ) );
2248 pts.push_back( end );
2265 std::vector<VECTOR2I> pts;
2268 wxXmlNode* vertex = aTree->GetChildren();
2269 std::vector<EVERTEX> vertices;
2277 if( vertex->GetName() == wxT(
"vertex" ) )
2278 vertices.emplace_back( vertex );
2280 vertex = vertex->GetNext();
2283 vertices.push_back( vertices[0] );
2285 for(
size_t i = 0; i < vertices.size() - 1; i++ )
2290 pts.emplace_back( kicad_x(
v1.
x ), kicad_y(
v1.
y ) );
2299 double end_angle = atan2( kicad_y(
v2.
y ) - center.
y, kicad_x(
v2.
x ) - center.
x );
2300 double radius = sqrt( pow( center.
x - kicad_x(
v1.
x ), 2 )
2301 + pow( center.
y - kicad_y(
v1.
y ), 2 ) );
2309 double delta = angle / segCount;
2311 for(
double a = end_angle + angle; fabs( a - end_angle ) > fabs(
delta ); a -=
delta )
2327 ZONE* zone =
new ZONE( aFootprint );
2328 aFootprint->
Add( zone, ADD_MODE::APPEND );
2330 setKeepoutSettingsToZone( zone, p.
layer );
2343 wxLogMessage( wxString::Format(
_(
"Ignoring a polygon since Eagle layer '%s' (%d) "
2351 aFootprint->
Add( dwg );
2377 ZONE* zone =
new ZONE( aFootprint );
2378 aFootprint->
Add( zone, ADD_MODE::APPEND );
2380 setKeepoutSettingsToZone( zone, e.
layer );
2383 VECTOR2I center( kicad_x( e.
x ), kicad_y( e.
y ) );
2384 int outlineRadius = radius + ( width / 2 );
2390 VECTOR2I rotatedPoint( outlineRadius, 0 );
2398 int innerRadius = radius - ( width / 2 );
2404 VECTOR2I rotatedPoint( innerRadius, 0 );
2419 wxLogMessage( wxString::Format(
_(
"Ignoring a circle since Eagle layer '%s' (%d) "
2431 radius = radius / 2;
2435 aFootprint->
Add( gr );
2438 switch( (
int) layer )
2468 pad->SetAttribute( PAD_ATTRIB::NPTH );
2475 VECTOR2I padpos( kicad_x( e.
x ), kicad_y( e.
y ) );
2480 pad->SetPosition( padpos );
2489 pad->SetDrillSize( sz );
2506 transferPad( e,
pad );
2509 pad->SetAttribute( PAD_ATTRIB::SMD );
2513 pad->SetLayer( layer );
2519 pad->SetLayerSet( front );
2520 else if( layer ==
B_Cu )
2521 pad->SetLayerSet( back );
2523 int minPadSize = std::min( padSize.
x, padSize.
y );
2527 eagleClamp( m_rules->srMinRoundness * 2, (
int) ( minPadSize * m_rules->srRoundness ),
2528 m_rules->srMaxRoundness * 2 );
2532 double roundRatio = (double) roundRadius / minPadSize / 2.0;
2536 roundRatio = std::fmax( *e.
roundness / 200.0, roundRatio );
2548 pad->SetLocalSolderPasteMargin( -
eagleClamp( m_rules->mlMinCreamFrame,
2549 (
int) ( m_rules->mvCreamFrame * minPadSize ),
2550 m_rules->mlMaxCreamFrame ) );
2556 pad->SetLayerSet(
pad->GetLayerSet().set(
F_Mask,
false ) );
2557 else if( layer ==
B_Cu )
2558 pad->SetLayerSet(
pad->GetLayerSet().set(
B_Mask,
false ) );
2565 pad->SetLayerSet(
pad->GetLayerSet().set(
F_Paste,
false ) );
2566 else if( layer ==
B_Cu )
2567 pad->SetLayerSet(
pad->GetLayerSet().set(
B_Paste,
false ) );
2576 VECTOR2I padPos( kicad_x( aEaglePad.
x ), kicad_y( aEaglePad.
y ) );
2583 (
int) ( m_rules->mvStopFrame * std::min( padSize.
x, padSize.
y ) ),
2584 m_rules->mlMaxStopFrame ) );
2591 wxCHECK( footprint, );
2599 for(
const auto& [
name, footprint ] : m_templates )
2601 footprint->SetParent(
nullptr );
2605 m_templates.clear();
2617 m_xpath->push(
"classes.class",
"number" );
2619 std::vector<ECLASS> eClasses;
2620 wxXmlNode* classNode = aClasses->GetChildren();
2626 ECLASS eClass( classNode );
2627 std::shared_ptr<NETCLASS> netclass;
2629 if( eClass.
name.CmpNoCase( wxT(
"default" ) ) == 0 )
2639 netclass->SetTrackWidth( INT_MAX );
2640 netclass->SetViaDiameter( INT_MAX );
2641 netclass->SetViaDrill( INT_MAX );
2643 eClasses.emplace_back( eClass );
2644 m_classMap[ eClass.
number ] = netclass;
2647 classNode = classNode->GetNext();
2650 m_customRules = wxT(
"(version 1)" );
2652 for(
ECLASS& eClass : eClasses )
2654 for( std::pair<const wxString&, ECOORD> entry : eClass.clearanceMap )
2656 if( m_classMap[ entry.first ] !=
nullptr )
2659 rule.Printf( wxT(
"(rule \"class %s:%s\"\n"
2660 " (condition \"A.NetClass == '%s' && B.NetClass == '%s'\")\n"
2661 " (constraint clearance (min %smm)))\n" ),
2665 m_classMap[ entry.first ]->GetName(),
2668 m_customRules += wxT(
"\n" ) + rule;
2686 m_xpath->push(
"signals.signal",
"name" );
2689 wxXmlNode* net = aSignals->GetChildren();
2695 bool sawPad =
false;
2699 const wxString& netName =
escapeName( net->GetAttribute(
"name" ) );
2701 std::shared_ptr<NETCLASS> netclass;
2703 if( net->HasAttribute(
"class" ) )
2705 auto netclassIt = m_classMap.find( net->GetAttribute(
"class" ) );
2707 if( netclassIt != m_classMap.end() )
2709 m_board->GetDesignSettings().m_NetSettings->SetNetclassPatternAssignment(
2710 netName, netclassIt->second->GetName() );
2712 netclass = netclassIt->second;
2716 m_board->Add( netInfo );
2718 m_xpath->Value( netName.c_str() );
2721 wxXmlNode* netItem = net->GetChildren();
2726 const wxString& itemName = netItem->GetName();
2728 if( itemName == wxT(
"wire" ) )
2730 m_xpath->push(
"wire" );
2742 if( width < m_min_trace )
2743 m_min_trace = width;
2745 if( netclass && width < netclass->GetTrackWidth() )
2746 netclass->SetTrackWidth( width );
2751 double radius = sqrt( pow( center.
x - kicad_x( w.
x1 ), 2 ) +
2752 pow( center.
y - kicad_y( w.
y1 ), 2 ) );
2756 double radiusA = ( mid - center ).EuclideanNorm();
2757 double radiusB = ( otherMid - center ).EuclideanNorm();
2759 if(
abs( radiusA - radius ) >
abs( radiusB - radius ) )
2760 std::swap( mid, otherMid );
2771 m_board->Add( arc );
2783 m_board->Add( track );
2793 else if( itemName == wxT(
"via" ) )
2795 m_xpath->push(
"via" );
2805 && layer_front_most != layer_back_most )
2810 m_board->Add(
via );
2819 double annulus = drillz * m_rules->rvViaOuter;
2820 annulus =
eagleClamp( m_rules->rlMinViaOuter, annulus,
2821 m_rules->rlMaxViaOuter );
2822 kidiam =
KiROUND( drillz + 2 * annulus );
2826 via->SetDrill( drillz );
2833 m_rules->rlMinViaOuter,
2835 -
via->GetDrill() ),
2836 m_rules->rlMaxViaOuter );
2840 if( kidiam < m_min_via )
2843 if( netclass && kidiam < netclass->GetViaDiameter() )
2844 netclass->SetViaDiameter( kidiam );
2846 if( drillz < m_min_hole )
2847 m_min_hole = drillz;
2849 if( netclass && drillz < netclass->GetViaDrill() )
2850 netclass->SetViaDrill( drillz );
2852 if( ( kidiam - drillz ) / 2 < m_min_annulus )
2853 m_min_annulus = ( kidiam - drillz ) / 2;
2855 if( layer_front_most ==
F_Cu && layer_back_most ==
B_Cu )
2857 via->SetViaType( VIATYPE::THROUGH );
2864 via->SetViaType( VIATYPE::MICROVIA );
2868 via->SetViaType( VIATYPE::BLIND_BURIED );
2871 VECTOR2I pos( kicad_x( v.
x ), kicad_y( v.
y ) );
2873 via->SetLayerPair( layer_front_most, layer_back_most );
2874 via->SetPosition( pos );
2877 via->SetNetCode( netCode );
2883 else if( itemName == wxT(
"contactref" ) )
2885 m_xpath->push(
"contactref" );
2888 const wxString& reference = netItem->GetAttribute(
"element" );
2889 const wxString&
pad = netItem->GetAttribute(
"pad" );
2892 m_pads_to_nets[ key ] =
ENET( netCode, netName );
2899 else if( itemName == wxT(
"polygon" ) )
2901 m_xpath->push(
"polygon" );
2902 auto* zone = loadPolygon( netItem );
2906 zones.push_back( zone );
2908 if( !zone->GetIsRuleArea() )
2909 zone->SetNetCode( netCode );
2915 netItem = netItem->GetNext();
2918 if( zones.size() && !sawPad )
2922 for(
ZONE* zone : zones )
2933 net = net->GetNext();
2941 const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector )
2943 std::map<wxString, PCB_LAYER_ID> layer_map;
2947 PCB_LAYER_ID layerId = std::get<0>( defaultKicadLayer( eagle_layer_id( layer.Name ) ) );
2948 layer_map.emplace( layer.Name, layerId );
2957 std::vector<INPUT_LAYER_DESC> inputDescs;
2959 for (
const std::pair<const int, ELAYER>& layerPair : m_eagleLayers )
2961 const ELAYER& eLayer = layerPair.second;
2965 defaultKicadLayer( eLayer.
number, aIsLibraryCache );
2972 inputDescs.push_back( layerDesc );
2975 if( m_progressReporter &&
dynamic_cast<wxWindow*
>( m_progressReporter ) )
2976 dynamic_cast<wxWindow*
>( m_progressReporter )->Hide();
2978 m_layer_map = m_layer_mapping_handler( inputDescs );
2980 if( m_progressReporter &&
dynamic_cast<wxWindow*
>( m_progressReporter ))
2981 dynamic_cast<wxWindow*
>( m_progressReporter )->Show();
2987 auto result = m_layer_map.find( eagle_layer_name( aEagleLayer ) );
2988 return result == m_layer_map.end() ?
UNDEFINED_LAYER : result->second;
2993 bool aIsLibraryCache )
const
2996 if( aEagleLayer >= 1 && aEagleLayer <
int(
arrayDim( m_cu_map ) ) )
3000 for(
int copperLayer : m_cu_map )
3002 if( copperLayer >= 0 )
3003 copperLayers[copperLayer] =
true;
3006 return {
PCB_LAYER_ID( m_cu_map[aEagleLayer] ), copperLayers,
true };
3010 bool required =
false;
3011 LSET permittedLayers;
3013 permittedLayers.
set();
3016 switch( aEagleLayer )
3114 if( aIsLibraryCache )
3122 return {
PCB_LAYER_ID( kiLayer ), permittedLayers, required };
3128 static const wxString
unknown(
"unknown" );
3129 auto it = m_eagleLayers.find( aLayer );
3130 return it == m_eagleLayers.end() ?
unknown : it->second.name;
3136 static const int unknown = -1;
3137 auto it = m_eagleLayersIds.find( aLayerName );
3138 return it == m_eagleLayersIds.end() ?
unknown : it->second;
3149 if(
auto it = m_props->find(
"page_width" ); it != m_props->end() )
3150 page_width = it->second;
3152 if(
auto it = m_props->find(
"page_height" ); it != m_props->end() )
3153 page_height = it->second;
3155 if( !page_width.
empty() && !page_height.
empty() )
3157 BOX2I bbbox = m_board->GetBoardEdgesBoundingBox();
3159 int w = atoi( page_width.
c_str() );
3160 int h = atoi( page_height.
c_str() );
3162 int desired_x = ( w - bbbox.
GetWidth() ) / 2;
3163 int desired_y = ( h - bbbox.
GetHeight() ) / 2;
3165 m_board->Move(
VECTOR2I( desired_x - bbbox.
GetX(), desired_y - bbbox.
GetY() ) );
3174 if( aPath.IsEmpty() )
3175 return wxDateTime::Now();
3177 wxFileName fn( aPath );
3179 if( fn.IsFileReadable() )
3180 return fn.GetModificationTime();
3182 return wxDateTime( 0.0 );
3192 wxDateTime modtime = getModificationTime( aLibPath );
3197 bool load = !m_mod_time.IsValid() || !modtime.IsValid() || m_mod_time != modtime;
3199 if( aLibPath != m_lib_path || load )
3209 m_lib_path = aLibPath;
3214 string filename = (
const char*) aLibPath.char_str( wxConvFile );
3217 wxFileName fn( filename );
3218 wxFFileInputStream stream( fn.GetFullPath() );
3219 wxXmlDocument xmlDocument;
3221 if( !stream.IsOk() || !xmlDocument.Load( stream ) )
3224 fn.GetFullPath() ) );
3227 doc = xmlDocument.GetRoot();
3229 wxXmlNode* drawing =
MapChildren( doc )[
"drawing"];
3235 m_xpath->push(
"eagle.drawing.layers" );
3236 wxXmlNode* layers = drawingChildren[
"layers"];
3237 loadLayerDefs( layers );
3238 mapEagleLayersToKicad(
true );
3241 m_xpath->push(
"eagle.drawing.library" );
3242 wxXmlNode*
library = drawingChildren[
"library"];
3244 loadLibrary(
library,
nullptr );
3247 m_mod_time = modtime;
3274 bool aBestEfforts,
const std::map<std::string, UTF8>* aProperties )
3278 init( aProperties );
3282 cacheLib( aLibraryPath );
3286 errorMsg = ioe.
What();
3292 for(
const auto& [
name, footprint ] : m_templates )
3293 aFootprintNames.Add(
name );
3295 if( !errorMsg.IsEmpty() && !aBestEfforts )
3301 const wxString& aFootprintName,
bool aKeepUUID,
3302 const std::map<std::string, UTF8>* aProperties )
3304 init( aProperties );
3305 cacheLib( aLibraryPath );
3306 auto it = m_templates.find( aFootprintName );
3308 if( it == m_templates.end() )
3313 copy->SetParent(
nullptr );
3320 int minLayerCount = 2;
3322 std::map<wxString, PCB_LAYER_ID>::const_iterator it;
3324 for( it = m_layer_map.begin(); it != m_layer_map.end(); ++it )
3329 && ( layerId + 2 ) > minLayerCount )
3330 minLayerCount = layerId + 2;
3336 if( ( minLayerCount % 2 ) != 0 )
3339 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)
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
constexpr coord_type GetY() const
constexpr size_type GetWidth() const
constexpr coord_type GetX() const
constexpr size_type GetHeight() 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)
GR_TEXT_H_ALIGN_T GetHorizJustify() const
virtual void SetVisible(bool aVisible)
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
void SetKeepUpright(bool aKeepUpright)
GR_TEXT_V_ALIGN_T GetVertJustify() const
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.
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
void SetNumber(const wxString &aNumber)
Set the pad number (note that it can be alphanumeric, such as the array reference "AA12").
void SetLocalSolderMaskMargin(std::optional< int > aMargin)
void SetLocalZoneConnection(ZONE_CONNECTION aType)
void SetPosition(const VECTOR2I &aPos) override
const VECTOR2I & GetSize(PCB_LAYER_ID aLayer) 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 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...
BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr) override
Load information from some input file format that this PCB_IO implementation knows about into either ...
void loadLibraries(wxXmlNode *aLibs)
void init(const std::map< std::string, UTF8 > *aProperties)
initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
FOOTPRINT * FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PC...
int eagle_layer_id(const wxString &aLayerName) const
Get Eagle layer number by its name.
void loadAllSections(wxXmlNode *aDocument)
bool CanReadFootprint(const wxString &aFileName) const override
Checks if this PCB_IO can read a footprint from specified file or directory.
void packageWire(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
bool CanReadBoard(const wxString &aFileName) const override
Checks if this PCB_IO can read the specified board file.
const wxString & eagle_layer_name(int aLayer) const
Get Eagle layer name by its number.
ELAYERS::const_iterator EITER
void packageRectangle(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
int kicad_y(const ECOORD &y) const
Convert an Eagle distance to a KiCad distance.
void loadClasses(wxXmlNode *aClasses)
std::map< int, ELAYER > m_eagleLayers
Eagle layer data stored by layer number.
NET_MAP m_pads_to_nets
net list
void packageText(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
int getMinimumCopperLayerCount() const
Determines the minimum copper layer stackup count that includes all mapped layers.
void packageHole(FOOTPRINT *aFootprint, wxXmlNode *aTree, bool aCenter) const
void packagePolygon(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
void centerBoard()
move the BOARD into the center of the page
unsigned m_lastProgressCount
int m_cu_map[17]
map eagle to KiCad, cu layers only.
ZONE * loadPolygon(wxXmlNode *aPolyNode)
Load a copper or keepout polygon and adds it to the board.
int m_min_via
smallest via we find on Load(), in BIU.
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this IO object can read the specified library file/directory.
void packageCircle(FOOTPRINT *aFootprint, wxXmlNode *aTree) const
void loadLibrary(wxXmlNode *aLib, const wxString *aLibName)
Load the Eagle "library" XML element, which can occur either under a "libraries" element (if a *....
void packagePad(FOOTPRINT *aFootprint, wxXmlNode *aTree)
void loadSignals(wxXmlNode *aSignals)
ERULES * m_rules
Eagle design rules.
PCB_LAYER_ID kicad_layer(int aLayer) const
Convert an Eagle layer to a KiCad layer.
void orientFootprintAndText(FOOTPRINT *aFootprint, const EELEMENT &e, const EATTR *aNameAttr, const EATTR *aValueAttr)
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 FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aLibraryPath, bool aBestEfforts, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Return a list of footprint names contained within the library at aLibraryPath.
void setKeepoutSettingsToZone(ZONE *aZone, int aLayer) const
void transferPad(const EPAD_COMMON &aEaglePad, PAD *aPad) const
Deletes the footprint templates list.
int kicad_x(const ECOORD &x) const
void loadDesignRules(wxXmlNode *aDesignRules)
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
A base class that BOARD loading and saving plugins should derive from.
BOARD * m_board
The board BOARD being worked on, no ownership here.
virtual bool CanReadBoard(const wxString &aFileName) const
Checks if this PCB_IO can read the specified board file.
const std::map< std::string, UTF8 > * m_props
Properties passed via Save() or Load(), no ownership, may be NULL.
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
void 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 SetEnd(const VECTOR2I &aEnd)
void SetPosition(const VECTOR2I &aPos) override
virtual void SetWidth(int aWidth)
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
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 SetLayerSet(const LSET &aLayerSet) override
void SetDoNotAllowVias(bool aEnable)
void SetDoNotAllowFootprints(bool aEnable)
bool AppendCorner(VECTOR2I aPosition, int aHoleIdx, bool aAllowDuplication=false)
Add a new corner to the zone outline (to the main outline or a hole)
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
a few functions useful in geometry calculations.
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.
const VECTOR2I CalcArcMid(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aMinArcAngle=true)
Return the middle point of an arc, half-way between aStart and aEnd.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
double DEG2RAD(double deg)
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
constexpr int sign(T val)
VECTOR2< int32_t > VECTOR2I
ZONE_BORDER_DISPLAY_STYLE
Zone border styles.
#define ZONE_THICKNESS_MIN_VALUE_MM