mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-18 22:31:13 -06:00
Allow specifying print order within each layer (#3685)
* Allow reordering objects regardless of print seq * Add option to control the layer print order * Sort object by their order in object list instead of id * Show print order when print order is the same as the object list * Ensure the print order when print order is same as object list * Update option name --------- Co-authored-by: SoftFever <softfeverever@gmail.com>
This commit is contained in:
parent
e92be73894
commit
26505e23ee
9 changed files with 54 additions and 28 deletions
|
@ -1834,6 +1834,15 @@ static inline std::vector<const PrintInstance*> sort_object_instances_by_max_z(c
|
|||
//BBS: add sort logic for seq-print
|
||||
std::vector<const PrintInstance*> sort_object_instances_by_model_order(const Print& print, bool init_order)
|
||||
{
|
||||
auto find_object_index = [](const Model& model, const ModelObject* obj) {
|
||||
for (int index = 0; index < model.objects.size(); index++)
|
||||
{
|
||||
if (model.objects[index] == obj)
|
||||
return index;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
// Build up map from ModelInstance* to PrintInstance*
|
||||
std::vector<std::pair<const ModelInstance*, const PrintInstance*>> model_instance_to_print_instance;
|
||||
model_instance_to_print_instance.reserve(print.num_object_instances());
|
||||
|
@ -1841,10 +1850,16 @@ std::vector<const PrintInstance*> sort_object_instances_by_model_order(const Pri
|
|||
for (const PrintInstance &print_instance : print_object->instances())
|
||||
{
|
||||
if (init_order)
|
||||
const_cast<ModelInstance*>(print_instance.model_instance)->arrange_order = print_instance.model_instance->id().id;
|
||||
const_cast<ModelInstance*>(print_instance.model_instance)->arrange_order = find_object_index(print.model(), print_object->model_object());
|
||||
model_instance_to_print_instance.emplace_back(print_instance.model_instance, &print_instance);
|
||||
}
|
||||
std::sort(model_instance_to_print_instance.begin(), model_instance_to_print_instance.end(), [](auto &l, auto &r) { return l.first->arrange_order < r.first->arrange_order; });
|
||||
if (init_order) {
|
||||
// Re-assign the arrange_order so each instance has a unique order number
|
||||
for (int k = 0; k < model_instance_to_print_instance.size(); k++) {
|
||||
const_cast<ModelInstance*>(model_instance_to_print_instance[k].first)->arrange_order = k + 1;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<const PrintInstance*> instances;
|
||||
instances.reserve(model_instance_to_print_instance.size());
|
||||
|
@ -2203,8 +2218,11 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
|||
// In non-sequential print, the printing extruders may have been modified by the extruder switches stored in Model::custom_gcode_per_print_z.
|
||||
// Therefore initialize the printing extruders from there.
|
||||
this->set_extruders(tool_ordering.all_extruders());
|
||||
// Order object instances using a nearest neighbor search.
|
||||
print_object_instances_ordering = chain_print_object_instances(print);
|
||||
print_object_instances_ordering =
|
||||
// By default, order object instances using a nearest neighbor search.
|
||||
print.config().print_order == PrintOrder::Default ? chain_print_object_instances(print)
|
||||
// Otherwise same order as the object list
|
||||
: sort_object_instances_by_model_order(print);
|
||||
}
|
||||
if (initial_extruder_id == (unsigned int)-1) {
|
||||
// Nothing to print!
|
||||
|
@ -3972,7 +3990,7 @@ LayerResult GCode::process_layer(
|
|||
std::vector<InstanceToPrint> instances_to_print;
|
||||
bool has_prime_tower = print.config().enable_prime_tower
|
||||
&& print.extruders().size() > 1
|
||||
&& (print.config().print_sequence == PrintSequence::ByLayer
|
||||
&& ((print.config().print_sequence == PrintSequence::ByLayer && print.config().print_order == PrintOrder::Default)
|
||||
|| (print.config().print_sequence == PrintSequence::ByObject && print.objects().size() == 1));
|
||||
if (has_prime_tower) {
|
||||
int plate_idx = print.get_plate_index();
|
||||
|
|
|
@ -786,7 +786,7 @@ static std::vector<std::string> s_Preset_print_options {
|
|||
"independent_support_layer_height",
|
||||
"support_angle", "support_interface_top_layers", "support_interface_bottom_layers",
|
||||
"support_interface_pattern", "support_interface_spacing", "support_interface_loop_pattern",
|
||||
"support_top_z_distance", "support_on_build_plate_only","support_critical_regions_only", "bridge_no_support", "thick_bridges", "thick_internal_bridges","dont_filter_internal_bridges", "max_bridge_length", "print_sequence", "support_remove_small_overhang",
|
||||
"support_top_z_distance", "support_on_build_plate_only","support_critical_regions_only", "bridge_no_support", "thick_bridges", "thick_internal_bridges","dont_filter_internal_bridges", "max_bridge_length", "print_sequence", "print_order", "support_remove_small_overhang",
|
||||
"filename_format", "wall_filament", "support_bottom_z_distance",
|
||||
"sparse_infill_filament", "solid_infill_filament", "support_filament", "support_interface_filament","support_interface_not_for_body",
|
||||
"ooze_prevention", "standby_temperature_delta", "interface_shells", "line_width", "initial_layer_line_width",
|
||||
|
|
|
@ -314,6 +314,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
|||
//|| opt_key == "resolution"
|
||||
//BBS: when enable arc fitting, we must re-generate perimeter
|
||||
|| opt_key == "enable_arc_fitting"
|
||||
|| opt_key == "print_order"
|
||||
|| opt_key == "wall_sequence") {
|
||||
osteps.emplace_back(posPerimeters);
|
||||
osteps.emplace_back(posEstimateCurledExtrusions);
|
||||
|
|
|
@ -195,6 +195,12 @@ static t_config_enum_values s_keys_map_PrintSequence {
|
|||
};
|
||||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PrintSequence)
|
||||
|
||||
static t_config_enum_values s_keys_map_PrintOrder{
|
||||
{ "default", int(PrintOrder::Default) },
|
||||
{ "as_obj_list", int(PrintOrder::AsObjectList)},
|
||||
};
|
||||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PrintOrder)
|
||||
|
||||
static t_config_enum_values s_keys_map_SlicingMode {
|
||||
{ "regular", int(SlicingMode::Regular) },
|
||||
{ "even_odd", int(SlicingMode::EvenOdd) },
|
||||
|
@ -1171,6 +1177,17 @@ void PrintConfigDef::init_fff_params()
|
|||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionEnum<PrintSequence>(PrintSequence::ByLayer));
|
||||
|
||||
def = this->add("print_order", coEnum);
|
||||
def->label = L("Layer order");
|
||||
def->tooltip = L("Print order within a single layer");
|
||||
def->enum_keys_map = &ConfigOptionEnum<PrintOrder>::get_enum_values();
|
||||
def->enum_values.push_back("default");
|
||||
def->enum_values.push_back("as_obj_list");
|
||||
def->enum_labels.push_back(L("Default"));
|
||||
def->enum_labels.push_back(L("As object list"));
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionEnum<PrintOrder>(PrintOrder::Default));
|
||||
|
||||
def = this->add("slow_down_for_layer_cooling", coBools);
|
||||
def->label = L("Slow printing down for better layer cooling");
|
||||
def->tooltip = L("Enable this option to slow printing speed down to make the final layer time not shorter than "
|
||||
|
|
|
@ -106,6 +106,13 @@ enum class PrintSequence {
|
|||
Count,
|
||||
};
|
||||
|
||||
enum class PrintOrder
|
||||
{
|
||||
Default,
|
||||
AsObjectList,
|
||||
Count,
|
||||
};
|
||||
|
||||
enum class SlicingMode
|
||||
{
|
||||
// Regular, applying ClipperLib::pftNonZero rule when creating ExPolygons.
|
||||
|
@ -1101,6 +1108,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
|||
((ConfigOptionInts, overhang_fan_speed))
|
||||
((ConfigOptionEnumsGeneric, overhang_fan_threshold))
|
||||
((ConfigOptionEnum<PrintSequence>,print_sequence))
|
||||
((ConfigOptionEnum<PrintOrder>, print_order))
|
||||
((ConfigOptionInts, first_layer_print_sequence))
|
||||
((ConfigOptionBools, slow_down_for_layer_cooling))
|
||||
((ConfigOptionInts, close_fan_the_first_x_layers))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue