mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-07 23:17:35 -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))
|
||||
|
|
|
@ -661,9 +661,10 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
|||
for (auto el : { "ironing_pattern", "ironing_flow", "ironing_spacing", "ironing_speed", "ironing_angle" })
|
||||
toggle_line(el, has_ironing);
|
||||
|
||||
// bool have_sequential_printing = (config->opt_enum<PrintSequence>("print_sequence") == PrintSequence::ByObject);
|
||||
bool have_sequential_printing = (config->opt_enum<PrintSequence>("print_sequence") == PrintSequence::ByObject);
|
||||
// for (auto el : { "extruder_clearance_radius", "extruder_clearance_height_to_rod", "extruder_clearance_height_to_lid" })
|
||||
// toggle_field(el, have_sequential_printing);
|
||||
toggle_field("print_order", !have_sequential_printing);
|
||||
|
||||
bool have_ooze_prevention = config->opt_bool("ooze_prevention");
|
||||
toggle_field("standby_temperature_delta", have_ooze_prevention);
|
||||
|
|
|
@ -7304,10 +7304,10 @@ void GLCanvas3D::_render_overlays()
|
|||
|
||||
auto curr_plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
|
||||
auto curr_print_seq = curr_plate->get_real_print_seq();
|
||||
bool sequential_print = (curr_print_seq == PrintSequence::ByObject);
|
||||
const Print* print = fff_print();
|
||||
bool sequential_print = (curr_print_seq == PrintSequence::ByObject) || print->config().print_order == PrintOrder::AsObjectList;
|
||||
std::vector<const ModelInstance*> sorted_instances;
|
||||
if (sequential_print) {
|
||||
const Print* print = fff_print();
|
||||
if (print) {
|
||||
for (const PrintObject *print_object : print->objects())
|
||||
{
|
||||
|
|
|
@ -1545,26 +1545,6 @@ void ObjectList::OnBeginDrag(wxDataViewEvent &event)
|
|||
}
|
||||
|
||||
if (type & itObject) {
|
||||
int curr_obj_id = m_objects_model->GetIdByItem(event.GetItem());
|
||||
PartPlateList& partplate_list = wxGetApp().plater()->get_partplate_list();
|
||||
int from_plate = partplate_list.find_instance(curr_obj_id, 0);
|
||||
if (from_plate == -1) {
|
||||
event.Veto();
|
||||
return;
|
||||
}
|
||||
auto curr_plate_seq = partplate_list.get_plate(from_plate)->get_print_seq();
|
||||
if (curr_plate_seq == PrintSequence::ByDefault) {
|
||||
auto curr_preset_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
if (curr_preset_config.has("print_sequence"))
|
||||
curr_plate_seq = curr_preset_config.option<ConfigOptionEnum<PrintSequence>>("print_sequence")->value;
|
||||
}
|
||||
|
||||
if (curr_plate_seq != PrintSequence::ByObject) {
|
||||
//drag forbidden under bylayer mode
|
||||
event.Veto();
|
||||
return;
|
||||
}
|
||||
|
||||
m_dragged_data.init(m_objects_model->GetIdByItem(item), type);
|
||||
}
|
||||
else if (type & itVolume){
|
||||
|
|
|
@ -2188,6 +2188,7 @@ void TabPrint::build()
|
|||
optgroup = page->new_optgroup(L("Special mode"), L"param_special");
|
||||
optgroup->append_single_option_line("slicing_mode");
|
||||
optgroup->append_single_option_line("print_sequence", "sequent-print");
|
||||
optgroup->append_single_option_line("print_order");
|
||||
optgroup->append_single_option_line("spiral_mode", "spiral-vase");
|
||||
optgroup->append_single_option_line("spiral_mode_smooth", "spiral-vase#smooth");
|
||||
optgroup->append_single_option_line("spiral_mode_max_xy_smoothing", "spiral-vase#max-xy-smoothing");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue