diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6002091b6..d771a730a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -481,6 +481,7 @@ add_custom_target(gettext_make_pot
COMMAND xgettext --keyword=L --keyword=_L --keyword=_u8L --keyword=L_CONTEXT:1,2c --keyword=_L_PLURAL:1,2 --add-comments=TRN --from-code=UTF-8 --debug
-f "${L10N_DIR}/list.txt"
-o "${L10N_DIR}/PrusaSlicer.pot"
+ COMMAND hintsToPot ${SLIC3R_RESOURCES_DIR} ${L10N_DIR}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMENT "Generate pot file from strings in the source tree"
)
@@ -553,6 +554,8 @@ endfunction()
add_subdirectory(src)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT PrusaSlicer_app_console)
+add_dependencies(gettext_make_pot hintsToPot)
+
# Perl bindings, currently only used for the unit / integration tests of libslic3r.
# Also runs the unit / integration tests.
#FIXME Port the tests into C++ to finally get rid of the Perl!
diff --git a/resources/data/hints.ini b/resources/data/hints.ini
index 28a13236d..95060f9ec 100644
--- a/resources/data/hints.ini
+++ b/resources/data/hints.ini
@@ -49,7 +49,13 @@
# Algorithm shows hint only if ALL enabled tags are affirmative. (so never do enabled_tags = FFF; SLA;)
# Algorithm shows hint only if not in all disabled tags.
# if there are both disabled and preferred, only preferred that are not in disabled are valid.
-
+#
+#
+# Notifications shows in random order, already shown notifications are saved at cache/hints.cereal (as binary - human non-readable)
+# You can affect random ordering by seting weigh
+# weight = 5
+# Weight must be larger or equal to 1. Default weight is 1.
+# Weight defines probability as weight : sum_of_all_weights.
[hint:Fuzzy skin]
text = Fuzzy skin\nDid you know that you can create rough fibre-like texture on the sides of your models using theFuzzy skinfeature? You can also use modifiers to apply fuzzy-skin only to a portion of your model.
diff --git a/resources/shaders/printbed.vs b/resources/shaders/printbed.vs
index ee19098c1..7633017f1 100644
--- a/resources/shaders/printbed.vs
+++ b/resources/shaders/printbed.vs
@@ -7,6 +7,8 @@ varying vec2 tex_coords;
void main()
{
- gl_Position = gl_ModelViewProjectionMatrix * vec4(v_position, 1.0);
+ gl_Position = gl_ModelViewProjectionMatrix * vec4(v_position.x, v_position.y, v_position.z, 1.0);
+ // the following line leads to crash on some Intel graphics card
+ //gl_Position = gl_ModelViewProjectionMatrix * vec4(v_position, 1.0);
tex_coords = v_tex_coords;
}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index bbade8a97..9e89e82f6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -13,6 +13,7 @@ add_subdirectory(qhull)
add_subdirectory(Shiny)
add_subdirectory(semver)
add_subdirectory(libigl)
+add_subdirectory(hints)
# Adding libnest2d project for bin packing...
add_subdirectory(libnest2d)
diff --git a/src/hints/CMakeLists.txt b/src/hints/CMakeLists.txt
new file mode 100644
index 000000000..66550c786
--- /dev/null
+++ b/src/hints/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_minimum_required(VERSION 3.13)
+project(HintsToPot)
+
+add_executable(hintsToPot
+ HintsToPot.cpp)
+
+target_link_libraries(hintsToPot PRIVATE boost_libs)
+
+#encoding_check(HintsToPot)
+
+
+
diff --git a/src/hints/HintsToPot.cpp b/src/hints/HintsToPot.cpp
new file mode 100644
index 000000000..7c8029cde
--- /dev/null
+++ b/src/hints/HintsToPot.cpp
@@ -0,0 +1,84 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+bool write_to_pot(boost::filesystem::path path, const std::vector>& data)
+{
+ boost::filesystem::ofstream file(std::move(path), std::ios_base::app);
+ for (const auto& element : data)
+ {
+ //Example of .pot element
+ //#: src/slic3r/GUI/GUI_App.cpp:1647 src/slic3r/GUI/wxExtensions.cpp:687
+ //msgctxt "Mode"
+ //msgid "Advanced"
+ //msgstr ""
+ file << "\n#: resources/data/hints.ini: ["<< element.first << "]\nmsgid \"" << element.second << "\"\nmsgstr \"\"\n";
+ }
+ file.close();
+ return true;
+}
+bool read_hints_ini(boost::filesystem::path path, std::vector>& pot_elements)
+{
+ namespace pt = boost::property_tree;
+ pt::ptree tree;
+ boost::nowide::ifstream ifs(path.string());
+ try {
+ pt::read_ini(ifs, tree);
+ }
+ catch (const boost::property_tree::ini_parser::ini_parser_error& err) {
+ std::cout << err.what() << std::endl;
+ return false;
+ }
+ for (const auto& section : tree) {
+ if (boost::starts_with(section.first, "hint:")) {
+ for (const auto& data : section.second) {
+ if (data.first == "text")
+ {
+ pot_elements.emplace_back(section.first, data.second.data());
+ break;
+ }
+ }
+ }
+ }
+ return true;
+}
+
+int main(int argc, char* argv[])
+{
+ std::vector> data;
+ boost::filesystem::path path_to_ini;
+ boost::filesystem::path path_to_pot;
+ if (argc != 3)
+ {
+ std::cout << "HINTS_TO_POT FAILED: WRONG NUM OF ARGS" << std::endl;
+ return -1;
+ }
+ try {
+ path_to_ini = boost::filesystem::canonical(boost::filesystem::path(argv[1])).parent_path() / "resources" / "data" / "hints.ini";
+ path_to_pot = boost::filesystem::canonical(boost::filesystem::path(argv[2])).parent_path() / "localization" /"PrusaSlicer.pot";
+ } catch (std::exception&) {
+ std::cout << "HINTS_TO_POT FAILED: BOOST CANNONICAL" << std::endl;
+ return -1;
+ }
+
+ if (!boost::filesystem::exists(path_to_ini)){
+ std::cout << "HINTS_TO_POT FAILED: PATH TO INI DOES NOT EXISTS" << std::endl;
+ std::cout << path_to_ini.string() << std::endl;
+ return -1;
+ }
+ if (!read_hints_ini(std::move(path_to_ini), data)) {
+ std::cout << "HINTS_TO_POT FAILED TO READ HINTS INI" << std::endl;
+ return -1;
+ }
+ if (!write_to_pot(std::move(path_to_pot), data)) {
+ std::cout << "HINTS_TO_POT FAILED TO WRITE POT FILE" << std::endl;
+ return -1;
+ }
+ std::cout << "HINTS_TO_POT SUCCESS" << std::endl;
+ return 0;
+}
diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp
index 4166658f5..177d8d708 100644
--- a/src/libslic3r/AppConfig.cpp
+++ b/src/libslic3r/AppConfig.cpp
@@ -167,9 +167,6 @@ void AppConfig::set_defaults()
if (get("show_splash_screen").empty())
set("show_splash_screen", "1");
- if (get("last_hint").empty())
- set("last_hint", "0");
-
if (get("show_hints").empty())
set("show_hints", "1");
diff --git a/src/libslic3r/Brim.cpp b/src/libslic3r/Brim.cpp
index e73bed2c9..f4455fdd5 100644
--- a/src/libslic3r/Brim.cpp
+++ b/src/libslic3r/Brim.cpp
@@ -71,12 +71,16 @@ static ConstPrintObjectPtrs get_top_level_objects_with_brim(const Print &print,
Polygons islands;
ConstPrintObjectPtrs island_to_object;
for(size_t print_object_idx = 0; print_object_idx < print.objects().size(); ++print_object_idx) {
+ const PrintObject *object = print.objects()[print_object_idx];
+
+ if (! object->has_brim())
+ continue;
+
Polygons islands_object;
islands_object.reserve(bottom_layers_expolygons[print_object_idx].size());
for (const ExPolygon &ex_poly : bottom_layers_expolygons[print_object_idx])
islands_object.emplace_back(ex_poly.contour);
- const PrintObject *object = print.objects()[print_object_idx];
islands.reserve(islands.size() + object->instances().size() * islands_object.size());
for (const PrintInstance &instance : object->instances())
for (Polygon &poly : islands_object) {
diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp
index 235c35797..8eb5bb389 100644
--- a/src/libslic3r/Model.cpp
+++ b/src/libslic3r/Model.cpp
@@ -956,9 +956,22 @@ void ModelObject::center_around_origin(bool include_modifiers)
void ModelObject::ensure_on_bed(bool allow_negative_z)
{
- const double min_z = get_min_z();
- if (!allow_negative_z || min_z > SINKING_Z_THRESHOLD)
- translate_instances({ 0.0, 0.0, -min_z });
+ double z_offset = 0.0;
+
+ if (allow_negative_z) {
+ if (volumes.size() == 1)
+ z_offset = -get_min_z();
+ else {
+ const double max_z = get_max_z();
+ if (max_z < SINKING_MIN_Z_THRESHOLD)
+ z_offset = SINKING_MIN_Z_THRESHOLD - max_z;
+ }
+ }
+ else
+ z_offset = -get_min_z();
+
+ if (z_offset != 0.0)
+ translate_instances(z_offset * Vec3d::UnitZ());
}
void ModelObject::translate_instances(const Vec3d& vector)
@@ -1429,6 +1442,19 @@ double ModelObject::get_min_z() const
}
}
+double ModelObject::get_max_z() const
+{
+ if (instances.empty())
+ return 0.0;
+ else {
+ double max_z = -DBL_MAX;
+ for (size_t i = 0; i < instances.size(); ++i) {
+ max_z = std::max(max_z, get_instance_max_z(i));
+ }
+ return max_z;
+ }
+}
+
double ModelObject::get_instance_min_z(size_t instance_idx) const
{
double min_z = DBL_MAX;
@@ -1450,6 +1476,27 @@ double ModelObject::get_instance_min_z(size_t instance_idx) const
return min_z + inst->get_offset(Z);
}
+double ModelObject::get_instance_max_z(size_t instance_idx) const
+{
+ double max_z = -DBL_MAX;
+
+ const ModelInstance* inst = instances[instance_idx];
+ const Transform3d& mi = inst->get_matrix(true);
+
+ for (const ModelVolume* v : volumes) {
+ if (!v->is_model_part())
+ continue;
+
+ const Transform3d mv = mi * v->get_matrix();
+ const TriangleMesh& hull = v->get_convex_hull();
+ for (const stl_facet& facet : hull.stl.facet_start)
+ for (int i = 0; i < 3; ++i)
+ max_z = std::max(max_z, (mv * facet.vertex[i].cast()).z());
+ }
+
+ return max_z + inst->get_offset(Z);
+}
+
unsigned int ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_volume)
{
unsigned int num_printable = 0;
diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp
index 11dcfa775..25f19e792 100644
--- a/src/libslic3r/Model.hpp
+++ b/src/libslic3r/Model.hpp
@@ -358,7 +358,9 @@ public:
void bake_xy_rotation_into_meshes(size_t instance_idx);
double get_min_z() const;
+ double get_max_z() const;
double get_instance_min_z(size_t instance_idx) const;
+ double get_instance_max_z(size_t instance_idx) const;
// Called by Print::validate() from the UI thread.
unsigned int check_instances_print_volume_state(const BoundingBoxf3& print_volume);
@@ -1177,6 +1179,7 @@ void check_model_ids_equal(const Model &model1, const Model &model2);
#endif /* NDEBUG */
static const float SINKING_Z_THRESHOLD = -0.001f;
+static const double SINKING_MIN_Z_THRESHOLD = 0.05;
} // namespace Slic3r
diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp
index c0a956154..3883c4980 100644
--- a/src/libslic3r/Preset.cpp
+++ b/src/libslic3r/Preset.cpp
@@ -413,212 +413,181 @@ void Preset::set_visible_from_appconfig(const AppConfig &app_config)
}
}
-const std::vector& Preset::print_options()
-{
- static std::vector s_opts {
- "layer_height", "first_layer_height", "perimeters", "spiral_vase", "slice_closing_radius", "slicing_mode",
- "top_solid_layers", "top_solid_min_thickness", "bottom_solid_layers", "bottom_solid_min_thickness",
- "extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs",
- "seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "top_fill_pattern", "bottom_fill_pattern",
- "infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle",
- "solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first",
- "ironing", "ironing_type", "ironing_flowrate", "ironing_speed", "ironing_spacing",
- "max_print_speed", "max_volumetric_speed", "avoid_crossing_perimeters_max_detour",
- "fuzzy_skin", "fuzzy_skin_thickness", "fuzzy_skin_point_dist",
+static std::vector s_Preset_print_options {
+ "layer_height", "first_layer_height", "perimeters", "spiral_vase", "slice_closing_radius", "slicing_mode",
+ "top_solid_layers", "top_solid_min_thickness", "bottom_solid_layers", "bottom_solid_min_thickness",
+ "extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs",
+ "seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "top_fill_pattern", "bottom_fill_pattern",
+ "infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle",
+ "solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first",
+ "ironing", "ironing_type", "ironing_flowrate", "ironing_speed", "ironing_spacing",
+ "max_print_speed", "max_volumetric_speed", "avoid_crossing_perimeters_max_detour",
+ "fuzzy_skin", "fuzzy_skin_thickness", "fuzzy_skin_point_dist",
#ifdef HAS_PRESSURE_EQUALIZER
- "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative",
+ "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative",
#endif /* HAS_PRESSURE_EQUALIZER */
- "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed",
- "top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed",
- "bridge_speed", "gap_fill_speed", "gap_fill_enabled", "travel_speed", "travel_speed_z", "first_layer_speed", "perimeter_acceleration", "infill_acceleration",
- "bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield",
- "min_skirt_length", "brim_width", "brim_offset", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
- "raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
- "support_material_pattern", "support_material_with_sheath", "support_material_spacing", "support_material_closing_radius", "support_material_style",
- "support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers", "support_material_bottom_interface_layers",
- "support_material_interface_pattern", "support_material_interface_spacing", "support_material_interface_contact_loops",
- "support_material_contact_distance", "support_material_bottom_contact_distance",
- "support_material_buildplate_only", "dont_support_bridges", "thick_bridges", "notes", "complete_objects", "extruder_clearance_radius",
- "extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "perimeter_extruder",
- "infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder",
- "ooze_prevention", "standby_temperature_delta", "interface_shells", "extrusion_width", "first_layer_extrusion_width",
- "perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
- "top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "infill_anchor", "infill_anchor_max", "bridge_flow_ratio", "clip_multipart_objects",
- "elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
- "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width",
- "wipe_tower_no_sparse_layers", "compatible_printers", "compatible_printers_condition", "inherits"
- };
- return s_opts;
-}
+ "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed",
+ "top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed",
+ "bridge_speed", "gap_fill_speed", "gap_fill_enabled", "travel_speed", "travel_speed_z", "first_layer_speed", "perimeter_acceleration", "infill_acceleration",
+ "bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield",
+ "min_skirt_length", "brim_width", "brim_offset", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
+ "raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
+ "support_material_pattern", "support_material_with_sheath", "support_material_spacing", "support_material_closing_radius", "support_material_style",
+ "support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers", "support_material_bottom_interface_layers",
+ "support_material_interface_pattern", "support_material_interface_spacing", "support_material_interface_contact_loops",
+ "support_material_contact_distance", "support_material_bottom_contact_distance",
+ "support_material_buildplate_only", "dont_support_bridges", "thick_bridges", "notes", "complete_objects", "extruder_clearance_radius",
+ "extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "perimeter_extruder",
+ "infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder",
+ "ooze_prevention", "standby_temperature_delta", "interface_shells", "extrusion_width", "first_layer_extrusion_width",
+ "perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
+ "top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "infill_anchor", "infill_anchor_max", "bridge_flow_ratio", "clip_multipart_objects",
+ "elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
+ "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width",
+ "wipe_tower_no_sparse_layers", "compatible_printers", "compatible_printers_condition", "inherits"
+};
-const std::vector& Preset::filament_options()
-{
- static std::vector s_opts {
- "filament_colour", "filament_diameter", "filament_type", "filament_soluble", "filament_notes", "filament_max_volumetric_speed",
- "extrusion_multiplier", "filament_density", "filament_cost", "filament_spool_weight", "filament_loading_speed", "filament_loading_speed_start", "filament_load_time",
- "filament_unloading_speed", "filament_unloading_speed_start", "filament_unload_time", "filament_toolchange_delay", "filament_cooling_moves",
- "filament_cooling_initial_speed", "filament_cooling_final_speed", "filament_ramming_parameters", "filament_minimal_purge_on_wipe_tower",
- "temperature", "first_layer_temperature", "bed_temperature", "first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed",
- "max_fan_speed", "bridge_fan_speed", "disable_fan_first_layers", "full_fan_speed_layer", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed",
- "start_filament_gcode", "end_filament_gcode",
- // Retract overrides
- "filament_retract_length", "filament_retract_lift", "filament_retract_lift_above", "filament_retract_lift_below", "filament_retract_speed", "filament_deretract_speed", "filament_retract_restart_extra", "filament_retract_before_travel",
- "filament_retract_layer_change", "filament_wipe", "filament_retract_before_wipe",
- // Profile compatibility
- "filament_vendor", "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits"
- };
- return s_opts;
-}
+static std::vector s_Preset_filament_options {
+ "filament_colour", "filament_diameter", "filament_type", "filament_soluble", "filament_notes", "filament_max_volumetric_speed",
+ "extrusion_multiplier", "filament_density", "filament_cost", "filament_spool_weight", "filament_loading_speed", "filament_loading_speed_start", "filament_load_time",
+ "filament_unloading_speed", "filament_unloading_speed_start", "filament_unload_time", "filament_toolchange_delay", "filament_cooling_moves",
+ "filament_cooling_initial_speed", "filament_cooling_final_speed", "filament_ramming_parameters", "filament_minimal_purge_on_wipe_tower",
+ "temperature", "first_layer_temperature", "bed_temperature", "first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed",
+ "max_fan_speed", "bridge_fan_speed", "disable_fan_first_layers", "full_fan_speed_layer", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed",
+ "start_filament_gcode", "end_filament_gcode",
+ // Retract overrides
+ "filament_retract_length", "filament_retract_lift", "filament_retract_lift_above", "filament_retract_lift_below", "filament_retract_speed", "filament_deretract_speed", "filament_retract_restart_extra", "filament_retract_before_travel",
+ "filament_retract_layer_change", "filament_wipe", "filament_retract_before_wipe",
+ // Profile compatibility
+ "filament_vendor", "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits"
+};
-const std::vector& Preset::machine_limits_options()
-{
- static std::vector s_opts;
- if (s_opts.empty()) {
- s_opts = {
- "machine_max_acceleration_extruding", "machine_max_acceleration_retracting", "machine_max_acceleration_travel",
- "machine_max_acceleration_x", "machine_max_acceleration_y", "machine_max_acceleration_z", "machine_max_acceleration_e",
- "machine_max_feedrate_x", "machine_max_feedrate_y", "machine_max_feedrate_z", "machine_max_feedrate_e",
- "machine_min_extruding_rate", "machine_min_travel_rate",
- "machine_max_jerk_x", "machine_max_jerk_y", "machine_max_jerk_z", "machine_max_jerk_e",
- };
- }
- return s_opts;
-}
+static std::vector s_Preset_machine_limits_options {
+ "machine_max_acceleration_extruding", "machine_max_acceleration_retracting", "machine_max_acceleration_travel",
+ "machine_max_acceleration_x", "machine_max_acceleration_y", "machine_max_acceleration_z", "machine_max_acceleration_e",
+ "machine_max_feedrate_x", "machine_max_feedrate_y", "machine_max_feedrate_z", "machine_max_feedrate_e",
+ "machine_min_extruding_rate", "machine_min_travel_rate",
+ "machine_max_jerk_x", "machine_max_jerk_y", "machine_max_jerk_z", "machine_max_jerk_e",
+};
+
+static std::vector s_Preset_printer_options {
+ "printer_technology",
+ "bed_shape", "bed_custom_texture", "bed_custom_model", "z_offset", "gcode_flavor", "use_relative_e_distances",
+ "use_firmware_retraction", "use_volumetric_e", "variable_layer_height",
+ //FIXME the print host keys are left here just for conversion from the Printer preset to Physical Printer preset.
+ "host_type", "print_host", "printhost_apikey", "printhost_cafile",
+ "single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
+ "color_change_gcode", "pause_print_gcode", "template_custom_gcode",
+ "between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction",
+ "cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "max_print_height",
+ "default_print_profile", "inherits",
+ "remaining_times", "silent_mode",
+ "machine_limits_usage", "thumbnails"
+};
+
+static std::vector s_Preset_sla_print_options {
+ "layer_height",
+ "faded_layers",
+ "supports_enable",
+ "support_head_front_diameter",
+ "support_head_penetration",
+ "support_head_width",
+ "support_pillar_diameter",
+ "support_small_pillar_diameter_percent",
+ "support_max_bridges_on_pillar",
+ "support_pillar_connection_mode",
+ "support_buildplate_only",
+ "support_pillar_widening_factor",
+ "support_base_diameter",
+ "support_base_height",
+ "support_base_safety_distance",
+ "support_critical_angle",
+ "support_max_bridge_length",
+ "support_max_pillar_link_distance",
+ "support_object_elevation",
+ "support_points_density_relative",
+ "support_points_minimal_distance",
+ "slice_closing_radius",
+ "slicing_mode",
+ "pad_enable",
+ "pad_wall_thickness",
+ "pad_wall_height",
+ "pad_brim_size",
+ "pad_max_merge_distance",
+ // "pad_edge_radius",
+ "pad_wall_slope",
+ "pad_object_gap",
+ "pad_around_object",
+ "pad_around_object_everywhere",
+ "pad_object_connector_stride",
+ "pad_object_connector_width",
+ "pad_object_connector_penetration",
+ "hollowing_enable",
+ "hollowing_min_thickness",
+ "hollowing_quality",
+ "hollowing_closing_distance",
+ "output_filename_format",
+ "default_sla_print_profile",
+ "compatible_printers",
+ "compatible_printers_condition",
+ "inherits"
+};
+
+static std::vector s_Preset_sla_material_options {
+ "material_type",
+ "initial_layer_height",
+ "bottle_cost",
+ "bottle_volume",
+ "bottle_weight",
+ "material_density",
+ "exposure_time",
+ "initial_exposure_time",
+ "material_correction",
+ "material_notes",
+ "material_vendor",
+ "default_sla_material_profile",
+ "compatible_prints", "compatible_prints_condition",
+ "compatible_printers", "compatible_printers_condition", "inherits"
+};
+
+static std::vector s_Preset_sla_printer_options {
+ "printer_technology",
+ "bed_shape", "bed_custom_texture", "bed_custom_model", "max_print_height",
+ "display_width", "display_height", "display_pixels_x", "display_pixels_y",
+ "display_mirror_x", "display_mirror_y",
+ "display_orientation",
+ "fast_tilt_time", "slow_tilt_time", "area_fill",
+ "relative_correction",
+ "absolute_correction",
+ "elefant_foot_compensation",
+ "elefant_foot_min_width",
+ "gamma_correction",
+ "min_exposure_time", "max_exposure_time",
+ "min_initial_exposure_time", "max_initial_exposure_time",
+ //FIXME the print host keys are left here just for conversion from the Printer preset to Physical Printer preset.
+ "print_host", "printhost_apikey", "printhost_cafile",
+ "printer_notes",
+ "inherits"
+};
+
+const std::vector& Preset::print_options() { return s_Preset_print_options; }
+const std::vector& Preset::filament_options() { return s_Preset_filament_options; }
+const std::vector& Preset::machine_limits_options() { return s_Preset_machine_limits_options; }
+// The following nozzle options of a printer profile will be adjusted to match the size
+// of the nozzle_diameter vector.
+const std::vector& Preset::nozzle_options() { return print_config_def.extruder_option_keys(); }
+const std::vector& Preset::sla_print_options() { return s_Preset_sla_print_options; }
+const std::vector& Preset::sla_material_options() { return s_Preset_sla_material_options; }
+const std::vector& Preset::sla_printer_options() { return s_Preset_sla_printer_options; }
const std::vector& Preset::printer_options()
{
- static std::vector s_opts;
- if (s_opts.empty()) {
- s_opts = {
- "printer_technology",
- "bed_shape", "bed_custom_texture", "bed_custom_model", "z_offset", "gcode_flavor", "use_relative_e_distances",
- "use_firmware_retraction", "use_volumetric_e", "variable_layer_height",
- //FIXME the print host keys are left here just for conversion from the Printer preset to Physical Printer preset.
- "host_type", "print_host", "printhost_apikey", "printhost_cafile",
- "single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
- "color_change_gcode", "pause_print_gcode", "template_custom_gcode",
- "between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction",
- "cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "max_print_height",
- "default_print_profile", "inherits",
- "remaining_times", "silent_mode",
- "machine_limits_usage", "thumbnails"
- };
- s_opts.insert(s_opts.end(), Preset::machine_limits_options().begin(), Preset::machine_limits_options().end());
- s_opts.insert(s_opts.end(), Preset::nozzle_options().begin(), Preset::nozzle_options().end());
- }
- return s_opts;
-}
-
-// The following nozzle options of a printer profile will be adjusted to match the size
-// of the nozzle_diameter vector.
-const std::vector& Preset::nozzle_options()
-{
- return print_config_def.extruder_option_keys();
-}
-
-const std::vector& Preset::sla_print_options()
-{
- static std::vector s_opts;
- if (s_opts.empty()) {
- s_opts = {
- "layer_height",
- "faded_layers",
- "supports_enable",
- "support_head_front_diameter",
- "support_head_penetration",
- "support_head_width",
- "support_pillar_diameter",
- "support_small_pillar_diameter_percent",
- "support_max_bridges_on_pillar",
- "support_pillar_connection_mode",
- "support_buildplate_only",
- "support_pillar_widening_factor",
- "support_base_diameter",
- "support_base_height",
- "support_base_safety_distance",
- "support_critical_angle",
- "support_max_bridge_length",
- "support_max_pillar_link_distance",
- "support_object_elevation",
- "support_points_density_relative",
- "support_points_minimal_distance",
- "slice_closing_radius",
- "slicing_mode",
- "pad_enable",
- "pad_wall_thickness",
- "pad_wall_height",
- "pad_brim_size",
- "pad_max_merge_distance",
- // "pad_edge_radius",
- "pad_wall_slope",
- "pad_object_gap",
- "pad_around_object",
- "pad_around_object_everywhere",
- "pad_object_connector_stride",
- "pad_object_connector_width",
- "pad_object_connector_penetration",
- "hollowing_enable",
- "hollowing_min_thickness",
- "hollowing_quality",
- "hollowing_closing_distance",
- "output_filename_format",
- "default_sla_print_profile",
- "compatible_printers",
- "compatible_printers_condition",
- "inherits"
- };
- }
- return s_opts;
-}
-
-const std::vector& Preset::sla_material_options()
-{
- static std::vector s_opts;
- if (s_opts.empty()) {
- s_opts = {
- "material_type",
- "initial_layer_height",
- "bottle_cost",
- "bottle_volume",
- "bottle_weight",
- "material_density",
- "exposure_time",
- "initial_exposure_time",
- "material_correction",
- "material_notes",
- "material_vendor",
- "default_sla_material_profile",
- "compatible_prints", "compatible_prints_condition",
- "compatible_printers", "compatible_printers_condition", "inherits"
- };
- }
- return s_opts;
-}
-
-const std::vector& Preset::sla_printer_options()
-{
- static std::vector s_opts;
- if (s_opts.empty()) {
- s_opts = {
- "printer_technology",
- "bed_shape", "bed_custom_texture", "bed_custom_model", "max_print_height",
- "display_width", "display_height", "display_pixels_x", "display_pixels_y",
- "display_mirror_x", "display_mirror_y",
- "display_orientation",
- "fast_tilt_time", "slow_tilt_time", "area_fill",
- "relative_correction",
- "absolute_correction",
- "elefant_foot_compensation",
- "elefant_foot_min_width",
- "gamma_correction",
- "min_exposure_time", "max_exposure_time",
- "min_initial_exposure_time", "max_initial_exposure_time",
- //FIXME the print host keys are left here just for conversion from the Printer preset to Physical Printer preset.
- "print_host", "printhost_apikey", "printhost_cafile",
- "printer_notes",
- "inherits"
- };
- }
+ static std::vector s_opts = [](){
+ std::vector opts = s_Preset_printer_options;
+ append(opts, s_Preset_machine_limits_options);
+ append(opts, Preset::nozzle_options());
+ return opts;
+ }();
return s_opts;
}
@@ -1426,26 +1395,25 @@ std::string PhysicalPrinter::separator()
return " * ";
}
+static std::vector s_PhysicalPrinter_opts {
+ "preset_name", // temporary option to compatibility with older Slicer
+ "preset_names",
+ "printer_technology",
+ "host_type",
+ "print_host",
+ "printhost_apikey",
+ "printhost_cafile",
+ "printhost_port",
+ "printhost_authorization_type",
+ // HTTP digest authentization (RFC 2617)
+ "printhost_user",
+ "printhost_password",
+ "printhost_ssl_ignore_revoke"
+};
+
const std::vector& PhysicalPrinter::printer_options()
{
- static std::vector s_opts;
- if (s_opts.empty()) {
- s_opts = {
- "preset_name", // temporary option to compatibility with older Slicer
- "preset_names",
- "printer_technology",
- "host_type",
- "print_host",
- "printhost_apikey",
- "printhost_cafile",
- "printhost_port",
- "printhost_authorization_type",
- // HTTP digest authentization (RFC 2617)
- "printhost_user",
- "printhost_password"
- };
- }
- return s_opts;
+ return s_PhysicalPrinter_opts;
}
static constexpr auto legacy_print_host_options = {
diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp
index d0e7561db..849dd7b80 100644
--- a/src/libslic3r/Preset.hpp
+++ b/src/libslic3r/Preset.hpp
@@ -371,7 +371,7 @@ public:
const Preset& get_edited_preset() const { return m_edited_preset; }
// Return the last saved preset.
- const Preset& get_saved_preset() const { return m_saved_preset; }
+// const Preset& get_saved_preset() const { return m_saved_preset; }
// Return vendor of the first parent profile, for which the vendor is defined, or null if such profile does not exist.
PresetWithVendorProfile get_preset_with_vendor_profile(const Preset &preset) const;
@@ -395,7 +395,7 @@ public:
void discard_current_changes() {
m_presets[m_idx_selected].reset_dirty();
m_edited_preset = m_presets[m_idx_selected];
- update_saved_preset_from_current_preset();
+// update_saved_preset_from_current_preset();
}
// Return a preset by its name. If the preset is active, a temporary copy is returned.
@@ -474,7 +474,7 @@ public:
// Compare the content of get_saved_preset() with get_edited_preset() configs, return true if they differ.
bool saved_is_dirty() const
- { return is_dirty(&this->get_edited_preset(), &this->get_saved_preset()); }
+ { return is_dirty(&this->get_edited_preset(), &m_saved_preset); }
// Compare the content of get_saved_preset() with get_edited_preset() configs, return the list of keys where they differ.
// std::vector saved_dirty_options() const
// { return dirty_options(&this->get_edited_preset(), &this->get_saved_preset(), /* deep_compare */ false); }
diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp
index b3a1bc993..48737f830 100644
--- a/src/libslic3r/Print.cpp
+++ b/src/libslic3r/Print.cpp
@@ -159,7 +159,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|| opt_key == "wipe_tower_rotation_angle") {
steps.emplace_back(psSkirtBrim);
} else if (
- opt_key == "nozzle_diameter"
+ opt_key == "first_layer_height"
+ || opt_key == "nozzle_diameter"
|| opt_key == "resolution"
// Spiral Vase forces different kind of slicing than the normal model:
// In Spiral Vase mode, holes are closed and only the largest area contour is kept at each layer.
diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp
index 491960705..0056aee33 100644
--- a/src/libslic3r/Print.hpp
+++ b/src/libslic3r/Print.hpp
@@ -271,7 +271,11 @@ public:
// Centering offset of the sliced mesh from the scaled and rotated mesh of the model.
const Point& center_offset() const { return m_center_offset; }
- bool has_brim() const { return this->config().brim_type != btNoBrim && this->config().brim_width.value > 0.; }
+ bool has_brim() const {
+ return this->config().brim_type != btNoBrim
+ && this->config().brim_width.value > 0.
+ && ! this->has_raft();
+ }
// This is the *total* layer count (including support layers)
// this value is not supposed to be compared with Layer::id
@@ -321,7 +325,7 @@ public:
bool has_raft() const { return m_config.raft_layers > 0; }
bool has_support_material() const { return this->has_support() || this->has_raft(); }
// Checks if the model object is painted using the multi-material painting gizmo.
- bool is_mm_painted() const { return this->model_object()->is_mm_painted(); };
+ bool is_mm_painted() const { return this->model_object()->is_mm_painted(); }
// returns 0-based indices of extruders used to print the object (without brim, support and other helper extrusions)
std::vector object_extruders() const;
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index e64824d0d..f010bad39 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -232,6 +232,16 @@ void PrintConfigDef::init_common_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionString(""));
+ def = this->add("elefant_foot_compensation", coFloat);
+ def->label = L("Elephant foot compensation");
+ def->category = L("Advanced");
+ def->tooltip = L("The first layer will be shrunk in the XY plane by the configured value "
+ "to compensate for the 1st layer squish aka an Elephant Foot effect.");
+ def->sidetext = L("mm");
+ def->min = 0;
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionFloat(0.));
+
def = this->add("thumbnails", coPoints);
def->label = L("G-code thumbnails");
def->tooltip = L("Picture sizes to be stored into a .gcode and .sl1 / .sl1s files, in the following format: \"XxY, XxY, ...\"");
@@ -264,6 +274,7 @@ void PrintConfigDef::init_common_params()
"Print host behind HAProxy with basic auth enabled can be accessed by putting the user name and password into the URL "
"in the following format: https://username:password@your-octopi-address/");
def->mode = comAdvanced;
+ def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionString(""));
def = this->add("printhost_apikey", coString);
@@ -271,6 +282,7 @@ void PrintConfigDef::init_common_params()
def->tooltip = L("Slic3r can upload G-code files to a printer host. This field should contain "
"the API Key or the password required for authentication.");
def->mode = comAdvanced;
+ def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionString(""));
def = this->add("printhost_port", coString);
@@ -278,6 +290,7 @@ void PrintConfigDef::init_common_params()
def->tooltip = L("Name of the printer");
def->gui_type = ConfigOptionDef::GUIType::select_open;
def->mode = comAdvanced;
+ def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionString(""));
def = this->add("printhost_cafile", coString);
@@ -285,31 +298,33 @@ void PrintConfigDef::init_common_params()
def->tooltip = L("Custom CA certificate file can be specified for HTTPS OctoPrint connections, in crt/pem format. "
"If left blank, the default OS CA certificate repository is used.");
def->mode = comAdvanced;
+ def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionString(""));
- def = this->add("elefant_foot_compensation", coFloat);
- def->label = L("Elephant foot compensation");
- def->category = L("Advanced");
- def->tooltip = L("The first layer will be shrunk in the XY plane by the configured value "
- "to compensate for the 1st layer squish aka an Elephant Foot effect.");
- def->sidetext = L("mm");
- def->min = 0;
- def->mode = comAdvanced;
- def->set_default_value(new ConfigOptionFloat(0.));
-
// Options used by physical printers
def = this->add("printhost_user", coString);
def->label = L("User");
// def->tooltip = L("");
def->mode = comAdvanced;
+ def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionString(""));
def = this->add("printhost_password", coString);
def->label = L("Password");
// def->tooltip = L("");
def->mode = comAdvanced;
+ def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionString(""));
+
+ // Only available on Windows.
+ def = this->add("printhost_ssl_ignore_revoke", coBool);
+ def->label = L("Ignore HTTPS certificate revocation checks");
+ def->tooltip = L("Ignore HTTPS certificate revocation checks in case of missing or offline distribution points. "
+ "One may want to enable this option for self signed certificates if connection fails.");
+ def->mode = comAdvanced;
+ def->cli = ConfigOptionDef::nocli;
+ def->set_default_value(new ConfigOptionBool(false));
def = this->add("preset_names", coStrings);
def->label = L("Printer preset names");
@@ -317,12 +332,6 @@ void PrintConfigDef::init_common_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionStrings());
- // temporary workaround for compatibility with older Slicer
- {
- def = this->add("preset_name", coString);
- def->set_default_value(new ConfigOptionString());
- }
-
def = this->add("printhost_authorization_type", coEnum);
def->label = L("Authorization Type");
// def->tooltip = L("");
@@ -332,7 +341,14 @@ void PrintConfigDef::init_common_params()
def->enum_labels.push_back(L("API key"));
def->enum_labels.push_back(L("HTTP digest"));
def->mode = comAdvanced;
+ def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionEnum(atKeyPassword));
+
+ // temporary workaround for compatibility with older Slicer
+ {
+ def = this->add("preset_name", coString);
+ def->set_default_value(new ConfigOptionString());
+ }
}
void PrintConfigDef::init_fff_params()
@@ -465,7 +481,8 @@ void PrintConfigDef::init_fff_params()
def = this->add("brim_width", coFloat);
def->label = L("Brim width");
def->category = L("Skirt and brim");
- def->tooltip = L("Horizontal width of the brim that will be printed around each object on the first layer.");
+ def->tooltip = L("Horizontal width of the brim that will be printed around each object on the first layer."
+ "When raft is used, no brim is generated (use raft_first_layer_expansion).");
def->sidetext = L("mm");
def->min = 0;
def->max = 200;
@@ -1809,6 +1826,7 @@ void PrintConfigDef::init_fff_params()
def->enum_labels.push_back("AstroBox");
def->enum_labels.push_back("Repetier");
def->mode = comAdvanced;
+ def->cli = ConfigOptionDef::nocli;
def->set_default_value(new ConfigOptionEnum(htOctoPrint));
def = this->add("only_retract_when_crossing_perimeters", coBool);
diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp
index ae9816531..ee09e0f5b 100644
--- a/src/libslic3r/PrintObject.cpp
+++ b/src/libslic3r/PrintObject.cpp
@@ -535,7 +535,6 @@ bool PrintObject::invalidate_state_by_config_options(
steps.emplace_back(posPerimeters);
} else if (
opt_key == "layer_height"
- || opt_key == "first_layer_height"
|| opt_key == "mmu_segmented_region_max_width"
|| opt_key == "raft_layers"
|| opt_key == "raft_contact_distance"
diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp
index 9c0341ff4..7a9fdc388 100644
--- a/src/slic3r/GUI/3DScene.cpp
+++ b/src/slic3r/GUI/3DScene.cpp
@@ -595,7 +595,7 @@ bool GLVolume::is_sinking() const
bool GLVolume::is_below_printbed() const
{
- return transformed_convex_hull_bounding_box().max(2) < 0.0;
+ return transformed_convex_hull_bounding_box().max.z() < 0.0;
}
#if ENABLE_SINKING_CONTOURS
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index 06d805eeb..58ce12ae4 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -87,6 +87,11 @@
#include
#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG
+// Needed for forcing menu icons back under gtk2 and gtk3
+#if defined(__WXGTK20__) || defined(__WXGTK3__)
+ #include
+#endif
+
namespace Slic3r {
namespace GUI {
@@ -799,6 +804,14 @@ bool GUI_App::OnInit()
bool GUI_App::on_init_inner()
{
+ // Forcing back menu icons under gtk2 and gtk3. Solution is based on:
+ // https://docs.gtk.org/gtk3/class.Settings.html
+ // see also https://docs.wxwidgets.org/3.0/classwx_menu_item.html#a2b5d6bcb820b992b1e4709facbf6d4fb
+ // TODO: Find workaround for GTK4
+#if defined(__WXGTK20__) || defined(__WXGTK3__)
+ g_object_set (gtk_settings_get_default (), "gtk-menu-images", TRUE, NULL);
+#endif
+
// Verify resources path
const wxString resources_dir = from_u8(Slic3r::resources_dir());
wxCHECK_MSG(wxDirExists(resources_dir), false,
diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp
index 732a12db2..1e17b828a 100644
--- a/src/slic3r/GUI/GUI_ObjectList.cpp
+++ b/src/slic3r/GUI/GUI_ObjectList.cpp
@@ -1049,7 +1049,7 @@ void ObjectList::key_event(wxKeyEvent& event)
|| event.GetKeyCode() == WXK_BACK
#endif //__WXOSX__
) {
- remove();
+ wxGetApp().plater()->remove_selected();
}
else if (event.GetKeyCode() == WXK_F5)
wxGetApp().plater()->reload_all_from_disk();
@@ -1920,16 +1920,15 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con
if (vol->is_model_part())
++solid_cnt;
if (volume->is_model_part() && solid_cnt == 1) {
- Slic3r::GUI::show_error(nullptr, _(L("From Object List You can't delete the last solid part from object.")));
+ Slic3r::GUI::show_error(nullptr, _L("From Object List You can't delete the last solid part from object."));
return false;
}
- take_snapshot(_(L("Delete Subobject")));
+ take_snapshot(_L("Delete Subobject"));
object->delete_volume(idx);
- if (object->volumes.size() == 1)
- {
+ if (object->volumes.size() == 1) {
const auto last_volume = object->volumes[0];
if (!last_volume->config.empty()) {
object->config.apply(last_volume->config);
@@ -1948,11 +1947,11 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con
}
else if (type == itInstance) {
if (object->instances.size() == 1) {
- Slic3r::GUI::show_error(nullptr, _(L("Last instance of an object cannot be deleted.")));
+ Slic3r::GUI::show_error(nullptr, _L("Last instance of an object cannot be deleted."));
return false;
}
- take_snapshot(_(L("Delete Instance")));
+ take_snapshot(_L("Delete Instance"));
object->delete_instance(idx);
}
else
diff --git a/src/slic3r/GUI/HintNotification.cpp b/src/slic3r/GUI/HintNotification.cpp
index 2b079b6ff..1d5931c48 100644
--- a/src/slic3r/GUI/HintNotification.cpp
+++ b/src/slic3r/GUI/HintNotification.cpp
@@ -14,6 +14,31 @@
#include
#include
#include