diff --git a/resources/ui_layout/Readme.md b/resources/ui_layout/Readme.md index 81f962a11a9..0deef5af739 100644 --- a/resources/ui_layout/Readme.md +++ b/resources/ui_layout/Readme.md @@ -206,6 +206,8 @@ These functions can only be called in a `set` or `reset` function. If you need t ### others * void **ask_for_refresh**() ask for a OPTNAME_set() after the current OPTNAME_get(), to be able to set settings. + * bool **is_enabled**(string setting_key) + Experimental. Ask if this setting is currently enabled. Dangerous, as it will be true if it's not constructed. ### to get/set the value of a custom variable The first argument is the index of the tab setting: 0 for print settings, 1 for filament settings and 2 for printer settings. diff --git a/resources/ui_layout/default/print.as b/resources/ui_layout/default/print.as index e8f161a7d99..f3c6b53b9e4 100644 --- a/resources/ui_layout/default/print.as +++ b/resources/ui_layout/default/print.as @@ -141,6 +141,11 @@ void s_seam_position_set(string &in set_val, int idx) } } +bool s_seam_position_is_enabled() +{ + return get_int("perimeters") > 0; +} + // s_wall_thickness // set the perimeter_spacing & external_perimeter_spacing // as m * 2 perimeter_spacing + n * 2 * external_perimeter_spacing = o * s_wall_thickness diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 1bd8201931a..17680200b8b 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -4787,7 +4787,7 @@ std::string GCode::extrude_entity(const ExtrusionEntity &entity, const std::stri } void GCode::use(const ExtrusionEntityCollection &collection) { - if (!collection.can_sort() || collection.role() == erMixed || collection.entities().size() <= 1) { + if (!collection.can_sort() /*|| collection.role() == erMixed*/ || collection.entities().size() <= 1) { for (const ExtrusionEntity* next_entity : collection.entities()) { next_entity->visit(*this); } @@ -4912,10 +4912,15 @@ std::string GCode::extrude_perimeters(const Print &print, const std::vectorid()); else if (m_layer != nullptr && m_layer->bottom_z() < EPSILON && m_config.first_layer_temperature.get_at(m_writer.tool()->id()) > 0) gcode += m_writer.set_temperature(m_config.first_layer_temperature.get_at(m_writer.tool()->id()), false, m_writer.tool()->id()); - else if (m_config.temperature.get_at(m_writer.tool()->id()) > 0) // don't set it if disabled - gcode += m_writer.set_temperature(m_config.temperature.get_at(m_writer.tool()->id()), false, m_writer.tool()->id()); - for (const ExtrusionEntity *ee : region.perimeters) + else if (m_config.temperature.get_at(m_writer.tool()->id()) > 0) { // don't set it if disabled + gcode += m_writer.set_temperature(m_config.temperature.get_at(m_writer.tool()->id()), false, + m_writer.tool()->id()); + } + ExtrusionEntitiesPtr extrusions{region.perimeters}; + chain_and_reorder_extrusion_entities(extrusions, &m_last_pos); + for (const ExtrusionEntity *ee : extrusions) { gcode += this->extrude_entity(*ee, "perimeter", -1.); + } } m_seam_perimeters = false; return gcode; diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp index d63a343e2d0..f173823a336 100644 --- a/src/libslic3r/GCode/SeamPlacer.cpp +++ b/src/libslic3r/GCode/SeamPlacer.cpp @@ -429,7 +429,7 @@ Polygons extract_perimeter_polygons(const Layer *layer, const SeamPosition confi class PerimeterCopy : public ExtrusionVisitorConst { Polygons* polygons; std::vector* corresponding_regions_out; - LayerRegion* current_layer_region; + const LayerRegion* current_layer_region; SeamPosition configured_seam_preference; public: PerimeterCopy(std::vector* regions_out, Polygons* polys, SeamPosition configured_seam) @@ -457,41 +457,20 @@ Polygons extract_perimeter_polygons(const Layer *layer, const SeamPosition confi entity->visit(*this); } } + void set_current_layer_region(const LayerRegion *set) { current_layer_region = set; } } visitor(&corresponding_regions_out, &polygons, configured_seam_preference); for (const LayerRegion *layer_region : layer->regions()) { for (const ExtrusionEntity *ex_entity : layer_region->perimeters.entities()) { - if (ex_entity->is_collection()) { //collection of inner, outer, and overhang perimeters - //ex_entity->visit(visitor); - for (const ExtrusionEntity *perimeter : static_cast(ex_entity)->entities()) { - ExtrusionRole role = perimeter->role(); - if (perimeter->is_loop()) { - for (const ExtrusionPath &path : static_cast(perimeter)->paths) { - if (path.role() == ExtrusionRole::erExternalPerimeter) { - role = ExtrusionRole::erExternalPerimeter; - } - } - } - - if (role == ExtrusionRole::erExternalPerimeter - || (is_perimeter(role) && (configured_seam_preference == spAllRandom) )) { //for random seam alignment, extract all perimeters - Points p; - perimeter->collect_points(p); - polygons.emplace_back(std::move(p)); - corresponding_regions_out.push_back(layer_region); - } - } - if (polygons.empty()) { - Points p; - ex_entity->collect_points(p); - polygons.emplace_back(std::move(p)); - corresponding_regions_out.push_back(layer_region); - } - } else { + visitor.set_current_layer_region(layer_region); + ex_entity->visit(visitor); + if (polygons.empty()) { Points p; ex_entity->collect_points(p); polygons.emplace_back(std::move(p)); corresponding_regions_out.push_back(layer_region); + //shouldn't happen + assert(false); } } } @@ -814,8 +793,8 @@ struct SeamComparator { // Standard comparator, must respect the requirements of comparators (e.g. give same result on same inputs) for sorting usage // should return if a is better seamCandidate than b - bool is_first_better(const SeamCandidate &a, const SeamCandidate &b, const Vec2f &preffered_location = Vec2f { 0.0f, - 0.0f }) const { + bool is_first_better(const SeamCandidate &a, const SeamCandidate &b, const Vec2f &preffered_location = Vec2f { 0.0f, 0.0f}) const + { if ((setup == SeamPosition::spAligned || setup == SeamPosition::spExtremlyAligned) && a.central_enforcer != b.central_enforcer) { return a.central_enforcer; } diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index a8378a3d4e5..00771703452 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -354,8 +354,10 @@ ProcessSurfaceResult PerimeterGenerator::process_arachne(int& loop_number, const } } - if (ExtrusionEntityCollection extrusion_coll = _traverse_extrusions(ordered_extrusions); !extrusion_coll.empty()) + if (ExtrusionEntityCollection extrusion_coll = _traverse_extrusions(ordered_extrusions); !extrusion_coll.empty()) { + extrusion_coll.set_can_sort_reverse(false, false); this->loops->append(extrusion_coll); + } ExPolygons infill_contour = union_ex(wallToolPaths.getInnerContour()); const coord_t spacing = (perimeters.size() == 1) ? ext_perimeter_spacing2 : perimeter_spacing; @@ -2562,7 +2564,6 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops( } assert(thin_walls.empty()); ExtrusionEntityCollection children = this->_traverse_loops(loop.children, thin_walls, has_overhang ? 1 : count_since_overhang < 0 ? -1 : (count_since_overhang+1)); - coll_out.set_entities().reserve(coll_out.entities().size() + children.entities().size() + 1); coll[idx.first] = nullptr; if (loop.is_contour) { //note: this->layer->id() % 2 == 1 already taken into account in the is_steep_overhang compute (to save time). @@ -2570,15 +2571,39 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops( eloop->make_clockwise(); else eloop->make_counter_clockwise(); - coll_out.append(std::move(children.entities())); - coll_out.append(*eloop); + //ensure that our children are printed before us + if (!children.empty()) { + ExtrusionEntityCollection print_child_beforeplz; + print_child_beforeplz.set_can_sort_reverse(false, false); + if (children.entities().size() > 1) { + print_child_beforeplz.append(children); + } else { + print_child_beforeplz.append(std::move(children.entities())); + } + print_child_beforeplz.append(*eloop); + coll_out.append(std::move(print_child_beforeplz)); + } else { + coll_out.append(*eloop); + } } else { if (loop.is_steep_overhang && this->layer->id() % 2 == 1) eloop->make_counter_clockwise(); else eloop->make_clockwise(); - coll_out.append(*eloop); - coll_out.append(std::move(children.entities())); + // ensure that our children are printed after us + if (!children.empty()) { + ExtrusionEntityCollection print_child_beforeplz; + print_child_beforeplz.set_can_sort_reverse(false, false); + print_child_beforeplz.append(*eloop); + if (children.entities().size() > 1) { + print_child_beforeplz.append(children); + } else { + print_child_beforeplz.append(std::move(children.entities())); + } + coll_out.append(std::move(print_child_beforeplz)); + } else { + coll_out.append(*eloop); + } } } } @@ -2974,7 +2999,7 @@ PerimeterGenerator::_get_nearest_point(const PerimeterGeneratorLoops &children, if ((myPolylines.paths[idx_poly].role() == erExternalPerimeter || child.is_external() ) && (this->object_config->seam_position.value != SeamPosition::spRandom && this->object_config->seam_position.value != SeamPosition::spAllRandom)) { - //first, try to find 2 point near enough + //first, try to find 2 point near enough //TODO: use seam placer or at least an equivalent. for (size_t idx_point = 0; idx_point < myPolylines.paths[idx_poly].polyline.size(); idx_point++) { const Point &p = myPolylines.paths[idx_poly].polyline.get_points()[idx_point]; const Point &nearest_p = *child.polygon.closest_point(p); diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index 75bad269ad4..d70fa6c3474 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -126,10 +126,21 @@ class Preset TYPE_SLA_MATERIAL = TYPE_SLA | TYPE_MATERIAL, TYPE_TECHNOLOGY = TYPE_FFF | TYPE_SLA, + TYPE_FREQUENT = 1 << 5, + TYPE_FREQUENT_FFF = TYPE_FFF | TYPE_FREQUENT, + TYPE_FREQUENT_SLA = TYPE_SLA | TYPE_FREQUENT, // This type is here to support PresetConfigSubstitutions for physical printers, however it does not belong to the Preset class, // PhysicalPrinter class is used instead. - TYPE_PHYSICAL_PRINTER = 1 << 5, + TYPE_PHYSICAL_PRINTER = 1 << 6, }; + static inline PrinterTechnology get_tech(Type type) + { + if ((type & TYPE_FFF) == TYPE_FFF) + return PrinterTechnology::ptFFF; + if ((type & TYPE_FFF) == TYPE_SLA) + return PrinterTechnology::ptSLA; + return PrinterTechnology::ptUnknown; + } static std::string type_name(Type t); Type type = TYPE_INVALID; diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 0ee54d26a50..006c9387fed 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -86,6 +86,9 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con && config->opt_bool("overhangs_reverse") == false && config->opt_bool("gap_fill_last") == false && config->opt_int("solid_over_perimeters") == 0 + && config->option("seam_notch_all")->getFloat() == 0 + && config->option("seam_notch_inner")->getFloat() == 0 + && config->option("seam_notch_outer")->getFloat() == 0 )) { wxString msg_text = _(L("The Spiral Vase mode requires:\n" "- no top solid layers\n" @@ -98,7 +101,8 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con "- unchecked 'dense infill'\n" "- unchecked 'extra perimeters'" "- unchecked 'gap fill after last perimeter'" - "- disabled 'no solid fill over X perimeters'")); + "- disabled 'no solid fill over X perimeters'" + "- disabled 'seam notch'")); if (is_global_config) msg_text += "\n\n" + _(L("Shall I adjust those settings in order to enable Spiral Vase?")); MessageDialog dialog(m_msg_dlg_parent, msg_text, _(L("Spiral Vase")), @@ -137,6 +141,12 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con new_conf.set_key_value("gap_fill_last", new ConfigOptionBool(false)); else if (this->local_config->get().optptr("solid_over_perimeters")) new_conf.set_key_value("solid_over_perimeters", new ConfigOptionInt(0)); + else if (this->local_config->get().optptr("seam_notch_all")) + new_conf.set_key_value("seam_notch_all", new ConfigOptionFloatOrPercent(0, false)); + else if (this->local_config->get().optptr("seam_notch_inner")) + new_conf.set_key_value("seam_notch_all", new ConfigOptionFloatOrPercent(0, false)); + else if (this->local_config->get().optptr("seam_notch_outer")) + new_conf.set_key_value("seam_notch_all", new ConfigOptionFloatOrPercent(0, false)); this->local_config->apply_only(new_conf, this->local_config->keys(), true); } else if (answer == wxID_YES) { new_conf.set_key_value("top_solid_layers", new ConfigOptionInt(0)); @@ -153,6 +163,9 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con new_conf.set_key_value("overhangs_reverse", new ConfigOptionBool(false)); new_conf.set_key_value("gap_fill_last", new ConfigOptionBool(false)); new_conf.set_key_value("solid_over_perimeters", new ConfigOptionInt(0)); + new_conf.set_key_value("seam_notch_all", new ConfigOptionFloatOrPercent(0, false)); + new_conf.set_key_value("seam_notch_inner", new ConfigOptionFloatOrPercent(0, false)); + new_conf.set_key_value("seam_notch_outer", new ConfigOptionFloatOrPercent(0, false)); fill_density = 0; support = false; } else { @@ -327,7 +340,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config) "external_perimeters_first", "external_perimeter_extrusion_width", "external_perimeter_extrusion_spacing","external_perimeter_extrusion_change_odd_layers", "overhangs","perimeter_speed", "seam_position", "small_perimeter_speed", "small_perimeter_min_length", " small_perimeter_max_length", "spiral_vase", - "perimeter_generator"}) + "perimeter_generator", "seam_notch_all", "seam_notch_inner", "seam_notch_outer"}) toggle_field(el, have_perimeters); bool has_spiral_vase = have_perimeters && config->opt_bool("spiral_vase"); @@ -361,6 +374,11 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config) toggle_field("perimeter_loop_seam", config->opt_bool("perimeter_loop")); + bool have_notch = have_perimeters && (config->option("seam_notch_all")->getFloat() != 0 || + config->option("seam_notch_inner")->getFloat() != 0 || + config->option("seam_notch_outer")->getFloat() != 0); + toggle_field("seam_notch_angle", have_notch); + bool have_gap_fill = !have_arachne; toggle_field("gap_fill_enabled", have_gap_fill); for (auto el : { "gap_fill_extension", "gap_fill_last", "gap_fill_max_width", "gap_fill_min_area", "gap_fill_min_length", "gap_fill_min_width" }) diff --git a/src/slic3r/GUI/CreateMMUTiledCanvas.cpp b/src/slic3r/GUI/CreateMMUTiledCanvas.cpp index cef390fbf82..6c2a2b345bc 100644 --- a/src/slic3r/GUI/CreateMMUTiledCanvas.cpp +++ b/src/slic3r/GUI/CreateMMUTiledCanvas.cpp @@ -1113,31 +1113,31 @@ void CreateMMUTiledCanvas::create_main_tab(wxPanel* tab) //group_size->append_single_option_line(option); //line = { L("Size"), "" }; - group_size->append_single_option_line(group_size->get_option("size")); + group_size->append_single_option_line(group_size->create_option_from_def("size")); //line.append_option(Option(def, "size")); - group_size->append_single_option_line(group_size->get_option("size_px")); + group_size->append_single_option_line(group_size->create_option_from_def("size_px")); //line.append_option(Option(def, "size_px")); //group_size->append_line(line); - group_size->append_single_option_line(group_size->get_option("height")); + group_size->append_single_option_line(group_size->create_option_from_def("height")); - group_size->append_single_option_line(group_size->get_option("offset")); + group_size->append_single_option_line(group_size->create_option_from_def("offset")); line = { L("Gap"), "" }; - line.append_option(group_size->get_option("separation_xy")); + line.append_option(group_size->create_option_from_def("separation_xy")); - line.append_option(group_size->get_option("separation_z")); + line.append_option(group_size->create_option_from_def("separation_z")); group_size->append_line(line); - group_size->append_single_option_line(group_size->get_option("bezel")); - group_size->append_single_option_line(group_size->get_option("border")); + group_size->append_single_option_line(group_size->create_option_from_def("bezel")); + group_size->append_single_option_line(group_size->create_option_from_def("border")); - //group_size->append_single_option_line(group_size->get_option("bump")); + //group_size->append_single_option_line(group_size->create_option_from_def("bump")); group_size->activate([]() {}, wxALIGN_RIGHT); group_size->reload_config(); @@ -1156,23 +1156,23 @@ void CreateMMUTiledCanvas::create_main_tab(wxPanel* tab) }; group_colors->title_width = 15; - group_colors->append_single_option_line(group_colors->get_option("spool_colors")); + group_colors->append_single_option_line(group_colors->create_option_from_def("spool_colors")); //line = { L("Separation"), "" }; - //line.append_option(group_colors->get_option("near_color")); - //line.append_option(group_colors->get_option("color_comp")); + //line.append_option(group_colors->create_option_from_def("near_color")); + //line.append_option(group_colors->create_option_from_def("color_comp")); //group_colors->append_line(line); - group_colors->append_single_option_line(group_colors->get_option("near_color")); + group_colors->append_single_option_line(group_colors->create_option_from_def("near_color")); - group_colors->append_single_option_line(group_colors->get_option("color_comp")); + group_colors->append_single_option_line(group_colors->create_option_from_def("color_comp")); - group_colors->append_single_option_line(group_colors->get_option("order_dark")); + group_colors->append_single_option_line(group_colors->create_option_from_def("order_dark")); - group_colors->append_single_option_line(group_colors->get_option("original")); + group_colors->append_single_option_line(group_colors->create_option_from_def("original")); - group_colors->append_single_option_line(group_colors->get_option("extruders")); + group_colors->append_single_option_line(group_colors->create_option_from_def("extruders")); - group_colors->append_single_option_line(group_colors->get_option("background_color")); + group_colors->append_single_option_line(group_colors->create_option_from_def("background_color")); //line = { "", "" }; //line.full_width = 1; diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp index 28bf409e7a0..a567b5d67a5 100644 --- a/src/slic3r/GUI/Field.hpp +++ b/src/slic3r/GUI/Field.hpp @@ -102,13 +102,16 @@ class Field { // This is used to avoid recursive invocation of the field change/update by wxWidgets. bool m_disable_change_event {false}; bool m_is_modified_value {false}; - bool m_is_nonsys_value {true}; + bool m_is_nonsys_value{true}; /// Copy of ConfigOption for deduction purposes const ConfigOptionDef m_opt {ConfigOptionDef()}; const t_config_option_key m_opt_id;//! {""}; int m_opt_idx = 0; + // for saving state + bool m_is_enable{true}; + double opt_height{ 0.0 }; bool parent_is_custom_ctrl{ false }; @@ -127,7 +130,11 @@ class Field { virtual void disable() = 0; /// Fires the enable or disable function, based on the input. - inline void toggle(bool en) { en ? enable() : disable(); } + inline void toggle(bool en) { + m_is_enable = en; + en ? enable() : disable(); + } + inline bool is_enabled() const { return m_is_enable; } virtual wxString get_tooltip_text(const wxString& default_string); // hack via richtooltip that are also hacked diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp index 1a58decce16..c00bd630a4a 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.cpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp @@ -6,6 +6,7 @@ #include "GUI_App.hpp" #include "wxExtensions.hpp" #include "Plater.hpp" +#include "ScriptExecutor.hpp" #include "libslic3r/PresetBundle.hpp" #include "libslic3r/Model.hpp" diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 1d5a97b85e0..2cd61874e06 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -603,6 +603,15 @@ void OptionsGroup::update_script_presets(bool init) { } } } +bool ConfigOptionsGroup::has_option_def(const std::string &opt_key) +{ + return this->m_options.find(opt_key) != this->m_options.end(); +} +const Option *ConfigOptionsGroup::get_option_def(const std::string &opt_key) +{ + auto it = this->m_options.find(opt_key); + return it == m_options.end() ? nullptr : &it->second; +} bool ConfigOptionsGroup::has_option(const std::string& opt_key, int opt_index /*= -1*/) { @@ -614,17 +623,17 @@ bool ConfigOptionsGroup::has_option(const std::string& opt_key, int opt_index /* return m_opt_map.find(opt_id) != m_opt_map.end(); } -Option ConfigOptionsGroup::get_option(const std::string& opt_key, int opt_index /*= -1*/) +Option ConfigOptionsGroup::create_option_from_def(const std::string &opt_key, int opt_index /*= -1*/) { - if (!m_config->has(opt_key)) { - std::cerr << "No " << opt_key << " in ConfigOptionsGroup config.\n"; - } + if (!m_config->has(opt_key)) { + std::cerr << "No " << opt_key << " in ConfigOptionsGroup config.\n"; + } - std::string opt_id = opt_index == -1 ? opt_key : opt_key + "#" + std::to_string(opt_index); - std::pair pair(opt_key, opt_index); - m_opt_map.emplace(opt_id, pair); + std::string opt_id = opt_index == -1 ? opt_key : opt_key + "#" + std::to_string(opt_index); + std::pair pair(opt_key, opt_index); + m_opt_map.emplace(opt_id, pair); - return Option(*m_config->def()->get(opt_key), opt_id); + return Option(*m_config->def()->get(opt_key), opt_id); } void ConfigOptionsGroup::register_to_search(const std::string& opt_key, const ConfigOptionDef& option_def, int opt_index /*= -1*/, bool reset) diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index 9a494d23ddb..7eca3b9231e 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -265,12 +265,16 @@ class ConfigOptionsGroup: public OptionsGroup { void set_config(DynamicPrintConfig* config) { m_config = config; m_modelconfig = nullptr; } - bool has_option(const std::string& opt_key, int opt_index = -1); - // more like "create option from def" - Option get_option(const std::string& opt_key, int opt_index = -1); + + bool has_option_def(const std::string &opt_key); + const Option* get_option_def(const std::string &opt_key); + //these 'has' and 'get' are about m_opt_map and not m_options. it's the option + id + bool has_option(const std::string &opt_key, int opt_index = -1); + // more like "create option from def" (old "get_option") + Option create_option_from_def(const std::string& opt_key, int opt_index = -1); void register_to_search(const std::string& opt_key, const ConfigOptionDef& option_def, int opt_index, bool reset); Option get_option_and_register(const std::string& opt_key, int opt_index = -1) { - Option opt = get_option(opt_key, opt_index); + Option opt = create_option_from_def(opt_key, opt_index); if(m_use_custom_ctrl) // fill group and category values just for options from Settings Tab register_to_search(opt_key, opt.opt, opt_index, true); return opt; diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.cpp b/src/slic3r/GUI/PhysicalPrinterDialog.cpp index ea9cf0afcb1..328df639204 100644 --- a/src/slic3r/GUI/PhysicalPrinterDialog.cpp +++ b/src/slic3r/GUI/PhysicalPrinterDialog.cpp @@ -396,7 +396,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr }; // Set a wider width for a better alignment - Option option = m_optgroup->get_option("print_host"); + Option option = m_optgroup->create_option_from_def("print_host"); option.opt.width = Field::def_width_wider(); Line host_line = m_optgroup->create_single_option_line(option); host_line.append_widget(printhost_browse); @@ -405,11 +405,11 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr m_optgroup->append_single_option_line("printhost_authorization_type"); - option = m_optgroup->get_option("printhost_apikey"); + option = m_optgroup->create_option_from_def("printhost_apikey"); option.opt.width = Field::def_width_wider(); m_optgroup->append_single_option_line(option); - option = m_optgroup->get_option("printhost_port"); + option = m_optgroup->create_option_from_def("printhost_port"); option.opt.width = Field::def_width_wider(); Line port_line = m_optgroup->create_single_option_line(option); port_line.append_widget(print_host_printers); @@ -427,7 +427,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr m_optgroup->append_single_option_line(option); } - option = m_optgroup->get_option("printhost_client_cert"); + option = m_optgroup->create_option_from_def("printhost_client_cert"); option.opt.width = Field::def_width_wider(); Line client_cert_line = m_optgroup->create_single_option_line(option); @@ -466,14 +466,14 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr }; m_optgroup->append_line(clientcert_hint); - option = m_optgroup->get_option("printhost_client_cert_password"); + option = m_optgroup->create_option_from_def("printhost_client_cert_password"); option.opt.width = Field::def_width_wider(); m_optgroup->append_single_option_line(option); const auto ca_file_hint = _u8L("HTTPS CA file is optional. It is only needed if you use HTTPS with a self-signed certificate."); if (Http::ca_file_supported()) { - option = m_optgroup->get_option("printhost_cafile"); + option = m_optgroup->create_option_from_def("printhost_cafile"); option.opt.width = Field::def_width_wider(); Line cafile_line = m_optgroup->create_single_option_line(option); @@ -525,13 +525,13 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr } for (const std::string& opt_key : std::vector{ "printhost_user", "printhost_password" }) { - option = m_optgroup->get_option(opt_key); + option = m_optgroup->create_option_from_def(opt_key); option.opt.width = Field::def_width_wider(); m_optgroup->append_single_option_line(option); } #ifdef WIN32 - option = m_optgroup->get_option("printhost_ssl_ignore_revoke"); + option = m_optgroup->create_option_from_def("printhost_ssl_ignore_revoke"); option.opt.width = Field::def_width_wider(); m_optgroup->append_single_option_line(option); #endif diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 7d2ad2465d4..9d09ffb23f9 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -388,14 +388,14 @@ void FreqChangedParams::init() }; std::vector pages; - if(tab_print != nullptr) pages = tab_print->create_pages("freq_fff.ui"); + if(tab_print != nullptr) pages = tab_print->create_pages("freq_fff.ui", -1, Preset::Type::TYPE_FREQUENT_FFF); if (!pages.empty()) { m_og->set_config(config); m_og->hide_labels(); m_og->m_on_change = Tab::set_or_add(m_og->m_on_change, [tab_print, this](t_config_option_key opt_key, boost::any value) //m_og->m_on_change = [tab_print, this](t_config_option_key opt_key, boost::any value) { - Option opt = this->m_og->get_option(opt_key); + Option opt = this->m_og->create_option_from_def(opt_key); if (!opt.opt.is_script) { tab_print->update_dirty(); tab_print->reload_config(); @@ -470,14 +470,14 @@ void FreqChangedParams::init() // Frequently changed parameters for SLA_technology tab_print = wxGetApp().get_tab(Preset::TYPE_SLA_PRINT); pages.clear(); - if (tab_print != nullptr) pages = tab_print->create_pages("freq_sla.ui"); + if (tab_print != nullptr) pages = tab_print->create_pages("freq_sla.ui", -1, Preset::Type::TYPE_FREQUENT_SLA); if (!pages.empty()) { std::shared_ptr m_og_sla = m_og_other[ptSLA] = std::make_shared(m_parent, ""); m_og_sla->set_config(config); m_og_sla->hide_labels(); m_og_sla->m_on_change = Tab::set_or_add(m_og_sla->m_on_change, [tab_print, this](t_config_option_key opt_key, boost::any value) { - Option opt = this->m_og_other[ptSLA]->get_option(opt_key); + Option opt = this->m_og_other[ptSLA]->create_option_from_def(opt_key); if (!opt.opt.is_script) { tab_print->update_dirty(); tab_print->reload_config(); diff --git a/src/slic3r/GUI/ScriptExecutor.cpp b/src/slic3r/GUI/ScriptExecutor.cpp index e923bb5e82c..70dce80063c 100644 --- a/src/slic3r/GUI/ScriptExecutor.cpp +++ b/src/slic3r/GUI/ScriptExecutor.cpp @@ -586,6 +586,15 @@ void as_ask_for_refresh() current_script->request_refresh(); } +bool as_is_enabled(std::string &key) +{ + Page *selected_page; + Field *f = current_script->tab()->get_field(selected_page, key, -1); + if (!f) + return true; + return f->is_enabled(); +} + //function to reset a field void as_back_initial_value(std::string& key) { current_script->add_to_reset(key); @@ -672,6 +681,7 @@ void ScriptContainer::init(const std::string& tab_key, Tab* tab) m_script_engine.get()->RegisterGlobalFunction("void back_initial_value(string &in)", WRAP_FN(as_back_initial_value), AngelScript::asCALL_GENERIC); m_script_engine.get()->RegisterGlobalFunction("void back_custom_initial_value(int, string &in)", WRAP_FN(as_back_custom_initial_value), AngelScript::asCALL_GENERIC); m_script_engine.get()->RegisterGlobalFunction("void ask_for_refresh()", WRAP_FN(as_ask_for_refresh), AngelScript::asCALL_GENERIC); + m_script_engine.get()->RegisterGlobalFunction("bool is_enabled(string &in)", WRAP_FN(as_is_enabled), AngelScript::asCALL_GENERIC); #else m_script_engine.get()->RegisterGlobalFunction("void print(string &in)", AngelScript::asFUNCTION(as_print), AngelScript::asCALL_CDECL); @@ -702,6 +712,7 @@ void ScriptContainer::init(const std::string& tab_key, Tab* tab) m_script_engine.get()->RegisterGlobalFunction("void back_initial_value(string &in)", AngelScript::asFUNCTION(as_back_initial_value), AngelScript::asCALL_CDECL); m_script_engine.get()->RegisterGlobalFunction("void back_custom_initial_value(int, string &in)", AngelScript::asFUNCTION(as_back_custom_initial_value), AngelScript::asCALL_CDECL); m_script_engine.get()->RegisterGlobalFunction("void ask_for_refresh()", AngelScript::asFUNCTION(as_ask_for_refresh), AngelScript::asCALL_CDECL); + m_script_engine.get()->RegisterGlobalFunction("bool is_enabled(string &in)", AngelScript::asFUNCTION(as_is_enabled), AngelScript::asCALL_CDECL); #endif } @@ -1086,6 +1097,26 @@ void ScriptContainer::refresh(const ConfigOptionDef& def, boost::any value) m_currently_reset.erase(it); } + bool ScriptContainer::call_script_function_is_enable(const ConfigOptionDef &def) +{ + std::string func_name = ("bool " + def.opt_key + "_is_enabled()"); + AngelScript::asIScriptFunction *func = m_script_module->GetFunctionByDecl(func_name.c_str()); + if (func == nullptr) { + // default true + return true; + } + AngelScript::asIScriptContext *ctx = m_script_engine->CreateContext(); + if (ctx == nullptr) { + BOOST_LOG_TRIVIAL(error) << "Error, can't create script context for function '" << func_name << "'"; + return true; + } + ctx->Prepare(func); + // exec + /*int res = */ ctx->Execute(); + uint8_t ret = ctx->GetReturnByte(); + return ret != 0; +} + //TODO find a way to use the depends_on to add the same lock & points as real configoption in the gui } }//namespace Slic3r Gui diff --git a/src/slic3r/GUI/ScriptExecutor.hpp b/src/slic3r/GUI/ScriptExecutor.hpp index 4b6e3c0797d..26251cdaf18 100644 --- a/src/slic3r/GUI/ScriptExecutor.hpp +++ b/src/slic3r/GUI/ScriptExecutor.hpp @@ -57,6 +57,7 @@ class ScriptContainer bool call_script_function_reset(const ConfigOptionDef& def); //void call_script_function_refresh(const std::string& def_id); boost::any call_script_function_get_value(const ConfigOptionDef& def); + bool call_script_function_is_enable(const ConfigOptionDef &def); }; } } //namespace Slic3r Gui diff --git a/src/slic3r/GUI/Search.cpp b/src/slic3r/GUI/Search.cpp index f5400a45431..f5cbf41fb31 100644 --- a/src/slic3r/GUI/Search.cpp +++ b/src/slic3r/GUI/Search.cpp @@ -515,11 +515,52 @@ void OptionsSearcher::check_and_update(PrinterTechnology pt_in, ConfigOptionMode for (auto i : input_values) append_options(i.config, i.type); + + for (Option &opt : script_options) { + if (Preset::get_tech(opt.type)) + options.insert(options.end(), opt); + } + sort_options(); search(search_line, true); } +void OptionsSearcher::append_script_option(const ConfigOptionDef &opt, + Preset::Type preset_type, + int16_t idx) +{ + wxString label = opt.full_label; + if (label.IsEmpty()) + label = opt.label; + if (label.IsEmpty()) + return; + wxString tooltip = opt.tooltip; + wxString tooltip_lc = tooltip; + tooltip_lc.LowerCase(); + + std::string key = get_key(opt.opt_key, preset_type); + const GroupAndCategory &gc = get_group_and_category(key, opt.mode); + if (gc.group.IsEmpty() && gc.category.IsEmpty()) + return; // have to do ConfigOptionGroup::register_to_search + + script_options.emplace_back(Search::Option{ + boost::nowide::widen(opt.opt_key), + preset_type, + idx, + opt.mode, + label.ToStdWstring(), + _(label).ToStdWstring(), + gc.group.ToStdWstring(), + _(gc.group).ToStdWstring(), + gc.category.ToStdWstring(), + _(gc.category).ToStdWstring(), + tooltip.ToStdWstring(), + _(tooltip).ToStdWstring(), + tooltip_lc.ToStdWstring(), + _(tooltip_lc).ToStdWstring(), + }); +} const Option& OptionsSearcher::get_option(size_t pos_in_filter) const { assert(pos_in_filter != size_t(-1) && found[pos_in_filter].option_idx != size_t(-1)); diff --git a/src/slic3r/GUI/Search.hpp b/src/slic3r/GUI/Search.hpp index e335fd8c9b2..c836379214d 100644 --- a/src/slic3r/GUI/Search.hpp +++ b/src/slic3r/GUI/Search.hpp @@ -106,6 +106,7 @@ class OptionsSearcher ConfigOptionMode current_tags {comNone}; std::vector