aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjaseg <git@jaseg.de>2021-01-30 15:18:56 +0100
committerjaseg <git@jaseg.de>2021-01-30 15:18:56 +0100
commitf88134f9caccafd30f4598cdb583e5fcd6585c55 (patch)
tree00a1d7f341706a649291b8b1beb568239716a17f
parenta6540b73dabc3af766643657b226f942ef05656c (diff)
downloadgerbolyze-f88134f9caccafd30f4598cdb583e5fcd6585c55.tar.gz
gerbolyze-f88134f9caccafd30f4598cdb583e5fcd6585c55.tar.bz2
gerbolyze-f88134f9caccafd30f4598cdb583e5fcd6585c55.zip
Add dilation option
-rw-r--r--Makefile1
-rw-r--r--include/gerbolyze.hpp15
-rw-r--r--src/main.cpp35
-rw-r--r--src/out_dilater.cpp90
-rw-r--r--src/svg_doc.cpp1
5 files changed, 134 insertions, 8 deletions
diff --git a/Makefile b/Makefile
index 520100b..541af04 100644
--- a/Makefile
+++ b/Makefile
@@ -18,6 +18,7 @@ SOURCES := src/svg_color.cpp \
src/out_gerber.cpp \
src/out_sexp.cpp \
src/out_flattener.cpp \
+ src/out_dilater.cpp \
src/lambda_sink.cpp \
CLIPPER_SOURCES ?= upstream/clipper-6.4.2/cpp/clipper.cpp upstream/clipper-6.4.2/cpp/cpp_cairo/cairo_clipper.cpp
diff --git a/include/gerbolyze.hpp b/include/gerbolyze.hpp
index a48c3bf..1fe13ae 100644
--- a/include/gerbolyze.hpp
+++ b/include/gerbolyze.hpp
@@ -71,6 +71,21 @@ namespace gerbolyze {
Flattener_D *d;
};
+ class Dilater : public PolygonSink {
+ public:
+ Dilater(PolygonSink &sink, double dilation) : m_sink(sink), m_dilation(dilation) {}
+ virtual void header(d2p origin, d2p size);
+ virtual Dilater &operator<<(const Polygon &poly);
+ virtual Dilater &operator<<(const LayerNameToken &layer_name);
+ virtual Dilater &operator<<(GerberPolarityToken pol);
+ virtual void footer();
+
+ private:
+ PolygonSink &m_sink;
+ double m_dilation;
+ GerberPolarityToken m_current_polarity = GRB_POL_DARK;
+ };
+
class StreamPolygonSink : public PolygonSink {
public:
StreamPolygonSink(std::ostream &out, bool only_polys=false) : m_only_polys(only_polys), m_out(out) {}
diff --git a/src/main.cpp b/src/main.cpp
index 45e2cfb..135a4c1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -49,6 +49,9 @@ int main(int argc, char **argv) {
{"no_flatten", {"--no-flatten"},
"Disable automatic flattening for KiCAD S-Exp export",
0},
+ {"dilate", {"--dilate"},
+ "Dilate output gerber primitives by this amount in mm. Used for masking out other layers.",
+ 1},
{"only_groups", {"-g", "--only-groups"},
"Comma-separated list of group IDs to export.",
1},
@@ -163,8 +166,10 @@ int main(int argc, char **argv) {
string sexp_layer = args["sexp_layer"] ? args["sexp_layer"].as<string>() : "auto";
bool force_flatten = false;
+ bool is_sexp = false;
PolygonSink *sink = nullptr;
PolygonSink *flattener = nullptr;
+ PolygonSink *dilater = nullptr;
if (fmt == "svg") {
string dark_color = args["svg_dark_color"] ? args["svg_dark_color"] : "#000000";
string clear_color = args["svg_clear_color"] ? args["svg_clear_color"] : "#ffffff";
@@ -183,6 +188,7 @@ int main(int argc, char **argv) {
sink = new KicadSexpOutput(*out_f, args["sexp_mod_name"], sexp_layer, only_polys);
force_flatten = true;
+ is_sexp = true;
} else {
cerr << "Unknown output format \"" << fmt << "\"" << endl;
@@ -191,8 +197,16 @@ int main(int argc, char **argv) {
return EXIT_FAILURE;
}
+ PolygonSink *top_sink = sink;
+
+ if (args["dilate"]) {
+ dilater = new Dilater(*top_sink, args["dilate"].as<double>());
+ top_sink = dilater;
+ }
+
if (args["flatten"] || (force_flatten && !args["no_flatten"])) {
- flattener = new Flattener(*sink);
+ flattener = new Flattener(*top_sink);
+ top_sink = flattener;
}
/* Because the C++ stdlib is bullshit */
@@ -208,7 +222,7 @@ int main(int argc, char **argv) {
id_match(args["only_groups"], sel.include);
if (args["exclude_groups"])
id_match(args["exclude_groups"], sel.exclude);
- if (sexp_layer == "auto") {
+ if (is_sexp && sexp_layer == "auto") {
sel.layers = &gerbolyze::kicad_default_layers;
}
@@ -223,11 +237,6 @@ int main(int argc, char **argv) {
}
delete vec;
- /*
- double min_feature_size_px = mm_to_doc_units(rset.m_minimum_feature_size_mm);
- vec->vectorize_image(cr, node, clip_path, viewport_matrix, *polygon_sink, min_feature_size_px);
- delete vec;
- */
double min_feature_size = 0.1; /* mm */
if (args["min_feature_size"]) {
min_feature_size = args["min_feature_size"].as<double>();
@@ -365,12 +374,22 @@ int main(int argc, char **argv) {
return EXIT_FAILURE;
}
- doc.render(rset, flattener ? *flattener : *sink, &sel);
+ doc.render(rset, *top_sink, &sel);
if (!is_svg) {
remove(frob.c_str());
remove(barf.c_str());
}
+
+ if (flattener) {
+ delete flattener;
+ }
+ if (dilater) {
+ delete dilater;
+ }
+ if (sink) {
+ delete sink;
+ }
return EXIT_SUCCESS;
}
diff --git a/src/out_dilater.cpp b/src/out_dilater.cpp
new file mode 100644
index 0000000..c0e5969
--- /dev/null
+++ b/src/out_dilater.cpp
@@ -0,0 +1,90 @@
+/*
+ * 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 <clipper.hpp>
+#include <svg_import_defs.h>
+#include <svg_geom.h>
+#include "polylinecombine.hpp"
+
+using namespace gerbolyze;
+using namespace std;
+
+void Dilater::header(d2p origin, d2p size) {
+ m_sink.header(origin, size);
+}
+
+void Dilater::footer() {
+ m_sink.footer();
+}
+
+Dilater &Dilater::operator<<(const LayerNameToken &layer_name) {
+ m_sink << layer_name;
+
+ return *this;
+}
+
+Dilater &Dilater::operator<<(GerberPolarityToken pol) {
+ m_current_polarity = pol;
+ m_sink << pol;
+
+ return *this;
+}
+
+Dilater &Dilater::operator<<(const Polygon &poly) {
+ static int i = 0;
+ cerr << "dilating poly " << i++ << endl;
+
+ cerr << "got poly of " << poly.size() << " nodes" << endl;
+ ClipperLib::Path poly_c;
+ for (auto &p : poly) {
+ poly_c.push_back({(ClipperLib::cInt)round(p[0] * clipper_scale), (ClipperLib::cInt)round(p[1] * clipper_scale)});
+ }
+
+ ClipperLib::ClipperOffset offx;
+ offx.ArcTolerance = 0.01 * clipper_scale; /* 10µm; TODO: Make this configurable */
+ offx.AddPath(poly_c, ClipperLib::jtRound, ClipperLib::etClosedPolygon);
+ double dilation = m_dilation;
+ if (m_current_polarity == GRB_POL_CLEAR) {
+ dilation = -dilation;
+ }
+
+ ClipperLib::PolyTree solution;
+ offx.Execute(solution, dilation * clipper_scale);
+
+ ClipperLib::Paths c_nice_polys;
+ dehole_polytree(solution, c_nice_polys);
+
+ for (auto &nice_poly : c_nice_polys) {
+ Polygon new_poly;
+ for (auto &p : nice_poly) {
+ new_poly.push_back({
+ (double)p.X / clipper_scale,
+ (double)p.Y / clipper_scale });
+ }
+ m_sink << new_poly;
+ }
+
+ return *this;
+}
+
diff --git a/src/svg_doc.cpp b/src/svg_doc.cpp
index 21af576..3b253be 100644
--- a/src/svg_doc.cpp
+++ b/src/svg_doc.cpp
@@ -301,6 +301,7 @@ void gerbolyze::SVGDocument::export_svg_path(const RenderSettings &rset, const p
if (stroke_color && stroke_width > 0.0) {
ClipperOffset offx;
+ offx.ArcTolerance = 0.01 * clipper_scale; /* 10µm; TODO: Make this configurable */
/* For stroking we have to separately handle open and closed paths */
for (const auto &poly : closed_paths) {