svg-flatten: Add 'complete pattern tiles only' switch

This is not part of the SVG spec, but it is useful for generating proto
boards using SVG patterns.
wip
jaseg 2022-06-20 10:24:26 +02:00
rodzic f58cca0ba6
commit d09cf6ef3b
4 zmienionych plików z 48 dodań i 8 usunięć

Wyświetl plik

@ -143,17 +143,28 @@ namespace gerbolyze {
/* Transform given clipper paths */
void transform_paths(ClipperLib::Paths &paths) {
for (auto &p : paths) {
std::transform(p.begin(), p.end(), p.begin(),
[this](ClipperLib::IntPoint p) -> ClipperLib::IntPoint {
d2p out(this->doc2phys(d2p{p.X / clipper_scale, p.Y / clipper_scale}));
return {
(ClipperLib::cInt)round(out[0] * clipper_scale),
(ClipperLib::cInt)round(out[1] * clipper_scale)
};
});
transform_clipper_path(p);
}
}
void transform_clipper_path(ClipperLib::Path &path) {
std::transform(path.begin(), path.end(), path.begin(),
[this](ClipperLib::IntPoint p) -> ClipperLib::IntPoint {
d2p out(this->doc2phys(d2p{p.X / clipper_scale, p.Y / clipper_scale}));
return {
(ClipperLib::cInt)round(out[0] * clipper_scale),
(ClipperLib::cInt)round(out[1] * clipper_scale)
};
});
}
void transform_polygon(Polygon &poly) {
std::transform(poly.begin(), poly.end(), poly.begin(),
[this](d2p p) -> d2p {
return this->doc2phys(d2p{p[0], p[1]});
});
}
string dbg_str() {
ostringstream os;
os << "xform2d< " << setw(5);

Wyświetl plik

@ -197,6 +197,7 @@ namespace gerbolyze {
VectorizerSelectorizer &m_vec_sel;
bool outline_mode = false;
bool flip_color_interpretation = false;
bool pattern_complete_tiles_only = false;
};
class RenderContext {

Wyświetl plik

@ -73,6 +73,9 @@ int main(int argc, char **argv) {
{"flip_svg_color_interpretation", {"-i", "--svg-white-is-gerber-dark"},
"Flip polarity of SVG color interpretation. This affects only SVG primitives like paths and NOT embedded bitmaps. With -i: white -> silk there/\"dark\" gerber primitive.",
0},
{"pattern_complete_tiles_only", {"--pattern-complete-tiles-only"},
"Break SVG spec by only rendering complete pattern tiles, i.e. pattern tiles that entirely fit the target area, instead of performing clipping.",
0},
{"min_feature_size", {"-d", "--trace-space"},
"Minimum feature size of elements in vectorized graphics (trace/space) in mm. Default: 0.1mm.",
1},
@ -423,6 +426,7 @@ int main(int argc, char **argv) {
VectorizerSelectorizer vec_sel(vectorizer, args["vectorizer_map"] ? args["vectorizer_map"].as<string>() : "");
bool flip_svg_colors = args["flip_svg_color_interpretation"];
bool pattern_complete_tiles_only = args["pattern_complete_tiles_only"];
RenderSettings rset {
min_feature_size,
@ -431,6 +435,7 @@ int main(int argc, char **argv) {
vec_sel,
outline_mode,
flip_svg_colors,
pattern_complete_tiles_only,
};
SVGDocument doc;

Wyświetl plik

@ -108,6 +108,29 @@ void gerbolyze::Pattern::tile (gerbolyze::RenderContext &ctx) {
/* Export the pattern tile's content like a group */
RenderContext elem_ctx(pat_ctx, elem_xf);
if (ctx.settings().pattern_complete_tiles_only) {
ClipperLib::Clipper c;
double eps = 1e-6;
Polygon poly = {{eps, eps}, {inst_w-eps, eps}, {inst_w-eps, inst_h-eps}, {eps, inst_h-eps}};
elem_ctx.mat().transform_polygon(poly);
ClipperLib::Path path(poly.size());
for (size_t i=0; i<poly.size(); i++) {
long long int x = poly[i][0] * clipper_scale, y = poly[i][1] * clipper_scale;
path[i] = {x, y};
}
ClipperLib::Paths out;
c.StrictlySimple(true);
c.AddPath(path, ClipperLib::ptSubject, /* closed */ true);
c.AddPaths(elem_ctx.clip(), ClipperLib::ptClip, /* closed */ true);
c.Execute(ClipperLib::ctDifference, out, ClipperLib::pftNonZero);
if (out.size() > 0) {
continue;
}
}
doc->export_svg_group(elem_ctx, _node);
}
}