From 25b8111341c4c61c7618dd84fddc4926c911c06f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 17 Oct 2017 10:18:54 +0200 Subject: [PATCH] Modified Eagle import plugins to use nanometers as the internal unit --- common/eagle_parser.cpp | 200 +++++++++++++++++++++++----------- eeschema/sch_eagle_plugin.cpp | 138 ++++++++++------------- include/eagle_parser.h | 182 ++++++++++++++++++++----------- pcbnew/eagle_plugin.cpp | 77 ++++++------- pcbnew/eagle_plugin.h | 15 +-- 5 files changed, 351 insertions(+), 261 deletions(-) diff --git a/common/eagle_parser.cpp b/common/eagle_parser.cpp index 3be97bfc71..c4a57ed19d 100644 --- a/common/eagle_parser.cpp +++ b/common/eagle_parser.cpp @@ -29,6 +29,68 @@ #include #include #include +#include + +constexpr auto DEFAULT_ALIGNMENT = ETEXT::BOTTOM_LEFT; + + +ECOORD::ECOORD( const wxString& aValue, enum ECOORD::UNIT aUnit ) +{ + // this array is used to adjust the fraction part value basing on the number of digits in the fraction + constexpr int DIVIDERS[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 }; + constexpr unsigned int DIVIDERS_MAX_IDX = sizeof( DIVIDERS ) / sizeof( DIVIDERS[0] ) - 1; + + int integer, fraction, pre_fraction, post_fraction; + + // the following check is needed to handle correctly negative fractions where the integer part == 0 + bool negative = ( aValue[0] == '-' ); + + // %n is used to find out how many digits contains the fraction part, e.g. 0.001 contains 3 digits + int ret = sscanf( aValue.c_str(), "%d.%n%d%n", &integer, &pre_fraction, &fraction, &post_fraction ); + + if( ret == 0 ) + throw XML_PARSER_ERROR( "Invalid coordinate" ); + + // process the integer part + value = ToNanoMeters( integer, aUnit ); + + // process the fraction part + if( ret == 2 ) + { + int digits = post_fraction - pre_fraction; + + // adjust the number of digits if necessary as we cannot handle anything smaller than nanometers (rounding) + if( (unsigned) digits > DIVIDERS_MAX_IDX ) + { + int diff = digits - DIVIDERS_MAX_IDX; + digits = DIVIDERS_MAX_IDX; + fraction /= DIVIDERS[diff]; + } + + int frac_value = ToNanoMeters( fraction, aUnit ) / DIVIDERS[digits]; + + // keep the sign in mind + value = negative ? value - frac_value : value + frac_value; + } +} + + +long long int ECOORD::ToNanoMeters( int aValue, enum UNIT aUnit ) +{ + long long int ret; + + switch( aUnit ) + { + case NM: ret = aValue; break; + case MM: ret = (long long) aValue * 1000000; break; + case INCH: ret = (long long) aValue * 25400000; break; + case MIL: ret = (long long) aValue * 25400; break; + } + + wxASSERT( ( ret > 0 ) == ( aValue > 0 ) ); // check for overflow + return ret; +} + // Template specializations below parse wxString to the used types: // - string @@ -36,8 +98,7 @@ // - int // - bool // - EROT - -constexpr auto DEFAULT_ALIGNMENT = ETEXT::BOTTOM_LEFT; +// - ECOORD template<> string Convert( const wxString& aValue ) @@ -99,6 +160,15 @@ EROT Convert( const wxString& aRot ) return value; } + +template<> +ECOORD Convert( const wxString& aCoord ) +{ + // Eagle uses millimeters as the default unit + return ECOORD( aCoord, ECOORD::UNIT::MM ); +} + + /** * Function parseRequiredAttribute * parsese the aAttribute of the XML node aNode. @@ -182,6 +252,8 @@ wxPoint ConvertArcCenter( const wxPoint& aStart, const wxPoint& aEnd, double aAn wxPoint mid = ( aStart + aEnd ) / 2; double dlen = sqrt( dx*dx + dy*dy ); + wxASSERT( dlen != 0 ); + wxASSERT( aAngle != 0 ); double dist = dlen / ( 2 * tan( DEG2RAD( aAngle ) / 2 ) ); wxPoint center( @@ -238,11 +310,11 @@ EWIRE::EWIRE( wxXmlNode* aWire ) > */ - x1 = parseRequiredAttribute( aWire, "x1" ); - y1 = parseRequiredAttribute( aWire, "y1" ); - x2 = parseRequiredAttribute( aWire, "x2" ); - y2 = parseRequiredAttribute( aWire, "y2" ); - width = parseRequiredAttribute( aWire, "width" ); + x1 = parseRequiredAttribute( aWire, "x1" ); + y1 = parseRequiredAttribute( aWire, "y1" ); + x2 = parseRequiredAttribute( aWire, "x2" ); + y2 = parseRequiredAttribute( aWire, "y2" ); + width = parseRequiredAttribute( aWire, "width" ); layer = parseRequiredAttribute( aWire, "layer" ); curve = parseOptionalAttribute( aWire, "curve" ); @@ -276,8 +348,8 @@ EJUNCTION::EJUNCTION( wxXmlNode* aJunction ) > */ - x = parseRequiredAttribute( aJunction, "x" ); - y = parseRequiredAttribute( aJunction, "y" ); + x = parseRequiredAttribute( aJunction, "x" ); + y = parseRequiredAttribute( aJunction, "y" ); } @@ -297,9 +369,9 @@ ELABEL::ELABEL( wxXmlNode* aLabel, const wxString& aNetName ) > */ - x = parseRequiredAttribute( aLabel, "x" ); - y = parseRequiredAttribute( aLabel, "y" ); - size = parseRequiredAttribute( aLabel, "size" ); + x = parseRequiredAttribute( aLabel, "x" ); + y = parseRequiredAttribute( aLabel, "y" ); + size = parseRequiredAttribute( aLabel, "size" ); layer = parseRequiredAttribute( aLabel, "layer" ); rot = parseOptionalAttribute( aLabel, "rot" ); xref = parseOptionalAttribute( aLabel, "xref" ); @@ -322,15 +394,15 @@ EVIA::EVIA( wxXmlNode* aVia ) > */ - x = parseRequiredAttribute( aVia, "x" ); - y = parseRequiredAttribute( aVia, "y" ); + x = parseRequiredAttribute( aVia, "x" ); + y = parseRequiredAttribute( aVia, "y" ); string ext = parseRequiredAttribute( aVia, "extent" ); sscanf( ext.c_str(), "%d-%d", &layer_front_most, &layer_back_most ); - drill = parseRequiredAttribute( aVia, "drill" ); - diam = parseOptionalAttribute( aVia, "diameter" ); + drill = parseRequiredAttribute( aVia, "drill" ); + diam = parseOptionalAttribute( aVia, "diameter" ); shape = parseOptionalAttribute( aVia, "shape" ); } @@ -348,10 +420,10 @@ ECIRCLE::ECIRCLE( wxXmlNode* aCircle ) > */ - x = parseRequiredAttribute( aCircle, "x" ); - y = parseRequiredAttribute( aCircle, "y" ); - radius = parseRequiredAttribute( aCircle, "radius" ); - width = parseRequiredAttribute( aCircle, "width" ); + x = parseRequiredAttribute( aCircle, "x" ); + y = parseRequiredAttribute( aCircle, "y" ); + radius = parseRequiredAttribute( aCircle, "radius" ); + width = parseRequiredAttribute( aCircle, "width" ); layer = parseRequiredAttribute( aCircle, "layer" ); } @@ -370,10 +442,10 @@ ERECT::ERECT( wxXmlNode* aRect ) > */ - x1 = parseRequiredAttribute( aRect, "x1" ); - y1 = parseRequiredAttribute( aRect, "y1" ); - x2 = parseRequiredAttribute( aRect, "x2" ); - y2 = parseRequiredAttribute( aRect, "y2" ); + x1 = parseRequiredAttribute( aRect, "x1" ); + y1 = parseRequiredAttribute( aRect, "y1" ); + x2 = parseRequiredAttribute( aRect, "x2" ); + y2 = parseRequiredAttribute( aRect, "y2" ); layer = parseRequiredAttribute( aRect, "layer" ); rot = parseOptionalAttribute( aRect, "rot" ); } @@ -401,9 +473,9 @@ EATTR::EATTR( wxXmlNode* aTree ) name = parseRequiredAttribute( aTree, "name" ); value = parseOptionalAttribute( aTree, "value" ); - x = parseOptionalAttribute( aTree, "x" ); - y = parseOptionalAttribute( aTree, "y" ); - size = parseOptionalAttribute( aTree, "size" ); + x = parseOptionalAttribute( aTree, "x" ); + y = parseOptionalAttribute( aTree, "y" ); + size = parseOptionalAttribute( aTree, "size" ); // KiCad cannot currently put a TEXTE_MODULE on a different layer than the MODULE // Eagle can it seems. @@ -445,12 +517,12 @@ EDIMENSION::EDIMENSION( wxXmlNode* aDimension ) > */ - x1 = parseRequiredAttribute( aDimension, "x1" ); - y1 = parseRequiredAttribute( aDimension, "y1" ); - x2 = parseRequiredAttribute( aDimension, "x2" ); - y2 = parseRequiredAttribute( aDimension, "y2" ); - x3 = parseRequiredAttribute( aDimension, "x3" ); - y3 = parseRequiredAttribute( aDimension, "y3" ); + x1 = parseRequiredAttribute( aDimension, "x1" ); + y1 = parseRequiredAttribute( aDimension, "y1" ); + x2 = parseRequiredAttribute( aDimension, "x2" ); + y2 = parseRequiredAttribute( aDimension, "y2" ); + x3 = parseRequiredAttribute( aDimension, "x3" ); + y3 = parseRequiredAttribute( aDimension, "y3" ); layer = parseRequiredAttribute( aDimension, "layer" ); opt_string dimType = parseOptionalAttribute( aDimension, "dtype" ); @@ -479,9 +551,9 @@ ETEXT::ETEXT( wxXmlNode* aText ) */ text = aText->GetNodeContent(); - x = parseRequiredAttribute( aText, "x" ); - y = parseRequiredAttribute( aText, "y" ); - size = parseRequiredAttribute( aText, "size" ); + x = parseRequiredAttribute( aText, "x" ); + y = parseRequiredAttribute( aText, "y" ); + size = parseRequiredAttribute( aText, "size" ); layer = parseRequiredAttribute( aText, "layer" ); font = parseOptionalAttribute( aText, "font" ); @@ -504,21 +576,21 @@ wxSize ETEXT::ConvertSize() const if( fontName == "vector" ) { - textsize = wxSize( size * EUNIT_TO_MIL, size * EUNIT_TO_MIL ); + textsize = wxSize( size.ToSchUnits(), size.ToSchUnits() ); } else if( fontName == "fixed" ) { - textsize = wxSize( size * EUNIT_TO_MIL, size * EUNIT_TO_MIL * 0.80 ); + textsize = wxSize( size.ToSchUnits(), size.ToSchUnits() * 0.80 ); } else { wxASSERT( false ); - textsize = wxSize( size * EUNIT_TO_MIL, size * EUNIT_TO_MIL ); + textsize = wxSize( size.ToSchUnits(), size.ToSchUnits() ); } } else { - textsize = wxSize( size * EUNIT_TO_MIL * 0.85, size * EUNIT_TO_MIL ); + textsize = wxSize( size.ToSchUnits() * 0.85, size.ToSchUnits() ); } return textsize; @@ -545,12 +617,12 @@ EPAD::EPAD( wxXmlNode* aPad ) // #REQUIRED says DTD, throw exception if not found name = parseRequiredAttribute( aPad, "name" ); - x = parseRequiredAttribute( aPad, "x" ); - y = parseRequiredAttribute( aPad, "y" ); - drill = parseRequiredAttribute( aPad, "drill" ); + x = parseRequiredAttribute( aPad, "x" ); + y = parseRequiredAttribute( aPad, "y" ); + drill = parseRequiredAttribute( aPad, "drill" ); // Optional attributes - diameter = parseOptionalAttribute( aPad, "diameter" ); + diameter = parseOptionalAttribute( aPad, "diameter" ); opt_string s = parseOptionalAttribute( aPad, "shape" ); @@ -593,10 +665,10 @@ ESMD::ESMD( wxXmlNode* aSMD ) // DTD #REQUIRED, throw exception if not found name = parseRequiredAttribute( aSMD, "name" ); - x = parseRequiredAttribute( aSMD, "x" ); - y = parseRequiredAttribute( aSMD, "y" ); - dx = parseRequiredAttribute( aSMD, "dx" ); - dy = parseRequiredAttribute( aSMD, "dy" ); + x = parseRequiredAttribute( aSMD, "x" ); + y = parseRequiredAttribute( aSMD, "y" ); + dx = parseRequiredAttribute( aSMD, "dx" ); + dy = parseRequiredAttribute( aSMD, "dy" ); layer = parseRequiredAttribute( aSMD, "layer" ); roundness = parseOptionalAttribute( aSMD, "roundness" ); @@ -627,8 +699,8 @@ EPIN::EPIN( wxXmlNode* aPin ) // DTD #REQUIRED, throw exception if not found name = parseRequiredAttribute( aPin, "name" ); - x = parseRequiredAttribute( aPin, "x" ); - y = parseRequiredAttribute( aPin, "y" ); + x = parseRequiredAttribute( aPin, "x" ); + y = parseRequiredAttribute( aPin, "y" ); visible = parseOptionalAttribute( aPin, "visible" ); length = parseOptionalAttribute( aPin, "length" ); @@ -650,8 +722,8 @@ EVERTEX::EVERTEX( wxXmlNode* aVertex ) > */ - x = parseRequiredAttribute( aVertex, "x" ); - y = parseRequiredAttribute( aVertex, "y" ); + x = parseRequiredAttribute( aVertex, "x" ); + y = parseRequiredAttribute( aVertex, "y" ); } @@ -670,11 +742,11 @@ EPOLYGON::EPOLYGON( wxXmlNode* aPolygon ) > */ - width = parseRequiredAttribute( aPolygon, "width" ); + width = parseRequiredAttribute( aPolygon, "width" ); layer = parseRequiredAttribute( aPolygon, "layer" ); - spacing = parseOptionalAttribute( aPolygon, "spacing" ); - isolate = parseOptionalAttribute( aPolygon, "isolate" ); + spacing = parseOptionalAttribute( aPolygon, "spacing" ); + isolate = parseOptionalAttribute( aPolygon, "isolate" ); opt_string s = parseOptionalAttribute( aPolygon, "pour" ); // default pour to solid fill @@ -704,9 +776,9 @@ EHOLE::EHOLE( wxXmlNode* aHole ) */ // #REQUIRED: - x = parseRequiredAttribute( aHole, "x" ); - y = parseRequiredAttribute( aHole, "y" ); - drill = parseRequiredAttribute( aHole, "drill" ); + x = parseRequiredAttribute( aHole, "x" ); + y = parseRequiredAttribute( aHole, "y" ); + drill = parseRequiredAttribute( aHole, "drill" ); } @@ -734,8 +806,8 @@ EELEMENT::EELEMENT( wxXmlNode* aElement ) package = parseRequiredAttribute( aElement, "package" ); ReplaceIllegalFileNameChars( &package ); - x = parseRequiredAttribute( aElement, "x" ); - y = parseRequiredAttribute( aElement, "y" ); + x = parseRequiredAttribute( aElement, "x" ); + y = parseRequiredAttribute( aElement, "y" ); // optional locked = parseOptionalAttribute( aElement, "locked" ); @@ -807,8 +879,8 @@ EINSTANCE::EINSTANCE( wxXmlNode* aInstance ) part = parseRequiredAttribute( aInstance, "part" ); gate = parseRequiredAttribute( aInstance, "gate" ); - x = parseRequiredAttribute( aInstance, "x" ); - y = parseRequiredAttribute( aInstance, "y" ); + x = parseRequiredAttribute( aInstance, "x" ); + y = parseRequiredAttribute( aInstance, "y" ); // optional smashed = parseOptionalAttribute( aInstance, "smashed" ); @@ -833,8 +905,8 @@ EGATE::EGATE( wxXmlNode* aGate ) name = parseRequiredAttribute( aGate, "name" ); symbol = parseRequiredAttribute( aGate, "symbol" ); - x = parseRequiredAttribute( aGate, "x" ); - y = parseRequiredAttribute( aGate, "y" ); + x = parseRequiredAttribute( aGate, "x" ); + y = parseRequiredAttribute( aGate, "y" ); opt_string stemp = parseOptionalAttribute( aGate, "addlevel" ); diff --git a/eeschema/sch_eagle_plugin.cpp b/eeschema/sch_eagle_plugin.cpp index 2bf37dffa3..90607234ff 100644 --- a/eeschema/sch_eagle_plugin.cpp +++ b/eeschema/sch_eagle_plugin.cpp @@ -810,10 +810,10 @@ SCH_LINE* SCH_EAGLE_PLUGIN::loadWire( wxXmlNode* aWireNode ) wxPoint begin, end; - begin.x = ewire.x1 * EUNIT_TO_MIL; - begin.y = -ewire.y1 * EUNIT_TO_MIL; - end.x = ewire.x2 * EUNIT_TO_MIL; - end.y = -ewire.y2 * EUNIT_TO_MIL; + begin.x = ewire.x1.ToSchUnits(); + begin.y = -ewire.y1.ToSchUnits(); + end.x = ewire.x2.ToSchUnits(); + end.y = -ewire.y2.ToSchUnits(); wire->SetStartPoint( begin ); wire->SetEndPoint( end ); @@ -827,7 +827,7 @@ SCH_JUNCTION* SCH_EAGLE_PLUGIN::loadJunction( wxXmlNode* aJunction ) std::unique_ptr junction( new SCH_JUNCTION ); auto ejunction = EJUNCTION( aJunction ); - wxPoint pos( ejunction.x * EUNIT_TO_MIL, -ejunction.y * EUNIT_TO_MIL ); + wxPoint pos( ejunction.x.ToSchUnits(), -ejunction.y.ToSchUnits() ); junction->SetPosition( pos ); @@ -841,7 +841,7 @@ SCH_TEXT* SCH_EAGLE_PLUGIN::loadLabel( wxXmlNode* aLabelNode, { auto elabel = ELABEL( aLabelNode, aNetName ); - wxPoint elabelpos( elabel.x * EUNIT_TO_MIL, -elabel.y * EUNIT_TO_MIL ); + wxPoint elabelpos( elabel.x.ToSchUnits(), -elabel.y.ToSchUnits() ); wxString netname = escapeName( elabel.netname ); @@ -852,8 +852,7 @@ SCH_TEXT* SCH_EAGLE_PLUGIN::loadLabel( wxXmlNode* aLabelNode, std::unique_ptr glabel( new SCH_GLOBALLABEL ); glabel->SetPosition( elabelpos ); glabel->SetText( netname ); - glabel->SetTextSize( wxSize( elabel.size * EUNIT_TO_MIL, elabel.size * EUNIT_TO_MIL ) ); - + glabel->SetTextSize( wxSize( elabel.size.ToSchUnits(), elabel.size.ToSchUnits() ) ); glabel->SetLabelSpinStyle( 0 ); if( elabel.rot ) @@ -1039,7 +1038,7 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode ) std::unique_ptr component( new SCH_COMPONENT() ); component->SetLibId( libId ); component->SetUnit( unit ); - component->SetPosition( wxPoint( einstance.x * EUNIT_TO_MIL, -einstance.y * EUNIT_TO_MIL ) ); + component->SetPosition( wxPoint( einstance.x.ToSchUnits(), -einstance.y.ToSchUnits() ) ); component->GetField( FOOTPRINT )->SetText( wxString( package ) ); component->SetTimeStamp( EagleModuleTstamp( einstance.part, epart->value ? *epart->value : "", unit ) ); @@ -1050,7 +1049,7 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode ) if( einstance.rot->mirror ) { - component->MirrorY( einstance.x * EUNIT_TO_MIL ); + component->MirrorY( einstance.x.ToSchUnits() ); } } @@ -1131,7 +1130,7 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode ) valueAttributeFound = true; } - field->SetPosition( wxPoint( *attr.x * EUNIT_TO_MIL, *attr.y * -EUNIT_TO_MIL ) ); + field->SetPosition( wxPoint( attr.x->ToSchUnits(), -attr.y->ToSchUnits() ) ); int align = attr.align ? *attr.align : ETEXT::BOTTOM_LEFT; int absdegrees = attr.rot ? attr.rot->degrees : 0; bool mirror = attr.rot ? attr.rot->mirror : false; @@ -1461,9 +1460,9 @@ LIB_CIRCLE* SCH_EAGLE_PLUGIN::loadSymbolCircle( std::unique_ptr& aPart unique_ptr circle( new LIB_CIRCLE( aPart.get() ) ); - circle->SetPosition( wxPoint( c.x * EUNIT_TO_MIL, c.y * EUNIT_TO_MIL ) ); - circle->SetRadius( c.radius * EUNIT_TO_MIL ); - circle->SetWidth( c.width * EUNIT_TO_MIL ); + circle->SetPosition( wxPoint( c.x.ToSchUnits(), c.y.ToSchUnits() ) ); + circle->SetRadius( c.radius.ToSchUnits() ); + circle->SetWidth( c.width.ToSchUnits() ); circle->SetUnit( aGateNumber ); return circle.release(); @@ -1478,8 +1477,8 @@ LIB_RECTANGLE* SCH_EAGLE_PLUGIN::loadSymbolRectangle( std::unique_ptr& unique_ptr rectangle( new LIB_RECTANGLE( aPart.get() ) ); - rectangle->SetPosition( wxPoint( rect.x1 * EUNIT_TO_MIL, rect.y1 * EUNIT_TO_MIL ) ); - rectangle->SetEnd( wxPoint( rect.x2 * EUNIT_TO_MIL, rect.y2 * EUNIT_TO_MIL ) ); + rectangle->SetPosition( wxPoint( rect.x1.ToSchUnits(), rect.y1.ToSchUnits() ) ); + rectangle->SetEnd( wxPoint( rect.x2.ToSchUnits(), rect.y2.ToSchUnits() ) ); rectangle->SetUnit( aGateNumber ); // Eagle rectangles are filled by definition. @@ -1495,22 +1494,51 @@ LIB_ITEM* SCH_EAGLE_PLUGIN::loadSymbolWire( std::unique_ptr& aPart, { auto ewire = EWIRE( aWireNode ); - wxRealPoint begin, end; + wxPoint begin, end; - begin.x = ewire.x1 * EUNIT_TO_MIL; - begin.y = ewire.y1 * EUNIT_TO_MIL; - end.x = ewire.x2 * EUNIT_TO_MIL; - end.y = ewire.y2 * EUNIT_TO_MIL; + begin.x = ewire.x1.ToSchUnits(); + begin.y = ewire.y1.ToSchUnits(); + end.x = ewire.x2.ToSchUnits(); + end.y = ewire.y2.ToSchUnits(); // if the wire is an arc if( ewire.curve ) { std::unique_ptr arc( new LIB_ARC( aPart.get() ) ); - wxRealPoint center = ConvertArcCenter( begin, end, *ewire.curve * -1 ); + wxPoint center = ConvertArcCenter( begin, end, *ewire.curve * -1 ); + + double radius = sqrt( abs( ( ( center.x - begin.x ) * ( center.x - begin.x ) ) + + ( ( center.y - begin.y ) * ( center.y - begin.y ) ) ) ) * 2; + + // this emulates the filled semicircles created by a thick arc with flat ends caps. + if( ewire.width.ToSchUnits() * 2 > radius ) + { + wxPoint centerStartVector = begin - center; + wxPoint centerEndVector = end - center; + + centerStartVector.x = centerStartVector.x * ewire.width.ToSchUnits() * 2 / radius; + centerStartVector.y = centerStartVector.y * ewire.width.ToSchUnits() * 2 / radius; + + centerEndVector.x = centerEndVector.x * ewire.width.ToSchUnits() * 2 / radius; + centerEndVector.y = centerEndVector.y * ewire.width.ToSchUnits() * 2 / radius; + + begin = center + centerStartVector; + end = center + centerEndVector; + + radius = sqrt( abs( ( ( center.x - begin.x ) * ( center.x - begin.x ) ) + + ( ( center.y - begin.y ) * ( center.y - begin.y ) ) ) ) * 2; + + arc->SetWidth( 1 ); + arc->SetFillMode( FILLED_SHAPE ); + } + else + { + arc->SetWidth( ewire.width.ToSchUnits() ); + } arc->SetPosition( center ); - if( *ewire.curve >0 ) + if( *ewire.curve > 0 ) { arc->SetStart( begin ); arc->SetEnd( end ); @@ -1521,60 +1549,8 @@ LIB_ITEM* SCH_EAGLE_PLUGIN::loadSymbolWire( std::unique_ptr& aPart, arc->SetEnd( begin ); } - arc->SetWidth( ewire.width * EUNIT_TO_MIL ); - - - double radius = sqrt( abs( ( ( center.x - begin.x ) * ( center.x - begin.x ) ) - + ( ( center.y - begin.y ) * ( center.y - begin.y ) ) ) ) * 2; - arc->SetRadius( radius ); arc->CalcRadiusAngles(); - - // this emulates the filled semicircles created by a thick arc with flat ends caps. - if( ewire.width * 2 * EUNIT_TO_MIL > radius ) - { - wxRealPoint centerStartVector = begin - center; - - wxRealPoint centerEndVector = end - center; - centerStartVector.x = centerStartVector.x / radius; - centerStartVector.y = centerStartVector.y / radius; - - - centerEndVector.x = centerEndVector.x / radius; - centerEndVector.y = centerEndVector.y / radius; - centerStartVector.x = centerStartVector.x * (ewire.width * EUNIT_TO_MIL + radius); - centerStartVector.y = centerStartVector.y * (ewire.width * EUNIT_TO_MIL + radius); - - centerEndVector.x = centerEndVector.x * (ewire.width * EUNIT_TO_MIL + radius); - centerEndVector.y = centerEndVector.y * (ewire.width * EUNIT_TO_MIL + radius); - - - begin = center + centerStartVector; - end = center + centerEndVector; - radius = sqrt( abs( ( ( center.x - begin.x ) * ( center.x - begin.x ) ) - + ( ( center.y - begin.y ) * ( center.y - begin.y ) ) ) ) * 2; - - - arc->SetPosition( center ); - - if( *ewire.curve >0 ) - { - arc->SetStart( begin ); - arc->SetEnd( end ); - } - else - { - arc->SetStart( end ); - arc->SetEnd( begin ); - } - - arc->SetRadius( radius ); - arc->CalcRadiusAngles(); - arc->SetWidth( 1 ); - arc->SetFillMode( FILLED_SHAPE ); - } - - arc->SetUnit( aGateNumber ); return (LIB_ITEM*) arc.release(); @@ -1586,14 +1562,14 @@ LIB_ITEM* SCH_EAGLE_PLUGIN::loadSymbolWire( std::unique_ptr& aPart, polyLine->AddPoint( begin ); polyLine->AddPoint( end ); polyLine->SetUnit( aGateNumber ); + return (LIB_ITEM*) polyLine.release(); } } LIB_POLYLINE* SCH_EAGLE_PLUGIN::loadSymbolPolyLine( std::unique_ptr& aPart, - wxXmlNode* aPolygonNode, - int aGateNumber ) + wxXmlNode* aPolygonNode, int aGateNumber ) { std::unique_ptr polyLine( new LIB_POLYLINE( aPart.get() ) ); @@ -1608,7 +1584,7 @@ LIB_POLYLINE* SCH_EAGLE_PLUGIN::loadSymbolPolyLine( std::unique_ptr& a if( vertex->GetName() == "vertex" ) // skip node { EVERTEX evertex( vertex ); - pt = wxPoint( evertex.x * EUNIT_TO_MIL, evertex.y * EUNIT_TO_MIL ); + pt = wxPoint( evertex.x.ToSchUnits(), evertex.y.ToSchUnits() ); polyLine->AddPoint( pt ); } @@ -1628,7 +1604,7 @@ LIB_PIN* SCH_EAGLE_PLUGIN::loadPin( std::unique_ptr& aPart, int aGateNumber ) { std::unique_ptr pin( new LIB_PIN( aPart.get() ) ); - pin->SetPosition( wxPoint( aEPin->x * EUNIT_TO_MIL, aEPin->y * EUNIT_TO_MIL ) ); + pin->SetPosition( wxPoint( aEPin->x.ToSchUnits(), aEPin->y.ToSchUnits() ) ); pin->SetName( aEPin->name ); pin->SetUnit( aGateNumber ); @@ -1736,7 +1712,7 @@ LIB_TEXT* SCH_EAGLE_PLUGIN::loadSymbolText( std::unique_ptr& aPart, ETEXT etext( aLibText ); libtext->SetUnit( aGateNumber ); - libtext->SetPosition( wxPoint( etext.x * EUNIT_TO_MIL, etext.y * EUNIT_TO_MIL ) ); + libtext->SetPosition( wxPoint( etext.x.ToSchUnits(), etext.y.ToSchUnits() ) ); libtext->SetText( aLibText->GetNodeContent().IsEmpty() ? "~~" : aLibText->GetNodeContent() ); libtext->SetTextSize( etext.ConvertSize() ); @@ -1766,7 +1742,7 @@ SCH_TEXT* SCH_EAGLE_PLUGIN::loadPlainText( wxXmlNode* aSchText ) auto etext = ETEXT( aSchText ); schtext->SetItalic( false ); - schtext->SetPosition( wxPoint( etext.x * EUNIT_TO_MIL, -etext.y * EUNIT_TO_MIL ) ); + schtext->SetPosition( wxPoint( etext.x.ToSchUnits(), -etext.y.ToSchUnits() ) ); wxString thetext = aSchText->GetNodeContent(); schtext->SetText( aSchText->GetNodeContent().IsEmpty() ? "\" \"" : escapeName( thetext ) ); diff --git a/include/eagle_parser.h b/include/eagle_parser.h index 352573a25e..fa68c9cbe9 100644 --- a/include/eagle_parser.h +++ b/include/eagle_parser.h @@ -41,10 +41,6 @@ #include #include -// Eagle schematic internal units are millimeters -// Kicad schematic units are thousandths of an inch -constexpr double EUNIT_TO_MIL = 1000.0 / 25.4; - using std::string; class MODULE; @@ -372,12 +368,13 @@ wxPoint ConvertArcCenter( const wxPoint& aStart, const wxPoint& aEnd, double aAn // Pre-declare for typedefs struct EROT; - +struct ECOORD; typedef OPTIONAL_XML_ATTRIBUTE opt_string; typedef OPTIONAL_XML_ATTRIBUTE opt_int; typedef OPTIONAL_XML_ATTRIBUTE opt_double; typedef OPTIONAL_XML_ATTRIBUTE opt_bool; typedef OPTIONAL_XML_ATTRIBUTE opt_erot; +typedef OPTIONAL_XML_ATTRIBUTE opt_ecoord; // All of the 'E'STRUCTS below merely hold Eagle XML information verbatim, in binary. @@ -386,6 +383,65 @@ typedef OPTIONAL_XML_ATTRIBUTE opt_erot; // forms of information in these 'E'STRUCTS. They are only binary forms // of the Eagle information in the corresponding Eagle XML nodes. +// Eagle coordinates +struct ECOORD +{ + enum UNIT + { + NM, ///< nanometers + MM, ///< millimeters + INCH, ///< inches + MIL, ///< mils/thous + }; + + ///> Value expressed in nanometers + long long int value; + + ///> Unit used for the value field + static constexpr UNIT ECOORD_UNIT = NM; + + ECOORD() + : value( 0 ) + { + } + + ECOORD( int aValue, enum UNIT aUnit ) + : value( ToNanoMeters( aValue, aUnit ) ) + { + } + + ECOORD( const wxString& aValue, enum UNIT aUnit ); + + int ToSchUnits() const + { + // mils + return value / 25400; + } + + int ToPcbUnits() const + { + // nanometers + return value; + } + + ECOORD operator+( const ECOORD& aOther ) const + { + return ECOORD( value + aOther.value, ECOORD_UNIT ); + } + + ECOORD operator-( const ECOORD& aOther ) const + { + return ECOORD( value - aOther.value, ECOORD_UNIT ); + } + + bool operator==( const ECOORD& aOther ) const + { + return value == aOther.value; + } + + static long long int ToNanoMeters( int aValue, enum UNIT aUnit ); +}; + /// Eagle net struct ENET @@ -428,11 +484,11 @@ struct EROT /// Eagle wire struct EWIRE { - double x1; - double y1; - double x2; - double y2; - double width; + ECOORD x1; + ECOORD y1; + ECOORD x2; + ECOORD y2; + ECOORD width; LAYER_NUM layer; // for style: (continuous | longdash | shortdash | dashdot) @@ -459,8 +515,8 @@ struct EWIRE /// Eagle Junction struct EJUNCTION { - double x; - double y; + ECOORD x; + ECOORD y; EJUNCTION( wxXmlNode* aJunction); }; @@ -469,9 +525,9 @@ struct EJUNCTION /// Eagle label struct ELABEL { - double x; - double y; - double size; + ECOORD x; + ECOORD y; + ECOORD size; LAYER_NUM layer; opt_erot rot; opt_string xref; @@ -484,12 +540,12 @@ struct ELABEL /// Eagle via struct EVIA { - double x; - double y; + ECOORD x; + ECOORD y; int layer_front_most; /// < extent int layer_back_most; /// < inclusive - double drill; - opt_double diam; + ECOORD drill; + opt_ecoord diam; opt_string shape; EVIA( wxXmlNode* aVia ); @@ -499,10 +555,10 @@ struct EVIA /// Eagle circle struct ECIRCLE { - double x; - double y; - double radius; - double width; + ECOORD x; + ECOORD y; + ECOORD radius; + ECOORD width; LAYER_NUM layer; ECIRCLE( wxXmlNode* aCircle ); @@ -512,10 +568,10 @@ struct ECIRCLE /// Eagle XML rectangle in binary struct ERECT { - double x1; - double y1; - double x2; - double y2; + ECOORD x1; + ECOORD y1; + ECOORD x2; + ECOORD y2; int layer; opt_erot rot; @@ -533,9 +589,9 @@ struct EATTR { string name; opt_string value; - opt_double x; - opt_double y; - opt_double size; + opt_ecoord x; + opt_ecoord y; + opt_ecoord size; opt_int layer; opt_double ratio; opt_erot rot; @@ -557,12 +613,12 @@ struct EATTR /// Eagle dimension element struct EDIMENSION { - double x1; - double y1; - double x2; - double y2; - double x3; - double y3; + ECOORD x1; + ECOORD y1; + ECOORD x2; + ECOORD y2; + ECOORD x3; + ECOORD y3; int layer; opt_string dimensionType; @@ -575,9 +631,9 @@ struct EDIMENSION struct ETEXT { string text; - double x; - double y; - double size; + ECOORD x; + ECOORD y; + ECOORD size; int layer; opt_string font; opt_double ratio; @@ -610,10 +666,10 @@ struct ETEXT struct EPAD { string name; - double x; - double y; - double drill; - opt_double diameter; + ECOORD x; + ECOORD y; + ECOORD drill; + opt_ecoord diameter; // for shape: (square | round | octagon | long | offset) enum { @@ -637,10 +693,10 @@ struct EPAD struct ESMD { string name; - double x; - double y; - double dx; - double dy; + ECOORD x; + ECOORD y; + ECOORD dx; + ECOORD dy; int layer; opt_int roundness; opt_erot rot; @@ -656,8 +712,8 @@ struct ESMD struct EPIN { string name; - double x; - double y; + ECOORD x; + ECOORD y; opt_string visible; opt_string length; @@ -673,8 +729,8 @@ struct EPIN /// Eagle vertex struct EVERTEX { - double x; - double y; + ECOORD x; + ECOORD y; EVERTEX( wxXmlNode* aVertex ); }; @@ -683,9 +739,9 @@ struct EVERTEX /// Eagle polygon, without vertices which are parsed as needed struct EPOLYGON { - double width; + ECOORD width; int layer; - opt_double spacing; + opt_ecoord spacing; // KiCad priority is opposite of Eagle rank, that is: // - Eagle Low rank drawn first @@ -700,7 +756,7 @@ struct EPOLYGON CUTOUT, }; int pour; - opt_double isolate; + opt_ecoord isolate; opt_bool orphans; opt_bool thermals; opt_int rank; @@ -712,9 +768,9 @@ struct EPOLYGON /// Eagle hole element struct EHOLE { - double x; - double y; - double drill; + ECOORD x; + ECOORD y; + ECOORD drill; EHOLE( wxXmlNode* aHole ); }; @@ -727,8 +783,8 @@ struct EELEMENT string library; string package; string value; - double x; - double y; + ECOORD x; + ECOORD y; opt_bool locked; opt_bool smashed; opt_erot rot; @@ -861,8 +917,8 @@ struct EINSTANCE string part; string gate; - double x; - double y; + ECOORD x; + ECOORD y; opt_bool smashed; opt_erot rot; @@ -887,8 +943,8 @@ struct EGATE string name; string symbol; - double x; - double y; + ECOORD x; + ECOORD y; opt_int addlevel; opt_int swaplevel; diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp index 2b8de0013d..cb91b9a3fe 100644 --- a/pcbnew/eagle_plugin.cpp +++ b/pcbnew/eagle_plugin.cpp @@ -83,17 +83,17 @@ typedef MODULE_MAP::const_iterator MODULE_CITER; /// Parse an eagle distance which is either mm, or mils if there is "mil" suffix. /// Return is in BIU. -static double parseEagle( const wxString& aDistance ) +static int parseEagle( const wxString& aDistance ) { - double ret = strtod( aDistance.c_str(), NULL ); - if( aDistance.npos != aDistance.find( "mil" ) ) - ret = IU_PER_MILS * ret; - else - ret = IU_PER_MM * ret; + ECOORD::UNIT unit = ( aDistance.npos != aDistance.find( "mil" ) ) + ? ECOORD::UNIT::MIL : ECOORD::UNIT::MM; - return ret; + ECOORD coord( aDistance, unit ); + + return coord.ToPcbUnits(); } + /// Assemble a two part key as a simple concatenation of aFirst and aSecond parts, /// using a separator. static string makeKey( const string& aFirst, const string& aSecond ) @@ -170,16 +170,10 @@ const wxString EAGLE_PLUGIN::GetFileExtension() const } -int inline EAGLE_PLUGIN::kicad( double d ) const -{ - return KiROUND( biu_per_mm * d ); -} - - -wxSize inline EAGLE_PLUGIN::kicad_fontz( double d ) const +wxSize inline EAGLE_PLUGIN::kicad_fontz( const ECOORD& d ) const { // texts seem to better match eagle when scaled down by 0.95 - int kz = kicad( d ) * 95 / 100; + int kz = d.ToPcbUnits() * 95 / 100; return wxSize( kz, kz ); } @@ -285,8 +279,6 @@ void EAGLE_PLUGIN::init( const PROPERTIES* aProperties ) m_board = NULL; m_props = aProperties; - mm_per_biu = 1/IU_PER_MM; - biu_per_mm = IU_PER_MM; delete m_rules; m_rules = new ERULES(); @@ -498,9 +490,9 @@ void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics ) pcbtxt->SetTextSize( kicad_fontz( t.size ) ); - double ratio = t.ratio ? *t.ratio : 8; // DTD says 8 is default + double ratio = t.ratio ? *t.ratio : 8; // DTD says 8 is default - pcbtxt->SetThickness( kicad( t.size * ratio / 100 ) ); + pcbtxt->SetThickness( t.size.ToPcbUnits() * ratio / 100 ); int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT; @@ -604,7 +596,7 @@ void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics ) dseg->SetLayer( layer ); dseg->SetStart( wxPoint( kicad_x( c.x ), kicad_y( c.y ) ) ); dseg->SetEnd( wxPoint( kicad_x( c.x + c.radius ), kicad_y( c.y ) ) ); - dseg->SetWidth( kicad( c.width ) ); + dseg->SetWidth( c.width.ToPcbUnits() ); } m_xpath->pop(); } @@ -675,7 +667,7 @@ void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics ) pad->SetPosition( padpos + module->GetPosition() ); */ - wxSize sz( kicad( e.drill ), kicad( e.drill ) ); + wxSize sz( e.drill.ToPcbUnits(), e.drill.ToPcbUnits() ); pad->SetDrillSize( sz ); pad->SetSize( sz ); @@ -721,7 +713,7 @@ void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics ) // because the "height" of the dimension is perpendicular to that axis // Note the check is just if two axes are close enough to each other // Eagle appears to have some rounding errors - if( fabs( d.x1 - d.x2 ) < 0.05 ) + if( abs( ( d.x1 - d.x2 ).ToPcbUnits() ) < 50000 ) // 50000 nm = 0.05 mm dimension->SetHeight( kicad_x( d.x1 - d.x3 ) ); else dimension->SetHeight( kicad_y( d.y3 - d.y1 ) ); @@ -1096,7 +1088,7 @@ void EAGLE_PLUGIN::orientModuleText( MODULE* m, const EELEMENT& e, ratio = *a.ratio; } - int lw = int( fontz.y * ratio / 100.0 ); + int lw = int( fontz.y * ratio / 100 ); txt->SetThickness( lw ); int align = ETEXT::BOTTOM_LEFT; // bottom-left is eagle default @@ -1227,13 +1219,16 @@ void EAGLE_PLUGIN::packageWire( MODULE* aModule, wxXmlNode* aTree ) const if( IsCopperLayer( layer ) ) // skip copper "package.circle"s { - wxLogMessage( wxString::Format( "Line on copper layer in package %s ( %f, %f ) ( %f, %f )\n Moving to drawings layer", aModule->GetFPID().GetLibItemName().c_str(), w.x1 , w.y1 , w.x2 , w.y2 ) ); + wxLogMessage( wxString::Format( + "Line on copper layer in package %s ( %d, %d ) ( %d, %d )\n Moving to drawings layer", + aModule->GetFPID().GetLibItemName().c_str(), w.x1.ToPcbUnits(), w.y1.ToPcbUnits(), + w.x2.ToPcbUnits(), w.y2.ToPcbUnits() ) ); layer = Dwgs_User; } wxPoint start( kicad_x( w.x1 ), kicad_y( w.y1 ) ); wxPoint end( kicad_x( w.x2 ), kicad_y( w.y2 ) ); - int width = kicad( w.width ); + int width = w.width.ToPcbUnits(); // FIXME: the cap attribute is ignored because kicad can't create lines // with flat ends. @@ -1284,9 +1279,7 @@ void EAGLE_PLUGIN::packagePad( MODULE* aModule, wxXmlNode* aTree ) const RotatePoint( &padpos, aModule->GetOrientation() ); pad->SetPosition( padpos + aModule->GetPosition() ); - - pad->SetDrillSize( wxSize( kicad( e.drill ), kicad( e.drill ) ) ); - + pad->SetDrillSize( wxSize( e.drill.ToPcbUnits(), e.drill.ToPcbUnits() ) ); pad->SetLayerSet( LSET::AllCuMask().set( B_Mask ).set( F_Mask ) ); if( e.shape ) @@ -1322,7 +1315,7 @@ void EAGLE_PLUGIN::packagePad( MODULE* aModule, wxXmlNode* aTree ) const if( e.diameter ) { - int diameter = kicad( *e.diameter ); + int diameter = e.diameter->ToPcbUnits(); pad->SetSize( wxSize( diameter, diameter ) ); } else @@ -1394,7 +1387,7 @@ void EAGLE_PLUGIN::packageText( MODULE* aModule, wxXmlNode* aTree ) const double ratio = t.ratio ? *t.ratio : 8; // DTD says 8 is default - txt->SetThickness( kicad( t.size * ratio / 100 ) ); + txt->SetThickness( t.size.ToPcbUnits() * ratio / 100 ); int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT; // bottom-left is eagle default @@ -1470,7 +1463,9 @@ void EAGLE_PLUGIN::packageRectangle( MODULE* aModule, wxXmlNode* aTree ) const PCB_LAYER_ID layer = kicad_layer( r.layer ); // Rectangles are not supported yet in footprints as they are not editable. - wxLogMessage( wxString::Format( "Unsupported rectangle in package %s ( %f, %f ) ( %f, %f )", aModule->GetFPID().GetLibItemName().c_str(), r.x1 , r.y1 , r.x2 , r.y2 ) ); + wxLogMessage( wxString::Format( "Unsupported rectangle in package %s (%d, %d) (%d, %d)", + aModule->GetFPID().GetLibItemName().c_str(), r.x1.ToPcbUnits(), r.y1.ToPcbUnits(), + r.x2.ToPcbUnits(), r.y2.ToPcbUnits() ) ); return; @@ -1569,7 +1564,7 @@ void EAGLE_PLUGIN::packageCircle( MODULE* aModule, wxXmlNode* aTree ) const aModule->GraphicalItemsList().PushBack( gr ); - gr->SetWidth( kicad( e.width ) ); + gr->SetWidth( e.width.ToPcbUnits() ); switch( (int) layer ) { @@ -1614,7 +1609,7 @@ void EAGLE_PLUGIN::packageHole( MODULE* aModule, wxXmlNode* aTree ) const pad->SetPos0( padpos ); pad->SetPosition( padpos + aModule->GetPosition() ); - wxSize sz( kicad( e.drill ), kicad( e.drill ) ); + wxSize sz( e.drill.ToPcbUnits(), e.drill.ToPcbUnits() ); pad->SetDrillSize( sz ); pad->SetSize( sz ); @@ -1651,7 +1646,7 @@ void EAGLE_PLUGIN::packageSMD( MODULE* aModule, wxXmlNode* aTree ) const pad->SetPosition( padpos + aModule->GetPosition() ); - pad->SetSize( wxSize( kicad( e.dx ), kicad( e.dy ) ) ); + pad->SetSize( wxSize( e.dx.ToPcbUnits(), e.dy.ToPcbUnits() ) ); pad->SetLayer( layer ); @@ -1743,7 +1738,7 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals ) t->SetPosition( wxPoint( kicad_x( w.x1 ), kicad_y( w.y1 ) ) ); t->SetEnd( wxPoint( kicad_x( w.x2 ), kicad_y( w.y2 ) ) ); - int width = kicad( w.width ); + int width = w.width.ToPcbUnits(); if( width < m_min_trace ) m_min_trace = width; @@ -1773,7 +1768,7 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals ) IsCopperLayer( layer_back_most ) ) { int kidiam; - int drillz = kicad( v.drill ); + int drillz = v.drill.ToPcbUnits(); VIA* via = new VIA( m_board ); m_board->m_Track.Insert( via, NULL ); @@ -1781,7 +1776,7 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals ) if( v.diam ) { - kidiam = kicad( *v.diam ); + kidiam = v.diam->ToPcbUnits(); via->SetWidth( kidiam ); } else @@ -1898,14 +1893,14 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals ) // clearances, etc. zone->SetArcSegmentCount( 32 ); // @todo: should be a constructor default? - zone->SetMinThickness( kicad( p.width ) ); + zone->SetMinThickness( p.width.ToPcbUnits() ); // FIXME: KiCad zones have very rounded corners compared to eagle. // This means that isolation amounts that work well in eagle // tend to make copper intrude in soldermask free areas around pads. if( p.isolate ) { - zone->SetZoneClearance( kicad( *p.isolate ) ); + zone->SetZoneClearance( p.isolate->ToPcbUnits() ); } else { zone->SetZoneClearance( 0 ); @@ -1920,8 +1915,8 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals ) // based on what the zone is connecting to. // (i.e. width of spoke is half of the smaller side of an smd pad) // This is a basic workaround - zone->SetThermalReliefGap( kicad( p.width + 0.05 ) ); - zone->SetThermalReliefCopperBridge( kicad( p.width + 0.05 ) ); + zone->SetThermalReliefGap( p.width.ToPcbUnits() + 50000 ); // 50000nm == 0.05mm + zone->SetThermalReliefCopperBridge( p.width.ToPcbUnits() + 50000 ); } int rank = p.rank ? (p.max_priority - *p.rank) : p.max_priority; diff --git a/pcbnew/eagle_plugin.h b/pcbnew/eagle_plugin.h index 81b468c8cb..77b1a3a77f 100644 --- a/pcbnew/eagle_plugin.h +++ b/pcbnew/eagle_plugin.h @@ -148,9 +148,6 @@ private: int m_min_via; ///< smallest via we find on Load(), in BIU. int m_min_via_hole; ///< smallest via diameter hole we find on Load(), in BIU. - double mm_per_biu; ///< how many mm in each BIU - double biu_per_mm; ///< how many bius in a mm - wxString m_lib_path; wxDateTime m_mod_time; @@ -160,21 +157,15 @@ private: void clear_cu_map(); /// Convert an Eagle distance to a KiCad distance. - int kicad( double d ) const; - int kicad_y( double y ) const { return -kicad( y ); } - int kicad_x( double x ) const { return kicad( x ); } + int kicad_y( const ECOORD& y ) const { return -y.ToPcbUnits(); } + int kicad_x( const ECOORD& x ) const { return x.ToPcbUnits(); } /// create a font size (fontz) from an eagle font size scalar - wxSize kicad_fontz( double d ) const; + wxSize kicad_fontz( const ECOORD& d ) const; /// Convert an Eagle layer to a KiCad layer. PCB_LAYER_ID kicad_layer( int aLayer ) const; - /// Convert a KiCad distance to an Eagle distance. - double eagle( BIU d ) const { return mm_per_biu * d; } - double eagle_x( BIU x ) const { return eagle( x ); } - double eagle_y( BIU y ) const { return eagle( y ); } - /// This PLUGIN only caches one footprint library, this determines which one. void cacheLib( const wxString& aLibraryPath );