56#include <wx/xml/xml.h>
57#include <wx/filename.h>
59#include <wx/wfstream.h>
60#include <wx/txtstrm.h>
96 ECOORD coord( aDistance, unit );
107 T ret = std::max( aMin, aValue );
108 return std::min( aMax, ret );
114static wxString
makeKey(
const wxString& aFirst,
const wxString& aSecond )
116 wxString key = aFirst +
'\x02' + aSecond;
164 wxXmlNode* child = aRules->GetChildren();
170 if( child->GetName() == wxT(
"param" ) )
172 const wxString&
name = child->GetAttribute( wxT(
"name" ) );
173 const wxString& value = child->GetAttribute( wxT(
"value" ) );
175 if(
name == wxT(
"psElongationLong" ) )
177 else if(
name == wxT(
"psElongationOffset" ) )
179 else if(
name == wxT(
"mvStopFrame" ) )
181 else if(
name == wxT(
"mvCreamFrame" ) )
183 else if(
name == wxT(
"mlMinStopFrame" ) )
185 else if(
name == wxT(
"mlMaxStopFrame" ) )
187 else if(
name == wxT(
"mlMinCreamFrame" ) )
189 else if(
name == wxT(
"mlMaxCreamFrame" ) )
191 else if(
name == wxT(
"srRoundness" ) )
193 else if(
name == wxT(
"srMinRoundness" ) )
195 else if(
name == wxT(
"srMaxRoundness" ) )
197 else if(
name == wxT(
"psTop" ) )
198 psTop = wxAtoi( value );
199 else if(
name == wxT(
"psBottom" ) )
201 else if(
name == wxT(
"psFirst" ) )
203 else if(
name == wxT(
"rvPadTop" ) )
205 else if(
name == wxT(
"rlMinPadTop" ) )
207 else if(
name == wxT(
"rlMaxPadTop" ) )
209 else if(
name == wxT(
"rvViaOuter" ) )
211 else if(
name == wxT(
"rlMinViaOuter" ) )
213 else if(
name == wxT(
"rlMaxViaOuter" ) )
215 else if(
name == wxT(
"mdWireWire" ) )
219 child = child->GetNext();
227 m_xpath( new
XPATH() ),
228 m_progressReporter( nullptr ),
230 m_lastProgressCount( 0 ),
232 m_timestamp( wxDateTime::Now().GetValue().GetValue() )
234 using namespace std::placeholders;
276 wxFileInputStream input( aFileName );
281 wxTextInputStream
text( input );
283 for(
int i = 0; i < 8; i++ )
288 if(
text.ReadLine().Contains( wxS(
"<eagle" ) ) )
298 const unsigned PROGRESS_DELTA = 50;
319 return VECTOR2I( kz - aTextThickness, kz - aTextThickness );
324 const std::map<std::string, UTF8>* aProperties,
PROJECT* aProject )
339 unique_ptr<BOARD> deleter( aAppendToMe ?
nullptr :
m_board );
351 wxFileName fn = aFileName;
354 wxFFileInputStream stream( fn.GetFullPath() );
355 wxXmlDocument xmlDocument;
357 if( !stream.IsOk() || !xmlDocument.Load( stream ) )
360 fn.GetFullPath() ) );
363 doc = xmlDocument.GetRoot();
389 NETCLASS defaults( wxT(
"dummy" ) );
391 auto finishNetclass =
392 [&](
const std::shared_ptr<NETCLASS>& netclass )
398 if( netclass->GetTrackWidth() == INT_MAX )
401 if( netclass->GetViaDiameter() == INT_MAX )
404 if( netclass->GetViaDrill() == INT_MAX )
408 std::shared_ptr<NET_SETTINGS>& netSettings = bds.
m_NetSettings;
410 finishNetclass( netSettings->GetDefaultNetclass() );
412 for(
const auto& [
name, netclass] : netSettings->GetNetclasses() )
413 finishNetclass( netclass );
418 fn.SetExt( wxT(
"kicad_dru" ) );
419 wxFile rulesFile( fn.GetFullPath(), wxFile::write );
427 wxString errmsg = exc.what();
429 errmsg += wxT(
"\n@ " );
441 for(
const auto& [eagleLayerName, layer] :
m_layer_map )
442 enabledLayers.
set( layer );
455 std::vector<FOOTPRINT*> retval;
458 retval.push_back(
static_cast<FOOTPRINT*
>( footprint->Clone() ) );
494 wxXmlNode* drawing =
MapChildren( aDoc )[
"drawing"];
497 wxXmlNode* board = drawingChildren[
"board"];
500 auto count_children =
501 [
this]( wxXmlNode* aNode )
505 wxXmlNode* child = aNode->GetChildren();
510 child = child->GetNext();
515 wxXmlNode* designrules = boardChildren[
"designrules"];
516 wxXmlNode* layers = drawingChildren[
"layers"];
517 wxXmlNode* plain = boardChildren[
"plain"];
518 wxXmlNode* classes = boardChildren[
"classes"];
519 wxXmlNode* signals = boardChildren[
"signals"];
520 wxXmlNode* libs = boardChildren[
"libraries"];
521 wxXmlNode* elems = boardChildren[
"elements"];
528 count_children( designrules );
529 count_children( layers );
530 count_children( plain );
531 count_children( signals );
532 count_children( elems );
537 libs = libs->GetNext();
541 libs = boardChildren[
"libraries"];
602 wxXmlNode* layerNode = aLayers->GetChildren();
609 ELAYER elayer( layerNode );
615 cu.push_back( elayer );
617 layerNode = layerNode->GetNext();
621 int ki_layer_count = 0;
623 for(
EITER it = cu.begin(); it != cu.end(); ++it, ++ki_layer_count )
625 if( ki_layer_count == 0 )
629 else if( ki_layer_count ==
int( cu.size()-1 ) )
645 for(
EITER it = cu.begin(); it != cu.end(); ++it )
662#define DIMENSION_PRECISION DIM_PRECISION::X_XX
673 wxXmlNode* gr = aGraphics->GetChildren();
680 wxString grName = gr->GetName();
682 if( grName == wxT(
"wire" ) )
705 shape->
SetShape( SHAPE_T::SEGMENT );
725 else if( grName == wxT(
"text" ) )
766 if( degrees > 90 && degrees <= 270 )
791 offset.
y = -signY * (int) textbox.
GetHeight();
803 offset.
x = signX * (int) textbox.
GetWidth();
809 offset.
x = -signX * (int) textbox.
GetWidth();
868 if( pcbtxt->
IsMirrored() && degrees < -90 && degrees >= -270 )
886 else if( grName == wxT(
"circle" ) )
905 int outlineRadius =
radius + ( width / 2 );
911 VECTOR2I rotatedPoint( outlineRadius, 0 );
919 int innerRadius =
radius - ( width / 2 );
925 VECTOR2I rotatedPoint( innerRadius, 0 );
952 else if( grName == wxT(
"rectangle" ) )
972 const int outlineIdx = -1;
991 else if( grName == wxT(
"hole" ) )
1001 footprint->
SetReference( wxString::Format( wxT(
"UNK_HOLE_%d" ), hole_count ) );
1004 LIB_ID fpid( wxEmptyString, wxString::Format( wxT(
"dummyfp%d" ), hole_count ) );
1011 else if( grName == wxT(
"frame" ) )
1015 else if( grName == wxT(
"polygon" ) )
1021 else if( grName == wxT(
"dimension" ) )
1055 dimension->
SetEnd( pt2 );
1060 dimension->
SetUnits( EDA_UNITS::MM );
1090 int newY = ( pt1.
y + pt2.
y ) / 2;
1096 int newX = ( pt1.
x + pt2.
x ) / 2;
1107 dimension->
SetEnd( pt2 );
1111 dimension->
SetUnits( EDA_UNITS::MM );
1117 if(
abs( pt1.
x - pt2.
x ) < 50000 )
1119 int offset = pt3.
x - pt1.
x;
1126 else if(
abs( pt1.
y - pt2.
y ) < 50000 )
1128 int offset = pt3.
y - pt1.
y;
1161 wxString urn = aLib->GetAttribute(
"urn" );
1163 wxString urnOrdinal;
1165 if( !urn.IsEmpty() )
1166 urnOrdinal = urn.AfterLast(
':' );
1169 wxXmlNode* packages =
MapChildren( aLib )[
"packages"];
1181 wxXmlNode*
package = packages->GetChildren();
1187 m_xpath->push(
"package",
"name" );
1189 wxString pack_ref = package->GetAttribute(
"name" );
1191 if( !urnOrdinal.IsEmpty() )
1192 pack_ref += wxS(
"_" ) + urnOrdinal;
1196 m_xpath->Value( pack_ref.ToUTF8() );
1198 wxString key = aLibName ?
makeKey( *aLibName, pack_ref ) : pack_ref;
1200 FOOTPRINT* footprint = makeFootprint( package, pack_ref );
1203 auto r = m_templates.insert( { key, footprint } );
1207 wxString lib = aLibName ? *aLibName : m_lib_path;
1208 const wxString& pkg = pack_ref;
1210 wxString emsg = wxString::Format(
_(
"<package> '%s' duplicated in <library> '%s'" ),
1218 package = package->GetNext();
1230 m_xpath->push(
"libraries.library",
"name" );
1233 wxXmlNode*
library = aLibs->GetChildren();
1237 const wxString& lib_name =
library->GetAttribute(
"name" );
1239 m_xpath->Value( lib_name.c_str() );
1240 loadLibrary(
library, &lib_name );
1253 m_xpath->push(
"elements.element",
"name" );
1257 bool refanceNamePresetInPackageLayout;
1258 bool valueNamePresetInPackageLayout;
1261 wxXmlNode* element = aElements->GetChildren();
1267 if( element->GetName() != wxT(
"element" ) )
1270 element = element->GetNext();
1277 EATTR* nameAttr =
nullptr;
1278 EATTR* valueAttr =
nullptr;
1280 m_xpath->Value( e.
name.c_str() );
1282 wxString packageName = e.
package;
1288 auto it = m_templates.find( pkg_key );
1290 if( it == m_templates.end() )
1292 wxString emsg = wxString::Format(
_(
"No '%s' package in library '%s'." ),
1299 m_board->
Add( footprint, ADD_MODE::APPEND );
1307 if( ni != m_pads_to_nets.end() )
1309 const ENET* enet = &ni->second;
1314 refanceNamePresetInPackageLayout =
true;
1315 valueNamePresetInPackageLayout =
true;
1322 refanceNamePresetInPackageLayout =
false;
1326 if( footprint->
GetValue().size() == 0 )
1329 valueNamePresetInPackageLayout =
false;
1332 wxString reference = e.
name;
1338 if( reference.find_first_not_of(
"0123456789" ) != 0 )
1339 reference.Prepend(
"UNK" );
1343 if( reference.find_first_not_of(
"#" ) != 0 )
1344 reference.Prepend(
"UNK" );
1347 if( reference.find_last_not_of(
"0123456789" ) == (reference.Length()-1) )
1348 reference.Append(
"0" );
1356 if( valueNamePresetInPackageLayout )
1359 if( refanceNamePresetInPackageLayout )
1369 m_xpath->push(
"attribute",
"name" );
1379 wxXmlNode* attribute = element->GetChildren();
1383 if( attribute->GetName() != wxT(
"attribute" ) )
1385 attribute = attribute->GetNext();
1389 EATTR a( attribute );
1391 if( a.
name == wxT(
"NAME" ) )
1404 nameAttr->
name = reference;
1406 if( refanceNamePresetInPackageLayout )
1413 if( refanceNamePresetInPackageLayout )
1422 if( refanceNamePresetInPackageLayout )
1425 nameAttr->
name = nameAttr->
name + wxT(
" = " ) + e.
name;
1436 if( refanceNamePresetInPackageLayout )
1446 else if( a.
name == wxT(
"VALUE" ) )
1460 if( valueNamePresetInPackageLayout )
1466 if( valueNamePresetInPackageLayout )
1469 footprint->
SetValue( wxT(
"VALUE" ) );
1473 if( valueNamePresetInPackageLayout )
1487 if( valueNamePresetInPackageLayout )
1499 attribute = attribute->GetNext();
1505 orientFootprintAndText( footprint, e, nameAttr, valueAttr );
1508 element = element->GetNext();
1525 wxLogMessage( wxString::Format(
_(
"Ignoring a polygon since Eagle layer '%s' (%d) was not mapped" ),
1526 eagle_layer_name( p.
layer ),
1532 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( m_board );
1535 zone->SetLayer( layer );
1537 setKeepoutSettingsToZone( zone.get(), p.
layer );
1540 wxXmlNode* vertex = aPolyNode->GetChildren();
1541 std::vector<EVERTEX> vertices;
1549 if( vertex->GetName() == wxT(
"vertex" ) )
1550 vertices.emplace_back( vertex );
1552 vertex = vertex->GetNext();
1558 zone->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::ALWAYS );
1560 zone->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::NEVER );
1562 vertices.push_back( vertices[0] );
1567 for(
size_t i = 0; i < vertices.size() - 1; i++ )
1585 double delta_angle = angle / segCount;
1587 for(
double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta_angle ); a -= delta_angle )
1602 wxLogMessage( wxString::Format(
_(
"Skipping a polygon on layer '%s' (%d): outline count is not 1" ),
1603 eagle_layer_name( p.
layer ),
1609 zone->AddPolygon( polygon.
COutline( 0 ) );
1614 zone->SetIsRuleArea(
true );
1615 zone->SetDoNotAllowVias(
false );
1616 zone->SetDoNotAllowTracks(
false );
1617 zone->SetDoNotAllowPads(
false );
1618 zone->SetDoNotAllowFootprints(
false );
1619 zone->SetDoNotAllowZoneFills(
true );
1620 zone->SetHatchStyle( ZONE_BORDER_DISPLAY_STYLE::NO_HATCH );
1626 zone->SetFillMode( ZONE_FILL_MODE::HATCH_PATTERN );
1629 zone->SetHatchOrientation(
ANGLE_0 );
1640 zone->SetLocalClearance( 1 );
1644 zone->SetPadConnection( thermals ? ZONE_CONNECTION::THERMAL : ZONE_CONNECTION::FULL );
1657 zone->SetAssignedPriority( rank );
1659 ZONE* zonePtr = zone.release();
1660 m_board->Add( zonePtr, ADD_MODE::APPEND );
1667 const EATTR* aNameAttr,
const EATTR* aValueAttr )
1674 aFootprint->
Flip( aFootprint->
GetPosition(), FLIP_DIRECTION::TOP_BOTTOM );
1682 orientFPText( aFootprint, e, &aFootprint->
Reference(), aNameAttr );
1683 orientFPText( aFootprint, e, &aFootprint->
Value(), aValueAttr );
1688 const EATTR* aAttr )
1694 const EATTR& a = *aAttr;
1701 VECTOR2I pos( kicad_x( *a.
x ), kicad_y( *a.
y ) );
1713 int textThickness =
KiROUND( fontz.
y * ratio / 100.0 );
1719 fontz = kicad_fontsize( *a.
size, textThickness );
1743 if( degrees == 90 || degrees == 0 || spin )
1747 else if( degrees == 180 )
1752 else if( degrees == 270 )
1755 degrees =
sign * 90;
1759 degrees = 90 - (
sign * degrees);
1816 if( aFPText->
IsMirrored() && degrees < -90 && degrees >= -270 )
1853 std::unique_ptr<FOOTPRINT> m = std::make_unique<FOOTPRINT>( m_board );
1856 fpID.
Parse( aPkgName,
true );
1860 wxXmlNode* packageItem = aPackage->GetChildren();
1865 m.get()->Value().SetLayer( layer );
1867 while( packageItem )
1869 const wxString& itemName = packageItem->GetName();
1871 if( itemName == wxT(
"description" ) )
1874 m->SetLibDescription( descr );
1876 else if( itemName == wxT(
"wire" ) )
1877 packageWire( m.get(), packageItem );
1878 else if( itemName == wxT(
"pad" ) )
1879 packagePad( m.get(), packageItem );
1880 else if( itemName == wxT(
"text" ) )
1881 packageText( m.get(), packageItem );
1882 else if( itemName == wxT(
"rectangle" ) )
1883 packageRectangle( m.get(), packageItem );
1884 else if( itemName == wxT(
"polygon" ) )
1885 packagePolygon( m.get(), packageItem );
1886 else if( itemName == wxT(
"circle" ) )
1887 packageCircle( m.get(), packageItem );
1888 else if( itemName == wxT(
"hole" ) )
1889 packageHole( m.get(), packageItem,
false );
1890 else if( itemName == wxT(
"smd" ) )
1891 packageSMD( m.get(), packageItem );
1893 packageItem = packageItem->GetNext();
1910 wxLogMessage( wxString::Format(
_(
"Ignoring a wire since Eagle layer '%s' (%d) was not mapped" ),
1911 eagle_layer_name( w.
layer ),
1949 dwg =
new PCB_SHAPE( aFootprint, SHAPE_T::SEGMENT );
1956 dwg =
new PCB_SHAPE( aFootprint, SHAPE_T::ARC );
1969 aFootprint->
Add( dwg );
1980 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aFootprint );
1981 transferPad( e,
pad.get() );
1984 shape = m_rules->psFirst;
1986 shape = m_rules->psTop;
1988 shape = m_rules->psBottom;
1990 pad->SetDrillSize(
VECTOR2I( eagleDrillz, eagleDrillz ) );
1993 if( eagleDrillz < m_min_hole )
1994 m_min_hole = eagleDrillz;
2042 double drillz =
pad->GetDrillSize().x;
2043 double annulus = drillz * m_rules->rvPadTop;
2044 annulus =
eagleClamp( m_rules->rlMinPadTop, annulus, m_rules->rlMaxPadTop );
2045 int diameter =
KiROUND( drillz + 2 * annulus );
2053 sz.
x = ( sz.
x * ( 100 + m_rules->psElongationLong ) ) / 100;
2058 int offset =
KiROUND( ( sz.
x - sz.
y ) / 2.0 );
2069 if(
pad->GetSizeX() > 0 &&
pad->GetSizeY() > 0 &&
pad->HasHole() )
2071 aFootprint->
Add(
pad.release() );
2075 wxFileName fileName( m_lib_path );
2078 wxLogError(
_(
"Invalid zero-sized pad ignored in\nfile: %s" ), m_board->GetFileName() );
2080 wxLogError(
_(
"Invalid zero-sized pad ignored in\nfile: %s" ), fileName.GetFullName() );
2092 wxLogMessage( wxString::Format(
_(
"Ignoring a text since Eagle layer '%s' (%d) was not mapped" ),
2093 eagle_layer_name( t.
layer ),
2100 if( t.
text.Upper() == wxT(
">NAME" ) && aFootprint->
GetReference().IsEmpty() )
2104 textItem->
SetText( wxT(
"REF**" ) );
2106 else if( t.
text.Upper() == wxT(
">VALUE" ) && aFootprint->
GetValue().IsEmpty() )
2108 textItem = &aFootprint->
Value();
2114 textItem =
new PCB_TEXT( aFootprint );
2115 aFootprint->
Add( textItem );
2120 VECTOR2I pos( kicad_x( t.
x ), kicad_y( t.
y ) );
2203 ZONE* zone =
new ZONE( aFootprint );
2204 aFootprint->
Add( zone, ADD_MODE::APPEND );
2206 setKeepoutSettingsToZone( zone, r.
layer );
2208 const int outlineIdx = -1;
2217 ( kicad_y( r.
y1 ) + kicad_y( r.
y2 ) ) / 2 );
2230 wxLogMessage( wxString::Format(
_(
"Ignoring a rectangle since Eagle layer '%s' (%d) was not mapped" ),
2231 eagle_layer_name( r.
layer ),
2238 aFootprint->
Add( dwg );
2244 std::vector<VECTOR2I> pts;
2249 pts.push_back( start );
2250 pts.emplace_back( kicad_x( r.
x2 ), kicad_y( r.
y1 ) );
2251 pts.emplace_back( kicad_x( r.
x2 ), kicad_y( r.
y2 ) );
2252 pts.push_back(
end );
2269 std::vector<VECTOR2I> pts;
2272 wxXmlNode* vertex = aTree->GetChildren();
2273 std::vector<EVERTEX> vertices;
2281 if( vertex->GetName() == wxT(
"vertex" ) )
2282 vertices.emplace_back( vertex );
2284 vertex = vertex->GetNext();
2287 vertices.push_back( vertices[0] );
2289 for(
size_t i = 0; i < vertices.size() - 1; i++ )
2294 pts.emplace_back( kicad_x(
v1.
x ), kicad_y(
v1.
y ) );
2312 double delta = angle / segCount;
2314 for(
double a = end_angle + angle; fabs( a - end_angle ) > fabs(
delta ); a -=
delta )
2329 ZONE* zone =
new ZONE( aFootprint );
2330 aFootprint->
Add( zone, ADD_MODE::APPEND );
2332 setKeepoutSettingsToZone( zone, p.
layer );
2345 wxLogMessage( wxString::Format(
_(
"Ignoring a polygon since Eagle layer '%s' (%d) was not mapped" ),
2346 eagle_layer_name( p.
layer ),
2353 aFootprint->
Add( dwg );
2379 ZONE* zone =
new ZONE( aFootprint );
2380 aFootprint->
Add( zone, ADD_MODE::APPEND );
2382 setKeepoutSettingsToZone( zone, e.
layer );
2386 int outlineRadius =
radius + ( width / 2 );
2392 VECTOR2I rotatedPoint( outlineRadius, 0 );
2400 int innerRadius =
radius - ( width / 2 );
2406 VECTOR2I rotatedPoint( innerRadius, 0 );
2421 wxLogMessage( wxString::Format(
_(
"Ignoring a circle since Eagle layer '%s' (%d) was not mapped" ),
2422 eagle_layer_name( e.
layer ),
2437 aFootprint->
Add( gr );
2440 switch( (
int) layer )
2470 pad->SetAttribute( PAD_ATTRIB::NPTH );
2477 VECTOR2I padpos( kicad_x( e.
x ), kicad_y( e.
y ) );
2482 pad->SetPosition( padpos );
2491 pad->SetDrillSize( sz );
2508 transferPad( e,
pad );
2511 pad->SetAttribute( PAD_ATTRIB::SMD );
2515 pad->SetLayer( layer );
2521 pad->SetLayerSet( front );
2522 else if( layer ==
B_Cu )
2523 pad->SetLayerSet( back );
2525 int minPadSize = std::min( padSize.
x, padSize.
y );
2528 int roundRadius =
eagleClamp( m_rules->srMinRoundness * 2,
2529 (
int) ( minPadSize * m_rules->srRoundness ),
2530 m_rules->srMaxRoundness * 2 );
2534 double roundRatio = (double) roundRadius / minPadSize / 2.0;
2538 roundRatio = std::fmax( *e.
roundness / 200.0, roundRatio );
2550 pad->SetLocalSolderPasteMargin( -
eagleClamp( m_rules->mlMinCreamFrame,
2551 (
int) ( m_rules->mvCreamFrame * minPadSize ),
2552 m_rules->mlMaxCreamFrame ) );
2558 pad->SetLayerSet(
pad->GetLayerSet().set(
F_Mask,
false ) );
2559 else if( layer ==
B_Cu )
2560 pad->SetLayerSet(
pad->GetLayerSet().set(
B_Mask,
false ) );
2567 pad->SetLayerSet(
pad->GetLayerSet().set(
F_Paste,
false ) );
2568 else if( layer ==
B_Cu )
2569 pad->SetLayerSet(
pad->GetLayerSet().set(
B_Paste,
false ) );
2578 VECTOR2I padPos( kicad_x( aEaglePad.
x ), kicad_y( aEaglePad.
y ) );
2584 (
int) ( m_rules->mvStopFrame * std::min( padSize.
x, padSize.
y ) ),
2585 m_rules->mlMaxStopFrame ) );
2592 wxCHECK( footprint, );
2600 for(
const auto& [
name, footprint ] : m_templates )
2602 footprint->SetParent(
nullptr );
2606 m_templates.clear();
2618 m_xpath->push(
"classes.class",
"number" );
2620 std::vector<ECLASS> eClasses;
2621 wxXmlNode* classNode = aClasses->GetChildren();
2627 ECLASS eClass( classNode );
2628 std::shared_ptr<NETCLASS> netclass;
2630 if( eClass.
name.CmpNoCase( wxT(
"default" ) ) == 0 )
2640 netclass->SetTrackWidth( INT_MAX );
2641 netclass->SetViaDiameter( INT_MAX );
2642 netclass->SetViaDrill( INT_MAX );
2644 eClasses.emplace_back( eClass );
2645 m_classMap[ eClass.
number ] = netclass;
2648 classNode = classNode->GetNext();
2651 m_customRules = wxT(
"(version 1)" );
2653 for(
ECLASS& eClass : eClasses )
2655 for(
const auto& [className, pt] : eClass.clearanceMap )
2657 if( m_classMap[className] !=
nullptr )
2660 rule.Printf( wxT(
"(rule \"class %s:%s\"\n"
2661 " (condition \"A.NetClass == '%s' && B.NetClass == '%s'\")\n"
2662 " (constraint clearance (min %smm)))\n" ),
2666 m_classMap[className]->GetName(),
2669 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 bds.
m_NetSettings->SetNetclassPatternAssignment( netName, netclassIt->second->GetName() );
2714 netclass = netclassIt->second;
2718 m_board->Add( netInfo );
2720 m_xpath->Value( netName.c_str() );
2723 wxXmlNode* netItem = net->GetChildren();
2728 const wxString& itemName = netItem->GetName();
2730 if( itemName == wxT(
"wire" ) )
2732 m_xpath->push(
"wire" );
2744 if( width < m_min_trace )
2745 m_min_trace = width;
2747 if( netclass && width < netclass->GetTrackWidth() )
2748 netclass->SetTrackWidth( width );
2758 double radiusA = ( mid -
center ).EuclideanNorm();
2759 double radiusB = ( otherMid -
center ).EuclideanNorm();
2762 std::swap( mid, otherMid );
2773 m_board->Add( arc );
2785 m_board->Add( track );
2795 else if( itemName == wxT(
"via" ) )
2797 m_xpath->push(
"via" );
2807 && layer_front_most != layer_back_most )
2812 m_board->Add(
via );
2821 double annulus = drillz * m_rules->rvViaOuter;
2822 annulus =
eagleClamp( m_rules->rlMinViaOuter, annulus, m_rules->rlMaxViaOuter );
2823 kidiam =
KiROUND( drillz + 2 * annulus );
2827 via->SetDrill( drillz );
2833 if( !v.
diam || via_width <= via->GetDrill() )
2835 double annular_width = ( via_width -
via->GetDrill() ) / 2.0;
2836 double clamped_annular_width =
eagleClamp( m_rules->rlMinViaOuter,
2838 m_rules->rlMaxViaOuter );
2842 if( kidiam < m_min_via )
2845 if( netclass && kidiam < netclass->GetViaDiameter() )
2846 netclass->SetViaDiameter( kidiam );
2848 if( drillz < m_min_hole )
2849 m_min_hole = drillz;
2851 if( netclass && drillz < netclass->GetViaDrill() )
2852 netclass->SetViaDrill( drillz );
2854 if( ( kidiam - drillz ) / 2 < m_min_annulus )
2855 m_min_annulus = ( kidiam - drillz ) / 2;
2857 if( layer_front_most ==
F_Cu && layer_back_most ==
B_Cu )
2859 via->SetViaType( VIATYPE::THROUGH );
2866 via->SetViaType( VIATYPE::MICROVIA );
2870 via->SetViaType( VIATYPE::BLIND_BURIED );
2873 VECTOR2I pos( kicad_x( v.
x ), kicad_y( v.
y ) );
2875 via->SetLayerPair( layer_front_most, layer_back_most );
2876 via->SetPosition( pos );
2879 via->SetNetCode( netCode );
2885 else if( itemName == wxT(
"contactref" ) )
2887 m_xpath->push(
"contactref" );
2890 const wxString& reference = netItem->GetAttribute(
"element" );
2891 const wxString&
pad = netItem->GetAttribute(
"pad" );
2894 m_pads_to_nets[ key ] =
ENET( netCode, netName );
2901 else if( itemName == wxT(
"polygon" ) )
2903 m_xpath->push(
"polygon" );
2904 auto* zone = loadPolygon( netItem );
2908 zones.push_back( zone );
2910 if( !zone->GetIsRuleArea() )
2911 zone->SetNetCode( netCode );
2917 netItem = netItem->GetNext();
2920 if( zones.size() && !sawPad )
2924 for(
ZONE* zone : zones )
2935 net = net->GetNext();
2943 const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector )
2945 std::map<wxString, PCB_LAYER_ID> layer_map;
2949 PCB_LAYER_ID layerId = std::get<0>( defaultKicadLayer( eagle_layer_id( layer.Name ) ) );
2950 layer_map.emplace( layer.Name, layerId );
2959 std::vector<INPUT_LAYER_DESC> inputDescs;
2961 for (
const std::pair<const int, ELAYER>& layerPair : m_eagleLayers )
2963 const ELAYER& eLayer = layerPair.second;
2967 defaultKicadLayer( eLayer.
number, aIsLibraryCache );
2974 inputDescs.push_back( layerDesc );
2977 if( m_progressReporter &&
dynamic_cast<wxWindow*
>( m_progressReporter ) )
2978 dynamic_cast<wxWindow*
>( m_progressReporter )->Hide();
2980 m_layer_map = m_layer_mapping_handler( inputDescs );
2982 if( m_progressReporter &&
dynamic_cast<wxWindow*
>( m_progressReporter ))
2983 dynamic_cast<wxWindow*
>( m_progressReporter )->Show();
2989 auto result = m_layer_map.find( eagle_layer_name( aEagleLayer ) );
2990 return result == m_layer_map.end() ?
UNDEFINED_LAYER : result->second;
2995 bool aIsLibraryCache )
const
2998 if( aEagleLayer >= 1 && aEagleLayer <
int(
arrayDim( m_cu_map ) ) )
3002 for(
int copperLayer : m_cu_map )
3004 if( copperLayer >= 0 )
3005 copperLayers[copperLayer] =
true;
3008 return {
PCB_LAYER_ID( m_cu_map[aEagleLayer] ), copperLayers,
true };
3012 bool required =
false;
3013 LSET permittedLayers;
3015 permittedLayers.
set();
3018 switch( aEagleLayer )
3116 if( aIsLibraryCache )
3124 return {
PCB_LAYER_ID( kiLayer ), permittedLayers, required };
3130 static const wxString
unknown(
"unknown" );
3131 auto it = m_eagleLayers.find( aLayer );
3132 return it == m_eagleLayers.end() ?
unknown : it->second.name;
3138 static const int unknown = -1;
3139 auto it = m_eagleLayersIds.find( aLayerName );
3140 return it == m_eagleLayersIds.end() ?
unknown : it->second;
3151 if(
auto it = m_props->find(
"page_width" ); it != m_props->end() )
3152 page_width = it->second;
3154 if(
auto it = m_props->find(
"page_height" ); it != m_props->end() )
3155 page_height = it->second;
3157 if( !page_width.
empty() && !page_height.
empty() )
3159 BOX2I bbbox = m_board->GetBoardEdgesBoundingBox();
3161 int w = atoi( page_width.
c_str() );
3162 int h = atoi( page_height.
c_str() );
3164 int desired_x = ( w - bbbox.
GetWidth() ) / 2;
3165 int desired_y = ( h - bbbox.
GetHeight() ) / 2;
3167 m_board->Move(
VECTOR2I( desired_x - bbbox.
GetX(), desired_y - bbbox.
GetY() ) );
3176 if( aPath.IsEmpty() )
3177 return wxDateTime::Now().GetValue().GetValue();
3179 wxFileName fn( aPath );
3181 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
3182 return fn.GetModificationTime().GetValue().GetValue();
3194 long long timestamp = GetLibraryTimestamp( aLibPath );
3196 if( aLibPath != m_lib_path || m_timestamp != timestamp )
3205 m_lib_path = aLibPath;
3210 string filename = (
const char*) aLibPath.char_str( wxConvFile );
3213 wxFileName fn( filename );
3214 wxFFileInputStream stream( fn.GetFullPath() );
3215 wxXmlDocument xmlDocument;
3217 if( !stream.IsOk() || !xmlDocument.Load( stream ) )
3218 THROW_IO_ERROR( wxString::Format(
_(
"Unable to read file '%s'." ), fn.GetFullPath() ) );
3220 doc = xmlDocument.GetRoot();
3222 wxXmlNode* drawing =
MapChildren( doc )[
"drawing"];
3228 m_xpath->push(
"eagle.drawing.layers" );
3229 wxXmlNode* layers = drawingChildren[
"layers"];
3230 loadLayerDefs( layers );
3231 mapEagleLayersToKicad(
true );
3234 m_xpath->push(
"eagle.drawing.library" );
3235 wxXmlNode*
library = drawingChildren[
"library"];
3237 loadLibrary(
library,
nullptr );
3240 m_timestamp = timestamp;
3269 bool aBestEfforts,
const std::map<std::string, UTF8>* aProperties )
3273 init( aProperties );
3277 cacheLib( aLibraryPath );
3281 errorMsg = ioe.
What();
3287 for(
const auto& [
name, footprint ] : m_templates )
3288 aFootprintNames.Add(
name );
3290 if( !errorMsg.IsEmpty() && !aBestEfforts )
3296 bool aKeepUUID,
const std::map<std::string, UTF8>* aProperties )
3298 init( aProperties );
3299 cacheLib( aLibraryPath );
3300 auto it = m_templates.find( aFootprintName );
3302 if( it == m_templates.end() )
3307 copy->SetParent(
nullptr );
3314 int minLayerCount = 2;
3316 std::map<wxString, PCB_LAYER_ID>::const_iterator it;
3318 for( it = m_layer_map.begin(); it != m_layer_map.end(); ++it )
3327 if( ( ordinal + 2 ) > minLayerCount )
3328 minLayerCount = ordinal + 2;
3334 if( ( minLayerCount % 2 ) != 0 )
3337 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.
void SetEnabledLayers(const LSET &aMask)
Change the bit-mask of enabled layers to aMask.
std::shared_ptr< NET_SETTINGS > m_NetSettings
const LSET & GetEnabledLayers() const
Return a bit-mask of all the layers that are enabled.
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
LSET is a set of PCB_LAYER_IDs.
static LSET AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
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.
std::map< wxString, PCB_LAYER_ID > m_layer_map
Map of Eagle layers to KiCad layers.
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)
long long GetLibraryTimestamp(const wxString &aLibraryPath) const override
Generate a timestamp representing all the files in the library (including the library directory).
int m_min_annulus
smallest via annulus we find on Load(), in BIU.
void loadLayerDefs(wxXmlNode *aLayers)
void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aLibraryPath, bool aBestEfforts, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Return a list of footprint names contained within the library at aLibraryPath.
void setKeepoutSettingsToZone(ZONE *aZone, int aLayer) const
void transferPad(const EPAD_COMMON &aEaglePad, PAD *aPad) const
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.
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)
void SetDoNotAllowZoneFills(bool aEnable)
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
#define IGNORE_PARENT_GROUP
a few functions useful in geometry calculations.
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)
#define THROW_IO_ERROR(msg)
PCB_LAYER_ID BoardLayerFromLegacyId(int aLegacyId)
Retrieve a layer ID from an integer converted from a legacy (pre-V9) enum value.
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
size_t CopperLayerToOrdinal(PCB_LAYER_ID aLayer)
Converts KiCad copper layer enum to an ordinal between the front and back layers.
PCB_LAYER_ID
A quick note on layer IDs:
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