diff options
author | jaseg <git@jaseg.de> | 2021-01-30 15:18:56 +0100 |
---|---|---|
committer | jaseg <git@jaseg.de> | 2021-01-30 15:18:56 +0100 |
commit | f88134f9caccafd30f4598cdb583e5fcd6585c55 (patch) | |
tree | 00a1d7f341706a649291b8b1beb568239716a17f | |
parent | a6540b73dabc3af766643657b226f942ef05656c (diff) | |
download | gerbolyze-f88134f9caccafd30f4598cdb583e5fcd6585c55.tar.gz gerbolyze-f88134f9caccafd30f4598cdb583e5fcd6585c55.tar.bz2 gerbolyze-f88134f9caccafd30f4598cdb583e5fcd6585c55.zip |
Add dilation option
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | include/gerbolyze.hpp | 15 | ||||
-rw-r--r-- | src/main.cpp | 35 | ||||
-rw-r--r-- | src/out_dilater.cpp | 90 | ||||
-rw-r--r-- | src/svg_doc.cpp | 1 |
5 files changed, 134 insertions, 8 deletions
@@ -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) { |