Merge branch 'lm_cancel_object' into master_27x (SPE-1864)

This commit is contained in:
Lukas Matena 2024-03-11 12:53:12 +01:00
commit 718afc9876
3 changed files with 62 additions and 37 deletions

View File

@ -1136,7 +1136,7 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
this->print_machine_envelope(file, print); this->print_machine_envelope(file, print);
// Label all objects so printer knows about them since the start. // Label all objects so printer knows about them since the start.
m_label_objects.init(print); m_label_objects.init(print.objects(), print.config().gcode_label_objects, print.config().gcode_flavor);
file.write(m_label_objects.all_objects_header()); file.write(m_label_objects.all_objects_header());
// Update output variables after the extruders were initialized. // Update output variables after the extruders were initialized.
@ -1402,6 +1402,9 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
char buf[1024]; char buf[1024];
sprintf(buf, "%.2lf", m_max_layer_z); sprintf(buf, "%.2lf", m_max_layer_z);
binary_data.printer_metadata.raw_data.emplace_back("max_layer_z", buf); binary_data.printer_metadata.raw_data.emplace_back("max_layer_z", buf);
// Now the objects info.
binary_data.printer_metadata.raw_data.emplace_back("objects_info", m_label_objects.all_objects_header_singleline_json());
} }
else { else {
// if exporting gcode in ascii format, statistics export is done here // if exporting gcode in ascii format, statistics export is done here
@ -1413,6 +1416,8 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
file.write_format("; total toolchanges = %i\n", print.m_print_statistics.total_toolchanges); file.write_format("; total toolchanges = %i\n", print.m_print_statistics.total_toolchanges);
file.write_format(";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Estimated_Printing_Time_Placeholder).c_str()); file.write_format(";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Estimated_Printing_Time_Placeholder).c_str());
file.write_format("; objects_info = %s\n", m_label_objects.all_objects_header_singleline_json().c_str());
// if exporting gcode in ascii format, config export is done here // if exporting gcode in ascii format, config export is done here
// Append full config, delimited by two 'phony' configuration keys prusaslicer_config = begin and prusaslicer_config = end. // Append full config, delimited by two 'phony' configuration keys prusaslicer_config = begin and prusaslicer_config = end.
// The delimiters are structured as configuration key / value pairs to be parsable by older versions of PrusaSlicer G-code viewer. // The delimiters are structured as configuration key / value pairs to be parsable by older versions of PrusaSlicer G-code viewer.

View File

@ -5,6 +5,8 @@
#include "Print.hpp" #include "Print.hpp"
#include "TriangleMeshSlicer.hpp" #include "TriangleMeshSlicer.hpp"
#include "boost/algorithm/string/replace.hpp"
namespace Slic3r::GCode { namespace Slic3r::GCode {
@ -39,10 +41,10 @@ Polygon instance_outline(const PrintInstance* pi)
}; // anonymous namespace }; // anonymous namespace
void LabelObjects::init(const Print& print) void LabelObjects::init(const SpanOfConstPtrs<PrintObject>& objects, LabelObjectsStyle label_object_style, GCodeFlavor gcode_flavor)
{ {
m_label_objects_style = print.config().gcode_label_objects; m_label_objects_style = label_object_style;
m_flavor = print.config().gcode_flavor; m_flavor = gcode_flavor;
if (m_label_objects_style == LabelObjectsStyle::Disabled) if (m_label_objects_style == LabelObjectsStyle::Disabled)
return; return;
@ -51,7 +53,7 @@ void LabelObjects::init(const Print& print)
// Iterate over all PrintObjects and their PrintInstances, collect PrintInstances which // Iterate over all PrintObjects and their PrintInstances, collect PrintInstances which
// belong to the same ModelObject. // belong to the same ModelObject.
for (const PrintObject* po : print.objects()) for (const PrintObject* po : objects)
for (const PrintInstance& pi : po->instances()) for (const PrintInstance& pi : po->instances())
model_object_to_print_instances[pi.model_instance->get_object()].emplace_back(&pi); model_object_to_print_instances[pi.model_instance->get_object()].emplace_back(&pi);
@ -87,7 +89,23 @@ void LabelObjects::init(const Print& print)
} }
} }
m_label_data.emplace(pi, LabelData{name, unique_id}); // Now calculate the polygon and center for Cancel Object (this is not always used).
Polygon outline = instance_outline(pi);
assert(! outline.empty());
outline.douglas_peucker(50000.f);
Point center = outline.centroid();
char buffer[64];
std::snprintf(buffer, sizeof(buffer) - 1, "%.3f,%.3f", unscale<float>(center[0]), unscale<float>(center[1]));
std::string center_str(buffer);
std::string polygon_str = std::string("[");
for (const Point& point : outline) {
std::snprintf(buffer, sizeof(buffer) - 1, "[%.3f,%.3f],", unscale<float>(point[0]), unscale<float>(point[1]));
polygon_str += buffer;
}
polygon_str.pop_back();
polygon_str += "]";
m_label_data.emplace_back(LabelData{pi, name, center_str, polygon_str, unique_id});
++unique_id; ++unique_id;
} }
} }
@ -102,35 +120,31 @@ std::string LabelObjects::all_objects_header() const
std::string out; std::string out;
// Let's sort the values according to unique_id so they are in the same order in which they were added. out += "\n";
std::vector<std::pair<const PrintInstance*, LabelData>> label_data_sorted; for (const LabelData& label : m_label_data) {
for (const auto& pi_and_label : m_label_data) if (m_label_objects_style == LabelObjectsStyle::Firmware && m_flavor == gcfKlipper)
label_data_sorted.emplace_back(pi_and_label); out += "EXCLUDE_OBJECT_DEFINE NAME='" + label.name + "' CENTER=" + label.center + " POLYGON=" + label.polygon + "\n";
std::sort(label_data_sorted.begin(), label_data_sorted.end(), [](const auto& ld1, const auto& ld2) { return ld1.second.unique_id < ld2.second.unique_id; }); else {
out += start_object(*label.pi, IncludeName::Yes);
out += stop_object(*label.pi);
}
}
out += "\n";
return out;
}
out += "\n"; std::string LabelObjects::all_objects_header_singleline_json() const
for (const auto& [print_instance, label] : label_data_sorted) { {
if (m_label_objects_style == LabelObjectsStyle::Firmware && m_flavor == gcfKlipper) { std::string out;
char buffer[64]; out = "{\"objects\":[";
out += "EXCLUDE_OBJECT_DEFINE NAME='" + label.name + "'"; for (size_t i=0; i<m_label_data.size(); ++i) {
Polygon outline = instance_outline(print_instance); const LabelData& label = m_label_data[i];
assert(! outline.empty()); out += std::string("{\"name\":\"") + label.name + "\",";
outline.douglas_peucker(50000.f); out += "\"polygon\":" + label.polygon + "}";
Point center = outline.centroid(); if (i != m_label_data.size() - 1)
std::snprintf(buffer, sizeof(buffer) - 1, " CENTER=%.3f,%.3f", unscale<float>(center[0]), unscale<float>(center[1])); out += ",";
out += buffer + std::string(" POLYGON=[");
for (const Point& point : outline) {
std::snprintf(buffer, sizeof(buffer) - 1, "[%.3f,%.3f],", unscale<float>(point[0]), unscale<float>(point[1]));
out += buffer;
} }
out.pop_back(); out += "]}";
out += "]\n";
} else {
out += start_object(*print_instance, IncludeName::Yes);
out += stop_object(*print_instance);
}
}
out += "\n";
return out; return out;
} }
@ -141,7 +155,7 @@ std::string LabelObjects::start_object(const PrintInstance& print_instance, Incl
if (m_label_objects_style == LabelObjectsStyle::Disabled) if (m_label_objects_style == LabelObjectsStyle::Disabled)
return std::string(); return std::string();
const LabelData& label = m_label_data.at(&print_instance); const LabelData& label = *std::find_if(m_label_data.begin(), m_label_data.end(), [&print_instance](const LabelData& ld) { return ld.pi == &print_instance; });
std::string out; std::string out;
if (m_label_objects_style == LabelObjectsStyle::Octoprint) if (m_label_objects_style == LabelObjectsStyle::Octoprint)
@ -170,7 +184,7 @@ std::string LabelObjects::stop_object(const PrintInstance& print_instance) const
if (m_label_objects_style == LabelObjectsStyle::Disabled) if (m_label_objects_style == LabelObjectsStyle::Disabled)
return std::string(); return std::string();
const LabelData& label = m_label_data.at(&print_instance); const LabelData& label = *std::find_if(m_label_data.begin(), m_label_data.end(), [&print_instance](const LabelData& ld) { return ld.pi == &print_instance; });
std::string out; std::string out;
if (m_label_objects_style == LabelObjectsStyle::Octoprint) if (m_label_objects_style == LabelObjectsStyle::Octoprint)

View File

@ -2,7 +2,9 @@
#define slic3r_GCode_LabelObjects_hpp_ #define slic3r_GCode_LabelObjects_hpp_
#include <string> #include <string>
#include <unordered_map> #include <vector>
#include "libslic3r/Print.hpp"
namespace Slic3r { namespace Slic3r {
@ -21,20 +23,24 @@ public:
No, No,
Yes Yes
}; };
void init(const Print& print); void init(const SpanOfConstPtrs<PrintObject>& objects, LabelObjectsStyle label_object_style, GCodeFlavor gcode_flavor);
std::string all_objects_header() const; std::string all_objects_header() const;
std::string all_objects_header_singleline_json() const;
std::string start_object(const PrintInstance& print_instance, IncludeName include_name) const; std::string start_object(const PrintInstance& print_instance, IncludeName include_name) const;
std::string stop_object(const PrintInstance& print_instance) const; std::string stop_object(const PrintInstance& print_instance) const;
private: private:
struct LabelData { struct LabelData {
const PrintInstance* pi;
std::string name; std::string name;
std::string center;
std::string polygon;
int unique_id; int unique_id;
}; };
LabelObjectsStyle m_label_objects_style; LabelObjectsStyle m_label_objects_style;
GCodeFlavor m_flavor; GCodeFlavor m_flavor;
std::unordered_map<const PrintInstance*, LabelData> m_label_data; std::vector<LabelData> m_label_data;
}; };