Commit 69905af7 authored by Dick Hollenbeck's avatar Dick Hollenbeck

EAGLE_PLUGIN now positions text correct for most cases

parent 7bdcad15
...@@ -42,14 +42,11 @@ class EDA_DRAW_FRAME; ...@@ -42,14 +42,11 @@ class EDA_DRAW_FRAME;
class EDGE_MODULE : public DRAWSEGMENT class EDGE_MODULE : public DRAWSEGMENT
{ {
public:
wxPoint m_Start0; // Start point or center, relative to module origin, orient 0.
wxPoint m_End0; // End point, relative to module origin, orient 0.
public: public:
EDGE_MODULE( MODULE* parent, STROKE_T aShape = S_SEGMENT ); EDGE_MODULE( MODULE* parent, STROKE_T aShape = S_SEGMENT );
// Do not create a copy constructor. The one generated by the compiler is adequate. // Do not create a copy constructor. The one generated by the compiler is adequate.
// EDGE_MODULE( const EDGE_MODULE& );
~EDGE_MODULE(); ~EDGE_MODULE();
...@@ -90,6 +87,11 @@ public: ...@@ -90,6 +87,11 @@ public:
#if defined(DEBUG) #if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const; // overload void Show( int nestLevel, std::ostream& os ) const; // overload
#endif #endif
//protected: @todo: is it just me?
wxPoint m_Start0; // Start point or center, relative to module origin, orient 0.
wxPoint m_End0; // End point, relative to module origin, orient 0.
}; };
#endif // CLASS_EDGE_MOD_H_ #endif // CLASS_EDGE_MOD_H_
...@@ -52,7 +52,6 @@ Load() TODO's ...@@ -52,7 +52,6 @@ Load() TODO's
*) set layer counts, types and names into BOARD *) set layer counts, types and names into BOARD
*) footprint placement on board back *) footprint placement on board back
*) eagle "mirroring" does not mean put on board back *) eagle "mirroring" does not mean put on board back
*) fix text twisting and final location issues.
*) netclass info? *) netclass info?
*) code factoring, for polygon at least *) code factoring, for polygon at least
*) zone fill clearances *) zone fill clearances
...@@ -98,6 +97,54 @@ typedef boost::optional<bool> opt_bool; ...@@ -98,6 +97,54 @@ typedef boost::optional<bool> opt_bool;
//typedef boost::optional<CPTREE&> opt_cptree; //typedef boost::optional<CPTREE&> opt_cptree;
static opt_bool parseOptionalBool( CPTREE& attribs, const char* aName )
{
opt_bool ret;
opt_string stemp = attribs.get_optional<std::string>( aName );
if( stemp )
ret = !stemp->compare( "yes" );
return ret;
}
// None of the 'e'funcs do any "to KiCad" conversion, they merely convert
// some XML node into binary:
/// Eagle rotation
struct EROT
{
bool mirror;
bool spin;
double degrees;
};
typedef boost::optional<EROT> opt_erot;
static EROT erot( const std::string& aRot )
{
EROT rot;
rot.spin = aRot.find( 'S' ) != aRot.npos;
rot.mirror = aRot.find( 'M' ) != aRot.npos;
rot.degrees = strtod( aRot.c_str()
+ 1 // skip leading 'R'
+ int( rot.spin ) // skip optional leading 'S'
+ int( rot.mirror ), // skip optional leading 'M'
NULL );
return rot;
}
static opt_erot parseOptionalEROT( CPTREE& attribs )
{
opt_erot ret;
opt_string stemp = attribs.get_optional<std::string>( "rot" );
if( stemp )
ret = erot( *stemp );
return ret;
}
/// Eagle wire /// Eagle wire
struct EWIRE struct EWIRE
{ {
...@@ -107,8 +154,27 @@ struct EWIRE ...@@ -107,8 +154,27 @@ struct EWIRE
double y2; double y2;
double width; double width;
int layer; int layer;
EWIRE( CPTREE& aWire );
}; };
/**
* Constructor EWIRE
* converts a <wire>'s xml attributes to binary without additional conversion.
* @param aResult is an EWIRE to fill in with the <wire> data converted to binary.
*/
EWIRE::EWIRE( CPTREE& aWire )
{
CPTREE& attribs = aWire.get_child( "<xmlattr>" );
x1 = attribs.get<double>( "x1" );
y1 = attribs.get<double>( "y1" );
x2 = attribs.get<double>( "x2" );
y2 = attribs.get<double>( "y2" );
width = attribs.get<double>( "width" );
layer = attribs.get<int>( "layer" );
}
/// Eagle via /// Eagle via
struct EVIA struct EVIA
{ {
...@@ -119,8 +185,39 @@ struct EVIA ...@@ -119,8 +185,39 @@ struct EVIA
double drill; double drill;
opt_double diam; opt_double diam;
opt_string shape; opt_string shape;
EVIA( CPTREE& aVia );
}; };
EVIA::EVIA( CPTREE& aVia )
{
CPTREE& attribs = aVia.get_child( "<xmlattr>" );
/*
<!ELEMENT via EMPTY>
<!ATTLIST via
x %Coord; #REQUIRED
y %Coord; #REQUIRED
extent %Extent; #REQUIRED
drill %Dimension; #REQUIRED
diameter %Dimension; "0"
shape %ViaShape; "round"
alwaysstop %Bool; "no"
>
*/
x = attribs.get<double>( "x" );
y = attribs.get<double>( "y" );
std::string ext = attribs.get<std::string>( "extent" );
sscanf( ext.c_str(), "%u-%u", &layer_start, &layer_end );
drill = attribs.get<double>( "drill" );
diam = attribs.get_optional<double>( "diameter" );
shape = attribs.get_optional<std::string>( "shape" );
}
/// Eagle circle /// Eagle circle
struct ECIRCLE struct ECIRCLE
{ {
...@@ -129,8 +226,33 @@ struct ECIRCLE ...@@ -129,8 +226,33 @@ struct ECIRCLE
double radius; double radius;
double width; double width;
int layer; int layer;
ECIRCLE( CPTREE& aCircle );
}; };
ECIRCLE::ECIRCLE( CPTREE& aCircle )
{
CPTREE& attribs = aCircle.get_child( "<xmlattr>" );
/*
<!ELEMENT circle EMPTY>
<!ATTLIST circle
x %Coord; #REQUIRED
y %Coord; #REQUIRED
radius %Coord; #REQUIRED
width %Dimension; #REQUIRED
layer %Layer; #REQUIRED
>
*/
x = attribs.get<double>( "x" );
y = attribs.get<double>( "y" );
radius = attribs.get<double>( "radius" );
width = attribs.get<double>( "width" );
layer = attribs.get<int>( "layer" );
}
/// Eagle XML rectangle in binary /// Eagle XML rectangle in binary
struct ERECT struct ERECT
{ {
...@@ -139,17 +261,35 @@ struct ERECT ...@@ -139,17 +261,35 @@ struct ERECT
double x2; double x2;
double y2; double y2;
int layer; int layer;
opt_erot erot;
ERECT( CPTREE& aRect );
}; };
/// Eagle rotation ERECT::ERECT( CPTREE& aRect )
struct EROT
{ {
bool mirror; CPTREE& attribs = aRect.get_child( "<xmlattr>" );
bool spin;
double degrees; /*
}; <!ELEMENT rectangle EMPTY>
<!ATTLIST rectangle
x1 %Coord; #REQUIRED
y1 %Coord; #REQUIRED
x2 %Coord; #REQUIRED
y2 %Coord; #REQUIRED
layer %Layer; #REQUIRED
rot %Rotation; "R0"
>
*/
x1 = attribs.get<double>( "x1" );
y1 = attribs.get<double>( "y1" );
x2 = attribs.get<double>( "x2" );
y2 = attribs.get<double>( "y2" );
layer = attribs.get<int>( "layer" );
erot = parseOptionalEROT( attribs );
}
typedef boost::optional<EROT> opt_erot;
/// Eagle "attribute" XML element, no foolin'. /// Eagle "attribute" XML element, no foolin'.
struct EATTR struct EATTR
...@@ -159,7 +299,7 @@ struct EATTR ...@@ -159,7 +299,7 @@ struct EATTR
opt_double x; opt_double x;
opt_double y; opt_double y;
opt_double size; opt_double size;
// opt_int layer; opt_int layer;
opt_double ratio; opt_double ratio;
opt_erot erot; opt_erot erot;
opt_int display; opt_int display;
...@@ -170,8 +310,67 @@ struct EATTR ...@@ -170,8 +310,67 @@ struct EATTR
NAME, NAME,
BOTH, BOTH,
}; };
EATTR( CPTREE& aTree );
}; };
/**
* Constructor EATTR
* parses an Eagle "attribute" XML element. Note that an attribute element
* is different than an XML element attribute. The attribute element is a
* full XML node in and of itself, and has attributes of its own. Blame Eagle.
*/
EATTR::EATTR( CPTREE& aAttribute )
{
CPTREE& attribs = aAttribute.get_child( "<xmlattr>" );
/*
<!ELEMENT attribute EMPTY>
<!ATTLIST attribute
name %String; #REQUIRED
value %String; #IMPLIED
x %Coord; #IMPLIED
y %Coord; #IMPLIED
size %Dimension; #IMPLIED
layer %Layer; #IMPLIED
font %TextFont; #IMPLIED
ratio %Int; #IMPLIED
rot %Rotation; "R0"
display %AttributeDisplay; "value" -- only in <element> or <instance> context --
constant %Bool; "no" -- only in <device> context --
>
*/
name = attribs.get<std::string>( "name" ); // #REQUIRED
value = attribs.get_optional<std::string>( "value" );
x = attribs.get_optional<double>( "x" );
y = attribs.get_optional<double>( "y" );
size = attribs.get_optional<double>( "size" );
// KiCad cannot currently put a TEXTE_MODULE on a different layer than the MODULE
// Eagle can it seems.
layer = attribs.get_optional<int>( "layer" );
ratio = attribs.get_optional<double>( "ratio" );
erot = parseOptionalEROT( attribs );
opt_string stemp = attribs.get_optional<std::string>( "display" );
if( stemp )
{
// (off | value | name | both)
if( !stemp->compare( "off" ) )
display = EATTR::Off;
else if( !stemp->compare( "value" ) )
display = EATTR::VALUE;
else if( !stemp->compare( "name" ) )
display = EATTR::NAME;
else if( !stemp->compare( "both" ) )
display = EATTR::BOTH;
}
}
/// Eagle text element /// Eagle text element
struct ETEXT struct ETEXT
{ {
...@@ -199,8 +398,65 @@ struct ETEXT ...@@ -199,8 +398,65 @@ struct ETEXT
}; };
opt_int align; opt_int align;
ETEXT( CPTREE& aText );
}; };
ETEXT::ETEXT( CPTREE& aText )
{
CPTREE& attribs = aText.get_child( "<xmlattr>" );
/*
<!ELEMENT text (#PCDATA)>
<!ATTLIST text
x %Coord; #REQUIRED
y %Coord; #REQUIRED
size %Dimension; #REQUIRED
layer %Layer; #REQUIRED
font %TextFont; "proportional"
ratio %Int; "8"
rot %Rotation; "R0"
align %Align; "bottom-left"
>
*/
text = aText.data();
x = attribs.get<double>( "x" );
y = attribs.get<double>( "y" );
size = attribs.get<double>( "size" );
layer = attribs.get<int>( "layer" );
font = attribs.get_optional<std::string>( "font" );
ratio = attribs.get_optional<double>( "ratio" );
erot = parseOptionalEROT( attribs );
opt_string stemp = attribs.get_optional<std::string>( "align" );
if( stemp )
{
// (bottom-left | bottom-center | bottom-right | center-left |
// center | center-right | top-left | top-center | top-right)
if( !stemp->compare( "center" ) )
align = ETEXT::CENTER;
else if( !stemp->compare( "center-right" ) )
align = ETEXT::CENTER_RIGHT;
else if( !stemp->compare( "top-left" ) )
align = ETEXT::TOP_LEFT;
else if( !stemp->compare( "top-center" ) )
align = ETEXT::TOP_CENTER;
else if( !stemp->compare( "top-right" ) )
align = ETEXT::TOP_RIGHT;
else if( !stemp->compare( "bottom-left" ) )
align = ETEXT::BOTTOM_LEFT;
else if( !stemp->compare( "bottom-center" ) )
align = ETEXT::BOTTOM_CENTER;
else if( !stemp->compare( "bottom-right" ) )
align = ETEXT::BOTTOM_RIGHT;
else if( !stemp->compare( "center-left" ) )
align = ETEXT::CENTER_LEFT;
}
}
/// Eagle thru hol pad /// Eagle thru hol pad
struct EPAD struct EPAD
{ {
...@@ -226,8 +482,60 @@ struct EPAD ...@@ -226,8 +482,60 @@ struct EPAD
opt_bool stop; opt_bool stop;
opt_bool thermals; opt_bool thermals;
opt_bool first; opt_bool first;
EPAD( CPTREE& aPad );
}; };
EPAD::EPAD( CPTREE& aPad )
{
CPTREE& attribs = aPad.get_child( "<xmlattr>" );
/*
<!ELEMENT pad EMPTY>
<!ATTLIST pad
name %String; #REQUIRED
x %Coord; #REQUIRED
y %Coord; #REQUIRED
drill %Dimension; #REQUIRED
diameter %Dimension; "0"
shape %PadShape; "round"
rot %Rotation; "R0"
stop %Bool; "yes"
thermals %Bool; "yes"
first %Bool; "no"
>
*/
// the DTD says these must be present, throw exception if not found
name = attribs.get<std::string>( "name" );
x = attribs.get<double>( "x" );
y = attribs.get<double>( "y" );
drill = attribs.get<double>( "drill" );
diameter = attribs.get_optional<double>( "diameter" );
opt_string s = attribs.get_optional<std::string>( "shape" );
if( s )
{
// (square | round | octagon | long | offset)
if( !s->compare( "square" ) )
shape = EPAD::SQUARE;
else if( !s->compare( "round" ) )
shape = EPAD::ROUND;
else if( !s->compare( "octagon" ) )
shape = EPAD::OCTAGON;
else if( !s->compare( "long" ) )
shape = EPAD::LONG;
else if( !s->compare( "offset" ) )
shape = EPAD::OFFSET;
}
erot = parseOptionalEROT( attribs );
stop = parseOptionalBool( attribs, "stop" );
thermals = parseOptionalBool( attribs, "thermals" );
first = parseOptionalBool( attribs, "first" );
}
/// Eagle SMD pad /// Eagle SMD pad
struct ESMD struct ESMD
...@@ -243,14 +551,73 @@ struct ESMD ...@@ -243,14 +551,73 @@ struct ESMD
opt_bool stop; opt_bool stop;
opt_bool thermals; opt_bool thermals;
opt_bool cream; opt_bool cream;
ESMD( CPTREE& aSMD );
}; };
ESMD::ESMD( CPTREE& aSMD )
{
CPTREE& attribs = aSMD.get_child( "<xmlattr>" );
/*
<!ATTLIST smd
name %String; #REQUIRED
x %Coord; #REQUIRED
y %Coord; #REQUIRED
dx %Dimension; #REQUIRED
dy %Dimension; #REQUIRED
layer %Layer; #REQUIRED
roundness %Int; "0"
rot %Rotation; "R0"
stop %Bool; "yes"
thermals %Bool; "yes"
cream %Bool; "yes"
>
*/
// the DTD says these must be present, throw exception if not found
name = attribs.get<std::string>( "name" );
x = attribs.get<double>( "x" );
y = attribs.get<double>( "y" );
dx = attribs.get<double>( "dx" );
dy = attribs.get<double>( "dy" );
layer = attribs.get<int>( "layer" );
erot = parseOptionalEROT( attribs );
roundness = attribs.get_optional<int>( "roundness" );
thermals = parseOptionalBool( attribs, "thermals" );
stop = parseOptionalBool( attribs, "stop" );
thermals = parseOptionalBool( attribs, "thermals" );
cream = parseOptionalBool( attribs, "cream" );
}
struct EVERTEX struct EVERTEX
{ {
double x; double x;
double y; double y;
EVERTEX( CPTREE& aVertex );
}; };
EVERTEX::EVERTEX( CPTREE& aVertex )
{
CPTREE& attribs = aVertex.get_child( "<xmlattr>" );
/*
<!ELEMENT vertex EMPTY>
<!ATTLIST vertex
x %Coord; #REQUIRED
y %Coord; #REQUIRED
curve %WireCurve; "0" -- the curvature from this vertex to the next one --
>
*/
x = attribs.get<double>( "x" );
y = attribs.get<double>( "y" );
}
// Eagle polygon, without vertices which are parsed as needed // Eagle polygon, without vertices which are parsed as needed
struct EPOLYGON struct EPOLYGON
{ {
...@@ -269,33 +636,61 @@ struct EPOLYGON ...@@ -269,33 +636,61 @@ struct EPOLYGON
opt_bool orphans; opt_bool orphans;
opt_bool thermals; opt_bool thermals;
opt_int rank; opt_int rank;
};
EPOLYGON( CPTREE& aPolygon );
};
/// Assemble a two part key as a simple concatonation of aFirst and aSecond parts, EPOLYGON::EPOLYGON( CPTREE& aPolygon )
/// using '\x02' as a separator.
static inline std::string makeKey( const std::string& aFirst, const std::string& aSecond )
{ {
std::string key = aFirst + '\x02' + aSecond; CPTREE& attribs = aPolygon.get_child( "<xmlattr>" );
return key;
}
/// Make a unique time stamp, in this case from a unique tree memory location /*
static inline unsigned long timeStamp( CPTREE& aTree ) <!ATTLIST polygon
{ width %Dimension; #REQUIRED
return (unsigned long)(void*) &aTree; layer %Layer; #REQUIRED
spacing %Dimension; #IMPLIED
pour %PolygonPour; "solid"
isolate %Dimension; #IMPLIED -- only in <signal> or <package> context --
orphans %Bool; "no" -- only in <signal> context --
thermals %Bool; "yes" -- only in <signal> context --
rank %Int; "0" -- 1..6 in <signal> context, 0 or 7 in <package> context --
>
*/
width = attribs.get<double>( "width" );
layer = attribs.get<int>( "layer" );
spacing = attribs.get_optional<double>( "spacing" );
opt_string s = attribs.get_optional<std::string>( "pour" );
if( s )
{
// (solid | hatch | cutout)
if( !s->compare( "hatch" ) )
pour = EPOLYGON::HATCH;
else if( !s->compare( "cutout" ) )
pour = EPOLYGON::CUTOUT;
else
pour = EPOLYGON::SOLID;
}
orphans = parseOptionalBool( attribs, "orphans" );
thermals = parseOptionalBool( attribs, "thermals" );
rank = attribs.get_optional<int>( "rank" );
} }
static opt_bool parseOptionalBool( CPTREE& attribs, const char* aName ) /// Assemble a two part key as a simple concatonation of aFirst and aSecond parts,
/// using '\x02' as a separator.
static inline std::string makeKey( const std::string& aFirst, const std::string& aSecond )
{ {
opt_bool ret; std::string key = aFirst + '\x02' + aSecond;
opt_string stemp = attribs.get_optional<std::string>( aName ); return key;
}
if( stemp )
ret = !stemp->compare( "yes" );
return ret; /// Make a unique time stamp, in this case from a unique tree memory location
static inline unsigned long timeStamp( CPTREE& aTree )
{
return (unsigned long)(void*) &aTree;
} }
...@@ -429,7 +824,7 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics, const std::string& aXpath ) ...@@ -429,7 +824,7 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics, const std::string& aXpath )
{ {
if( !gr->first.compare( "wire" ) ) if( !gr->first.compare( "wire" ) )
{ {
EWIRE w = ewire( gr->second ); EWIRE w( gr->second );
DRAWSEGMENT* dseg = new DRAWSEGMENT( m_board ); DRAWSEGMENT* dseg = new DRAWSEGMENT( m_board );
m_board->Add( dseg, ADD_APPEND ); m_board->Add( dseg, ADD_APPEND );
...@@ -442,18 +837,19 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics, const std::string& aXpath ) ...@@ -442,18 +837,19 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics, const std::string& aXpath )
} }
else if( !gr->first.compare( "text" ) ) else if( !gr->first.compare( "text" ) )
{ {
double ratio = 6;
int sign = 1;
#if defined(DEBUG) #if defined(DEBUG)
if( !gr->second.data().compare( "designed by" ) ) if( !gr->second.data().compare( "ATMEGA328" ) )
{ {
int breakhere = 1; int breakhere = 1;
(void) breakhere; (void) breakhere;
} }
#endif #endif
ETEXT t = etext( gr->second ); ETEXT t( gr->second );
int layer = kicad_layer( t.layer );
double ratio = 6;
int sign = 1;
TEXTE_PCB* pcbtxt = new TEXTE_PCB( m_board ); TEXTE_PCB* pcbtxt = new TEXTE_PCB( m_board );
m_board->Add( pcbtxt, ADD_APPEND ); m_board->Add( pcbtxt, ADD_APPEND );
...@@ -461,7 +857,7 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics, const std::string& aXpath ) ...@@ -461,7 +857,7 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics, const std::string& aXpath )
pcbtxt->SetTimeStamp( timeStamp( gr->second ) ); pcbtxt->SetTimeStamp( timeStamp( gr->second ) );
pcbtxt->SetText( FROM_UTF8( t.text.c_str() ) ); pcbtxt->SetText( FROM_UTF8( t.text.c_str() ) );
pcbtxt->SetPosition( wxPoint( kicad_x( t.x ), kicad_y( t.y ) ) ); pcbtxt->SetPosition( wxPoint( kicad_x( t.x ), kicad_y( t.y ) ) );
pcbtxt->SetLayer( kicad_layer( t.layer ) ); pcbtxt->SetLayer( layer );
pcbtxt->SetSize( kicad_fontz( t.size ) ); pcbtxt->SetSize( kicad_fontz( t.size ) );
...@@ -476,7 +872,11 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics, const std::string& aXpath ) ...@@ -476,7 +872,11 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics, const std::string& aXpath )
if( t.erot->spin || t.erot->degrees != 180 ) if( t.erot->spin || t.erot->degrees != 180 )
pcbtxt->SetOrientation( t.erot->degrees * 10 ); pcbtxt->SetOrientation( t.erot->degrees * 10 );
else // 180 degree no spin text, flip the justification to opposite else
// flip the justification to opposite
sign = -1;
if( t.erot->degrees == 270 )
sign = -1; sign = -1;
pcbtxt->SetMirrored( t.erot->mirror ); pcbtxt->SetMirrored( t.erot->mirror );
...@@ -529,7 +929,7 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics, const std::string& aXpath ) ...@@ -529,7 +929,7 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics, const std::string& aXpath )
} }
else if( !gr->first.compare( "circle" ) ) else if( !gr->first.compare( "circle" ) )
{ {
ECIRCLE c = ecircle( gr->second ); ECIRCLE c( gr->second );
DRAWSEGMENT* dseg = new DRAWSEGMENT( m_board ); DRAWSEGMENT* dseg = new DRAWSEGMENT( m_board );
m_board->Add( dseg, ADD_APPEND ); m_board->Add( dseg, ADD_APPEND );
...@@ -546,7 +946,7 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics, const std::string& aXpath ) ...@@ -546,7 +946,7 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics, const std::string& aXpath )
// net related info on it from the DTD. // net related info on it from the DTD.
else if( !gr->first.compare( "rectangle" ) ) else if( !gr->first.compare( "rectangle" ) )
{ {
ERECT r = erect( gr->second ); ERECT r( gr->second );
int layer = kicad_layer( r.layer ); int layer = kicad_layer( r.layer );
if( IsValidCopperLayerIndex( layer ) ) if( IsValidCopperLayerIndex( layer ) )
...@@ -581,616 +981,226 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics, const std::string& aXpath ) ...@@ -581,616 +981,226 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics, const std::string& aXpath )
// picture this // picture this
} }
else if( !gr->first.compare( "polygon" ) ) else if( !gr->first.compare( "polygon" ) )
{ {
// step up, be a man // step up, be a man
} }
} }
} }
void EAGLE_PLUGIN::loadLibraries( CPTREE& aLibs, const std::string& aXpath )
{
for( CITER library = aLibs.begin(); library != aLibs.end(); ++library )
{
const std::string& lib_name = library->second.get<std::string>( "<xmlattr>.name" );
// library will have <xmlattr> node, skip that and get the packages node
CPTREE& packages = library->second.get_child( "packages" );
// Create a MODULE for all the eagle packages, for use later via a copy constructor
// to instantiate needed MODULES in our BOARD. Save the MODULE templates in
// a MODULE_MAP using a single lookup key consisting of libname+pkgname.
for( CITER package = packages.begin(); package != packages.end(); ++package )
{
const std::string& pack_name = package->second.get<std::string>( "<xmlattr>.name" );
#if defined(DEBUG)
if( !pack_name.compare( "TO220H" ) )
{
int breakhere = 1;
(void) breakhere;
}
#endif
std::string key = makeKey( lib_name, pack_name );
MODULE* m = makeModule( package->second, pack_name );
// add the templating MODULE to the MODULE template factory "m_templates"
std::pair<MODULE_ITER, bool> r = m_templates.insert( key, m );
if( !r.second )
{
wxString lib = FROM_UTF8( lib_name.c_str() );
wxString pkg = FROM_UTF8( pack_name.c_str() );
wxString emsg = wxString::Format(
_( "<package> name:'%s' duplicated in eagle <library>:'%s'" ),
GetChars( pkg ),
GetChars( lib )
);
THROW_IO_ERROR( emsg );
}
}
}
}
void EAGLE_PLUGIN::loadElements( CPTREE& aElements, const std::string& aXpath )
{
for( CITER it = aElements.begin(); it != aElements.end(); ++it )
{
if( it->first.compare( "element" ) )
continue;
CPTREE& attrs = it->second.get_child( "<xmlattr>" );
/*
a '*' means zero or more times
<!ELEMENT element (attribute*, variant*)>
<!ATTLIST element
name %String; #REQUIRED
library %String; #REQUIRED
package %String; #REQUIRED
value %String; #REQUIRED
x %Coord; #REQUIRED
y %Coord; #REQUIRED
locked %Bool; "no"
smashed %Bool; "no"
rot %Rotation; "R0"
>
*/
std::string name = attrs.get<std::string>( "name" );
std::string library = attrs.get<std::string>( "library" );
std::string package = attrs.get<std::string>( "package" );
std::string value = attrs.get<std::string>( "value" );
#if 1 && defined(DEBUG)
if( !name.compare( "GROUND" ) )
{
int breakhere = 1;
(void) breakhere;
}
#endif
double x = attrs.get<double>( "x" );
double y = attrs.get<double>( "y" );
opt_string rot = attrs.get_optional<std::string>( "rot" );
std::string key = makeKey( library, package );
MODULE_CITER mi = m_templates.find( key );
if( mi == m_templates.end() )
{
wxString emsg = wxString::Format( _( "No '%s' package in library '%s'" ),
GetChars( FROM_UTF8( package.c_str() ) ),
GetChars( FROM_UTF8( library.c_str() ) ) );
THROW_IO_ERROR( emsg );
}
#if defined(DEBUG)
if( !name.compare( "IC3" ) )
{
int breakhere = 1;
(void) breakhere;
}
#endif
// copy constructor to clone the template
MODULE* m = new MODULE( *mi->second );
m_board->Add( m, ADD_APPEND );
for( D_PAD* pad = m->m_Pads; pad; pad = pad->Next() )
{
std::string key = makeKey( name, TO_UTF8( pad->GetPadName() ) );
NET_MAP_CITER ni = m_pads_to_nets.find( key );
if( ni != m_pads_to_nets.end() )
{
pad->SetNetname( FROM_UTF8( ni->second.netname.c_str() ) );
pad->SetNet( ni->second.netcode );
}
}
m->SetPosition( wxPoint( kicad_x( x ), kicad_y( y ) ) );
m->SetReference( FROM_UTF8( name.c_str() ) );
m->SetValue( FROM_UTF8( value.c_str() ) );
// m->Value().SetVisible( false );
if( rot )
{
EROT r = erot( *rot );
m->SetOrientation( r.degrees * 10 );
if( r.mirror )
{
m->Flip( m->GetPosition() );
}
}
// VALUE and NAME can have something like our text "effects" overrides
// in SWEET and new schematic. Eagle calls these XML elements "attribute".
// There can be one for NAME and/or VALUE both.
CA_ITER_RANGE attributes = it->second.equal_range( "attribute" );
for( CA_ITER ait = attributes.first; ait != attributes.second; ++ait )
{
double ratio = 6;
EATTR a = eattr( ait->second );
TEXTE_MODULE* txt;
if( !a.name.compare( "NAME" ) )
txt = &m->Reference();
else // "VALUE" or else our understanding of file format is incomplete.
txt = &m->Value();
if( a.value )
{
txt->SetText( FROM_UTF8( a.value->c_str() ) );
}
if( a.x && a.y ) // boost::optional
{
wxPoint pos( kicad_x( *a.x ), kicad_y( *a.y ) );
wxPoint pos0 = pos - m->GetPosition();
txt->SetPosition( pos );
txt->SetPos0( pos0 );
}
if( a.ratio )
ratio = *a.ratio;
if( a.size )
{
wxSize fontz = kicad_fontz( *a.size );
txt->SetSize( fontz );
int lw = int( fontz.y * ratio / 100.0 );
txt->SetThickness( lw );
}
if( a.erot )
{
double angle = a.erot->degrees * 10;
if( angle != 1800 )
{
angle -= m->GetOrientation(); // subtract module's angle
txt->SetOrientation( angle );
}
else
{
txt->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
txt->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
}
}
}
}
}
EWIRE EAGLE_PLUGIN::ewire( CPTREE& aWire ) const
{
EWIRE w;
CPTREE& attribs = aWire.get_child( "<xmlattr>" );
w.x1 = attribs.get<double>( "x1" );
w.y1 = attribs.get<double>( "y1" );
w.x2 = attribs.get<double>( "x2" );
w.y2 = attribs.get<double>( "y2" );
w.width = attribs.get<double>( "width" );
w.layer = attribs.get<int>( "layer" );
return w;
}
EVIA EAGLE_PLUGIN::evia( CPTREE& aVia ) const
{
EVIA v;
CPTREE& attribs = aVia.get_child( "<xmlattr>" );
/*
<!ELEMENT via EMPTY>
<!ATTLIST via
x %Coord; #REQUIRED
y %Coord; #REQUIRED
extent %Extent; #REQUIRED
drill %Dimension; #REQUIRED
diameter %Dimension; "0"
shape %ViaShape; "round"
alwaysstop %Bool; "no"
>
*/
v.x = attribs.get<double>( "x" );
v.y = attribs.get<double>( "y" );
std::string ext = attribs.get<std::string>( "extent" );
sscanf( ext.c_str(), "%u-%u", &v.layer_start, &v.layer_end );
v.drill = attribs.get<double>( "drill" );
v.diam = attribs.get_optional<double>( "diameter" );
v.shape = attribs.get_optional<std::string>( "shape" );
return v;
}
ECIRCLE EAGLE_PLUGIN::ecircle( CPTREE& aCircle ) const
{
ECIRCLE c;
CPTREE& attribs = aCircle.get_child( "<xmlattr>" );
c.x = attribs.get<double>( "x" );
c.y = attribs.get<double>( "y" );
c.radius = attribs.get<double>( "radius" );
c.width = attribs.get<double>( "width" );
c.layer = attribs.get<int>( "layer" );
return c;
}
ERECT EAGLE_PLUGIN::erect( CPTREE& aRect ) const
{
ERECT r;
CPTREE& attribs = aRect.get_child( "<xmlattr>" );
/*
<!ELEMENT rectangle EMPTY>
<!ATTLIST rectangle
x1 %Coord; #REQUIRED
y1 %Coord; #REQUIRED
x2 %Coord; #REQUIRED
y2 %Coord; #REQUIRED
layer %Layer; #REQUIRED
rot %Rotation; "R0"
>
*/
r.x1 = attribs.get<double>( "x1" );
r.y1 = attribs.get<double>( "y1" );
r.x2 = attribs.get<double>( "x2" );
r.y2 = attribs.get<double>( "y2" );
r.layer = attribs.get<int>( "layer" );
// @todo: stop hoping that rot is not used
return r;
}
ETEXT EAGLE_PLUGIN::etext( CPTREE& aText ) const
{
ETEXT t;
CPTREE& attribs = aText.get_child( "<xmlattr>" );
/*
<!ELEMENT text (#PCDATA)>
<!ATTLIST text
x %Coord; #REQUIRED
y %Coord; #REQUIRED
size %Dimension; #REQUIRED
layer %Layer; #REQUIRED
font %TextFont; "proportional"
ratio %Int; "8"
rot %Rotation; "R0"
align %Align; "bottom-left"
>
*/
t.text = aText.data();
t.x = attribs.get<double>( "x" );
t.y = attribs.get<double>( "y" );
t.size = attribs.get<double>( "size" );
t.layer = attribs.get<int>( "layer" );
t.font = attribs.get_optional<std::string>( "font" );
t.ratio = attribs.get_optional<double>( "ratio" );
opt_string rot = attribs.get_optional<std::string>( "rot" );
if( rot )
{
t.erot = erot( *rot );
}
opt_string align = attribs.get_optional<std::string>( "align" );
if( align )
{
// (bottom-left | bottom-center | bottom-right | center-left |
// center | center-right | top-left | top-center | top-right)
if( !align->compare( "center" ) )
*t.align = ETEXT::CENTER;
else if( !align->compare( "center-right" ) )
*t.align = ETEXT::CENTER_RIGHT;
else if( !align->compare( "top-left" ) )
*t.align = ETEXT::TOP_LEFT;
else if( !align->compare( "top-center" ) )
*t.align = ETEXT::TOP_CENTER;
else if( !align->compare( "top-right" ) )
*t.align = ETEXT::TOP_RIGHT;
else if( !align->compare( "bottom-left" ) )
*t.align = ETEXT::BOTTOM_LEFT;
else if( !align->compare( "bottom-center" ) )
*t.align = ETEXT::BOTTOM_CENTER;
else if( !align->compare( "bottom-right" ) )
*t.align = ETEXT::BOTTOM_RIGHT;
else if( !align->compare( "center-left" ) )
*t.align = ETEXT::CENTER_LEFT;
}
return t;
}
EROT EAGLE_PLUGIN::erot( const std::string& aRot ) const
{
EROT rot;
rot.spin = aRot.find( 'S' ) != aRot.npos;
rot.mirror = aRot.find( 'M' ) != aRot.npos;
rot.degrees = strtod( aRot.c_str()
+ 1 // skip leading 'R'
+ int( rot.spin ) // skip optional leading 'S'
+ int( rot.mirror ), // skip optional leading 'M'
NULL );
return rot;
}
EATTR EAGLE_PLUGIN::eattr( CPTREE& aAttribute ) const
{
EATTR a;
CPTREE& attribs = aAttribute.get_child( "<xmlattr>" );
/*
<!ELEMENT attribute EMPTY>
<!ATTLIST attribute
name %String; #REQUIRED
value %String; #IMPLIED
x %Coord; #IMPLIED
y %Coord; #IMPLIED
size %Dimension; #IMPLIED
layer %Layer; #IMPLIED
font %TextFont; #IMPLIED
ratio %Int; #IMPLIED
rot %Rotation; "R0"
display %AttributeDisplay; "value" -- only in <element> or <instance> context --
constant %Bool; "no" -- only in <device> context --
>
*/
a.name = attribs.get<std::string>( "name" ); // #REQUIRED
a.value = attribs.get_optional<std::string>( "value" );
a.x = attribs.get_optional<double>( "x" ); void EAGLE_PLUGIN::loadLibraries( CPTREE& aLibs, const std::string& aXpath )
a.y = attribs.get_optional<double>( "y" ); {
for( CITER library = aLibs.begin(); library != aLibs.end(); ++library )
{
const std::string& lib_name = library->second.get<std::string>( "<xmlattr>.name" );
// KiCad cannot currently put a TEXTE_MODULE on a different layer than the MODULE // library will have <xmlattr> node, skip that and get the packages node
// Eagle can it seems. Skip layer. CPTREE& packages = library->second.get_child( "packages" );
a.size = attribs.get_optional<double>( "size" ); // Create a MODULE for all the eagle packages, for use later via a copy constructor
a.ratio = attribs.get_optional<double>( "ratio" ); // to instantiate needed MODULES in our BOARD. Save the MODULE templates in
// a MODULE_MAP using a single lookup key consisting of libname+pkgname.
opt_string rot = attribs.get_optional<std::string>( "rot" ); for( CITER package = packages.begin(); package != packages.end(); ++package )
if( rot )
{ {
a.erot = erot( *rot ); const std::string& pack_name = package->second.get<std::string>( "<xmlattr>.name" );
}
opt_string display = attribs.get_optional<std::string>( "display" ); #if defined(DEBUG)
if( display ) if( !pack_name.compare( "TO220H" ) )
{ {
// (off | value | name | both) int breakhere = 1;
if( !display->compare( "off" ) ) (void) breakhere;
a.display = EATTR::Off;
else if( !display->compare( "value" ) )
a.display = EATTR::VALUE;
else if( !display->compare( "name" ) )
a.display = EATTR::NAME;
else if( !display->compare( "both" ) )
a.display = EATTR::BOTH;
} }
#endif
std::string key = makeKey( lib_name, pack_name );
MODULE* m = makeModule( package->second, pack_name );
// add the templating MODULE to the MODULE template factory "m_templates"
std::pair<MODULE_ITER, bool> r = m_templates.insert( key, m );
return a; if( !r.second )
{
wxString lib = FROM_UTF8( lib_name.c_str() );
wxString pkg = FROM_UTF8( pack_name.c_str() );
wxString emsg = wxString::Format(
_( "<package> name:'%s' duplicated in eagle <library>:'%s'" ),
GetChars( pkg ),
GetChars( lib )
);
THROW_IO_ERROR( emsg );
}
}
}
} }
EPAD EAGLE_PLUGIN::epad( CPTREE& aPad ) const void EAGLE_PLUGIN::loadElements( CPTREE& aElements, const std::string& aXpath )
{ {
EPAD p; for( CITER it = aElements.begin(); it != aElements.end(); ++it )
CPTREE& attribs = aPad.get_child( "<xmlattr>" ); {
if( it->first.compare( "element" ) )
continue;
CPTREE& attrs = it->second.get_child( "<xmlattr>" );
/* /*
<!ELEMENT pad EMPTY>
<!ATTLIST pad a '*' means zero or more times
<!ELEMENT element (attribute*, variant*)>
<!ATTLIST element
name %String; #REQUIRED name %String; #REQUIRED
library %String; #REQUIRED
package %String; #REQUIRED
value %String; #REQUIRED
x %Coord; #REQUIRED x %Coord; #REQUIRED
y %Coord; #REQUIRED y %Coord; #REQUIRED
drill %Dimension; #REQUIRED locked %Bool; "no"
diameter %Dimension; "0" smashed %Bool; "no"
shape %PadShape; "round"
rot %Rotation; "R0" rot %Rotation; "R0"
stop %Bool; "yes"
thermals %Bool; "yes"
first %Bool; "no"
> >
*/ */
// the DTD says these must be present, throw exception if not found std::string name = attrs.get<std::string>( "name" );
p.name = attribs.get<std::string>( "name" ); std::string library = attrs.get<std::string>( "library" );
p.x = attribs.get<double>( "x" ); std::string package = attrs.get<std::string>( "package" );
p.y = attribs.get<double>( "y" ); std::string value = attrs.get<std::string>( "value" );
p.drill = attribs.get<double>( "drill" );
p.diameter = attribs.get_optional<double>( "diameter" );
opt_string s = attribs.get_optional<std::string>( "shape" ); #if 1 && defined(DEBUG)
if( s ) if( !name.compare( "GROUND" ) )
{ {
// (square | round | octagon | long | offset) int breakhere = 1;
if( !s->compare( "square" ) ) (void) breakhere;
p.shape = EPAD::SQUARE;
else if( !s->compare( "round" ) )
p.shape = EPAD::ROUND;
else if( !s->compare( "octagon" ) )
p.shape = EPAD::OCTAGON;
else if( !s->compare( "long" ) )
p.shape = EPAD::LONG;
else if( !s->compare( "offset" ) )
p.shape = EPAD::OFFSET;
} }
#endif
double x = attrs.get<double>( "x" );
double y = attrs.get<double>( "y" );
opt_erot erot = parseOptionalEROT( attrs );
std::string key = makeKey( library, package );
MODULE_CITER mi = m_templates.find( key );
opt_string rot = attribs.get_optional<std::string>( "rot" ); if( mi == m_templates.end() )
if( rot )
{ {
p.erot = erot( *rot ); wxString emsg = wxString::Format( _( "No '%s' package in library '%s'" ),
GetChars( FROM_UTF8( package.c_str() ) ),
GetChars( FROM_UTF8( library.c_str() ) ) );
THROW_IO_ERROR( emsg );
} }
p.stop = parseOptionalBool( attribs, "stop" ); #if defined(DEBUG)
p.thermals = parseOptionalBool( attribs, "thermals" ); if( !name.compare( "ATMEGA328" ) )
p.first = parseOptionalBool( attribs, "first" ); {
int breakhere = 1;
(void) breakhere;
}
#endif
return p; // copy constructor to clone the template
} MODULE* m = new MODULE( *mi->second );
m_board->Add( m, ADD_APPEND );
// update the nets within the pads of the clone
for( D_PAD* pad = m->m_Pads; pad; pad = pad->Next() )
{
std::string key = makeKey( name, TO_UTF8( pad->GetPadName() ) );
ESMD EAGLE_PLUGIN::esmd( CPTREE& aSMD ) const NET_MAP_CITER ni = m_pads_to_nets.find( key );
{ if( ni != m_pads_to_nets.end() )
ESMD s; {
CPTREE& attribs = aSMD.get_child( "<xmlattr>" ); pad->SetNetname( FROM_UTF8( ni->second.netname.c_str() ) );
pad->SetNet( ni->second.netcode );
}
}
/* m->SetPosition( wxPoint( kicad_x( x ), kicad_y( y ) ) );
<!ATTLIST smd m->SetReference( FROM_UTF8( name.c_str() ) );
name %String; #REQUIRED m->SetValue( FROM_UTF8( value.c_str() ) );
x %Coord; #REQUIRED // m->Value().SetVisible( false );
y %Coord; #REQUIRED
dx %Dimension; #REQUIRED
dy %Dimension; #REQUIRED
layer %Layer; #REQUIRED
roundness %Int; "0"
rot %Rotation; "R0"
stop %Bool; "yes"
thermals %Bool; "yes"
cream %Bool; "yes"
>
*/
// the DTD says these must be present, throw exception if not found if( erot )
s.name = attribs.get<std::string>( "name" ); {
s.x = attribs.get<double>( "x" ); m->SetOrientation( erot->degrees * 10 );
s.y = attribs.get<double>( "y" );
s.dx = attribs.get<double>( "dx" );
s.dy = attribs.get<double>( "dy" );
s.layer = attribs.get<int>( "layer" );
opt_string rot = attribs.get_optional<std::string>( "rot" ); if( erot->mirror )
if( rot )
{ {
s.erot = erot( *rot ); m->Flip( m->GetPosition() );
}
} }
s.roundness = attribs.get_optional<int>( "roundness" ); // VALUE and NAME can have something like our text "effects" overrides
s.thermals = parseOptionalBool( attribs, "thermals" ); // in SWEET and new schematic. Eagle calls these XML elements "attribute".
s.stop = parseOptionalBool( attribs, "stop" ); // There can be one for NAME and/or VALUE both.
s.thermals = parseOptionalBool( attribs, "thermals" ); for( CITER ait = it->second.begin(); ait != it->second.end(); ++ait )
s.cream = parseOptionalBool( attribs, "cream" ); {
if( ait->first.compare( "attribute" ) )
continue;
return s; double ratio = 6;
} EATTR a( ait->second );
TEXTE_MODULE* txt;
EVERTEX EAGLE_PLUGIN::evertex( CPTREE& aVertex ) const if( !a.name.compare( "NAME" ) )
{ txt = &m->Reference();
EVERTEX v; else if( !a.name.compare( "VALUE" ) )
CPTREE& attribs = aVertex.get_child( "<xmlattr>" ); txt = &m->Value();
else
{
// our understanding of file format is incomplete?
return;
}
/* if( a.value )
<!ELEMENT vertex EMPTY> {
<!ATTLIST vertex txt->SetText( FROM_UTF8( a.value->c_str() ) );
x %Coord; #REQUIRED }
y %Coord; #REQUIRED
curve %WireCurve; "0" -- the curvature from this vertex to the next one --
>
*/
v.x = attribs.get<double>( "x" ); if( a.x && a.y ) // boost::optional
v.y = attribs.get<double>( "y" ); {
wxPoint pos( kicad_x( *a.x ), kicad_y( *a.y ) );
wxPoint pos0 = pos - m->GetPosition();
return v; txt->SetPosition( pos );
} txt->SetPos0( pos0 );
}
if( a.ratio )
ratio = *a.ratio;
EPOLYGON EAGLE_PLUGIN::epolygon( CPTREE& aPolygon ) const if( a.size )
{ {
EPOLYGON p; wxSize fontz = kicad_fontz( *a.size );
CPTREE& attribs = aPolygon.get_child( "<xmlattr>" ); txt->SetSize( fontz );
/* int lw = int( fontz.y * ratio / 100.0 );
<!ATTLIST polygon txt->SetThickness( lw );
width %Dimension; #REQUIRED }
layer %Layer; #REQUIRED
spacing %Dimension; #IMPLIED
pour %PolygonPour; "solid"
isolate %Dimension; #IMPLIED -- only in <signal> or <package> context --
orphans %Bool; "no" -- only in <signal> context --
thermals %Bool; "yes" -- only in <signal> context --
rank %Int; "0" -- 1..6 in <signal> context, 0 or 7 in <package> context --
>
*/
p.width = attribs.get<double>( "width" ); double angle = 0;
p.layer = attribs.get<int>( "layer" ); if( a.erot )
p.spacing = attribs.get_optional<double>( "spacing" ); angle = a.erot->degrees * 10;
opt_string s = attribs.get_optional<std::string>( "pour" ); if( angle != 1800 )
if( s )
{ {
// (solid | hatch | cutout) angle -= m->GetOrientation(); // subtract module's angle
if( !s->compare( "hatch" ) ) txt->SetOrientation( angle );
p.pour = EPOLYGON::HATCH; }
else if( !s->compare( "cutout" ) )
p.pour = EPOLYGON::CUTOUT;
else else
p.pour = EPOLYGON::SOLID; {
txt->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
txt->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
}
}
} }
p.orphans = parseOptionalBool( attribs, "orphans" );
p.thermals = parseOptionalBool( attribs, "thermals" );
p.rank = attribs.get_optional<int>( "rank" );
return p;
} }
MODULE* EAGLE_PLUGIN::makeModule( CPTREE& aPackage, const std::string& aPkgName ) const MODULE* EAGLE_PLUGIN::makeModule( CPTREE& aPackage, const std::string& aPkgName ) const
{ {
std::auto_ptr<MODULE> m( new MODULE( NULL ) ); std::auto_ptr<MODULE> m( new MODULE( NULL ) );
...@@ -1236,7 +1246,7 @@ MODULE* EAGLE_PLUGIN::makeModule( CPTREE& aPackage, const std::string& aPkgName ...@@ -1236,7 +1246,7 @@ MODULE* EAGLE_PLUGIN::makeModule( CPTREE& aPackage, const std::string& aPkgName
void EAGLE_PLUGIN::packageWire( MODULE* aModule, CPTREE& aTree ) const void EAGLE_PLUGIN::packageWire( MODULE* aModule, CPTREE& aTree ) const
{ {
EWIRE w = ewire( aTree ); EWIRE w( aTree );
int layer = kicad_layer( w.layer ); int layer = kicad_layer( w.layer );
if( IsValidNonCopperLayerIndex( layer ) ) // skip copper package wires if( IsValidNonCopperLayerIndex( layer ) ) // skip copper package wires
...@@ -1250,6 +1260,13 @@ void EAGLE_PLUGIN::packageWire( MODULE* aModule, CPTREE& aTree ) const ...@@ -1250,6 +1260,13 @@ void EAGLE_PLUGIN::packageWire( MODULE* aModule, CPTREE& aTree ) const
dwg->SetStart0( start ); dwg->SetStart0( start );
dwg->SetEnd0( end ); dwg->SetEnd0( end );
switch( layer )
{
case ECO1_N: layer = SILKSCREEN_N_FRONT; break;
case ECO2_N: layer = SILKSCREEN_N_BACK; break;
}
dwg->SetLayer( layer ); dwg->SetLayer( layer );
dwg->SetWidth( width ); dwg->SetWidth( width );
} }
...@@ -1259,7 +1276,7 @@ void EAGLE_PLUGIN::packageWire( MODULE* aModule, CPTREE& aTree ) const ...@@ -1259,7 +1276,7 @@ void EAGLE_PLUGIN::packageWire( MODULE* aModule, CPTREE& aTree ) const
void EAGLE_PLUGIN::packagePad( MODULE* aModule, CPTREE& aTree ) const void EAGLE_PLUGIN::packagePad( MODULE* aModule, CPTREE& aTree ) const
{ {
// this is thru hole technology here, no SMDs // this is thru hole technology here, no SMDs
EPAD e = epad( aTree ); EPAD e( aTree );
/* from <ealge>/doc/eagle.dtd /* from <ealge>/doc/eagle.dtd
<!ELEMENT pad EMPTY> <!ELEMENT pad EMPTY>
...@@ -1304,8 +1321,8 @@ void EAGLE_PLUGIN::packagePad( MODULE* aModule, CPTREE& aTree ) const ...@@ -1304,8 +1321,8 @@ void EAGLE_PLUGIN::packagePad( MODULE* aModule, CPTREE& aTree ) const
} }
else else
{ {
// the pad size is optional in the eagle DTD, supply something here that is a // The pad size is optional in the eagle DTD, supply something here that is a
// 6 mil copper surround as a minimum. // 6 mil copper surround as a minimum, otherwise 120% of drillz.
int drillz = pad->GetDrillSize().x; int drillz = pad->GetDrillSize().x;
int diameter = std::max( drillz + 2 * Mils2iu( 6 ), int( drillz * 1.2 ) ); int diameter = std::max( drillz + 2 * Mils2iu( 6 ), int( drillz * 1.2 ) );
pad->SetSize( wxSize( diameter, diameter ) ); pad->SetSize( wxSize( diameter, diameter ) );
...@@ -1352,16 +1369,20 @@ void EAGLE_PLUGIN::packageText( MODULE* aModule, CPTREE& aTree ) const ...@@ -1352,16 +1369,20 @@ void EAGLE_PLUGIN::packageText( MODULE* aModule, CPTREE& aTree ) const
{ {
int sign = 1; int sign = 1;
double ratio = 6; double ratio = 6;
ETEXT t = etext( aTree ); ETEXT t( aTree );
int layer = kicad_layer( t.layer );
TEXTE_MODULE* txt; TEXTE_MODULE* txt;
if( !t.text.compare( ">NAME" ) ) if( !t.text.compare( ">NAME" ) || !t.text.compare( ">name" ) )
txt = &aModule->Reference(); txt = &aModule->Reference();
else if( !t.text.compare( ">VALUE" ) ) else if( !t.text.compare( ">VALUE" ) || !t.text.compare( ">value" ) )
txt = &aModule->Value(); txt = &aModule->Value();
else else
return; {
txt = new TEXTE_MODULE( aModule );
aModule->m_Drawings.PushBack( txt );
}
txt->SetTimeStamp( timeStamp( aTree ) ); txt->SetTimeStamp( timeStamp( aTree ) );
txt->SetText( FROM_UTF8( t.text.c_str() ) ); txt->SetText( FROM_UTF8( t.text.c_str() ) );
...@@ -1371,7 +1392,13 @@ void EAGLE_PLUGIN::packageText( MODULE* aModule, CPTREE& aTree ) const ...@@ -1371,7 +1392,13 @@ void EAGLE_PLUGIN::packageText( MODULE* aModule, CPTREE& aTree ) const
txt->SetPosition( pos ); txt->SetPosition( pos );
txt->SetPos0( pos - aModule->GetPosition() ); txt->SetPos0( pos - aModule->GetPosition() );
txt->SetLayer( kicad_layer( t.layer ) ); switch( layer )
{
case ECO1_N: layer = SILKSCREEN_N_FRONT; break;
case ECO2_N: layer = SILKSCREEN_N_BACK; break;
}
txt->SetLayer( layer );
txt->SetSize( kicad_fontz( t.size ) ); txt->SetSize( kicad_fontz( t.size ) );
...@@ -1442,9 +1469,9 @@ void EAGLE_PLUGIN::packageText( MODULE* aModule, CPTREE& aTree ) const ...@@ -1442,9 +1469,9 @@ void EAGLE_PLUGIN::packageText( MODULE* aModule, CPTREE& aTree ) const
void EAGLE_PLUGIN::packageRectangle( MODULE* aModule, CPTREE& aTree ) const void EAGLE_PLUGIN::packageRectangle( MODULE* aModule, CPTREE& aTree ) const
{ {
/* ERECT r( aTree );
ERECT r = erect( aTree );
*/
} }
...@@ -1456,7 +1483,25 @@ void EAGLE_PLUGIN::packagePolygon( MODULE* aModule, CPTREE& aTree ) const ...@@ -1456,7 +1483,25 @@ void EAGLE_PLUGIN::packagePolygon( MODULE* aModule, CPTREE& aTree ) const
void EAGLE_PLUGIN::packageCircle( MODULE* aModule, CPTREE& aTree ) const void EAGLE_PLUGIN::packageCircle( MODULE* aModule, CPTREE& aTree ) const
{ {
// CPTREE& attrs = aTree.get_child( "<xmlattr>" ); ECIRCLE e( aTree );
int layer = kicad_layer( e.layer );
EDGE_MODULE* gr = new EDGE_MODULE( aModule, S_CIRCLE );
aModule->m_Drawings.PushBack( gr );
gr->SetWidth( kicad( e.width ) );
switch( layer )
{
case ECO1_N: layer = SILKSCREEN_N_FRONT; break;
case ECO2_N: layer = SILKSCREEN_N_BACK; break;
}
gr->SetLayer( layer );
gr->SetTimeStamp( timeStamp( aTree ) );
gr->SetStart0( wxPoint( kicad_x( e.x ), kicad_y( e.y ) ) );
gr->SetEnd0( wxPoint( kicad_x( e.x + e.radius ), kicad_y( e.y ) ) );
} }
...@@ -1468,7 +1513,7 @@ void EAGLE_PLUGIN::packageHole( MODULE* aModule, CPTREE& aTree ) const ...@@ -1468,7 +1513,7 @@ void EAGLE_PLUGIN::packageHole( MODULE* aModule, CPTREE& aTree ) const
void EAGLE_PLUGIN::packageSMD( MODULE* aModule, CPTREE& aTree ) const void EAGLE_PLUGIN::packageSMD( MODULE* aModule, CPTREE& aTree ) const
{ {
ESMD e = esmd( aTree ); ESMD e( aTree );
int layer = kicad_layer( e.layer ); int layer = kicad_layer( e.layer );
if( !IsValidCopperLayerIndex( layer ) ) if( !IsValidCopperLayerIndex( layer ) )
...@@ -1536,7 +1581,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals, const std::string& aXpath ) ...@@ -1536,7 +1581,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals, const std::string& aXpath )
{ {
if( !it->first.compare( "wire" ) ) if( !it->first.compare( "wire" ) )
{ {
EWIRE w = ewire( it->second ); EWIRE w( it->second );
int layer = kicad_layer( w.layer ); int layer = kicad_layer( w.layer );
if( IsValidCopperLayerIndex( layer ) ) if( IsValidCopperLayerIndex( layer ) )
...@@ -1562,7 +1607,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals, const std::string& aXpath ) ...@@ -1562,7 +1607,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals, const std::string& aXpath )
else if( !it->first.compare( "via" ) ) else if( !it->first.compare( "via" ) )
{ {
EVIA v = evia( it->second ); EVIA v( it->second );
int layer_start = kicad_layer( v.layer_start ); int layer_start = kicad_layer( v.layer_start );
int layer_end = kicad_layer( v.layer_end ); int layer_end = kicad_layer( v.layer_end );
...@@ -1570,9 +1615,9 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals, const std::string& aXpath ) ...@@ -1570,9 +1615,9 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals, const std::string& aXpath )
if( IsValidCopperLayerIndex( layer_start ) && if( IsValidCopperLayerIndex( layer_start ) &&
IsValidCopperLayerIndex( layer_end ) ) IsValidCopperLayerIndex( layer_end ) )
{ {
int drill = kicad( v.drill ); int drillz = kicad( v.drill );
SEGVIA* via = new SEGVIA( m_board ); SEGVIA* via = new SEGVIA( m_board );
m_board->m_Track.Insert( via, NULL );
via->SetLayerPair( layer_start, layer_end ); via->SetLayerPair( layer_start, layer_end );
...@@ -1584,9 +1629,12 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals, const std::string& aXpath ) ...@@ -1584,9 +1629,12 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals, const std::string& aXpath )
via->SetWidth( kidiam ); via->SetWidth( kidiam );
} }
else else
via->SetWidth( drill * 3 ); {
int diameter = std::max( drillz + 2 * Mils2iu( 6 ), int( drillz * 2.0 ) );
via->SetWidth( diameter );
}
via->SetDrill( drill ); via->SetDrill( drillz );
via->SetTimeStamp( timeStamp( it->second ) ); via->SetTimeStamp( timeStamp( it->second ) );
...@@ -1598,8 +1646,6 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals, const std::string& aXpath ) ...@@ -1598,8 +1646,6 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals, const std::string& aXpath )
via->SetNet( netCode ); via->SetNet( netCode );
via->SetShape( S_CIRCLE ); // @todo should be in SEGVIA constructor via->SetShape( S_CIRCLE ); // @todo should be in SEGVIA constructor
m_board->m_Track.Insert( via, NULL );
} }
} }
...@@ -1620,7 +1666,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals, const std::string& aXpath ) ...@@ -1620,7 +1666,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals, const std::string& aXpath )
else if( !it->first.compare( "polygon" ) ) else if( !it->first.compare( "polygon" ) )
{ {
EPOLYGON p = epolygon( it->second ); EPOLYGON p( it->second );
int layer = kicad_layer( p.layer ); int layer = kicad_layer( p.layer );
if( IsValidCopperLayerIndex( layer ) ) if( IsValidCopperLayerIndex( layer ) )
...@@ -1644,7 +1690,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals, const std::string& aXpath ) ...@@ -1644,7 +1690,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals, const std::string& aXpath )
if( vi->first.compare( "vertex" ) ) // skip <xmlattr> node if( vi->first.compare( "vertex" ) ) // skip <xmlattr> node
continue; continue;
EVERTEX v = evertex( vi->second ); EVERTEX v( vi->second );
// the ZONE_CONTAINER API needs work, as you can see: // the ZONE_CONTAINER API needs work, as you can see:
if( first ) if( first )
......
...@@ -75,18 +75,6 @@ namespace boost { ...@@ -75,18 +75,6 @@ namespace boost {
typedef boost::property_tree::ptree PTREE; typedef boost::property_tree::ptree PTREE;
typedef const PTREE CPTREE; typedef const PTREE CPTREE;
struct EWIRE;
struct EVIA;
struct EROT;
struct EATTR;
struct ECIRCLE;
struct ETEXT;
struct ERECT;
struct EPAD;
struct ESMD;
struct EVERTEX;
struct EPOLYGON;
/** /**
* Class EAGLE_PLUGIN * Class EAGLE_PLUGIN
* works with Eagle 6.x XML board files and footprints. * works with Eagle 6.x XML board files and footprints.
...@@ -194,35 +182,6 @@ private: ...@@ -194,35 +182,6 @@ private:
void loadElements( CPTREE& aElements, const std::string& aXpath ); void loadElements( CPTREE& aElements, const std::string& aXpath );
// none of the 'e'funcs do any "to KiCad" conversion, they merely read the XML into binary:
/**
* Function ewire
* converts a <wire>'s xml attributes to binary without additional conversion.
* @param aResult is an EWIRE to fill in with the <wire> data converted to binary.
*/
EWIRE ewire( CPTREE& aWire ) const;
EVIA evia( CPTREE& aVia ) const;
ECIRCLE ecircle( CPTREE& aCircle ) const;
ETEXT etext( CPTREE& aText ) const;
ERECT erect( CPTREE& aRect ) const;
EROT erot( const std::string& aRot ) const;
EPAD epad( CPTREE& aPad ) const;
ESMD esmd( CPTREE& aSMD ) const;
EVERTEX evertex( CPTREE& aVertex ) const;
EPOLYGON epolygon( CPTREE& aPolygon ) const;
/**
* Function eattr
* parses an Eagle "attribute" element. Note that an attribute element
* is different than an XML element attribute. The attribute element is a
* full XML node in and of itself, and has attributes of its own. Blame Eagle.
*/
EATTR eattr( CPTREE& aAttribute ) const;
/** /**
* Function fmtDEG * Function fmtDEG
* formats an angle in a way particular to a board file format. This function * formats an angle in a way particular to a board file format. This function
......
...@@ -174,7 +174,7 @@ the changes?" ) ) ) ...@@ -174,7 +174,7 @@ the changes?" ) ) )
// This is a subset of all PLUGINs which are trusted to be able to // This is a subset of all PLUGINs which are trusted to be able to
// load a BOARD. Order is subject to change as KICAD plugin matures. // load a BOARD. Order is subject to change as KICAD plugin matures.
// User may occasionally use the wrong pluging to load a *.brd file, // User may occasionally use the wrong plugin to load a *.brd file,
// but eventually *.kicad_pcb will be more common than legacy *.brd files. // but eventually *.kicad_pcb will be more common than legacy *.brd files.
static const struct { static const struct {
const wxString& filter; const wxString& filter;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment