Initial import
commit
e275384313
|
@ -0,0 +1,181 @@
|
|||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <map>
|
||||
#include <pugixml.hpp>
|
||||
|
||||
enum KicadLayer
|
||||
{
|
||||
// visit: http://en.wikibooks.org/wiki/Kicad/file_formats#Layer_numbering
|
||||
TOP = 24,
|
||||
|
||||
TOP_SILKSCREEN = 23,
|
||||
BOTTOM_SILKSCREEN = 22,
|
||||
|
||||
TOP_PLACE_BOUND = 24,
|
||||
TOP_ASSEMBLY = 15
|
||||
};
|
||||
|
||||
int print_pads(const pugi::xml_document& doc, const std::string& footprint_name, std::ostream& out)
|
||||
{
|
||||
using namespace pugi;
|
||||
using namespace std;
|
||||
|
||||
xpath_node_set pins = doc.select_nodes((string("//footprint[@name='")
|
||||
+ footprint_name + "']/pcbpin").c_str());
|
||||
for (auto &pin : pins)
|
||||
{
|
||||
map<string, string> ul_kicad_shape = {
|
||||
{"round", "C"},
|
||||
{"rectangle", "R"}
|
||||
// ...others I don't know about
|
||||
};
|
||||
|
||||
const string pin_name = pin.node().attribute("name").value();
|
||||
const string pin_style = pin.node().attribute("style").value();
|
||||
|
||||
xpath_node_set shape_node = doc.select_nodes(
|
||||
(string("//padstyle[@name='") + pin_style + "']"
|
||||
+ "/padshape").c_str());
|
||||
|
||||
if (shape_node.empty())
|
||||
throw runtime_error("We're screwed!");
|
||||
|
||||
const string pin_shape = shape_node.first().node().attribute("shape").value();
|
||||
|
||||
double pin_width = shape_node.first().node().attribute("width").as_double()*10;
|
||||
double pin_height = shape_node.first().node().attribute("height").as_double()*10;
|
||||
|
||||
double pin_posx = pin.node().attribute("originx").as_double()*10;
|
||||
double pin_posy = pin.node().attribute("originy").as_double()*10;
|
||||
double pin_rotation = pin.node().attribute("rotation").as_double()*10;
|
||||
|
||||
out << "$PAD" << endl;
|
||||
out << ".LocalClearance 0.001" << endl;
|
||||
out << "Po " << pin_posx << " " << pin_posy << endl;
|
||||
out << "Sh \"" << pin_name << "\" " << ul_kicad_shape[pin_shape] << " "
|
||||
<< pin_width << " " << pin_height << " "
|
||||
<< 0 << " " << 0 << " "
|
||||
<< pin_rotation << endl;
|
||||
out << "At SMD N 00888000" << endl;
|
||||
out << "$EndPAD" << endl;
|
||||
}
|
||||
|
||||
return pins.size();
|
||||
}
|
||||
|
||||
int print_lines(const pugi::xml_document& doc, const std::string& footprint_name, std::ostream& out)
|
||||
{
|
||||
using namespace pugi;
|
||||
using namespace std;
|
||||
|
||||
xpath_node_set lines = doc.select_nodes((string("//footprint[@name='")
|
||||
+ footprint_name + "']/line").c_str());
|
||||
|
||||
for (auto &line : lines)
|
||||
{
|
||||
double originx = line.node().attribute("originx").as_double()*10;
|
||||
double originy = line.node().attribute("originy").as_double()*10;
|
||||
double endx = line.node().attribute("endx").as_double()*10;
|
||||
double endy = line.node().attribute("endy").as_double()*10;
|
||||
double width = line.node().attribute("width").as_double()*10;
|
||||
|
||||
out << "DS " << originx << " " << originy << " "
|
||||
<< endx << " " << endy << " "
|
||||
<< width << " " << TOP_SILKSCREEN << endl;
|
||||
}
|
||||
|
||||
return lines.size();
|
||||
}
|
||||
|
||||
int print_polygons(const pugi::xml_document& doc, const std::string& footprint_name, std::ostream& out)
|
||||
{
|
||||
using namespace pugi;
|
||||
using namespace std;
|
||||
|
||||
xpath_node_set polygons = doc.select_nodes((string("//footprint[@name='")
|
||||
+ footprint_name + "']/polygon").c_str());
|
||||
|
||||
for (auto &polygon : polygons)
|
||||
{
|
||||
// no better way to do this :(
|
||||
int count = 0;
|
||||
for (auto &vertex : polygon.node())
|
||||
++count;
|
||||
|
||||
double width = polygon.node().attribute("width").as_double()*10;
|
||||
|
||||
out << "DP 0 0 0 0 " << count << " " << width << " " << TOP_PLACE_BOUND << endl;
|
||||
for (auto &vertex : polygon.node())
|
||||
{
|
||||
double x = vertex.attribute("x").as_double()*10;
|
||||
double y = vertex.attribute("y").as_double()*10;
|
||||
out << "Dl " << x << " " << y << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int print_footprints(const pugi::xml_document& doc, std::ostream& out)
|
||||
{
|
||||
using namespace pugi;
|
||||
using namespace std;
|
||||
|
||||
xpath_node_set footprints = doc.select_nodes("//footprint");
|
||||
|
||||
for (auto &pin : footprints)
|
||||
{
|
||||
string footprint_name = pin.node().attribute("name").value();
|
||||
|
||||
out << "$MODULE " << footprint_name << endl
|
||||
<< "Po 0 0 0 15 00000000 00000000 ~~" << endl
|
||||
<< "Li " << footprint_name << endl;
|
||||
|
||||
//print_lines(doc, footprint_name, out);
|
||||
//print_polygons(doc, footprint_name, out);
|
||||
print_pads(doc, footprint_name, out);
|
||||
|
||||
out << ".LocalClearance 0" << endl;
|
||||
out << "$EndMODULE " << footprint_name << endl;
|
||||
}
|
||||
|
||||
return footprints.size();
|
||||
}
|
||||
|
||||
void print_index(const pugi::xml_document& doc, std::ostream& out)
|
||||
{
|
||||
using namespace pugi;
|
||||
using namespace std;
|
||||
|
||||
xpath_node_set footprints = doc.select_nodes("//footprint");
|
||||
|
||||
for (auto &footprint : footprints)
|
||||
out << footprint.node().attribute("name").value() << endl;
|
||||
}
|
||||
|
||||
void print_library(const pugi::xml_document& doc, std::ostream& out)
|
||||
{
|
||||
using namespace pugi;
|
||||
using namespace std;
|
||||
|
||||
out << "PCBNEW-LibModule-V1 Wed 17 Apr 2013 03:54:45 PM CEST" << endl;
|
||||
out << "$INDEX" << endl;
|
||||
print_index(doc,out);
|
||||
out << "$EndINDEX" << endl;
|
||||
print_footprints(doc, out);
|
||||
out << "$EndLIBRARY" << endl;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
using namespace std;
|
||||
using namespace pugi;
|
||||
|
||||
if (argc != 2)
|
||||
return 1;
|
||||
|
||||
xml_document doc;
|
||||
doc.load_file(argv[1]);
|
||||
print_library(doc,cout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue