Modified Eagle import plugins to use nanometers as the internal unit
This commit is contained in:
parent
7f697de432
commit
25b8111341
|
@ -29,6 +29,68 @@
|
|||
#include <functional>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <cstdio>
|
||||
|
||||
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<string>( const wxString& aValue )
|
||||
|
@ -99,6 +160,15 @@ EROT Convert<EROT>( const wxString& aRot )
|
|||
return value;
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
ECOORD Convert<ECOORD>( 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<double>( aWire, "x1" );
|
||||
y1 = parseRequiredAttribute<double>( aWire, "y1" );
|
||||
x2 = parseRequiredAttribute<double>( aWire, "x2" );
|
||||
y2 = parseRequiredAttribute<double>( aWire, "y2" );
|
||||
width = parseRequiredAttribute<double>( aWire, "width" );
|
||||
x1 = parseRequiredAttribute<ECOORD>( aWire, "x1" );
|
||||
y1 = parseRequiredAttribute<ECOORD>( aWire, "y1" );
|
||||
x2 = parseRequiredAttribute<ECOORD>( aWire, "x2" );
|
||||
y2 = parseRequiredAttribute<ECOORD>( aWire, "y2" );
|
||||
width = parseRequiredAttribute<ECOORD>( aWire, "width" );
|
||||
layer = parseRequiredAttribute<int>( aWire, "layer" );
|
||||
curve = parseOptionalAttribute<double>( aWire, "curve" );
|
||||
|
||||
|
@ -276,8 +348,8 @@ EJUNCTION::EJUNCTION( wxXmlNode* aJunction )
|
|||
>
|
||||
*/
|
||||
|
||||
x = parseRequiredAttribute<double>( aJunction, "x" );
|
||||
y = parseRequiredAttribute<double>( aJunction, "y" );
|
||||
x = parseRequiredAttribute<ECOORD>( aJunction, "x" );
|
||||
y = parseRequiredAttribute<ECOORD>( aJunction, "y" );
|
||||
}
|
||||
|
||||
|
||||
|
@ -297,9 +369,9 @@ ELABEL::ELABEL( wxXmlNode* aLabel, const wxString& aNetName )
|
|||
>
|
||||
*/
|
||||
|
||||
x = parseRequiredAttribute<double>( aLabel, "x" );
|
||||
y = parseRequiredAttribute<double>( aLabel, "y" );
|
||||
size = parseRequiredAttribute<double>( aLabel, "size" );
|
||||
x = parseRequiredAttribute<ECOORD>( aLabel, "x" );
|
||||
y = parseRequiredAttribute<ECOORD>( aLabel, "y" );
|
||||
size = parseRequiredAttribute<ECOORD>( aLabel, "size" );
|
||||
layer = parseRequiredAttribute<int>( aLabel, "layer" );
|
||||
rot = parseOptionalAttribute<EROT>( aLabel, "rot" );
|
||||
xref = parseOptionalAttribute<string>( aLabel, "xref" );
|
||||
|
@ -322,15 +394,15 @@ EVIA::EVIA( wxXmlNode* aVia )
|
|||
>
|
||||
*/
|
||||
|
||||
x = parseRequiredAttribute<double>( aVia, "x" );
|
||||
y = parseRequiredAttribute<double>( aVia, "y" );
|
||||
x = parseRequiredAttribute<ECOORD>( aVia, "x" );
|
||||
y = parseRequiredAttribute<ECOORD>( aVia, "y" );
|
||||
|
||||
string ext = parseRequiredAttribute<string>( aVia, "extent" );
|
||||
|
||||
sscanf( ext.c_str(), "%d-%d", &layer_front_most, &layer_back_most );
|
||||
|
||||
drill = parseRequiredAttribute<double>( aVia, "drill" );
|
||||
diam = parseOptionalAttribute<double>( aVia, "diameter" );
|
||||
drill = parseRequiredAttribute<ECOORD>( aVia, "drill" );
|
||||
diam = parseOptionalAttribute<ECOORD>( aVia, "diameter" );
|
||||
shape = parseOptionalAttribute<string>( aVia, "shape" );
|
||||
}
|
||||
|
||||
|
@ -348,10 +420,10 @@ ECIRCLE::ECIRCLE( wxXmlNode* aCircle )
|
|||
>
|
||||
*/
|
||||
|
||||
x = parseRequiredAttribute<double>( aCircle, "x" );
|
||||
y = parseRequiredAttribute<double>( aCircle, "y" );
|
||||
radius = parseRequiredAttribute<double>( aCircle, "radius" );
|
||||
width = parseRequiredAttribute<double>( aCircle, "width" );
|
||||
x = parseRequiredAttribute<ECOORD>( aCircle, "x" );
|
||||
y = parseRequiredAttribute<ECOORD>( aCircle, "y" );
|
||||
radius = parseRequiredAttribute<ECOORD>( aCircle, "radius" );
|
||||
width = parseRequiredAttribute<ECOORD>( aCircle, "width" );
|
||||
layer = parseRequiredAttribute<int>( aCircle, "layer" );
|
||||
}
|
||||
|
||||
|
@ -370,10 +442,10 @@ ERECT::ERECT( wxXmlNode* aRect )
|
|||
>
|
||||
*/
|
||||
|
||||
x1 = parseRequiredAttribute<double>( aRect, "x1" );
|
||||
y1 = parseRequiredAttribute<double>( aRect, "y1" );
|
||||
x2 = parseRequiredAttribute<double>( aRect, "x2" );
|
||||
y2 = parseRequiredAttribute<double>( aRect, "y2" );
|
||||
x1 = parseRequiredAttribute<ECOORD>( aRect, "x1" );
|
||||
y1 = parseRequiredAttribute<ECOORD>( aRect, "y1" );
|
||||
x2 = parseRequiredAttribute<ECOORD>( aRect, "x2" );
|
||||
y2 = parseRequiredAttribute<ECOORD>( aRect, "y2" );
|
||||
layer = parseRequiredAttribute<int>( aRect, "layer" );
|
||||
rot = parseOptionalAttribute<EROT>( aRect, "rot" );
|
||||
}
|
||||
|
@ -401,9 +473,9 @@ EATTR::EATTR( wxXmlNode* aTree )
|
|||
name = parseRequiredAttribute<string>( aTree, "name" );
|
||||
value = parseOptionalAttribute<string>( aTree, "value" );
|
||||
|
||||
x = parseOptionalAttribute<double>( aTree, "x" );
|
||||
y = parseOptionalAttribute<double>( aTree, "y" );
|
||||
size = parseOptionalAttribute<double>( aTree, "size" );
|
||||
x = parseOptionalAttribute<ECOORD>( aTree, "x" );
|
||||
y = parseOptionalAttribute<ECOORD>( aTree, "y" );
|
||||
size = parseOptionalAttribute<ECOORD>( 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<double>( aDimension, "x1" );
|
||||
y1 = parseRequiredAttribute<double>( aDimension, "y1" );
|
||||
x2 = parseRequiredAttribute<double>( aDimension, "x2" );
|
||||
y2 = parseRequiredAttribute<double>( aDimension, "y2" );
|
||||
x3 = parseRequiredAttribute<double>( aDimension, "x3" );
|
||||
y3 = parseRequiredAttribute<double>( aDimension, "y3" );
|
||||
x1 = parseRequiredAttribute<ECOORD>( aDimension, "x1" );
|
||||
y1 = parseRequiredAttribute<ECOORD>( aDimension, "y1" );
|
||||
x2 = parseRequiredAttribute<ECOORD>( aDimension, "x2" );
|
||||
y2 = parseRequiredAttribute<ECOORD>( aDimension, "y2" );
|
||||
x3 = parseRequiredAttribute<ECOORD>( aDimension, "x3" );
|
||||
y3 = parseRequiredAttribute<ECOORD>( aDimension, "y3" );
|
||||
layer = parseRequiredAttribute<int>( aDimension, "layer" );
|
||||
|
||||
opt_string dimType = parseOptionalAttribute<string>( aDimension, "dtype" );
|
||||
|
@ -479,9 +551,9 @@ ETEXT::ETEXT( wxXmlNode* aText )
|
|||
*/
|
||||
|
||||
text = aText->GetNodeContent();
|
||||
x = parseRequiredAttribute<double>( aText, "x" );
|
||||
y = parseRequiredAttribute<double>( aText, "y" );
|
||||
size = parseRequiredAttribute<double>( aText, "size" );
|
||||
x = parseRequiredAttribute<ECOORD>( aText, "x" );
|
||||
y = parseRequiredAttribute<ECOORD>( aText, "y" );
|
||||
size = parseRequiredAttribute<ECOORD>( aText, "size" );
|
||||
layer = parseRequiredAttribute<int>( aText, "layer" );
|
||||
|
||||
font = parseOptionalAttribute<string>( 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<string>( aPad, "name" );
|
||||
x = parseRequiredAttribute<double>( aPad, "x" );
|
||||
y = parseRequiredAttribute<double>( aPad, "y" );
|
||||
drill = parseRequiredAttribute<double>( aPad, "drill" );
|
||||
x = parseRequiredAttribute<ECOORD>( aPad, "x" );
|
||||
y = parseRequiredAttribute<ECOORD>( aPad, "y" );
|
||||
drill = parseRequiredAttribute<ECOORD>( aPad, "drill" );
|
||||
|
||||
// Optional attributes
|
||||
diameter = parseOptionalAttribute<double>( aPad, "diameter" );
|
||||
diameter = parseOptionalAttribute<ECOORD>( aPad, "diameter" );
|
||||
|
||||
opt_string s = parseOptionalAttribute<string>( aPad, "shape" );
|
||||
|
||||
|
@ -593,10 +665,10 @@ ESMD::ESMD( wxXmlNode* aSMD )
|
|||
|
||||
// DTD #REQUIRED, throw exception if not found
|
||||
name = parseRequiredAttribute<string>( aSMD, "name" );
|
||||
x = parseRequiredAttribute<double>( aSMD, "x" );
|
||||
y = parseRequiredAttribute<double>( aSMD, "y" );
|
||||
dx = parseRequiredAttribute<double>( aSMD, "dx" );
|
||||
dy = parseRequiredAttribute<double>( aSMD, "dy" );
|
||||
x = parseRequiredAttribute<ECOORD>( aSMD, "x" );
|
||||
y = parseRequiredAttribute<ECOORD>( aSMD, "y" );
|
||||
dx = parseRequiredAttribute<ECOORD>( aSMD, "dx" );
|
||||
dy = parseRequiredAttribute<ECOORD>( aSMD, "dy" );
|
||||
layer = parseRequiredAttribute<int>( aSMD, "layer" );
|
||||
|
||||
roundness = parseOptionalAttribute<int>( aSMD, "roundness" );
|
||||
|
@ -627,8 +699,8 @@ EPIN::EPIN( wxXmlNode* aPin )
|
|||
|
||||
// DTD #REQUIRED, throw exception if not found
|
||||
name = parseRequiredAttribute<string>( aPin, "name" );
|
||||
x = parseRequiredAttribute<double>( aPin, "x" );
|
||||
y = parseRequiredAttribute<double>( aPin, "y" );
|
||||
x = parseRequiredAttribute<ECOORD>( aPin, "x" );
|
||||
y = parseRequiredAttribute<ECOORD>( aPin, "y" );
|
||||
|
||||
visible = parseOptionalAttribute<string>( aPin, "visible" );
|
||||
length = parseOptionalAttribute<string>( aPin, "length" );
|
||||
|
@ -650,8 +722,8 @@ EVERTEX::EVERTEX( wxXmlNode* aVertex )
|
|||
>
|
||||
*/
|
||||
|
||||
x = parseRequiredAttribute<double>( aVertex, "x" );
|
||||
y = parseRequiredAttribute<double>( aVertex, "y" );
|
||||
x = parseRequiredAttribute<ECOORD>( aVertex, "x" );
|
||||
y = parseRequiredAttribute<ECOORD>( aVertex, "y" );
|
||||
}
|
||||
|
||||
|
||||
|
@ -670,11 +742,11 @@ EPOLYGON::EPOLYGON( wxXmlNode* aPolygon )
|
|||
>
|
||||
*/
|
||||
|
||||
width = parseRequiredAttribute<double>( aPolygon, "width" );
|
||||
width = parseRequiredAttribute<ECOORD>( aPolygon, "width" );
|
||||
layer = parseRequiredAttribute<int>( aPolygon, "layer" );
|
||||
|
||||
spacing = parseOptionalAttribute<double>( aPolygon, "spacing" );
|
||||
isolate = parseOptionalAttribute<double>( aPolygon, "isolate" );
|
||||
spacing = parseOptionalAttribute<ECOORD>( aPolygon, "spacing" );
|
||||
isolate = parseOptionalAttribute<ECOORD>( aPolygon, "isolate" );
|
||||
opt_string s = parseOptionalAttribute<string>( aPolygon, "pour" );
|
||||
|
||||
// default pour to solid fill
|
||||
|
@ -704,9 +776,9 @@ EHOLE::EHOLE( wxXmlNode* aHole )
|
|||
*/
|
||||
|
||||
// #REQUIRED:
|
||||
x = parseRequiredAttribute<double>( aHole, "x" );
|
||||
y = parseRequiredAttribute<double>( aHole, "y" );
|
||||
drill = parseRequiredAttribute<double>( aHole, "drill" );
|
||||
x = parseRequiredAttribute<ECOORD>( aHole, "x" );
|
||||
y = parseRequiredAttribute<ECOORD>( aHole, "y" );
|
||||
drill = parseRequiredAttribute<ECOORD>( aHole, "drill" );
|
||||
}
|
||||
|
||||
|
||||
|
@ -734,8 +806,8 @@ EELEMENT::EELEMENT( wxXmlNode* aElement )
|
|||
package = parseRequiredAttribute<string>( aElement, "package" );
|
||||
ReplaceIllegalFileNameChars( &package );
|
||||
|
||||
x = parseRequiredAttribute<double>( aElement, "x" );
|
||||
y = parseRequiredAttribute<double>( aElement, "y" );
|
||||
x = parseRequiredAttribute<ECOORD>( aElement, "x" );
|
||||
y = parseRequiredAttribute<ECOORD>( aElement, "y" );
|
||||
|
||||
// optional
|
||||
locked = parseOptionalAttribute<bool>( aElement, "locked" );
|
||||
|
@ -807,8 +879,8 @@ EINSTANCE::EINSTANCE( wxXmlNode* aInstance )
|
|||
part = parseRequiredAttribute<string>( aInstance, "part" );
|
||||
gate = parseRequiredAttribute<string>( aInstance, "gate" );
|
||||
|
||||
x = parseRequiredAttribute<double>( aInstance, "x" );
|
||||
y = parseRequiredAttribute<double>( aInstance, "y" );
|
||||
x = parseRequiredAttribute<ECOORD>( aInstance, "x" );
|
||||
y = parseRequiredAttribute<ECOORD>( aInstance, "y" );
|
||||
|
||||
// optional
|
||||
smashed = parseOptionalAttribute<bool>( aInstance, "smashed" );
|
||||
|
@ -833,8 +905,8 @@ EGATE::EGATE( wxXmlNode* aGate )
|
|||
name = parseRequiredAttribute<string>( aGate, "name" );
|
||||
symbol = parseRequiredAttribute<string>( aGate, "symbol" );
|
||||
|
||||
x = parseRequiredAttribute<double>( aGate, "x" );
|
||||
y = parseRequiredAttribute<double>( aGate, "y" );
|
||||
x = parseRequiredAttribute<ECOORD>( aGate, "x" );
|
||||
y = parseRequiredAttribute<ECOORD>( aGate, "y" );
|
||||
|
||||
opt_string stemp = parseOptionalAttribute<string>( aGate, "addlevel" );
|
||||
|
||||
|
|
|
@ -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<SCH_JUNCTION> 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<SCH_GLOBALLABEL> 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<SCH_COMPONENT> 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<LIB_PART>& aPart
|
|||
|
||||
unique_ptr<LIB_CIRCLE> 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<LIB_PART>&
|
|||
|
||||
unique_ptr<LIB_RECTANGLE> 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<LIB_PART>& 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<LIB_ARC> 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<LIB_PART>& 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<LIB_PART>& aPart,
|
|||
polyLine->AddPoint( begin );
|
||||
polyLine->AddPoint( end );
|
||||
polyLine->SetUnit( aGateNumber );
|
||||
|
||||
return (LIB_ITEM*) polyLine.release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LIB_POLYLINE* SCH_EAGLE_PLUGIN::loadSymbolPolyLine( std::unique_ptr<LIB_PART>& aPart,
|
||||
wxXmlNode* aPolygonNode,
|
||||
int aGateNumber )
|
||||
wxXmlNode* aPolygonNode, int aGateNumber )
|
||||
{
|
||||
std::unique_ptr<LIB_POLYLINE> polyLine( new LIB_POLYLINE( aPart.get() ) );
|
||||
|
||||
|
@ -1608,7 +1584,7 @@ LIB_POLYLINE* SCH_EAGLE_PLUGIN::loadSymbolPolyLine( std::unique_ptr<LIB_PART>& a
|
|||
if( vertex->GetName() == "vertex" ) // skip <xmlattr> 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<LIB_PART>& aPart,
|
|||
int aGateNumber )
|
||||
{
|
||||
std::unique_ptr<LIB_PIN> 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<LIB_PART>& 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 ) );
|
||||
|
|
|
@ -41,10 +41,6 @@
|
|||
#include <trigo.h>
|
||||
#include <kicad_string.h>
|
||||
|
||||
// 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<string> opt_string;
|
||||
typedef OPTIONAL_XML_ATTRIBUTE<int> opt_int;
|
||||
typedef OPTIONAL_XML_ATTRIBUTE<double> opt_double;
|
||||
typedef OPTIONAL_XML_ATTRIBUTE<bool> opt_bool;
|
||||
typedef OPTIONAL_XML_ATTRIBUTE<EROT> opt_erot;
|
||||
typedef OPTIONAL_XML_ATTRIBUTE<ECOORD> opt_ecoord;
|
||||
|
||||
|
||||
// All of the 'E'STRUCTS below merely hold Eagle XML information verbatim, in binary.
|
||||
|
@ -386,6 +383,65 @@ typedef OPTIONAL_XML_ATTRIBUTE<EROT> 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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
Loading…
Reference in New Issue