eagle plugin first work
This commit is contained in:
parent
ea467e6730
commit
5cda6bc1a6
|
@ -117,6 +117,7 @@ set(PCB_COMMON_SRCS
|
|||
../pcbnew/sel_layer.cpp
|
||||
../pcbnew/pcb_plot_params.cpp
|
||||
../pcbnew/io_mgr.cpp
|
||||
../pcbnew/eagle_plugin.cpp
|
||||
../pcbnew/legacy_plugin.cpp
|
||||
../pcbnew/kicad_plugin.cpp
|
||||
pcb_plot_params_keywords.cpp
|
||||
|
|
|
@ -110,7 +110,6 @@ set(PCBNEW_SRCS
|
|||
drc.cpp
|
||||
drc_clearance_test_functions.cpp
|
||||
drc_marker_functions.cpp
|
||||
eagle_plugin.cpp
|
||||
edgemod.cpp
|
||||
edit.cpp
|
||||
editedge.cpp
|
||||
|
|
|
@ -232,7 +232,7 @@ public:
|
|||
unsigned m_RatsnestEndIdx; // Ending point of ratsnests of this net
|
||||
// (excluded) in this buffer
|
||||
|
||||
NETINFO_ITEM( BOARD_ITEM* aParent );
|
||||
NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName = NETCLASS::Default, int aNetCode = 0 );
|
||||
~NETINFO_ITEM();
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
/* class NETINFO_ITEM: handle data relative to a given net */
|
||||
/*********************************************************/
|
||||
|
||||
NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent )
|
||||
NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName, int aNetCode )
|
||||
{
|
||||
SetNet( 0 );
|
||||
SetNet( aNetCode );
|
||||
m_NbNodes = 0;
|
||||
m_NbLink = 0;
|
||||
m_NbNoconn = 0;
|
||||
|
@ -33,7 +33,7 @@ NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent )
|
|||
// general buffer of ratsnest
|
||||
m_RatsnestEndIdx = 0; // Ending point of ratsnests of this net
|
||||
|
||||
m_NetClassName = NETCLASS::Default;
|
||||
m_NetClassName = aNetName;
|
||||
|
||||
m_NetClass = 0;
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ void NETINFO_LIST::buildListOfNets()
|
|||
|
||||
// Create and add the "unconnected net", always existing,
|
||||
// used to handle pads and tracks that are not member of a "real" net
|
||||
net_item = new NETINFO_ITEM( (BOARD_ITEM*) m_Parent );
|
||||
net_item = new NETINFO_ITEM( m_Parent );
|
||||
AppendNet( net_item );
|
||||
|
||||
// Build the PAD list, sorted by net
|
||||
|
@ -108,15 +108,15 @@ void NETINFO_LIST::buildListOfNets()
|
|||
if( last_pad == NULL || ( pad->GetNetname() != last_pad->GetNetname() ) )
|
||||
{
|
||||
netcode++;
|
||||
net_item = new NETINFO_ITEM( (BOARD_ITEM*)m_Parent );
|
||||
net_item->SetNet( netcode );
|
||||
net_item->SetNetname( pad->GetNetname() );
|
||||
net_item = new NETINFO_ITEM( m_Parent, pad->GetNetname(), netcode );
|
||||
AppendNet( net_item );
|
||||
}
|
||||
|
||||
pad->SetNet( netcode );
|
||||
net_item->m_PadInNetList.push_back( pad );
|
||||
|
||||
nodes_count++;
|
||||
|
||||
last_pad = pad;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,55 +24,136 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Pcbnew PLUGIN for Eagle 6.x XML *.brd and footprint format.
|
||||
|
||||
XML parsing and converting:
|
||||
Getting line numbers and byte offsets from the source XML file is not
|
||||
possible using currently available XML libraries within KiCad project:
|
||||
wxXmlDocument and boost::property_tree.
|
||||
|
||||
property_tree will give line numbers but no byte offsets, and only during
|
||||
document loading. This means that if we have a problem after the document is
|
||||
successfully loaded, there is no way to correlate back to line number and byte
|
||||
offset of the problem. So a different approach is taken, one which relies on the
|
||||
XML elements themselves using an XPATH type of reporting mechanism. The path to
|
||||
the problem is reported in the error messages. This means keeping track of that
|
||||
path as we traverse the XML document for the sole purpose of accurate error
|
||||
reporting.
|
||||
|
||||
User can load the source XML file into firefox or other xml browser and follow
|
||||
our error message.
|
||||
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <wx/string.h>
|
||||
#include <io_mgr.h>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/xml_parser.hpp>
|
||||
|
||||
#include <eagle_plugin.h>
|
||||
|
||||
class EAGLE_PLUGIN : public PLUGIN
|
||||
#include <common.h>
|
||||
#include <macros.h>
|
||||
#include <fctsys.h>
|
||||
#include <class_board.h>
|
||||
#include <class_module.h>
|
||||
#include <class_track.h>
|
||||
#include <class_edge_mod.h>
|
||||
|
||||
|
||||
using namespace boost::property_tree;
|
||||
|
||||
typedef EAGLE_PLUGIN::BIU BIU;
|
||||
typedef PTREE::const_assoc_iterator CA_ITER;
|
||||
typedef PTREE::const_iterator CITER;
|
||||
|
||||
typedef MODULE_MAP::iterator MODULE_ITER;
|
||||
typedef MODULE_MAP::const_iterator MODULE_CITER;
|
||||
|
||||
|
||||
static inline std::string makePkgKey( const std::string& aLibName, const std::string& aPkgName )
|
||||
{
|
||||
public:
|
||||
// The MODULE factory key is a simple concatonation of library name and
|
||||
// package name, using '\x02' as a separator.
|
||||
std::string key = aLibName + '\x02' + aPkgName;
|
||||
|
||||
//-----<PUBLIC PLUGIN API>-------------------------------------------------
|
||||
const wxString& PluginName();
|
||||
|
||||
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe, PROPERTIES* aProperties = NULL );
|
||||
|
||||
void Save( const wxString& aFileName, BOARD* aBoard, PROPERTIES* aProperties = NULL );
|
||||
|
||||
wxArrayString FootprintEnumerate( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL);
|
||||
|
||||
MODULE* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName, PROPERTIES* aProperties = NULL );
|
||||
|
||||
void FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint, PROPERTIES* aProperties = NULL );
|
||||
|
||||
void FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName );
|
||||
|
||||
void FootprintLibCreate( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
|
||||
|
||||
void FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
|
||||
|
||||
bool IsFootprintLibWritable( const wxString& aLibraryPath );
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
const wxString& GetFileExtension() const = 0;
|
||||
#endif
|
||||
|
||||
};
|
||||
EAGLE_PLUGIN::EAGLE_PLUGIN()
|
||||
{
|
||||
init( NULL );
|
||||
}
|
||||
|
||||
|
||||
const wxString& EAGLE_PLUGIN::PluginName()
|
||||
EAGLE_PLUGIN::~EAGLE_PLUGIN()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const wxString& EAGLE_PLUGIN::PluginName() const
|
||||
{
|
||||
static const wxString name = wxT( "Eagle" );
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
const wxString& EAGLE_PLUGIN::GetFileExtension() const
|
||||
{
|
||||
static const wxString extension = wxT( "brd" );
|
||||
return extension;
|
||||
}
|
||||
|
||||
|
||||
int inline EAGLE_PLUGIN::kicad( double d ) const
|
||||
{
|
||||
return KiROUND( biu_per_mm * d );
|
||||
}
|
||||
|
||||
|
||||
BOARD* EAGLE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, PROPERTIES* aProperties )
|
||||
{
|
||||
return aAppendToMe;
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
PTREE doc;
|
||||
|
||||
init( aProperties );
|
||||
|
||||
m_board = aAppendToMe ? aAppendToMe : new BOARD();
|
||||
|
||||
// delete on exception, iff I own m_board, according to aAppendToMe
|
||||
auto_ptr<BOARD> deleter( aAppendToMe ? NULL : m_board );
|
||||
|
||||
try
|
||||
{
|
||||
// 8 bit filename should be encoded in current locale, not necessarily utf8.
|
||||
std::string filename = (const char*) aFileName.fn_str();
|
||||
|
||||
read_xml( filename, doc, xml_parser::trim_whitespace | xml_parser::no_comments );
|
||||
|
||||
std::string xpath = "eagle.drawing.board";
|
||||
CPTREE& brd = doc.get_child( xpath );
|
||||
|
||||
loadAllSections( brd, xpath, bool( aAppendToMe ) );
|
||||
}
|
||||
|
||||
// Class ptree_error is a base class for xml_parser_error & file_parser_error,
|
||||
// so one catch should be OK for all errors.
|
||||
catch( ptree_error pte )
|
||||
{
|
||||
// for xml_parser_error, what() has the line number in it,
|
||||
// but no byte offset. That should be an adequate error message.
|
||||
THROW_IO_ERROR( pte.what() );
|
||||
}
|
||||
|
||||
// IO_ERROR exceptions are left uncaught, they pass upwards from here.
|
||||
|
||||
deleter.release();
|
||||
return m_board;
|
||||
}
|
||||
|
||||
|
||||
|
@ -81,6 +162,362 @@ void EAGLE_PLUGIN::Save( const wxString& aFileName, BOARD* aBoard, PROPERTIES* a
|
|||
}
|
||||
|
||||
|
||||
void EAGLE_PLUGIN::init( PROPERTIES* aProperties )
|
||||
{
|
||||
m_modules.clear();
|
||||
|
||||
m_board = NULL;
|
||||
m_props = aProperties;
|
||||
|
||||
mm_per_biu = 1/IU_PER_MM;
|
||||
biu_per_mm = IU_PER_MM;
|
||||
}
|
||||
|
||||
/*
|
||||
int EAGLE_PLUGIN::biuSprintf( char* buf, BIU aValue ) const
|
||||
{
|
||||
double engUnits = mm_per_biu * aValue;
|
||||
int len;
|
||||
|
||||
if( engUnits != 0.0 && fabs( engUnits ) <= 0.0001 )
|
||||
{
|
||||
// printf( "f: " );
|
||||
len = sprintf( buf, "%.10f", engUnits );
|
||||
|
||||
while( --len > 0 && buf[len] == '0' )
|
||||
buf[len] = '\0';
|
||||
|
||||
++len;
|
||||
}
|
||||
else
|
||||
{
|
||||
// printf( "g: " );
|
||||
len = sprintf( buf, "%.10g", engUnits );
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
std::string EAGLE_PLUGIN::fmtBIU( BIU aValue ) const
|
||||
{
|
||||
char temp[50];
|
||||
|
||||
int len = biuSprintf( temp, aValue );
|
||||
|
||||
return std::string( temp, len );
|
||||
}
|
||||
|
||||
|
||||
double EAGLE_PLUGIN::dblParse( const char* aValue, const std::string& aXpath )
|
||||
{
|
||||
char* nptr;
|
||||
|
||||
errno = 0;
|
||||
|
||||
double fval = strtod( aValue, &nptr );
|
||||
|
||||
if( errno )
|
||||
{
|
||||
wxString emsg = wxString::Format(
|
||||
_( "invalid float number:'%s' in XML document at '%s'" ),
|
||||
aValue, aXpath.c_str() );
|
||||
|
||||
THROW_IO_ERROR( emsg );
|
||||
}
|
||||
|
||||
if( aValue == nptr )
|
||||
{
|
||||
wxString emsg = wxString::Format(
|
||||
_( "missing float number:'%s' in XML document at '%s'" ),
|
||||
aValue, aXpath.c_str() );
|
||||
|
||||
THROW_IO_ERROR( emsg );
|
||||
}
|
||||
|
||||
return fval;
|
||||
}
|
||||
|
||||
|
||||
BIU EAGLE_PLUGIN::biuParse( const char* aValue, const std::string& aXpath )
|
||||
{
|
||||
double mm = dblParse( aValue, aXpath );
|
||||
return BIU( KiROUND( mm * biu_per_mm ) );
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
void EAGLE_PLUGIN::loadAllSections( CPTREE& aEagleBoard, const std::string& aXpath, bool aAppendToMe )
|
||||
{
|
||||
std::string xpath;
|
||||
|
||||
{
|
||||
xpath = aXpath + '.' + "libraries";
|
||||
CPTREE& libs = aEagleBoard.get_child( "libraries" );
|
||||
loadModules( libs, xpath );
|
||||
}
|
||||
|
||||
// assume that MODULE_MAP is already loaded.
|
||||
{
|
||||
xpath = aXpath + '.' + "signals";
|
||||
CPTREE& signals = aEagleBoard.get_child( "signals" );
|
||||
loadNetsAndTracks( signals, xpath );
|
||||
}
|
||||
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
void EAGLE_PLUGIN::loadModules( CPTREE& aLibs, const std::string& aXpath )
|
||||
{
|
||||
m_modules.clear();
|
||||
|
||||
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" );
|
||||
|
||||
std::string key = makePkgKey( lib_name, pack_name );
|
||||
|
||||
MODULE* m = makeModule( package->second, pack_name );
|
||||
|
||||
// add the templating MODULE to the MODULE template factory "m_modules"
|
||||
std::pair<MODULE_ITER, bool> r = m_modules.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( lib ),
|
||||
GetChars( pkg )
|
||||
);
|
||||
THROW_IO_ERROR( emsg );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EWIRE EAGLE_PLUGIN::wire( 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;
|
||||
}
|
||||
|
||||
|
||||
MODULE* EAGLE_PLUGIN::makeModule( CPTREE& aPackage, const std::string& aPkgName ) const
|
||||
{
|
||||
std::auto_ptr<MODULE> m( new MODULE( NULL ) );
|
||||
|
||||
m->SetLibRef( FROM_UTF8( aPkgName.c_str() ) );
|
||||
|
||||
boost::optional<std::string> description = aPackage.get_optional<std::string>( "description" );
|
||||
if( description )
|
||||
m->SetDescription( FROM_UTF8( description->c_str() ) );
|
||||
|
||||
for( CITER it = aPackage.begin(); it != aPackage.end(); ++it )
|
||||
{
|
||||
CPTREE& t = it->second;
|
||||
|
||||
if( !it->first.compare( "wire " ) )
|
||||
packageWire( m.get(), t );
|
||||
|
||||
else if( !it->first.compare( "pad" ) )
|
||||
packagePad( m.get(), t );
|
||||
|
||||
else if( !it->first.compare( "text" ) )
|
||||
packageText( m.get(), t );
|
||||
|
||||
else if( !it->first.compare( "rectangle" ) )
|
||||
packageRectangle( m.get(), t );
|
||||
|
||||
else if( !it->first.compare( "polygon" ) )
|
||||
packagePolygon( m.get(), t );
|
||||
|
||||
else if( !it->first.compare( "circle" ) )
|
||||
packageCircle( m.get(), t );
|
||||
|
||||
else if( !it->first.compare( "hole" ) )
|
||||
packageHole( m.get(), t );
|
||||
|
||||
else if( !it->first.compare( "smd" ) )
|
||||
packageSMD( m.get(), t );
|
||||
}
|
||||
|
||||
return m.release();
|
||||
}
|
||||
|
||||
|
||||
void EAGLE_PLUGIN::packageWire( MODULE* aModule, CPTREE aTree ) const
|
||||
{
|
||||
EWIRE w = wire( aTree );
|
||||
|
||||
int layer = kicad_layer( w.layer );
|
||||
wxPoint start( kicad_x( w.x1 ), kicad_y( w.y1 ) );
|
||||
wxPoint end( kicad_x( w.x2 ), kicad_y( w.x2 ) );
|
||||
int width = kicad( w.width );
|
||||
|
||||
EDGE_MODULE* dwg = new EDGE_MODULE( aModule, S_SEGMENT );
|
||||
aModule->m_Drawings.PushBack( dwg );
|
||||
|
||||
dwg->SetStart0( start );
|
||||
dwg->SetEnd0( end );
|
||||
dwg->SetLayer( layer );
|
||||
dwg->SetWidth( width );
|
||||
}
|
||||
|
||||
|
||||
void EAGLE_PLUGIN::packagePad( MODULE* aModule, CPTREE aTree ) const
|
||||
{
|
||||
CPTREE attrs = aTree.get_child( "<xmlattr>" );
|
||||
}
|
||||
|
||||
|
||||
void EAGLE_PLUGIN::packageText( MODULE* aModule, CPTREE aTree ) const
|
||||
{
|
||||
CPTREE attrs = aTree.get_child( "<xmlattr>" );
|
||||
}
|
||||
|
||||
|
||||
void EAGLE_PLUGIN::packageRectangle( MODULE* aModule, CPTREE aTree ) const
|
||||
{
|
||||
CPTREE attrs = aTree.get_child( "<xmlattr>" );
|
||||
}
|
||||
|
||||
|
||||
void EAGLE_PLUGIN::packagePolygon( MODULE* aModule, CPTREE aTree ) const
|
||||
{
|
||||
CPTREE attrs = aTree.get_child( "<xmlattr>" );
|
||||
}
|
||||
|
||||
|
||||
void EAGLE_PLUGIN::packageCircle( MODULE* aModule, CPTREE aTree ) const
|
||||
{
|
||||
CPTREE attrs = aTree.get_child( "<xmlattr>" );
|
||||
}
|
||||
|
||||
|
||||
void EAGLE_PLUGIN::packageHole( MODULE* aModule, CPTREE aTree ) const
|
||||
{
|
||||
CPTREE attrs = aTree.get_child( "<xmlattr>" );
|
||||
}
|
||||
|
||||
|
||||
void EAGLE_PLUGIN::packageSMD( MODULE* aModule, CPTREE aTree ) const
|
||||
{
|
||||
CPTREE attrs = aTree.get_child( "<xmlattr>" );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
<package name="2X03">
|
||||
<description><b>PIN HEADER</b></description>
|
||||
<wire x1="-3.81" y1="-1.905" x2="-3.175" y2="-2.54" width="0.1524" layer="21"/>
|
||||
<wire x1="-1.905" y1="-2.54" x2="-1.27" y2="-1.905" width="0.1524" layer="21"/>
|
||||
<wire x1="-1.27" y1="-1.905" x2="-0.635" y2="-2.54" width="0.1524" layer="21"/>
|
||||
<wire x1="0.635" y1="-2.54" x2="1.27" y2="-1.905" width="0.1524" layer="21"/>
|
||||
<wire x1="-3.81" y1="-1.905" x2="-3.81" y2="1.905" width="0.1524" layer="21"/>
|
||||
<wire x1="-3.81" y1="1.905" x2="-3.175" y2="2.54" width="0.1524" layer="21"/>
|
||||
<wire x1="-3.175" y1="2.54" x2="-1.905" y2="2.54" width="0.1524" layer="21"/>
|
||||
<wire x1="-1.905" y1="2.54" x2="-1.27" y2="1.905" width="0.1524" layer="21"/>
|
||||
<wire x1="-1.27" y1="1.905" x2="-0.635" y2="2.54" width="0.1524" layer="21"/>
|
||||
<wire x1="-0.635" y1="2.54" x2="0.635" y2="2.54" width="0.1524" layer="21"/>
|
||||
<wire x1="0.635" y1="2.54" x2="1.27" y2="1.905" width="0.1524" layer="21"/>
|
||||
<wire x1="-1.27" y1="1.905" x2="-1.27" y2="-1.905" width="0.1524" layer="21"/>
|
||||
<wire x1="1.27" y1="1.905" x2="1.27" y2="-1.905" width="0.1524" layer="21"/>
|
||||
<wire x1="-0.635" y1="-2.54" x2="0.635" y2="-2.54" width="0.1524" layer="21"/>
|
||||
<wire x1="-3.175" y1="-2.54" x2="-1.905" y2="-2.54" width="0.1524" layer="21"/>
|
||||
<wire x1="1.27" y1="-1.905" x2="1.905" y2="-2.54" width="0.1524" layer="21"/>
|
||||
<wire x1="3.175" y1="-2.54" x2="3.81" y2="-1.905" width="0.1524" layer="21"/>
|
||||
<wire x1="1.27" y1="1.905" x2="1.905" y2="2.54" width="0.1524" layer="21"/>
|
||||
<wire x1="1.905" y1="2.54" x2="3.175" y2="2.54" width="0.1524" layer="21"/>
|
||||
<wire x1="3.175" y1="2.54" x2="3.81" y2="1.905" width="0.1524" layer="21"/>
|
||||
<wire x1="3.81" y1="1.905" x2="3.81" y2="-1.905" width="0.1524" layer="21"/>
|
||||
<wire x1="1.905" y1="-2.54" x2="3.175" y2="-2.54" width="0.1524" layer="21"/>
|
||||
<pad name="1" x="-2.54" y="-1.27" drill="1.016" shape="octagon"/>
|
||||
<pad name="2" x="-2.54" y="1.27" drill="1.016" shape="octagon"/>
|
||||
<pad name="3" x="0" y="-1.27" drill="1.016" shape="octagon"/>
|
||||
<pad name="4" x="0" y="1.27" drill="1.016" shape="octagon"/>
|
||||
<pad name="5" x="2.54" y="-1.27" drill="1.016" shape="octagon"/>
|
||||
<pad name="6" x="2.54" y="1.27" drill="1.016" shape="octagon"/>
|
||||
<text x="-3.81" y="3.175" size="1.27" layer="25" ratio="10">>NAME</text>
|
||||
<text x="-3.81" y="-4.445" size="1.27" layer="27">>VALUE</text>
|
||||
<rectangle x1="-2.794" y1="-1.524" x2="-2.286" y2="-1.016" layer="51"/>
|
||||
<rectangle x1="-2.794" y1="1.016" x2="-2.286" y2="1.524" layer="51"/>
|
||||
<rectangle x1="-0.254" y1="1.016" x2="0.254" y2="1.524" layer="51"/>
|
||||
<rectangle x1="-0.254" y1="-1.524" x2="0.254" y2="-1.016" layer="51"/>
|
||||
<rectangle x1="2.286" y1="1.016" x2="2.794" y2="1.524" layer="51"/>
|
||||
<rectangle x1="2.286" y1="-1.524" x2="2.794" y2="-1.016" layer="51"/>
|
||||
</package>
|
||||
*/
|
||||
|
||||
|
||||
void EAGLE_PLUGIN::loadNetsAndTracks( CPTREE& aSignals, const std::string& aXpath )
|
||||
{
|
||||
int netCode = 1;
|
||||
|
||||
time_t now = time( NULL );
|
||||
|
||||
for( CITER nit = aSignals.begin(); nit != aSignals.end(); ++nit, ++netCode )
|
||||
{
|
||||
wxString netName = FROM_UTF8( nit->second.get<std::string>( "<xmlattr>.name" ).c_str() );
|
||||
|
||||
m_board->AppendNet( new NETINFO_ITEM( m_board, netName, netCode ) );
|
||||
|
||||
std::pair<CA_ITER, CA_ITER> wires = nit->second.equal_range( "wire" );
|
||||
|
||||
for( CA_ITER wit = wires.first; wit != wires.second; ++wit )
|
||||
{
|
||||
EWIRE w = wire( wit->second );
|
||||
|
||||
TRACK* t = new TRACK( m_board );
|
||||
|
||||
t->SetTimeStamp( now );
|
||||
|
||||
t->SetPosition( wxPoint( kicad_x( w.x1 ), kicad_y( w.y1 ) ) );
|
||||
t->SetEnd( wxPoint( kicad_x( w.x2 ), kicad_y( w.y2 ) ) );
|
||||
|
||||
t->SetWidth( kicad( w.width ) );
|
||||
t->SetLayer( kicad_layer( w.layer ) );
|
||||
t->SetNet( netCode );
|
||||
|
||||
m_board->m_Track.Insert( t, NULL );
|
||||
|
||||
D(printf("wire:%s\n", wit->first.c_str() );)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int EAGLE_PLUGIN::kicad_layer( int aLayer ) const
|
||||
{
|
||||
return aLayer;
|
||||
}
|
||||
|
||||
|
||||
wxArrayString EAGLE_PLUGIN::FootprintEnumerate( const wxString& aLibraryPath, PROPERTIES* aProperties )
|
||||
{
|
||||
return wxArrayString();
|
||||
|
@ -118,54 +555,3 @@ bool EAGLE_PLUGIN::IsFootprintLibWritable( const wxString& aLibraryPath )
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
wxXmlDocument xml;
|
||||
|
||||
xml.SetFileEncoding( wxT( "UTF-8" ) );
|
||||
|
||||
if( !xml.Load( dlg.GetFilename() ) )
|
||||
return;
|
||||
|
||||
XNODE *macrosNode = (XNODE*) xml.GetRoot()->GetChildren();
|
||||
|
||||
while( macrosNode )
|
||||
{
|
||||
int number = -1;
|
||||
|
||||
if( macrosNode->GetName() == wxT( "macros" ) )
|
||||
{
|
||||
number = wxAtoi( macrosNode->GetAttribute( wxT( "number" ), wxT( "-1" ) ) );
|
||||
|
||||
if( number >= 0 && number < 10 )
|
||||
{
|
||||
m_Macros[number].m_Record.clear();
|
||||
|
||||
XNODE *hotkeyNode = (XNODE*) macrosNode->GetChildren();
|
||||
|
||||
while( hotkeyNode )
|
||||
{
|
||||
if( hotkeyNode->GetName() == wxT( "hotkey" ) )
|
||||
{
|
||||
int x = wxAtoi( hotkeyNode->GetAttribute( wxT( "x" ), wxT( "0" ) ) );
|
||||
int y = wxAtoi( hotkeyNode->GetAttribute( wxT( "y" ), wxT( "0" ) ) );
|
||||
int hk = wxAtoi( hotkeyNode->GetAttribute( wxT( "hkcode" ), wxT( "0" ) ) );
|
||||
|
||||
MACROS_RECORD macros_record;
|
||||
macros_record.m_HotkeyCode = hk;
|
||||
macros_record.m_Position.x = x;
|
||||
macros_record.m_Position.y = y;
|
||||
m_Macros[number].m_Record.push_back( macros_record );
|
||||
}
|
||||
|
||||
hotkeyNode = (XNODE*) hotkeyNode->GetNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macrosNode = (XNODE*) macrosNode->GetNext();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,241 @@
|
|||
#ifndef EAGLE_PLUGIN_H_
|
||||
#define EAGLE_PLUGIN_H_
|
||||
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2012 KiCad Developers, see change_log.txt for contributors.
|
||||
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <io_mgr.h>
|
||||
|
||||
|
||||
// forward declaration on ptree template so we can confine use of big boost
|
||||
// headers to only the implementation *.cpp file.
|
||||
|
||||
#include <boost/property_tree/ptree_fwd.hpp>
|
||||
#include <boost/ptr_container/ptr_map.hpp>
|
||||
|
||||
class MODULE;
|
||||
typedef boost::ptr_map< std::string, MODULE > MODULE_MAP;
|
||||
|
||||
|
||||
/*
|
||||
#include
|
||||
namespace boost {
|
||||
namespace property_tree
|
||||
{
|
||||
template < class Key, class Data, class KeyCompare = std::less<Key> >
|
||||
class basic_ptree;
|
||||
|
||||
typedef basic_ptree< std::string, std::string > ptree;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
typedef boost::property_tree::ptree PTREE;
|
||||
typedef const PTREE CPTREE;
|
||||
|
||||
struct EWIRE ///< Eagle wire
|
||||
{
|
||||
double x1;
|
||||
double y1;
|
||||
double x2;
|
||||
double y2;
|
||||
double width;
|
||||
int layer;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class EAGLE_PLUGIN
|
||||
* works with Eagle 6.x XML board files and footprints.
|
||||
*/
|
||||
class EAGLE_PLUGIN : public PLUGIN
|
||||
{
|
||||
public:
|
||||
|
||||
//-----<PUBLIC PLUGIN API>--------------------------------------------------
|
||||
const wxString& PluginName() const;
|
||||
|
||||
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe, PROPERTIES* aProperties = NULL );
|
||||
|
||||
void Save( const wxString& aFileName, BOARD* aBoard, PROPERTIES* aProperties = NULL );
|
||||
|
||||
wxArrayString FootprintEnumerate( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL);
|
||||
|
||||
MODULE* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName, PROPERTIES* aProperties = NULL );
|
||||
|
||||
void FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint, PROPERTIES* aProperties = NULL );
|
||||
|
||||
void FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName );
|
||||
|
||||
void FootprintLibCreate( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
|
||||
|
||||
void FootprintLibDelete( const wxString& aLibraryPath, PROPERTIES* aProperties = NULL );
|
||||
|
||||
bool IsFootprintLibWritable( const wxString& aLibraryPath );
|
||||
|
||||
const wxString& GetFileExtension() const;
|
||||
|
||||
//-----</PUBLIC PLUGIN API>-------------------------------------------------
|
||||
|
||||
typedef int BIU;
|
||||
|
||||
EAGLE_PLUGIN();
|
||||
~EAGLE_PLUGIN();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
MODULE_MAP m_modules; ///< is a factory by use of MODULE copy constructor,
|
||||
///< lookup is based on libname.packagename
|
||||
|
||||
PROPERTIES* m_props; ///< passed via Save() or Load(), no ownership, may be NULL.
|
||||
|
||||
BOARD* m_board; ///< which BOARD, no ownership here
|
||||
double mm_per_biu; ///< how many mm in each BIU
|
||||
double biu_per_mm; ///< how many bius in a mm
|
||||
|
||||
/// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed.
|
||||
void init( PROPERTIES* aProperties );
|
||||
|
||||
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_layer( int aLayer ) const;
|
||||
|
||||
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 ); }
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Function dblParse
|
||||
* parses an ASCII decimal floating point value and reports any error by throwing
|
||||
* an exception using the xpath in the error message text.
|
||||
*
|
||||
* @param aValue is the ASCII value in C locale form with possible leading whitespace
|
||||
*
|
||||
* @param aXpath tells where the value is within the XML document.
|
||||
*
|
||||
* @return double - aValue in binary, not scaled.
|
||||
*/
|
||||
static double dblParse( const char* aValue, const std::string& aXpath );
|
||||
|
||||
/**
|
||||
* Function biuParse
|
||||
* parses an ASCII decimal floating point value and scales it into a BIU
|
||||
* according to the current mm_per_biu. This fuction is the complement of
|
||||
* fmtBIU(). One has to know what the other is doing.
|
||||
*
|
||||
* @param aValue is the ASCII value in C locale form with possible leading whitespace
|
||||
*
|
||||
* @param aXpath tells where the value is within the XML document.
|
||||
*
|
||||
* @return BIU - the converted Board Internal Unit.
|
||||
*/
|
||||
BIU biuParse( const char* aValue, const std::string& aXpath );
|
||||
|
||||
/**
|
||||
* Function degParse
|
||||
* parses an ASCII decimal floating point value which is certainly an angle. This
|
||||
* is a dedicated function for encapsulating support for the migration from
|
||||
* tenths of degrees to degrees in floating point. This function is the complement of
|
||||
* fmtDEG(). One has to know what the other is doing.
|
||||
*
|
||||
* @param aValue is the ASCII value in C locale form with possible leading whitespace
|
||||
*
|
||||
* @param nptrptr may be NULL, but if not, then it tells where to put a
|
||||
* pointer to the next unconsumed input text. See "man strtod" for more information.
|
||||
*
|
||||
* @return double - the string converted to a primitive double type
|
||||
*/
|
||||
double degParse( const char* aValue, const char** nptrptr = NULL );
|
||||
|
||||
/// encapsulate the BIU formatting tricks in one place.
|
||||
int biuSprintf( char* buf, BIU aValue ) const;
|
||||
|
||||
/**
|
||||
* Function fmtBIU
|
||||
* converts a BIU to engineering units by scaling and formatting to ASCII.
|
||||
* This function is the complement of biuParse(). One has to know what the
|
||||
* other is doing.
|
||||
*/
|
||||
std::string fmtBIU( BIU aValue ) const;
|
||||
|
||||
std::string fmtBIUPair( BIU first, BIU second ) const;
|
||||
|
||||
std::string fmtBIUPoint( const wxPoint& aPoint ) const
|
||||
{
|
||||
return fmtBIUPair( aPoint.x, aPoint.y );
|
||||
}
|
||||
|
||||
std::string fmtBIUSize( const wxSize& aSize ) const
|
||||
{
|
||||
return fmtBIUPair( aSize.x, aSize.y );
|
||||
}
|
||||
#endif
|
||||
|
||||
// all these loadXXX() throw IO_ERROR or ptree_error exceptions:
|
||||
|
||||
void loadAllSections( CPTREE& aEagleBoard, const std::string& aXpath, bool aAppendToMe );
|
||||
|
||||
void loadNetsAndTracks( CPTREE& aSignals, const std::string& aXpath );
|
||||
|
||||
void loadModules( CPTREE& aLibs, const std::string& aXpath );
|
||||
|
||||
/**
|
||||
* Function wire
|
||||
* converts a <wire>'s xml attributes to binary without additional conversion.
|
||||
* @return EWIRE - an Eagle <wire> object in binary.
|
||||
*/
|
||||
EWIRE wire( CPTREE aWire ) const;
|
||||
|
||||
/**
|
||||
* Function fmtDEG
|
||||
* formats an angle in a way particular to a board file format. This function
|
||||
* is the opposite or complement of degParse(). One has to know what the
|
||||
* other is doing.
|
||||
*/
|
||||
std::string fmtDEG( double aAngle ) const;
|
||||
|
||||
/**
|
||||
* Function makeModule
|
||||
* creates a MODULE from an Eagle package.
|
||||
*/
|
||||
MODULE* makeModule( CPTREE& aPackage, const std::string& aPkgName ) const;
|
||||
|
||||
void packageWire( MODULE* aModule, CPTREE aTree ) const;
|
||||
void packagePad( MODULE* aModule, CPTREE aTree ) const;
|
||||
void packageText( MODULE* aModule, CPTREE aTree ) const;
|
||||
void packageRectangle( MODULE* aModule, CPTREE aTree ) const;
|
||||
void packagePolygon( MODULE* aModule, CPTREE aTree ) const;
|
||||
void packageCircle( MODULE* aModule, CPTREE aTree ) const;
|
||||
void packageHole( MODULE* aModule, CPTREE aTree ) const;
|
||||
void packageSMD( MODULE* aModule, CPTREE aTree ) const;
|
||||
|
||||
};
|
||||
|
||||
#endif // EAGLE_PLUGIN_H_
|
|
@ -26,6 +26,7 @@
|
|||
#include <io_mgr.h>
|
||||
#include <legacy_plugin.h>
|
||||
#include <kicad_plugin.h>
|
||||
#include <eagle_plugin.h>
|
||||
|
||||
|
||||
#define FMT_UNIMPLEMENTED _( "Plugin '%s' does not implement the '%s' function." )
|
||||
|
@ -60,10 +61,8 @@ PLUGIN* IO_MGR::PluginFind( PCB_FILE_T aFileType )
|
|||
case KICAD:
|
||||
return new PCB_IO();
|
||||
|
||||
/*
|
||||
case EAGLE:
|
||||
return &eagle_plugin;
|
||||
*/
|
||||
return new EAGLE_PLUGIN();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
|
@ -50,10 +50,10 @@ public:
|
|||
{
|
||||
LEGACY, //< Legacy Pcbnew file formats prior to s-expression.
|
||||
KICAD, //< S-expression Pcbnew file format.
|
||||
EAGLE,
|
||||
|
||||
// add your type here.
|
||||
|
||||
// EAGLE,
|
||||
// ALTIUM,
|
||||
// etc.
|
||||
};
|
||||
|
|
|
@ -88,11 +88,17 @@
|
|||
#include <wx/ffile.h>
|
||||
|
||||
|
||||
typedef LEGACY_PLUGIN::BIU BIU;
|
||||
|
||||
|
||||
#define VERSION_ERROR_FORMAT _( "File '%s' is format version: %d.\nI only support format version <= %d.\nPlease upgrade Pcbnew to load this file." )
|
||||
#define UNKNOWN_GRAPHIC_FORMAT _( "unknown graphic type: %d")
|
||||
#define UNKNOWN_PAD_FORMAT _( "unknown pad type: %d")
|
||||
#define UNKNOWN_PAD_ATTRIBUTE _( "unknown pad attribute: %d" )
|
||||
|
||||
|
||||
|
||||
|
||||
// Old internal units definition (UI = decimil)
|
||||
#define PCB_LEGACY_INTERNAL_UNIT 10000
|
||||
|
||||
|
@ -3729,7 +3735,7 @@ void LEGACY_PLUGIN::savePCB_TEXT( const TEXTE_PCB* me ) const
|
|||
#include <boost/ptr_container/ptr_map.hpp>
|
||||
#include <wx/filename.h>
|
||||
|
||||
typedef boost::ptr_map< wxString, MODULE > MODULE_MAP;
|
||||
typedef boost::ptr_map< std::string, MODULE > MODULE_MAP;
|
||||
typedef MODULE_MAP::iterator MODULE_ITER;
|
||||
typedef MODULE_MAP::const_iterator MODULE_CITER;
|
||||
|
||||
|
@ -3912,8 +3918,7 @@ void FPL_CACHE::LoadModules( LINE_READER* aReader )
|
|||
{
|
||||
MODULE* m = m_owner->LoadMODULE();
|
||||
|
||||
// wxString footprintName = m->GetReference();
|
||||
wxString footprintName = m->GetLibRef();
|
||||
std::string footprintName = TO_UTF8( m->GetLibRef() );
|
||||
|
||||
/*
|
||||
|
||||
|
@ -3944,11 +3949,15 @@ void FPL_CACHE::LoadModules( LINE_READER* aReader )
|
|||
{
|
||||
bool nameOK = false;
|
||||
int version = 2;
|
||||
char buf[48];
|
||||
|
||||
while( !nameOK )
|
||||
{
|
||||
wxString newName = footprintName;
|
||||
newName << wxT( "_v" ) << version++;
|
||||
std::string newName = footprintName;
|
||||
|
||||
newName += "_v";
|
||||
sprintf( buf, "%d", version++ );
|
||||
newName += buf;
|
||||
|
||||
it = m_modules.find( newName );
|
||||
|
||||
|
@ -3956,7 +3965,7 @@ void FPL_CACHE::LoadModules( LINE_READER* aReader )
|
|||
{
|
||||
nameOK = true;
|
||||
|
||||
m->SetLibRef( newName );
|
||||
m->SetLibRef( FROM_UTF8( newName.c_str() ) );
|
||||
std::pair<MODULE_ITER, bool> r = m_modules.insert( newName, m );
|
||||
|
||||
wxASSERT_MSG( r.second, wxT( "error doing cache insert using guaranteed unique name" ) );
|
||||
|
@ -4035,7 +4044,7 @@ void FPL_CACHE::SaveIndex( FILE* aFile )
|
|||
|
||||
for( MODULE_CITER it = m_modules.begin(); it != m_modules.end(); ++it )
|
||||
{
|
||||
fprintf( aFile, "%s\n", TO_UTF8( it->first ) );
|
||||
fprintf( aFile, "%s\n", it->first.c_str() );
|
||||
}
|
||||
|
||||
fprintf( aFile, "$EndINDEX\n" );
|
||||
|
@ -4081,7 +4090,7 @@ wxArrayString LEGACY_PLUGIN::FootprintEnumerate( const wxString& aLibraryPath, P
|
|||
|
||||
for( MODULE_CITER it = mods.begin(); it != mods.end(); ++it )
|
||||
{
|
||||
ret.Add( it->first );
|
||||
ret.Add( FROM_UTF8( it->first.c_str() ) );
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -4099,7 +4108,7 @@ MODULE* LEGACY_PLUGIN::FootprintLoad( const wxString& aLibraryPath, const wxStri
|
|||
|
||||
const MODULE_MAP& mods = m_cache->m_modules;
|
||||
|
||||
MODULE_CITER it = mods.find( aFootprintName );
|
||||
MODULE_CITER it = mods.find( TO_UTF8( aFootprintName ) );
|
||||
|
||||
if( it == mods.end() )
|
||||
{
|
||||
|
@ -4129,7 +4138,7 @@ void LEGACY_PLUGIN::FootprintSave( const wxString& aLibraryPath, const MODULE* a
|
|||
THROW_IO_ERROR( wxString::Format( _( "Library '%s' is read only" ), aLibraryPath.GetData() ) );
|
||||
}
|
||||
|
||||
wxString footprintName = aFootprint->GetLibRef();
|
||||
std::string footprintName = TO_UTF8( aFootprint->GetLibRef() );
|
||||
|
||||
MODULE_MAP& mods = m_cache->m_modules;
|
||||
|
||||
|
@ -4173,7 +4182,9 @@ void LEGACY_PLUGIN::FootprintDelete( const wxString& aLibraryPath, const wxStrin
|
|||
THROW_IO_ERROR( wxString::Format( _( "Library '%s' is read only" ), aLibraryPath.GetData() ) );
|
||||
}
|
||||
|
||||
size_t erasedCount = m_cache->m_modules.erase( aFootprintName );
|
||||
std::string footprintName = TO_UTF8( aFootprintName );
|
||||
|
||||
size_t erasedCount = m_cache->m_modules.erase( footprintName );
|
||||
|
||||
if( erasedCount != 1 )
|
||||
{
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#define FOOTPRINT_LIBRARY_HEADER "PCBNEW-LibModule-V1"
|
||||
#define FOOTPRINT_LIBRARY_HEADER_CNT 18
|
||||
|
||||
typedef int BIU;
|
||||
|
||||
class PCB_TARGET;
|
||||
class MODULE;
|
||||
|
@ -62,6 +61,7 @@ class LEGACY_PLUGIN : public PLUGIN
|
|||
{
|
||||
public:
|
||||
|
||||
|
||||
//-----<PLUGIN IMPLEMENTATION>----------------------------------------------
|
||||
|
||||
const wxString& PluginName() const
|
||||
|
@ -98,6 +98,8 @@ public:
|
|||
|
||||
//-----</PLUGIN IMPLEMENTATION>---------------------------------------------
|
||||
|
||||
typedef int BIU;
|
||||
|
||||
LEGACY_PLUGIN();
|
||||
~LEGACY_PLUGIN();
|
||||
|
||||
|
|
Loading…
Reference in New Issue