support Klipper Exclude objects natively.

Also remove fake slicer info
This commit is contained in:
SoftFever 2023-04-01 13:25:55 +08:00
parent 32d952587d
commit 22a24168e6
11 changed files with 141 additions and 34 deletions

View file

@ -1530,12 +1530,6 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
print.config().nozzle_temperature_initial_layer.get_at(0));
file.write("; CONFIG_BLOCK_END\n\n");
} else {
file.write_format("; hack-fix: write fake slicer info here so that "
"preprocess_cancellation can process.\n");
file.write_format("; %s\n\n", std::string(std::string("generated by SuperSlicer " SoftFever_VERSION " on ") +
Slic3r::Utils::local_timestamp())
.c_str());
DoExport::export_thumbnails_to_file(
thumbnail_cb, print.get_plate_index(), print.full_print_config().option<ConfigOptionPoints>("thumbnails")->values,
[&file](const char *sz) { file.write(sz); },
@ -1563,6 +1557,10 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
}
file.write_format("; EXECUTABLE_BLOCK_START\n");
// SoftFever
file.write(set_object_info(&print));
// adds tags for time estimators
file.write_format(";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::First_Line_M73_Placeholder).c_str());
@ -2474,7 +2472,7 @@ std::vector<GCode::InstanceToPrint> GCode::sort_print_object_instances(
const PrintObject *print_object = layers[layer_id].original_object;
//const PrintObject *print_object = layers[layer_id].object();
if (print_object)
out.emplace_back(object_by_extruder, layer_id, *print_object, single_object_instance_idx);
out.emplace_back(object_by_extruder, *print_object, single_object_instance_idx);
}
} else {
// Create mapping from PrintObject* to ObjectByExtruder*.
@ -2502,7 +2500,7 @@ std::vector<GCode::InstanceToPrint> GCode::sort_print_object_instances(
auto it = std::lower_bound(sorted.begin(), sorted.end(), key);
if (it != sorted.end() && it->first == &print_object)
// ObjectByExtruder for this PrintObject was found.
out.emplace_back(*it->second, it->second - objects_by_extruder.data(), print_object, instance - print_object.instances().data());
out.emplace_back(*it->second, print_object, instance->id);
}
}
}
@ -2670,6 +2668,14 @@ namespace Skirt {
} // namespace Skirt
inline std::string get_instance_name(const PrintObject *object, const PrintInstance &inst) {
return (boost::format("%1%_id_%2%_copy_%3%") % object->model_object()->name % object->get_id() % inst.id).str();
}
inline std::string get_instance_name(const PrintObject *object, size_t inst_id) {
return (boost::format("%1%_id_%2%_copy_%3%") % object->model_object()->name % object->get_id() % inst_id).str();
}
// In sequential mode, process_layer is called once per each object and its copy,
// therefore layers will contain a single entry and single_object_instance_idx will point to the copy of the object.
// In non-sequential mode, process_layer is called per each print_z height with all object and support layers accumulated.
@ -3172,7 +3178,7 @@ GCode::LayerResult GCode::process_layer(
if (is_anything_overridden && print_wipe_extrusions == 0)
gcode+="; PURGING FINISHED\n";
for (InstanceToPrint &instance_to_print : instances_to_print) {
const LayerToPrint &layer_to_print = layers[instance_to_print.layer_id];
const LayerToPrint &layer_to_print = layers[instance_to_print.get_object_id()];
// To control print speed of the 1st object layer printed over raft interface.
bool object_layer_over_raft = layer_to_print.object_layer && layer_to_print.object_layer->id() > 0 &&
instance_to_print.print_object.slicing_parameters().raft_layers() == layer_to_print.object_layer->id();
@ -3181,11 +3187,19 @@ GCode::LayerResult GCode::process_layer(
m_object_layer_over_raft = object_layer_over_raft;
if (m_config.reduce_crossing_wall)
m_avoid_crossing_perimeters.init_layer(*m_layer);
bool reset_e = false;
if (this->config().gcode_label_objects) {
gcode += std::string("; printing object ") + instance_to_print.print_object.model_object()->name + " id:" + std::to_string(instance_to_print.layer_id) + " copy " + std::to_string(instance_to_print.instance_id) + "\n";
if (!m_config.use_relative_e_distances)
gcode += m_writer.reset_e(true);
gcode += std::string("; printing object ") + instance_to_print.print_object.model_object()->name + " id:" + std::to_string(instance_to_print.print_object.get_id()) + " copy " + std::to_string(instance_to_print.instance_id) + "\n";
reset_e = true;
}
if (this->config().exclude_object && print.config().gcode_flavor.value == gcfKlipper) {
gcode += std::string("EXCLUDE_OBJECT_START NAME=") +
get_instance_name(&instance_to_print.print_object, instance_to_print.instance_id) + "\n";
reset_e = true;
}
// ref to: https://github.com/SoftFever/OrcaSlicer/pull/205/commits/7f1fe0bd544077626080aa1a9a0576aa735da1a4#r1083470162
if (reset_e && !m_config.use_relative_e_distances)
gcode += m_writer.reset_e(true);
m_extrusion_quality_estimator.set_current_object(&instance_to_print.print_object);
// When starting a new object, use the external motion planner for the first travel move.
@ -3196,7 +3210,7 @@ GCode::LayerResult GCode::process_layer(
m_last_obj_copy = this_object_copy;
this->set_origin(unscale(offset));
if (instance_to_print.object_by_extruder.support != nullptr) {
m_layer = layers[instance_to_print.layer_id].support_layer;
m_layer = layers[instance_to_print.get_object_id()].support_layer;
m_object_layer_over_raft = false;
//BBS: print supports' brims first
@ -3274,10 +3288,16 @@ GCode::LayerResult GCode::process_layer(
gcode += this->extrude_infill(print,by_region_specific, true);
}
if (this->config().gcode_label_objects) {
gcode += std::string("; stop printing object ") + instance_to_print.print_object.model_object()->name + " id:" + std::to_string(instance_to_print.layer_id) + " copy " + std::to_string(instance_to_print.instance_id) + "\n";
if (!m_config.use_relative_e_distances)
gcode += m_writer.reset_e(true);
gcode += std::string("; stop printing object ") + instance_to_print.print_object.model_object()->name + " id:" + std::to_string(instance_to_print.print_object.get_id()) + " copy " + std::to_string(instance_to_print.instance_id) + "\n";
reset_e = true;
}
if (this->config().exclude_object && print.config().gcode_flavor.value == gcfKlipper) {
gcode += std::string("EXCLUDE_OBJECT_END NAME=") +
get_instance_name(&instance_to_print.print_object, instance_to_print.instance_id) + "\n";
reset_e = true;
}
if (reset_e && !m_config.use_relative_e_distances)
gcode += m_writer.reset_e(true);
}
}
}
@ -4591,6 +4611,37 @@ std::string GCode::set_extruder(unsigned int extruder_id, double print_z)
return gcode;
}
inline std::string polygon_to_string(const Polygon &polygon) {
std::ostringstream gcode;
gcode << "[";
for (const Point &p : polygon.points) {
gcode << "[" << unscaled(p.x()) << "," << unscaled(p.y()) << "],";
}
gcode << "[" << unscaled(polygon.points.front().x()) << "," << unscaled(polygon.points.front().y()) << "]";
gcode << "]";
return gcode.str();
}
// this function iterator PrintObject and assign a seqential id to each object.
// this id is used to generate unique object id for each object.
std::string GCode::set_object_info(Print* print) {
std::ostringstream gcode;
size_t object_id = 0;
for (PrintObject* object : print->objects()) {
object->set_id(object_id++);
size_t inst_id = 0;
for (PrintInstance &inst : object->instances()) {
inst.id = inst_id;
if (this->config().exclude_object && print->config().gcode_flavor.value == gcfKlipper) {
auto bbox = inst.get_bounding_box();
gcode << "EXCLUDE_OBJECT_DEFINE NAME=" << get_instance_name(object, inst)
<< " CENTER=" << bbox.center().x() << "," << bbox.center().y()
<< " POLYGON=" << polygon_to_string(inst.get_convex_hull_2d()) << "\n";
}
}
}
return gcode.str();
}
// convert a model-space scaled point into G-code coordinates
Vec2d GCode::point_to_gcode(const Point &point) const
{
@ -4714,4 +4765,10 @@ void GCode::ObjectByExtruder::Island::Region::append(const Type type, const Extr
}
}
} // namespace Slic3r
// Index into std::vector<LayerToPrint>, which contains Object and Support layers for the current print_z, collected for
// a single object, or for possibly multiple objects with multiple instances.
inline size_t GCode::InstanceToPrint::get_object_id() const { return print_object.get_id(); }
} // namespace Slic3r