NEW: vase mode can be applied to one plate

jira: STUDIO-5838

Change-Id: Ifb315f7d79b570aeb7ee31d3495b4d465e3af0c6
This commit is contained in:
liz.li 2024-02-29 19:15:29 +08:00 committed by Lane.Wei
parent 17e4389220
commit 3fbc9931cb
9 changed files with 161 additions and 71 deletions

View File

@ -1026,7 +1026,7 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
if (m_config.spiral_mode) {
size_t total_copies_count = 0;
for (const PrintObject *object : m_objects)
for (const PrintObject* object : m_objects)
total_copies_count += object->instances().size();
// #4043
if (total_copies_count > 1 && m_config.print_sequence != PrintSequence::ByObject)

View File

@ -187,7 +187,7 @@ void ConfigManipulation::check_chamber_temperature(DynamicPrintConfig* config)
}
}
void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, const bool is_global_config)
void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, const bool is_global_config, const bool is_plate_config)
{
// #ys_FIXME_to_delete
//! Temporary workaround for the correct updates of the TextCtrl (like "layer_height"):
@ -197,6 +197,8 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
if (is_msg_dlg_already_exist)
return;
bool is_object_config = (!is_global_config && !is_plate_config);
// layer_height shouldn't be equal to zero
if (config->opt_float("layer_height") < EPSILON)
{
@ -299,34 +301,21 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
double sparse_infill_density = config->option<ConfigOptionPercent>("sparse_infill_density")->value;
auto timelapse_type = config->opt_enum<TimelapseType>("timelapse_type");
if (config->opt_bool("spiral_mode") &&
! (config->opt_int("wall_loops") == 1 &&
config->opt_int("top_shell_layers") == 0 &&
sparse_infill_density == 0 &&
! config->opt_bool("enable_support") &&
config->opt_int("enforce_support_layers") == 0 &&
config->opt_bool("ensure_vertical_shell_thickness") &&
! config->opt_bool("detect_thin_wall") &&
if (!is_plate_config &&
config->opt_bool("spiral_mode") &&
!(config->opt_int("wall_loops") == 1 &&
config->opt_int("top_shell_layers") == 0 &&
sparse_infill_density == 0 &&
!config->opt_bool("enable_support") &&
config->opt_int("enforce_support_layers") == 0 &&
config->opt_bool("ensure_vertical_shell_thickness") &&
!config->opt_bool("detect_thin_wall") &&
config->opt_enum<TimelapseType>("timelapse_type") == TimelapseType::tlTraditional))
{
wxString msg_text = _(L("Spiral mode only works when wall loops is 1, support is disabled, top shell layers is 0, sparse infill density is 0 and timelapse type is traditional."));
auto printer_structure_opt = wxGetApp().preset_bundle->printers.get_edited_preset().config.option<ConfigOptionEnum<PrinterStructure>>("printer_structure");
if (printer_structure_opt && printer_structure_opt->value == PrinterStructure::psI3) {
msg_text += _(L(" But machines with I3 structure will not generate timelapse videos."));
}
if (is_global_config)
msg_text += "\n\n" + _(L("Change these settings automatically? \n"
"Yes - Change these settings and enable spiral mode automatically\n"
"No - Give up using spiral mode this time"));
MessageDialog dialog(m_msg_dlg_parent, msg_text, "",
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
DynamicPrintConfig new_conf = *config;
is_msg_dlg_already_exist = true;
auto answer = dialog.ShowModal();
auto answer = show_spiral_mode_settings_dialog(is_object_config);
bool support = true;
if (!is_global_config || answer == wxID_YES) {
if (answer == wxID_YES) {
new_conf.set_key_value("wall_loops", new ConfigOptionInt(1));
new_conf.set_key_value("top_shell_layers", new ConfigOptionInt(0));
new_conf.set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
@ -498,7 +487,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
DynamicPrintConfig new_conf = *config;
is_msg_dlg_already_exist = true;
auto answer = dialog.ShowModal();
if (!is_global_config || answer == wxID_YES) {
if (is_object_config || answer == wxID_YES) {
new_conf.set_key_value("sparse_infill_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
sparse_infill_density = 100;
}
@ -813,5 +802,28 @@ void ConfigManipulation::toggle_print_sla_options(DynamicPrintConfig* config)
toggle_field("pad_object_connector_penetration", zero_elev);
}
int ConfigManipulation::show_spiral_mode_settings_dialog(bool is_object_config)
{
wxString msg_text = _(L("Spiral mode only works when wall loops is 1, support is disabled, top shell layers is 0, sparse infill density is 0 and timelapse type is traditional."));
auto printer_structure_opt = wxGetApp().preset_bundle->printers.get_edited_preset().config.option<ConfigOptionEnum<PrinterStructure>>("printer_structure");
if (printer_structure_opt && printer_structure_opt->value == PrinterStructure::psI3) {
msg_text += _(L(" But machines with I3 structure will not generate timelapse videos."));
}
if (!is_object_config)
msg_text += "\n\n" + _(L("Change these settings automatically? \n"
"Yes - Change these settings and enable spiral mode automatically\n"
"No - Give up using spiral mode this time"));
MessageDialog dialog(m_msg_dlg_parent, msg_text, "",
wxICON_WARNING | (!is_object_config ? wxYES | wxNO : wxOK));
is_msg_dlg_already_exist = true;
auto answer = dialog.ShowModal();
is_msg_dlg_already_exist = false;
if (is_object_config)
answer = wxID_YES;
return answer;
}
} // GUI
} // Slic3r

View File

@ -69,7 +69,7 @@ public:
void toggle_line(const std::string& field_key, const bool toggle);
// FFF print
void update_print_fff_config(DynamicPrintConfig* config, const bool is_global_config = false);
void update_print_fff_config(DynamicPrintConfig* config, const bool is_global_config = false, const bool is_plate_config = false);
void toggle_print_fff_options(DynamicPrintConfig* config, const bool is_global_config = false);
void apply_null_fff_config(DynamicPrintConfig *config, std::vector<std::string> const &keys, std::map<ObjectBase*, ModelConfig*> const & configs);
@ -90,6 +90,7 @@ public:
m_is_initialized_support_material_overhangs_queried = true;
m_support_material_overhangs_queried = queried;
}
int show_spiral_mode_settings_dialog(bool is_object_config = false);
private:
std::vector<int> get_temperature_range_by_filament_type(const std::string &filament_type);

View File

@ -209,36 +209,36 @@ bool ObjectSettings::update_settings_list()
ModelObject * parent_object = nullptr;
for (auto item : items) {
auto type = objects_model->GetItemType(item);
if (type == itPlate) {
is_plate_settings = true;
int plate_id = objects_model->GetPlateIdByItem(item);
static ModelConfig cfg;
PartPlateList& ppl = wxGetApp().plater()->get_partplate_list();
if (plate_id < 0 || plate_id >= ppl.get_plate_count()) {
plate_id = ppl.get_curr_plate_index();
}
assert(plate_id >= 0 && plate_id < ppl.get_plate_count());
cfg.assign_config(*ppl.get_plate(plate_id)->config());
plate_configs.emplace(ppl.get_plate(plate_id), &cfg);
}
if (type != itObject && type != itVolume && type != itLayerRoot && type != itLayer) {
if (type != itPlate && type != itObject && type != itVolume && type != itLayerRoot && type != itLayer) {
continue;
}
int plate_id = objects_model->GetPlateIdByItem(item);
PartPlateList& ppl = wxGetApp().plater()->get_partplate_list();
if (plate_id < 0 || plate_id >= ppl.get_plate_count()) {
plate_id = ppl.get_curr_plate_index();
}
assert(plate_id >= 0 && plate_id < ppl.get_plate_count());
static ModelConfig cfg;
cfg.assign_config(*ppl.get_plate(plate_id)->config());
if (type == itPlate) {
is_plate_settings = true;
plate_configs.emplace(ppl.get_plate(plate_id), &cfg);
break;
}
const int obj_idx = objects_model->GetObjectIdByItem(item);
assert(obj_idx >= 0);
auto object = wxGetApp().model().objects[obj_idx];
if (type == itObject) {
is_object_settings = true;
plate_configs.emplace(ppl.get_plate(plate_id), &cfg);
object_configs.emplace(object, &object->config);
}
else if(type == itVolume){
is_volume_settings = true;
if (parent_object && parent_object != object)
return false;
plate_configs.emplace(ppl.get_plate(plate_id), &cfg);
parent_object = object;
const int vol_idx = objects_model->GetVolumeIdByItem(item);
assert(vol_idx >= 0);
@ -249,6 +249,7 @@ bool ObjectSettings::update_settings_list()
is_layer_range_settings = true;
if (parent_object && parent_object != object)
return false;
plate_configs.emplace(ppl.get_plate(plate_id), &cfg);
parent_object = object;
t_layer_height_range height_range = objects_model->GetLayerRangeByItem(item);
@ -265,38 +266,38 @@ bool ObjectSettings::update_settings_list()
auto tab_layer = dynamic_cast<TabPrintModel*>(wxGetApp().get_layer_tab());
if (is_plate_settings) {
tab_plate->set_model_config(plate_configs);
tab_object->set_model_config({});
tab_volume->set_model_config({});
tab_layer->set_model_config({});
tab_plate->set_model_config(plate_configs);
;// m_tab_active = tab_plate;
}
else if (is_object_settings) {
tab_plate->set_model_config(plate_configs);
tab_object->set_model_config(object_configs);
tab_volume->set_model_config({});
tab_layer->set_model_config({});
tab_plate->set_model_config({});
//m_tab_active = tab_object;
}
else if (is_volume_settings) {
tab_plate->set_model_config(plate_configs);
tab_object->set_model_config({ {parent_object, &parent_object->config} });
tab_volume->set_model_config(object_configs);
tab_layer->set_model_config({});
tab_plate->set_model_config({});
//m_tab_active = tab_volume;
}
else if (is_layer_range_settings) {
tab_plate->set_model_config(plate_configs);
tab_object->set_model_config({ {parent_object, &parent_object->config} });
tab_volume->set_model_config({});
tab_layer->set_model_config(object_configs);
tab_plate->set_model_config({});
//m_tab_active = tab_layer;
}
else {
tab_plate->set_model_config({});
tab_object->set_model_config({});
tab_volume->set_model_config({});
tab_layer->set_model_config({});
tab_plate->set_model_config({});
//m_tab_active = nullptr;
}
((ParamsPanel*) tab_object->GetParent())->set_active_tab(nullptr);

View File

@ -281,8 +281,18 @@ void PartPlate::set_spiral_vase_mode(bool spiral_mode, bool as_global)
std::string key = "spiral_mode";
if (as_global)
m_config.erase(key);
else
m_config.set_key_value(key, new ConfigOptionBool(spiral_mode));
else {
if (spiral_mode) {
// Secondary confirmation
auto answer = static_cast<TabPrintPlate*>(wxGetApp().plate_tab)->show_spiral_mode_settings_dialog(false);
if (answer == wxID_YES) {
m_config.set_key_value(key, new ConfigOptionBool(true));
set_vase_mode_related_object_config();
}
}
else
m_config.set_key_value(key, new ConfigOptionBool(false));
}
}
bool PartPlate::valid_instance(int obj_id, int instance_id)
@ -1976,6 +1986,16 @@ bool PartPlate::is_valid_gcode_file()
return true;
}
ModelObjectPtrs PartPlate::get_objects_on_this_plate() {
ModelObjectPtrs objects_ptr;
int obj_id;
for (auto it = obj_to_instance_set.begin(); it != obj_to_instance_set.end(); it++) {
obj_id = it->first;
objects_ptr.push_back(m_model->objects[obj_id]);
}
return objects_ptr;
}
ModelInstance* PartPlate::get_instance(int obj_id, int instance_id)
{
if (!contain_instance(obj_id, instance_id))
@ -2133,7 +2153,7 @@ int PartPlate::add_instance(int obj_id, int instance_id, bool move_position, Bou
ModelInstance* instance = object->instances[instance_id];
std::pair<int, int> pair(obj_id, instance_id);
obj_to_instance_set.insert(pair);
obj_to_instance_set.insert(pair);
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": plate_id %1%, add instance obj_id %2%, instance_id %3%, move_position %4%") % m_plate_index % obj_id % instance_id % move_position;
@ -2331,6 +2351,28 @@ void PartPlate::update_object_index(int obj_idx_removed, int obj_idx_max)
}
void PartPlate::set_vase_mode_related_object_config(int obj_id) {
ModelObjectPtrs obj_ptrs;
if (obj_id != -1) {
ModelObject* object = m_model->objects[obj_id];
obj_ptrs.push_back(object);
}
else
obj_ptrs = get_objects_on_this_plate();
for (ModelObject* object : obj_ptrs) {
ModelConfigObject& config = object->config;
config.set_key_value("wall_loops", new ConfigOptionInt(1));
config.set_key_value("top_shell_layers", new ConfigOptionInt(0));
config.set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
config.set_key_value("enable_support", new ConfigOptionBool(false));
config.set_key_value("enforce_support_layers", new ConfigOptionInt(0));
config.set_key_value("ensure_vertical_shell_thickness", new ConfigOptionBool(true));
config.set_key_value("detect_thin_wall", new ConfigOptionBool(false));
config.set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
}
//wxGetApp().obj_list()->update_selections();
}
int PartPlate::printable_instance_size()
{
int size = 0;
@ -4193,6 +4235,21 @@ int PartPlateList::notify_instance_update(int obj_id, int instance_id)
}
}
auto is_object_config_compatible_with_spiral_vase = [](ModelObject* object) {
const DynamicPrintConfig& config = object->config.get();
if (config.has("wall_loops") && config.opt_int("wall_loops") == 1 &&
config.has("top_shell_layers") && config.opt_int("top_shell_layers") == 0 &&
config.has("sparse_infill_density") && config.option<ConfigOptionPercent>("sparse_infill_density")->value == 0 &&
config.has("enable_support") && !config.opt_bool("enable_support") &&
config.has("enforce_support_layers") && config.opt_int("enforce_support_layers") == 0 &&
config.has("ensure_vertical_shell_thickness") && config.opt_bool("ensure_vertical_shell_thickness") &&
config.has("detect_thin_wall") && !config.opt_bool("detect_thin_wall") &&
config.has("timelapse_type") && config.opt_enum<TimelapseType>("timelapse_type") == TimelapseType::tlTraditional)
return true;
else
return false;
};
//try to find a new plate
for (unsigned int i = 0; i < (unsigned int)m_plate_list.size(); ++i)
{
@ -4203,6 +4260,15 @@ int PartPlateList::notify_instance_update(int obj_id, int instance_id)
{
//found a new plate, add it to plate
plate->add_instance(obj_id, instance_id, false, &boundingbox);
// spiral mode, update object setting
if (plate->config()->has("spiral_mode") && plate->config()->opt_bool("spiral_mode") && !is_object_config_compatible_with_spiral_vase(object)) {
auto answer = static_cast<TabPrintPlate*>(wxGetApp().plate_tab)->show_spiral_mode_settings_dialog(true);
if (answer == wxID_YES) {
plate->set_vase_mode_related_object_config(obj_id);
}
}
plate->update_slice_result_valid_state();
plate->thumbnail_data.reset();
plate->top_thumbnail_data.reset();

View File

@ -301,6 +301,7 @@ public:
// BBS
Vec2d get_size() const { return Vec2d(m_width, m_depth); }
ModelObjectPtrs get_objects() { return m_model->objects; }
ModelObjectPtrs get_objects_on_this_plate();
ModelInstance* get_instance(int obj_id, int instance_id);
Vec3d get_origin() { return m_origin; }
@ -345,6 +346,9 @@ public:
//update object's index caused by original object deleted
void update_object_index(int obj_idx_removed, int obj_idx_max);
// set objects configs when enabling spiral vase mode.
void set_vase_mode_related_object_config(int obj_id = -1);
//whether it is empty
bool empty() { return obj_to_instance_set.empty(); }

View File

@ -373,6 +373,7 @@ PlateSettingsDialog::PlateSettingsDialog(wxWindow* parent, const wxString& title
top_sizer->SetFlexibleDirection(wxBOTH);
top_sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
// Plate type
m_bed_type_choice = new ComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(240),-1), 0, NULL, wxCB_READONLY );
for (BedType i = btDefault; i < btCount; i = BedType(int(i) + 1)) {
m_bed_type_choice->Append(to_bed_type_name(i));
@ -382,6 +383,7 @@ PlateSettingsDialog::PlateSettingsDialog(wxWindow* parent, const wxString& title
top_sizer->Add(m_bed_type_txt, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxTOP | wxBOTTOM, FromDIP(5));
top_sizer->Add(m_bed_type_choice, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxTOP | wxBOTTOM, FromDIP(5));
// Print Sequence
m_print_seq_choice = new ComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(240),-1), 0, NULL, wxCB_READONLY );
m_print_seq_choice->Append(_L("Same as Global Print Sequence"));
for (auto i = PrintSequence::ByLayer; i < PrintSequence::ByDefault; i = PrintSequence(int(i) + 1)) {
@ -392,7 +394,18 @@ PlateSettingsDialog::PlateSettingsDialog(wxWindow* parent, const wxString& title
top_sizer->Add(m_print_seq_txt, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxTOP | wxBOTTOM, FromDIP(5));
top_sizer->Add(m_print_seq_choice, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxTOP | wxBOTTOM, FromDIP(5));
// first layer filament sequence
// Spiral mode
m_spiral_mode_choice = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(240), -1), 0, NULL, wxCB_READONLY);
m_spiral_mode_choice->Append(_L("Same as Global"));
m_spiral_mode_choice->Append(_L("Enable"));
m_spiral_mode_choice->Append(_L("Disable"));
m_spiral_mode_choice->SetSelection(0);
wxStaticText* spiral_mode_txt = new wxStaticText(this, wxID_ANY, _L("Spiral vase"));
spiral_mode_txt->SetFont(Label::Body_14);
top_sizer->Add(spiral_mode_txt, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxTOP | wxBOTTOM, FromDIP(5));
top_sizer->Add(m_spiral_mode_choice, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxTOP | wxBOTTOM, FromDIP(5));
// First layer filament sequence
m_first_layer_print_seq_choice = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(240), -1), 0, NULL, wxCB_READONLY);
m_first_layer_print_seq_choice->Append(_L("Auto"));
m_first_layer_print_seq_choice->Append(_L("Customize"));
@ -420,7 +433,7 @@ PlateSettingsDialog::PlateSettingsDialog(wxWindow* parent, const wxString& title
m_drag_canvas = new DragCanvas(this, extruder_colours, order);
m_drag_canvas->Hide();
top_sizer->Add(0, 0, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT, 0);
top_sizer->Add(m_drag_canvas, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxBOTTOM, FromDIP(10));
top_sizer->Add(m_drag_canvas, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxBOTTOM, FromDIP(10));
m_sizer_main->Add(top_sizer, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, FromDIP(30));
@ -429,18 +442,6 @@ PlateSettingsDialog::PlateSettingsDialog(wxWindow* parent, const wxString& title
m_sizer_main->AddSpacer(FromDIP(5));
m_sizer_main->Add(m_other_layers_seq_panel, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(30));
// hidden
// spiral mode
//m_spiral_mode_choice = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(240), -1), 0, NULL, wxCB_READONLY);
//m_spiral_mode_choice->Append(_L("Same as Global"));
//m_spiral_mode_choice->Append(_L("Enable"));
//m_spiral_mode_choice->Append(_L("Disable"));
//m_spiral_mode_choice->SetSelection(0);
//wxStaticText* spiral_mode_txt = new wxStaticText(this, wxID_ANY, _L("Spiral vase"));
//spiral_mode_txt->SetFont(Label::Body_14);
//top_sizer->Add(spiral_mode_txt, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5));
//top_sizer->Add(m_spiral_mode_choice, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5));
auto sizer_button = new wxBoxSizer(wxHORIZONTAL);
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),

View File

@ -53,6 +53,8 @@ namespace GUI {
#define DISABLE_UNDO_SYS
static const std::vector<std::string> plate_keys = { "curr_bed_type", "first_layer_print_sequence", "first_layer_sequence_choice", "other_layers_print_sequence", "other_layers_sequence_choice", "print_sequence", "spiral_mode"};
void Tab::Highlighter::set_timer_owner(wxEvtHandler* owner, int timerid/* = wxID_ANY*/)
{
m_timer.SetOwner(owner, timerid);
@ -2226,7 +2228,7 @@ void TabPrint::update()
m_config_manipulation.initialize_support_material_overhangs_queried(is_user_and_saved_preset && support_material_overhangs_queried);
}
m_config_manipulation.update_print_fff_config(m_config, m_type < Preset::TYPE_COUNT);
m_config_manipulation.update_print_fff_config(m_config, m_type < Preset::TYPE_COUNT, m_type == Preset::TYPE_PLATE);
update_description_lines();
//BBS: GUI refactor
@ -2341,6 +2343,9 @@ void TabPrintModel::update_model_config()
return;
}
m_config->apply(*m_parent_tab->m_config);
if (m_type != Preset::TYPE_PLATE) {
m_config->apply_only(*wxGetApp().plate_tab->get_config(), plate_keys);
}
m_null_keys.clear();
if (!m_object_configs.empty()) {
DynamicPrintConfig const & global_config= *m_config;
@ -2519,7 +2524,6 @@ void TabPrintModel::update_custom_dirty()
}
//BBS: GUI refactor
static const std::vector<std::string> plate_keys = { "curr_bed_type", "first_layer_print_sequence", "first_layer_sequence_choice", "other_layers_print_sequence", "other_layers_sequence_choice", "print_sequence"/*, "spiral_mode"*/};
TabPrintPlate::TabPrintPlate(ParamsPanel* parent) :
TabPrintModel(parent, plate_keys)
{
@ -2548,10 +2552,10 @@ void TabPrintPlate::build()
auto optgroup = page->new_optgroup("");
optgroup->append_single_option_line("curr_bed_type");
optgroup->append_single_option_line("print_sequence");
optgroup->append_single_option_line("spiral_mode");
optgroup->append_single_option_line("first_layer_sequence_choice");
optgroup->append_single_option_line("other_layers_sequence_choice");
// hidden
//optgroup->append_single_option_line("spiral_mode");
for (auto& line : const_cast<std::vector<Line>&>(optgroup->get_lines())) {
line.undo_to_sys = true;
}

View File

@ -499,6 +499,7 @@ public:
~TabPrintPlate() {}
void build() override;
void reset_model_config() override;
int show_spiral_mode_settings_dialog(bool is_object_config) { return m_config_manipulation.show_spiral_mode_settings_dialog(is_object_config); }
protected:
virtual void on_value_change(const std::string& opt_key, const boost::any& value) override;