From 2eb127240f6e3f709d55ffd8a8dfec2272066973 Mon Sep 17 00:00:00 2001 From: supermerill Date: Mon, 31 Jan 2022 18:40:22 +0100 Subject: [PATCH] Fix first_layer_print_min and first_layer_print_max when complete_objects supermerill/SuperSlicer#2201 --- src/libslic3r/GCode.cpp | 64 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 5c7e36042..23146f3ec 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1389,7 +1389,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu m_placeholder_parser.set("print_bed_max", new ConfigOptionFloats({ bbox.max.x(), bbox.max.y() })); m_placeholder_parser.set("print_bed_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() })); } - { + if(!print.config().complete_objects.value){ // Convex hull of the 1st layer extrusions, for bed leveling and placing the initial purge line. // It encompasses the object extrusions, support extrusions, skirt, brim, wipe tower. // It does NOT encompass user extrusions generated by custom G-code, @@ -1404,6 +1404,68 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu m_placeholder_parser.set("first_layer_print_min", new ConfigOptionFloats({ bbox.min.x(), bbox.min.y() })); m_placeholder_parser.set("first_layer_print_max", new ConfigOptionFloats({ bbox.max.x(), bbox.max.y() })); m_placeholder_parser.set("first_layer_print_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() })); + } else { + //have to compute it ourself :-/ + class BoundingBoxVisitor : public ExtrusionVisitorRecursiveConst { + public: + Point offset; + Points hull; + virtual void use(const ExtrusionPath& path) override { + for (Point pt : path.polyline.points) { + pt += offset; + hull.emplace_back(std::move(pt)); + } + } + virtual void use(const ExtrusionPath3D& path3D) override { + for (Point pt : path3D.polyline.points) { + pt += offset; + hull.emplace_back(std::move(pt)); + } + } + BoundingBoxf get_bb() { + BoundingBox bbox(hull); + return BoundingBoxf(unscaled(bbox.min), unscaled(bbox.max)); + } + Polygon get_hull() { return Geometry::convex_hull(hull); } + } bbvisitor; + if (print.skirt_first_layer().has_value()) { + print.skirt_first_layer()->visit(bbvisitor); + } else if (print.skirt().entities().size() > 0) { + print.skirt().visit(bbvisitor); + } else if (print.config().complete_objects_one_brim.value && !print.brim().empty()) { + print.brim().visit(bbvisitor); + } else { + print.brim().visit(bbvisitor); + for (const PrintObject* po : print.objects()) { + for (const PrintInstance& inst : po->instances()) { + bbvisitor.offset = inst.shift; + if (po->skirt_first_layer().has_value()) { + po->skirt_first_layer()->visit(bbvisitor); + } else if (po->skirt().entities().size() > 0) { + po->skirt().visit(bbvisitor); + } else { + po->brim().visit(bbvisitor); + if (po->layers().empty()) continue; + const Layer* l = po->layers().front(); + if (l->id() != 0) continue; + for (const LayerRegion* lr : l->regions()) { + lr->perimeters.visit(bbvisitor); + lr->fills.visit(bbvisitor); + } + } + } + } + } + BoundingBoxf bbox = bbvisitor.get_bb(); + Polygon first_layer_hull = bbvisitor.get_hull(); + auto pts = std::make_unique(); + pts->values.reserve(first_layer_hull.size()); + for (const Point& pt : first_layer_hull.points) + pts->values.emplace_back(unscale(pt)); + m_placeholder_parser.set("first_layer_print_convex_hull", pts.release()); + m_placeholder_parser.set("first_layer_print_min", new ConfigOptionFloats({ bbox.min.x(), bbox.min.y() })); + m_placeholder_parser.set("first_layer_print_max", new ConfigOptionFloats({ bbox.max.x(), bbox.max.y() })); + m_placeholder_parser.set("first_layer_print_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() })); } //misc if (config().thumbnails_color.value.length() == 7) {