diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index f2b4e8480b..bea09c5833 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -130,6 +130,43 @@ namespace Slic3r { return ok; } + inline std::string make_klipper_exclude_object_name(const std::string &name, int object_id, int instance_id) + { + constexpr char banned_chars[] = "-. \r\n\v\t\f"; + std::string cleaned_name = name; + const char *next = cleaned_name.c_str(); + while (next = std::strpbrk(next, banned_chars)) + cleaned_name[next - cleaned_name.c_str()] = '_'; + return cleaned_name + "_id_" + std::to_string(object_id) + "_copy_" + std::to_string(instance_id); + } + + // Label excluded objects for Klipper + std::string make_klipper_exclude_object_header(const Print &print) { + std::string output; + int object_id = 0; + for (auto object : print.objects()) { + int instance_id = 0; + for (auto instance : object->instances()) { + char buffer[64]; + output += "EXCLUDE_OBJECT_DEFINE NAME="; + output += make_klipper_exclude_object_name(object->model_object()->name, object_id, instance_id++); + Polygon outline = object->model_object()->convex_hull_2d(instance.model_instance->get_matrix()); + outline.douglas_peucker(50000.f); + auto center = outline.centroid(); + std::snprintf(buffer, sizeof(buffer) - 1, " CENTER=%.3f,%.3f", unscale(center[0]), unscale(center[1])); + output += buffer + std::string(" POLYGON=["); + for (auto point : outline) { + std::snprintf(buffer, sizeof(buffer) - 1, "[%.3f,%.3f],", unscale(point[0]), unscale(point[1])); + output += buffer; + } + output.pop_back(); + output += "]\n"; + } + ++object_id; + } + return output; + } + std::string OozePrevention::pre_toolchange(GCodeGenerator &gcodegen) { std::string gcode;