aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjaseg <git@jaseg.de>2021-01-30 00:27:43 +0100
committerjaseg <git@jaseg.de>2021-01-30 00:27:43 +0100
commiteac89409b80c8f61efc98a20b4d742c878cde637 (patch)
tree469f2188f3930f74ee91d90f627fcedfd4420dfe /src
parent52dcceb87f5847dc235f5b5965f57881f327143c (diff)
downloadgerbolyze-eac89409b80c8f61efc98a20b4d742c878cde637.tar.gz
gerbolyze-eac89409b80c8f61efc98a20b4d742c878cde637.tar.bz2
gerbolyze-eac89409b80c8f61efc98a20b4d742c878cde637.zip
Add KiCAD sexp output
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp25
-rw-r--r--src/out_sexp.cpp86
2 files changed, 109 insertions, 2 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 915b71f..52110b6 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -46,6 +46,9 @@ int main(int argc, char **argv) {
{"flatten", {"--flatten"},
"Flatten output so it only consists of non-overlapping white polygons. This perform composition at the vector level. Potentially slow.",
0},
+ {"no_flatten", {"--no-flatten"},
+ "Disable automatic flattening for KiCAD S-Exp export",
+ 0},
{"only_groups", {"-g", "--only-groups"},
"Comma-separated list of group IDs to export.",
1},
@@ -64,6 +67,12 @@ int main(int argc, char **argv) {
{"size", {"-s", "--size"},
"Bitmap mode only: Physical size of output image in mm. Format: 12.34x56.78",
1},
+ {"sexp_mod_name", {"--sexp-mod-name"},
+ "Module name for KiCAD S-Exp output",
+ 1},
+ {"sexp_layer", {"--sexp-layer"},
+ "Layer for KiCAD S-Exp output",
+ 1},
{"preserve_aspect_ratio", {"-a", "--preserve-aspect-ratio"},
"Bitmap mode only: Preserve aspect ratio of image. Allowed values are meet, slice. Can also parse full SVG preserveAspectRatio syntax.",
1},
@@ -151,6 +160,7 @@ int main(int argc, char **argv) {
string fmt = args["ofmt"] ? args["ofmt"] : "gerber";
transform(fmt.begin(), fmt.end(), fmt.begin(), [](unsigned char c){ return std::tolower(c); }); /* c++ yeah */
+ bool force_flatten = false;
PolygonSink *sink = nullptr;
PolygonSink *flattener = nullptr;
if (fmt == "svg") {
@@ -161,6 +171,17 @@ int main(int argc, char **argv) {
} else if (fmt == "gbr" || fmt == "grb" || fmt == "gerber") {
sink = new SimpleGerberOutput(*out_f, only_polys, 4, precision);
+ } else if (fmt == "s-exp" || fmt == "sexp" || fmt == "kicad") {
+ if (!args["sexp_mod_name"] || !args["sexp_layer"]) {
+ cerr << "--sexp-mod-name and --sexp-layer must be given for sexp export" << endl;
+ argagg::fmt_ostream fmt(cerr);
+ fmt << usage.str() << argparser;
+ return EXIT_FAILURE;
+ }
+
+ sink = new KicadSexpOutput(*out_f, args["sexp_mod_name"], args["sexp_layer"], only_polys);
+ force_flatten = true;
+
} else {
cerr << "Unknown output format \"" << fmt << "\"" << endl;
argagg::fmt_ostream fmt(cerr);
@@ -168,7 +189,7 @@ int main(int argc, char **argv) {
return EXIT_FAILURE;
}
- if (args["flatten"]) {
+ if (args["flatten"] || (force_flatten && !args["no_flatten"])) {
flattener = new Flattener(*sink);
}
@@ -294,7 +315,7 @@ int main(int argc, char **argv) {
}
if (args["skip_usvg"]) {
- cerr << "skippint usvg" << endl;
+ cerr << "skipping usvg" << endl;
frob = barf;
} else {
diff --git a/src/out_sexp.cpp b/src/out_sexp.cpp
new file mode 100644
index 0000000..90adef2
--- /dev/null
+++ b/src/out_sexp.cpp
@@ -0,0 +1,86 @@
+/*
+ * This file is part of gerbolyze, a vector image preprocessing toolchain
+ * Copyright (C) 2021 Jan Sebastian Götte <gerbolyze@jaseg.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <cmath>
+#include <algorithm>
+#include <string>
+#include <iostream>
+#include <iomanip>
+#include <gerbolyze.hpp>
+#include <svg_import_defs.h>
+#include <ctime>
+
+using namespace gerbolyze;
+using namespace std;
+
+
+KicadSexpOutput::KicadSexpOutput(ostream &out, string mod_name, string layer, bool only_polys, string ref_text, string val_text, d2p ref_pos, d2p val_pos)
+ : StreamPolygonSink(out, only_polys),
+ m_mod_name(mod_name),
+ m_layer(layer),
+ m_val_text(val_text),
+ m_ref_pos(ref_pos),
+ m_val_pos(val_pos)
+{
+ if (ref_text.empty()) {
+ m_ref_text = mod_name;
+ } else {
+ m_ref_text = ref_text;
+ }
+}
+
+void KicadSexpOutput::header_impl(d2p, d2p) {
+ auto tedit = std::time(0);
+ m_out << "(module " << m_mod_name << " (layer F.Cu) (tedit " << std::hex << std::setfill('0') << std::setw(8) << tedit << ")" << endl;
+ m_out << " (fp_text reference " << m_ref_text << " (at " << m_ref_pos[0] << " " << m_ref_pos[1] << ") (layer F.SilkS) hide" << endl;
+ m_out << " (effects (font (size 1 1) (thickness 0.15)))" << endl;
+ m_out << " )" << endl;
+ m_out << " (fp_text value " << m_val_text << " (at " << m_val_pos[0] << " " << m_val_pos[1] << ") (layer F.SilkS) hide" << endl;
+ m_out << " (effects (font (size 1 1) (thickness 0.15)))" << endl;
+ m_out << " )" << endl;
+}
+
+KicadSexpOutput &KicadSexpOutput::operator<<(GerberPolarityToken pol) {
+ if (pol == GRB_POL_CLEAR) {
+ cerr << "Warning: clear polarity not supported since KiCAD manages to have an even worse graphics model than gerber, except it can't excuse itself by its age..... -.-" << endl;
+ }
+
+ return *this;
+}
+
+KicadSexpOutput &KicadSexpOutput::operator<<(const Polygon &poly) {
+ if (poly.size() < 3) {
+ cerr << "Warning: " << poly.size() << "-element polygon passed to KicadSexpOutput" << endl;
+ return *this;
+ }
+
+ m_out << " (fp_poly (pts";
+ for (auto &p : poly) {
+ m_out << " (xy " << p[0] << " " << p[1] << ")";
+ }
+ m_out << ")";
+ m_out << " (layer " << m_layer << ") (width 0))" << endl;
+
+ return *this;
+}
+
+void KicadSexpOutput::footer_impl() {
+ m_out << ")" << endl;
+}
+
+