Add group id include/exclude matching
This commit is contained in:
parent
70d0021df1
commit
5285b6dce8
3 changed files with 56 additions and 10 deletions
|
|
@ -76,6 +76,14 @@ namespace gerbolyze {
|
|||
bool m_only_polys = false;
|
||||
std::ostream &m_out;
|
||||
};
|
||||
|
||||
class ElementSelector {
|
||||
public:
|
||||
bool match(const pugi::xml_node &node, bool included) const;
|
||||
|
||||
std::vector<std::string> include;
|
||||
std::vector<std::string> exclude;
|
||||
};
|
||||
|
||||
class SVGDocument {
|
||||
public:
|
||||
|
|
@ -95,8 +103,8 @@ namespace gerbolyze {
|
|||
double width() const { return page_w_mm; }
|
||||
double height() const { return page_h_mm; }
|
||||
|
||||
void render(PolygonSink &sink);
|
||||
void render_to_list(std::vector<std::pair<Polygon, GerberPolarityToken>> &out);
|
||||
void render(PolygonSink &sink, const ElementSelector *sel=nullptr);
|
||||
void render_to_list(std::vector<std::pair<Polygon, GerberPolarityToken>> &out, const ElementSelector *sel=nullptr);
|
||||
|
||||
private:
|
||||
friend class Pattern;
|
||||
|
|
@ -105,7 +113,7 @@ namespace gerbolyze {
|
|||
const ClipperLib::Paths *lookup_clip_path(const pugi::xml_node &node);
|
||||
Pattern *lookup_pattern(const std::string id);
|
||||
|
||||
void export_svg_group(const pugi::xml_node &group, ClipperLib::Paths &parent_clip_path);
|
||||
void export_svg_group(const pugi::xml_node &group, ClipperLib::Paths &parent_clip_path, const ElementSelector *sel=nullptr, bool included=true);
|
||||
void export_svg_path(const pugi::xml_node &node, ClipperLib::Paths &clip_path);
|
||||
void setup_debug_output(std::string filename="");
|
||||
void setup_viewport_clip();
|
||||
|
|
|
|||
23
src/main.cpp
23
src/main.cpp
|
|
@ -38,6 +38,13 @@ 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},
|
||||
{"only_groups", {"-g", "--only-groups"},
|
||||
"Comma-separated list of group IDs to export.",
|
||||
1},
|
||||
{"exclude_groups", {"-e", "--exclude-groups"},
|
||||
"Comma-separated list of group IDs to exclude from export. Takes precedence over --only-groups.",
|
||||
1},
|
||||
|
||||
}};
|
||||
|
||||
|
||||
|
|
@ -143,7 +150,21 @@ int main(int argc, char **argv) {
|
|||
flattener = new Flattener(*sink);
|
||||
}
|
||||
|
||||
doc.render(flattener ? *flattener : *sink);
|
||||
/* Because the C++ stdlib is bullshit */
|
||||
auto id_match = [](string in, vector<string> &out) {
|
||||
stringstream ss(in);
|
||||
while (getline(ss, out.emplace_back(), ',')) {
|
||||
}
|
||||
out.pop_back();
|
||||
};
|
||||
|
||||
ElementSelector sel;
|
||||
if (args["only_groups"])
|
||||
id_match(args["only_groups"], sel.include);
|
||||
if (args["exclude_groups"])
|
||||
id_match(args["exclude_groups"], sel.exclude);
|
||||
|
||||
doc.render(flattener ? *flattener : *sink, &sel);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,8 +116,22 @@ double gerbolyze::SVGDocument::doc_units_to_mm(double px) const {
|
|||
return px / (vb_w / page_w_mm);
|
||||
}
|
||||
|
||||
bool ElementSelector::match(const pugi::xml_node &node, bool included) const {
|
||||
if (include.empty() && exclude.empty())
|
||||
return true;
|
||||
|
||||
bool include_match = std::find(include.begin(), include.end(), node.attribute("id").value()) != include.end();
|
||||
bool exclude_match = std::find(exclude.begin(), exclude.end(), node.attribute("id").value()) != exclude.end();
|
||||
|
||||
if (exclude_match || (!included && !include_match)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Recursively export all SVG elements in the given group. */
|
||||
void gerbolyze::SVGDocument::export_svg_group(const pugi::xml_node &group, Paths &parent_clip_path) {
|
||||
void gerbolyze::SVGDocument::export_svg_group(const pugi::xml_node &group, Paths &parent_clip_path, const ElementSelector *sel, bool included) {
|
||||
/* Enter the group's coordinate system */
|
||||
cairo_save(cr);
|
||||
apply_cairo_transform_from_svg(cr, group.attribute("transform").value());
|
||||
|
|
@ -147,9 +161,12 @@ void gerbolyze::SVGDocument::export_svg_group(const pugi::xml_node &group, Paths
|
|||
|
||||
/* Iterate over the group's children, exporting them one by one. */
|
||||
for (const auto &node : group.children()) {
|
||||
if (sel && !sel->match(node, included))
|
||||
continue;
|
||||
|
||||
string name(node.name());
|
||||
if (name == "g") {
|
||||
export_svg_group(node, clip_path);
|
||||
export_svg_group(node, clip_path, sel, true);
|
||||
|
||||
} else if (name == "path") {
|
||||
export_svg_path(node, clip_path);
|
||||
|
|
@ -342,7 +359,7 @@ void gerbolyze::SVGDocument::export_svg_path(const pugi::xml_node &node, Paths &
|
|||
}
|
||||
}
|
||||
|
||||
void gerbolyze::SVGDocument::render(PolygonSink &sink) {
|
||||
void gerbolyze::SVGDocument::render(PolygonSink &sink, const ElementSelector *sel) {
|
||||
assert(_valid);
|
||||
/* Export the actual SVG document to both SVG for debuggin and to gerber. We do this as we go, i.e. we immediately
|
||||
* process each element to gerber as we encounter it instead of first rendering everything to a giant list of gerber
|
||||
|
|
@ -354,15 +371,15 @@ void gerbolyze::SVGDocument::render(PolygonSink &sink) {
|
|||
c.AddPaths(vb_paths, ptSubject, /* closed */ true);
|
||||
ClipperLib::IntRect bbox = c.GetBounds();
|
||||
cerr << "document viewbox clip: bbox={" << bbox.left << ", " << bbox.top << "} - {" << bbox.right << ", " << bbox.bottom << "}" << endl;
|
||||
export_svg_group(root_elem, vb_paths);
|
||||
export_svg_group(root_elem, vb_paths, sel, false);
|
||||
sink.footer();
|
||||
}
|
||||
|
||||
void gerbolyze::SVGDocument::render_to_list(vector<pair<Polygon, GerberPolarityToken>> &out) {
|
||||
void gerbolyze::SVGDocument::render_to_list(vector<pair<Polygon, GerberPolarityToken>> &out, const ElementSelector *sel) {
|
||||
LambdaPolygonSink sink([&out](const Polygon &poly, GerberPolarityToken pol) {
|
||||
out.emplace_back(pair<Polygon, GerberPolarityToken>{poly, pol});
|
||||
});
|
||||
render(sink);
|
||||
render(sink, sel);
|
||||
}
|
||||
|
||||
void gerbolyze::SVGDocument::setup_debug_output(string filename) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue