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 < 8; 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;
1278 auto it = m_templates.find( pkg_key );
1280 if( it == m_templates.end() )
1282 wxString emsg = wxString::Format(
_(
"No '%s' package in library '%s'." ),
1289 m_board->
Add( footprint, ADD_MODE::APPEND );
1297 if( ni != m_pads_to_nets.end() )
1299 const ENET* enet = &ni->second;
1304 refanceNamePresetInPackageLayout =
true;
1305 valueNamePresetInPackageLayout =
true;
1312 refanceNamePresetInPackageLayout =
false;
1316 if( footprint->
GetValue().size() == 0 )
1319 valueNamePresetInPackageLayout =
false;
1322 wxString reference = e.
name;
1328 if( reference.find_first_not_of(
"0123456789" ) != 0 )
1329 reference.Prepend(
"UNK" );
1333 if( reference.find_first_not_of(
"#" ) != 0 )
1334 reference.Prepend(
"UNK" );
1337 if( reference.find_last_not_of(
"0123456789" ) == (reference.Length()-1) )
1338 reference.Append(
"0" );
1346 if( valueNamePresetInPackageLayout )
1349 if( refanceNamePresetInPackageLayout )
1359 m_xpath->push(
"attribute",
"name" );
1369 wxXmlNode* attribute = element->GetChildren();
1373 if( attribute->GetName() != wxT(
"attribute" ) )
1375 attribute = attribute->GetNext();
1379 EATTR a( attribute );
1381 if( a.
name == wxT(
"NAME" ) )
1394 nameAttr->
name = reference;
1396 if( refanceNamePresetInPackageLayout )
1403 if( refanceNamePresetInPackageLayout )
1412 if( refanceNamePresetInPackageLayout )
1415 nameAttr->
name = nameAttr->
name + wxT(
" = " ) + e.
name;
1426 if( refanceNamePresetInPackageLayout )
1436 else if( a.
name == wxT(
"VALUE" ) )
1450 if( valueNamePresetInPackageLayout )
1456 if( valueNamePresetInPackageLayout )
1459 footprint->
SetValue( wxT(
"VALUE" ) );
1463 if( valueNamePresetInPackageLayout )
1477 if( valueNamePresetInPackageLayout )
1489 attribute = attribute->GetNext();
1495 orientFootprintAndText( footprint, e, nameAttr, valueAttr );
1498 element = element->GetNext();
1515 wxLogMessage( wxString::Format(
_(
"Ignoring a polygon since Eagle layer '%s' (%d) "
1522 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( m_board );
1525 zone->SetLayer( layer );
1527 setKeepoutSettingsToZone( zone.get(), p.
layer );
1530 wxXmlNode* vertex = aPolyNode->GetChildren();
1531 std::vector<EVERTEX> vertices;
1539 if( vertex->GetName() == wxT(
"vertex" ) )
1540 vertices.emplace_back( vertex );
1542 vertex = vertex->GetNext();
1548 zone->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::ALWAYS );
1550 zone->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::NEVER );
1552 vertices.push_back( vertices[0] );
1557 for(
size_t i = 0; i < vertices.size() - 1; i++ )
1571 double end_angle = atan2( kicad_y(
v2.
y ) - center.
y, kicad_x(
v2.
x ) - center.
x );
1572 double radius = sqrt( pow( center.
x - kicad_x(
v1.
x ), 2 )
1573 + pow( center.
y - kicad_y(
v1.
y ), 2 ) );
1577 double delta_angle = angle / segCount;
1579 for(
double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta_angle );
1583 KiROUND( radius * sin( a ) ) + center.
y );
1598 wxLogMessage( wxString::Format(
1599 _(
"Skipping a polygon on layer '%s' (%d): outline count is not 1" ),
1605 zone->AddPolygon( polygon.
COutline( 0 ) );
1610 zone->SetIsRuleArea(
true );
1611 zone->SetDoNotAllowVias(
false );
1612 zone->SetDoNotAllowTracks(
false );
1613 zone->SetDoNotAllowPads(
false );
1614 zone->SetDoNotAllowFootprints(
false );
1615 zone->SetDoNotAllowCopperPour(
true );
1616 zone->SetHatchStyle( ZONE_BORDER_DISPLAY_STYLE::NO_HATCH );
1622 zone->SetFillMode( ZONE_FILL_MODE::HATCH_PATTERN );
1625 zone->SetHatchOrientation(
ANGLE_0 );
1636 zone->SetLocalClearance( 1 );
1640 zone->SetPadConnection( thermals ? ZONE_CONNECTION::THERMAL : ZONE_CONNECTION::FULL );
1653 zone->SetAssignedPriority( rank );
1655 ZONE* zonePtr = zone.release();
1656 m_board->Add( zonePtr, ADD_MODE::APPEND );
1663 const EATTR* aNameAttr,
const EATTR* aValueAttr )
1670 aFootprint->
Flip( aFootprint->
GetPosition(), FLIP_DIRECTION::TOP_BOTTOM );
1678 orientFPText( aFootprint, e, &aFootprint->
Reference(), aNameAttr );
1679 orientFPText( aFootprint, e, &aFootprint->
Value(), aValueAttr );
1684 const EATTR* aAttr )
1690 const EATTR& a = *aAttr;
1699 VECTOR2I pos( kicad_x( *a.
x ), kicad_y( *a.
y ) );
1711 int textThickness =
KiROUND( fontz.
y * ratio / 100 );
1716 fontz = kicad_fontsize( *a.
size, textThickness );
1742 if( degrees == 90 || degrees == 0 || spin )
1746 else if( degrees == 180 )
1751 else if( degrees == 270 )
1754 degrees =
sign * 90;
1758 degrees = 90 - (
sign * degrees);
1815 if( aFPText->
IsMirrored() && degrees < -90 && degrees >= -270 )
1852 std::unique_ptr<FOOTPRINT> m = std::make_unique<FOOTPRINT>( m_board );
1855 fpID.
Parse( aPkgName,
true );
1859 wxXmlNode* packageItem = aPackage->GetChildren();
1864 m.get()->Value().SetLayer( layer );
1866 while( packageItem )
1868 const wxString& itemName = packageItem->GetName();
1870 if( itemName == wxT(
"description" ) )
1873 m->SetLibDescription( descr );
1875 else if( itemName == wxT(
"wire" ) )
1876 packageWire( m.get(), packageItem );
1877 else if( itemName == wxT(
"pad" ) )
1878 packagePad( m.get(), packageItem );
1879 else if( itemName == wxT(
"text" ) )
1880 packageText( m.get(), packageItem );
1881 else if( itemName == wxT(
"rectangle" ) )
1882 packageRectangle( m.get(), packageItem );
1883 else if( itemName == wxT(
"polygon" ) )
1884 packagePolygon( m.get(), packageItem );
1885 else if( itemName == wxT(
"circle" ) )
1886 packageCircle( m.get(), packageItem );
1887 else if( itemName == wxT(
"hole" ) )
1888 packageHole( m.get(), packageItem,
false );
1889 else if( itemName == wxT(
"smd" ) )
1890 packageSMD( m.get(), packageItem );
1892 packageItem = packageItem->GetNext();
1909 wxLogMessage( wxString::Format(
_(
"Ignoring a wire since Eagle layer '%s' (%d) "
1948 dwg =
new PCB_SHAPE( aFootprint, SHAPE_T::SEGMENT );
1955 dwg =
new PCB_SHAPE( aFootprint, SHAPE_T::ARC );
1968 aFootprint->
Add( dwg );
1979 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
1980 transferPad( e,
pad.get() );
1983 shape = m_rules->psFirst;
1985 shape = m_rules->psTop;
1987 shape = m_rules->psBottom;
1989 pad->SetDrillSize(
VECTOR2I( eagleDrillz, eagleDrillz ) );
1992 if( eagleDrillz < m_min_hole )
1993 m_min_hole = eagleDrillz;
2041 double drillz =
pad->GetDrillSize().x;
2042 double annulus = drillz * m_rules->rvPadTop;
2043 annulus =
eagleClamp( m_rules->rlMinPadTop, annulus, m_rules->rlMaxPadTop );
2044 int diameter =
KiROUND( drillz + 2 * annulus );
2052 sz.
x = ( sz.
x * ( 100 + m_rules->psElongationLong ) ) / 100;
2057 int offset =
KiROUND( ( sz.
x - sz.
y ) / 2.0 );
2068 if(
pad->GetSizeX() > 0 &&
pad->GetSizeY() > 0 &&
pad->HasHole() )
2070 aFootprint->
Add(
pad.release() );
2074 wxFileName fileName( m_lib_path );
2077 wxLogError(
_(
"Invalid zero-sized pad ignored in\nfile: %s" ), m_board->GetFileName() );
2079 wxLogError(
_(
"Invalid zero-sized pad ignored in\nfile: %s" ), fileName.GetFullName() );
2091 wxLogMessage( wxString::Format(
_(
"Ignoring a text since Eagle layer '%s' (%d) "
2099 if( t.
text.Upper() == wxT(
">NAME" ) && aFootprint->
GetReference().IsEmpty() )
2103 textItem->
SetText( wxT(
"REF**" ) );
2105 else if( t.
text.Upper() == wxT(
">VALUE" ) && aFootprint->
GetValue().IsEmpty() )
2107 textItem = &aFootprint->
Value();
2113 textItem =
new PCB_TEXT( aFootprint );
2114 aFootprint->
Add( textItem );
2119 VECTOR2I pos( kicad_x( t.
x ), kicad_y( t.
y ) );
2202 ZONE* zone =
new ZONE( aFootprint );
2203 aFootprint->
Add( zone, ADD_MODE::APPEND );
2205 setKeepoutSettingsToZone( zone, r.
layer );
2207 const int outlineIdx = -1;
2215 VECTOR2I center( ( kicad_x( r.
x1 ) + kicad_x( r.
x2 ) ) / 2,
2216 ( kicad_y( r.
y1 ) + kicad_y( r.
y2 ) ) / 2 );
2229 wxLogMessage( wxString::Format(
_(
"Ignoring a rectangle since Eagle layer '%s' (%d) "
2237 aFootprint->
Add( dwg );
2243 std::vector<VECTOR2I> pts;
2248 pts.push_back( start );
2249 pts.emplace_back( kicad_x( r.
x2 ), kicad_y( r.
y1 ) );
2250 pts.emplace_back( kicad_x( r.
x2 ), kicad_y( r.
y2 ) );
2251 pts.push_back( end );
2268 std::vector<VECTOR2I> pts;
2271 wxXmlNode* vertex = aTree->GetChildren();
2272 std::vector<EVERTEX> vertices;
2280 if( vertex->GetName() == wxT(
"vertex" ) )
2281 vertices.emplace_back( vertex );
2283 vertex = vertex->GetNext();
2286 vertices.push_back( vertices[0] );
2288 for(
size_t i = 0; i < vertices.size() - 1; i++ )
2293 pts.emplace_back( kicad_x(
v1.
x ), kicad_y(
v1.
y ) );
2302 double end_angle = atan2( kicad_y(
v2.
y ) - center.
y, kicad_x(
v2.
x ) - center.
x );
2303 double radius = sqrt( pow( center.
x - kicad_x(
v1.
x ), 2 )
2304 + pow( center.
y - kicad_y(
v1.
y ), 2 ) );
2312 double delta = angle / segCount;
2314 for(
double a = end_angle + angle; fabs( a - end_angle ) > fabs(
delta ); a -=
delta )
2330 ZONE* zone =
new ZONE( aFootprint );
2331 aFootprint->
Add( zone, ADD_MODE::APPEND );
2333 setKeepoutSettingsToZone( zone, p.
layer );
2346 wxLogMessage( wxString::Format(
_(
"Ignoring a polygon since Eagle layer '%s' (%d) "
2354 aFootprint->
Add( dwg );
2380 ZONE* zone =
new ZONE( aFootprint );
2381 aFootprint->
Add( zone, ADD_MODE::APPEND );
2383 setKeepoutSettingsToZone( zone, e.
layer );
2386 VECTOR2I center( kicad_x( e.
x ), kicad_y( e.
y ) );
2387 int outlineRadius = radius + ( width / 2 );
2393 VECTOR2I rotatedPoint( outlineRadius, 0 );
2401 int innerRadius = radius - ( width / 2 );
2407 VECTOR2I rotatedPoint( innerRadius, 0 );
2422 wxLogMessage( wxString::Format(
_(
"Ignoring a circle since Eagle layer '%s' (%d) "
2434 radius = radius / 2;
2438 aFootprint->
Add( gr );
2441 switch( (
int) layer )
2471 pad->SetAttribute( PAD_ATTRIB::NPTH );
2478 VECTOR2I padpos( kicad_x( e.
x ), kicad_y( e.
y ) );
2483 pad->SetPosition( padpos );
2492 pad->SetDrillSize( sz );
2509 transferPad( e,
pad );
2512 pad->SetAttribute( PAD_ATTRIB::SMD );
2516 pad->SetLayer( layer );
2522 pad->SetLayerSet( front );
2523 else if( layer ==
B_Cu )
2524 pad->SetLayerSet( back );
2526 int minPadSize = std::min( padSize.
x, padSize.
y );
2530 eagleClamp( m_rules->srMinRoundness * 2, (
int) ( minPadSize * m_rules->srRoundness ),
2531 m_rules->srMaxRoundness * 2 );
2535 double roundRatio = (double) roundRadius / minPadSize / 2.0;
2539 roundRatio = std::fmax( *e.
roundness / 200.0, roundRatio );
2551 pad->SetLocalSolderPasteMargin( -
eagleClamp( m_rules->mlMinCreamFrame,
2552 (
int) ( m_rules->mvCreamFrame * minPadSize ),
2553 m_rules->mlMaxCreamFrame ) );
2559 pad->SetLayerSet(
pad->GetLayerSet().set(
F_Mask,
false ) );
2560 else if( layer ==
B_Cu )
2561 pad->SetLayerSet(
pad->GetLayerSet().set(
B_Mask,
false ) );
2568 pad->SetLayerSet(
pad->GetLayerSet().set(
F_Paste,
false ) );
2569 else if( layer ==
B_Cu )
2570 pad->SetLayerSet(
pad->GetLayerSet().set(
B_Paste,
false ) );
2579 VECTOR2I padPos( kicad_x( aEaglePad.
x ), kicad_y( aEaglePad.
y ) );
2586 (
int) ( m_rules->mvStopFrame * std::min( padSize.
x, padSize.
y ) ),
2587 m_rules->mlMaxStopFrame ) );
2594 wxCHECK( footprint, );
2602 for(
const auto& [
name, footprint ] : m_templates )
2604 footprint->SetParent(
nullptr );
2608 m_templates.clear();
2620 m_xpath->push(
"classes.class",
"number" );
2622 std::vector<ECLASS> eClasses;
2623 wxXmlNode* classNode = aClasses->GetChildren();
2629 ECLASS eClass( classNode );
2630 std::shared_ptr<NETCLASS> netclass;
2632 if( eClass.
name.CmpNoCase( wxT(
"default" ) ) == 0 )
2642 netclass->SetTrackWidth( INT_MAX );
2643 netclass->SetViaDiameter( INT_MAX );
2644 netclass->SetViaDrill( INT_MAX );
2646 eClasses.emplace_back( eClass );
2647 m_classMap[ eClass.
number ] = netclass;
2650 classNode = classNode->GetNext();
2653 m_customRules = wxT(
"(version 1)" );
2655 for(
ECLASS& eClass : eClasses )
2657 for( std::pair<const wxString&, ECOORD> entry : eClass.clearanceMap )
2659 if( m_classMap[ entry.first ] !=
nullptr )
2662 rule.Printf( wxT(
"(rule \"class %s:%s\"\n"
2663 " (condition \"A.NetClass == '%s' && B.NetClass == '%s'\")\n"
2664 " (constraint clearance (min %smm)))\n" ),
2668 m_classMap[ entry.first ]->GetName(),
2671 m_customRules += wxT(
"\n" ) + rule;
2689 m_xpath->push(
"signals.signal",
"name" );
2692 wxXmlNode* net = aSignals->GetChildren();
2698 bool sawPad =
false;
2702 const wxString& netName =
escapeName( net->GetAttribute(
"name" ) );
2704 std::shared_ptr<NETCLASS> netclass;
2706 if( net->HasAttribute(
"class" ) )
2708 auto netclassIt = m_classMap.find( net->GetAttribute(
"class" ) );
2710 if( netclassIt != m_classMap.end() )
2712 m_board->GetDesignSettings().m_NetSettings->SetNetclassPatternAssignment(
2713 netName, netclassIt->second->GetName() );
2715 netclass = netclassIt->second;
2719 m_board->Add( netInfo );
2721 m_xpath->Value( netName.c_str() );
2724 wxXmlNode* netItem = net->GetChildren();
2729 const wxString& itemName = netItem->GetName();
2731 if( itemName == wxT(
"wire" ) )
2733 m_xpath->push(
"wire" );
2745 if( width < m_min_trace )
2746 m_min_trace = width;
2748 if( netclass && width < netclass->GetTrackWidth() )
2749 netclass->SetTrackWidth( width );
2754 double radius = sqrt( pow( center.
x - kicad_x( w.
x1 ), 2 ) +
2755 pow( center.
y - kicad_y( w.
y1 ), 2 ) );
2759 double radiusA = ( mid - center ).EuclideanNorm();
2760 double radiusB = ( otherMid - center ).EuclideanNorm();
2762 if(
abs( radiusA - radius ) >
abs( radiusB - radius ) )
2763 std::swap( mid, otherMid );
2774 m_board->Add( arc );
2786 m_board->Add( track );
2796 else if( itemName == wxT(
"via" ) )
2798 m_xpath->push(
"via" );
2808 && layer_front_most != layer_back_most )
2813 m_board->Add(
via );
2822 double annulus = drillz * m_rules->rvViaOuter;
2823 annulus =
eagleClamp( m_rules->rlMinViaOuter, annulus,
2824 m_rules->rlMaxViaOuter );
2825 kidiam =
KiROUND( drillz + 2 * annulus );
2829 via->SetDrill( drillz );
2836 m_rules->rlMinViaOuter,
2838 -
via->GetDrill() ),
2839 m_rules->rlMaxViaOuter );
2843 if( kidiam < m_min_via )
2846 if( netclass && kidiam < netclass->GetViaDiameter() )
2847 netclass->SetViaDiameter( kidiam );
2849 if( drillz < m_min_hole )
2850 m_min_hole = drillz;
2852 if( netclass && drillz < netclass->GetViaDrill() )
2853 netclass->SetViaDrill( drillz );
2855 if( ( kidiam - drillz ) / 2 < m_min_annulus )
2856 m_min_annulus = ( kidiam - drillz ) / 2;
2858 if( layer_front_most ==
F_Cu && layer_back_most ==
B_Cu )
2860 via->SetViaType( VIATYPE::THROUGH );
2867 via->SetViaType( VIATYPE::MICROVIA );
2871 via->SetViaType( VIATYPE::BLIND_BURIED );
2874 VECTOR2I pos( kicad_x( v.
x ), kicad_y( v.
y ) );
2876 via->SetLayerPair( layer_front_most, layer_back_most );
2877 via->SetPosition( pos );
2880 via->SetNetCode( netCode );
2886 else if( itemName == wxT(
"contactref" ) )
2888 m_xpath->push(
"contactref" );
2891 const wxString& reference = netItem->GetAttribute(
"element" );
2892 const wxString&
pad = netItem->GetAttribute(
"pad" );
2895 m_pads_to_nets[ key ] =
ENET( netCode, netName );
2902 else if( itemName == wxT(
"polygon" ) )
2904 m_xpath->push(
"polygon" );
2905 auto* zone = loadPolygon( netItem );
2909 zones.push_back( zone );
2911 if( !zone->GetIsRuleArea() )
2912 zone->SetNetCode( netCode );
2918 netItem = netItem->GetNext();
2921 if( zones.size() && !sawPad )
2925 for(
ZONE* zone : zones )
2936 net = net->GetNext();
2944 const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector )
2946 std::map<wxString, PCB_LAYER_ID> layer_map;
2950 PCB_LAYER_ID layerId = std::get<0>( defaultKicadLayer( eagle_layer_id( layer.Name ) ) );
2951 layer_map.emplace( layer.Name, layerId );
2960 std::vector<INPUT_LAYER_DESC> inputDescs;
2962 for (
const std::pair<const int, ELAYER>& layerPair : m_eagleLayers )
2964 const ELAYER& eLayer = layerPair.second;
2968 defaultKicadLayer( eLayer.
number, aIsLibraryCache );
2975 inputDescs.push_back( layerDesc );
2978 if( m_progressReporter &&
dynamic_cast<wxWindow*
>( m_progressReporter ) )
2979 dynamic_cast<wxWindow*
>( m_progressReporter )->Hide();
2981 m_layer_map = m_layer_mapping_handler( inputDescs );
2983 if( m_progressReporter &&
dynamic_cast<wxWindow*
>( m_progressReporter ))
2984 dynamic_cast<wxWindow*
>( m_progressReporter )->Show();
2990 auto result = m_layer_map.find( eagle_layer_name( aEagleLayer ) );
2991 return result == m_layer_map.end() ?
UNDEFINED_LAYER : result->second;
2996 bool aIsLibraryCache )
const
2999 if( aEagleLayer >= 1 && aEagleLayer <
int(
arrayDim( m_cu_map ) ) )
3003 for(
int copperLayer : m_cu_map )
3005 if( copperLayer >= 0 )
3006 copperLayers[copperLayer] =
true;
3009 return {
PCB_LAYER_ID( m_cu_map[aEagleLayer] ), copperLayers,
true };
3013 bool required =
false;
3014 LSET permittedLayers;
3016 permittedLayers.
set();
3019 switch( aEagleLayer )
3117 if( aIsLibraryCache )
3125 return {
PCB_LAYER_ID( kiLayer ), permittedLayers, required };
3131 static const wxString
unknown(
"unknown" );
3132 auto it = m_eagleLayers.find( aLayer );
3133 return it == m_eagleLayers.end() ?
unknown : it->second.name;
3139 static const int unknown = -1;
3140 auto it = m_eagleLayersIds.find( aLayerName );
3141 return it == m_eagleLayersIds.end() ?
unknown : it->second;
3152 if(
auto it = m_props->find(
"page_width" ); it != m_props->end() )
3153 page_width = it->second;
3155 if(
auto it = m_props->find(
"page_height" ); it != m_props->end() )
3156 page_height = it->second;
3158 if( !page_width.
empty() && !page_height.
empty() )
3160 BOX2I bbbox = m_board->GetBoardEdgesBoundingBox();
3162 int w = atoi( page_width.
c_str() );
3163 int h = atoi( page_height.
c_str() );
3165 int desired_x = ( w - bbbox.
GetWidth() ) / 2;
3166 int desired_y = ( h - bbbox.
GetHeight() ) / 2;
3168 m_board->Move(
VECTOR2I( desired_x - bbbox.
GetX(), desired_y - bbbox.
GetY() ) );
3177 if( aPath.IsEmpty() )
3178 return wxDateTime::Now();
3180 wxFileName fn( aPath );
3182 if( fn.IsFileReadable() )
3183 return fn.GetModificationTime();
3185 return wxDateTime( 0.0 );
3195 wxDateTime modtime = getModificationTime( aLibPath );
3200 bool load = !m_mod_time.IsValid() || !modtime.IsValid() || m_mod_time != modtime;
3202 if( aLibPath != m_lib_path || load )
3212 m_lib_path = aLibPath;
3217 string filename = (
const char*) aLibPath.char_str( wxConvFile );
3220 wxFileName fn( filename );
3221 wxFFileInputStream stream( fn.GetFullPath() );
3222 wxXmlDocument xmlDocument;
3224 if( !stream.IsOk() || !xmlDocument.Load( stream ) )
3227 fn.GetFullPath() ) );
3230 doc = xmlDocument.GetRoot();
3232 wxXmlNode* drawing =
MapChildren( doc )[
"drawing"];
3238 m_xpath->push(
"eagle.drawing.layers" );
3239 wxXmlNode* layers = drawingChildren[
"layers"];
3240 loadLayerDefs( layers );
3241 mapEagleLayersToKicad(
true );
3244 m_xpath->push(
"eagle.drawing.library" );
3245 wxXmlNode*
library = drawingChildren[
"library"];
3247 loadLibrary(
library,
nullptr );
3250 m_mod_time = modtime;
3277 bool aBestEfforts,
const std::map<std::string, UTF8>* aProperties )
3281 init( aProperties );
3285 cacheLib( aLibraryPath );
3289 errorMsg = ioe.
What();
3295 for(
const auto& [
name, footprint ] : m_templates )
3296 aFootprintNames.Add(
name );
3298 if( !errorMsg.IsEmpty() && !aBestEfforts )
3304 const wxString& aFootprintName,
bool aKeepUUID,
3305 const std::map<std::string, UTF8>* aProperties )
3307 init( aProperties );
3308 cacheLib( aLibraryPath );
3309 auto it = m_templates.find( aFootprintName );
3311 if( it == m_templates.end() )
3316 copy->SetParent(
nullptr );
3323 int minLayerCount = 2;
3325 std::map<wxString, PCB_LAYER_ID>::const_iterator it;
3327 for( it = m_layer_map.begin(); it != m_layer_map.end(); ++it )
3332 && ( layerId + 2 ) > minLayerCount )
3333 minLayerCount = layerId + 2;
3339 if( ( minLayerCount % 2 ) != 0 )
3342 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()
virtual 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)
Translates Eagle special characters to their counterparts in KiCad.
wxString interpretText(const wxString &aText)
Interprets special characters in Eagle text and converts them to KiCAD notation.
VECTOR2I ConvertArcCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, double aAngle)
Convert an Eagle curve end to a KiCad center for S_ARC.
wxString convertDescription(wxString aDescr)
Converts Eagle's HTML description into KiCad description format.
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)
Test 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)
Return 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
Value expressed in nanometers.
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.
wxString assetId
The unique asset identifier for the asset type.
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