From 4199d1aef6d626f2c343954313c2522901b852ad Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Sat, 18 Feb 2023 00:50:32 +0100 Subject: [PATCH 01/16] Bumped up version to 2.6.0-alpha4 --- version.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.inc b/version.inc index 1891f98197..0e4612fe00 100644 --- a/version.inc +++ b/version.inc @@ -3,7 +3,7 @@ set(SLIC3R_APP_NAME "PrusaSlicer") set(SLIC3R_APP_KEY "PrusaSlicer") -set(SLIC3R_VERSION "2.6.0-alpha3") +set(SLIC3R_VERSION "2.6.0-alpha4") set(SLIC3R_BUILD_ID "PrusaSlicer-${SLIC3R_VERSION}+UNKNOWN") set(SLIC3R_RC_VERSION "2,6,0,0") set(SLIC3R_RC_VERSION_DOTS "2.6.0.0") From 3b174c37a0291d630df3ac37b292c3c1dd360197 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 20 Feb 2023 07:52:50 +0100 Subject: [PATCH 02/16] Fixed procedural generation of wipe tower model --- src/slic3r/GUI/3DScene.cpp | 48 +++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index b070806f16..588aca51fb 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -493,6 +493,9 @@ int GLVolumeCollection::load_wipe_tower_preview( if (height == 0.0f) height = 0.1f; + static const float brim_height = 0.2f; + const float scaled_brim_height = brim_height / height; + TriangleMesh mesh; ColorRGBA color = ColorRGBA::DARK_YELLOW(); @@ -506,8 +509,6 @@ int GLVolumeCollection::load_wipe_tower_preview( depth = std::max(depth, 10.f); float min_width = 30.f; - const float scaled_brim_height = 0.2f / height; - // We'll now create the box with jagged edge. y-coordinates of the pre-generated model // are shifted so that the front edge has y=0 and centerline of the back edge has y=depth: // We split the box in three main pieces, @@ -553,6 +554,10 @@ int GLVolumeCollection::load_wipe_tower_preview( // central parts generator auto generate_central = [&]() { const std::vector vertices = { + // this part is not watertight to avoid to have different geometries for the cases + // brim_width < 10.0 + // brim_width == 10.0 + // brim_width > 10.0 { 38.453f, -(depth + brim_width), 0.0f }, { 61.547f, -(depth + brim_width), 0.0f }, { 38.453f, -(depth + brim_width), scaled_brim_height }, @@ -562,33 +567,33 @@ int GLVolumeCollection::load_wipe_tower_preview( { 38.453f, -depth, 1.0f }, { 61.547f, -depth, 1.0f }, { 38.453f, 0.0f, 1.0f }, - { 38.453f + 0.57735f * brim_width, brim_width, 1.0f }, { 44.2265f, 10.0f, 1.0f }, - { 50.0f - 0.57735f * brim_width, brim_width, 1.0f }, { 50.0f, 0.0f, 1.0f }, { 55.7735f, -10.0f, 1.0f }, { 61.547f, 0.0f, 1.0f }, { 38.453f, 0.0f, scaled_brim_height }, - { 38.453f, brim_width, scaled_brim_height }, - { 38.453f + 0.57735f * brim_width, brim_width, scaled_brim_height }, - { 50.0f - 0.57735f * brim_width, brim_width, scaled_brim_height }, + { 44.2265f, 10.0f, scaled_brim_height }, { 50.0f, 0.0f, scaled_brim_height }, { 55.7735f, -10.0f, scaled_brim_height }, { 61.547f, 0.0f, scaled_brim_height }, + { 38.453f, 0.0f, 0.0f }, + { 44.2265f, 10.0f, 0.0f }, + { 50.0f, 0.0f, 0.0f }, + { 55.7735f, -10.0f, 0.0f }, + { 61.547f, 0.0f, 0.0f }, + { 38.453f, brim_width, scaled_brim_height }, { 61.547f, brim_width, scaled_brim_height }, { 38.453f, brim_width, 0.0f }, - { 38.453f + 0.57735f * brim_width, brim_width, 0.0f }, - { 44.2265f, 10.0f, 0.0f }, - { 50.0f - 0.57735f * brim_width, brim_width, 0.0f }, - { 61.547f, brim_width, 0.0f } + { 61.547f, brim_width, 0.0f }, }; const std::vector triangles = { - { 0, 1, 3 }, { 0, 3, 2 }, { 2, 3, 5 }, { 2, 5, 4 }, { 4, 5, 7 }, { 4, 7, 6 }, { 7, 14, 13 }, { 7, 13, 6 }, - { 6, 13, 12 }, { 6, 12, 8 }, { 8, 12, 11 }, { 8, 11, 9 }, { 9, 11, 10 }, { 18, 19, 22 }, { 22, 19, 21 }, { 19, 20, 21 }, - { 15, 17, 16 }, { 17, 15, 8 }, { 17, 8, 9 }, { 21, 13, 14 }, { 21, 20, 13 }, { 20, 19, 12 }, { 20, 12, 13 }, { 19, 18, 11 }, - { 19, 11, 12 }, { 27, 26, 18 }, { 27, 18, 22 }, { 26, 25, 18 }, { 18, 25, 11 }, { 11, 25, 10 }, { 25, 24, 17 }, { 25, 17, 9 }, - { 25, 9, 10 }, { 24, 23, 16 }, { 24, 16, 17 }, { 1, 26, 27 }, { 1, 23, 26 }, { 1, 0, 23 }, { 0, 23, 24 }, { 24, 25, 26 } + { 0, 1, 3 }, { 0, 3, 2 }, { 2, 3, 5 }, { 2, 5, 4 }, { 4, 5, 7 }, { 4, 7, 6 }, + { 6, 7, 11 }, { 6, 11, 10 }, { 6, 10, 8 }, { 8, 10, 9 }, { 11, 7, 12 }, { 14, 13, 8 }, + { 14, 8, 9 }, { 19, 18, 13 }, { 19, 13, 14 }, { 15, 14, 9 }, { 15, 9, 10 }, { 20, 19, 14 }, + { 20, 14, 15 }, { 16, 15, 10 }, { 16, 10, 11 }, { 21, 20, 15 }, { 21, 15, 16 }, { 17, 16, 11 }, + { 17, 11, 12 }, { 22, 21, 16 }, { 22, 16, 17 }, { 15, 16, 17 }, { 13, 15, 23 }, { 15, 17, 24 }, + { 15, 24, 23 }, { 26, 25, 23 }, { 26, 23, 24 }, { 0, 25, 1 }, { 1, 25, 26 }, { 20, 18, 19 } }; indexed_triangle_set its; @@ -614,7 +619,7 @@ int GLVolumeCollection::load_wipe_tower_preview( // We have the mesh ready. It has one tooth and width of min_width. We will now // append several of these together until we are close to the required width // of the block. Than we can scale it precisely. - size_t n = std::max(1, int(width / min_width)); // How many shall be merged? + const size_t n = std::max(1, int(width / min_width)); // How many shall be merged? for (size_t i = 0; i < n; ++i) { mesh.merge(tooth_mesh); tooth_mesh.translate(100.0f, 0.0f, 0.0f); @@ -695,8 +700,13 @@ int GLVolumeCollection::load_wipe_tower_preview( mesh.merge(TriangleMesh(std::move(data))); mesh.scale(Vec3f(width / (n * 100.0f), 1.0f, height)); // Scaling to proper width } - else - mesh = make_cube(width, depth, height); + else { + mesh = make_cube(width, depth, height - brim_height); + mesh.translate(0.0f, 0.0f, brim_height); + TriangleMesh brim_mesh = make_cube(width + 2.0f * brim_width, depth + 2.0f * brim_width, brim_height); + brim_mesh.translate(-brim_width, -brim_width, 0.0f); + mesh.merge(brim_mesh); + } volumes.emplace_back(new GLVolume(color)); GLVolume& v = *volumes.back(); From 043dccdea0ebe811680fe78511e404440b472732 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 20 Feb 2023 08:46:38 +0100 Subject: [PATCH 03/16] Follow-up of 991aedd37ce64883a86af23dd5eb940f89a93377 - Fixed extruder temperature for single extruder multi material prints --- src/libslic3r/GCode/GCodeProcessor.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index eb7c46861f..5664768242 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -3378,9 +3378,9 @@ void GCodeProcessor::process_T(const std::string_view command) extra_time += m_kissslicer_toolchange_time_correction; simulate_st_synchronize(extra_time); - // specific to single extruder multi material, set the extruder temperature - // if not done yet - if (m_single_extruder_multi_material && m_extruder_temps[m_extruder_id] == 0.0f) + // specific to single extruder multi material, set the new extruder temperature + // to match the old one + if (m_single_extruder_multi_material) m_extruder_temps[m_extruder_id] = m_extruder_temps[old_extruder_id]; m_result.extruders_count = std::max(m_result.extruders_count, m_extruder_id + 1); From 14c3152ac9c68cc20b114d2598affb0454f6d1aa Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 20 Feb 2023 14:27:31 +0100 Subject: [PATCH 04/16] Fix for #9795 - Text emboss input dialog doesn't allow pasting in text from clipboard --- src/slic3r/GUI/ImGuiWrapper.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 8908a5ef9d..6b85af966d 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -1082,7 +1082,7 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co // The press on Esc key invokes editing of InputText (removes last changes) // So we should save previous value... std::string str = search_str; - ImGui::InputTextEx("", NULL, search_str, 40, search_size, ImGuiInputTextFlags_AutoSelectAll, NULL, NULL); + ImGui::InputTextEx("", NULL, search_str, 240, search_size, ImGuiInputTextFlags_AutoSelectAll, NULL, NULL); edited = ImGui::IsItemEdited(); if (edited) hovered_id = 0; @@ -2056,7 +2056,11 @@ const char* ImGuiWrapper::clipboard_get(void* user_data) const char* res = ""; if (wxTheClipboard->Open()) { - if (wxTheClipboard->IsSupported(wxDF_TEXT)) { + if (wxTheClipboard->IsSupported(wxDF_TEXT) +#if wxUSE_UNICODE + || wxTheClipboard->IsSupported(wxDF_UNICODETEXT) +#endif // wxUSE_UNICODE + ) { wxTextDataObject data; wxTheClipboard->GetData(data); From 5e550709ffbd88e72554629e82ed754582b26368 Mon Sep 17 00:00:00 2001 From: Pavel Mikus Date: Mon, 20 Feb 2023 21:14:34 +0100 Subject: [PATCH 05/16] fix issue 9800 - Avoid Crossing Curled Overhangs Not Respecting Printer Bed Size Fix Avoid curled overhang functionality actually not working correctly, especially on multiple objects/instances --- src/libslic3r/GCode.cpp | 12 ++++++++++-- src/libslic3r/JumpPointSearch.cpp | 20 +++++++++++--------- src/libslic3r/JumpPointSearch.hpp | 14 ++++++++------ src/libslic3r/SupportSpotsGenerator.cpp | 2 ++ 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 16696e49a3..460ddc1114 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1032,6 +1032,10 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_pressure_equalizer = make_unique(print.config()); m_enable_extrusion_role_markers = (bool)m_pressure_equalizer; + if (print.config().avoid_crossing_curled_overhangs){ + this->m_avoid_crossing_curled_overhangs.init_bed_shape(get_bed_shape(print.config())); + } + // Write information on the generator. file.write_format("; %s\n\n", Slic3r::header_slic3r_generated().c_str()); @@ -2107,8 +2111,12 @@ LayerResult GCode::process_layer( if (this->config().avoid_crossing_curled_overhangs) { m_avoid_crossing_curled_overhangs.clear(); for (const ObjectLayerToPrint &layer_to_print : layers) { - m_avoid_crossing_curled_overhangs.add_obstacles(layer_to_print.object_layer, Point(scaled(this->origin()))); - m_avoid_crossing_curled_overhangs.add_obstacles(layer_to_print.support_layer, Point(scaled(this->origin()))); + if (layer_to_print.object() == nullptr) + continue; + for (const auto &instance : layer_to_print.object()->instances()) { + m_avoid_crossing_curled_overhangs.add_obstacles(layer_to_print.object_layer, instance.shift); + m_avoid_crossing_curled_overhangs.add_obstacles(layer_to_print.support_layer, instance.shift); + } } } diff --git a/src/libslic3r/JumpPointSearch.cpp b/src/libslic3r/JumpPointSearch.cpp index 888db296b1..ef3dba45e7 100644 --- a/src/libslic3r/JumpPointSearch.cpp +++ b/src/libslic3r/JumpPointSearch.cpp @@ -1,5 +1,6 @@ #include "JumpPointSearch.hpp" #include "BoundingBox.hpp" +#include "ExPolygon.hpp" #include "Point.hpp" #include "libslic3r/AStar.hpp" #include "libslic3r/KDTreeIndirect.hpp" @@ -181,17 +182,18 @@ public: void JPSPathFinder::clear() { inpassable.clear(); - obstacle_max = Pixel(std::numeric_limits::min(), std::numeric_limits::min()); - obstacle_min = Pixel(std::numeric_limits::max(), std::numeric_limits::max()); + max_search_box.max = Pixel(std::numeric_limits::min(), std::numeric_limits::min()); + max_search_box.min = Pixel(std::numeric_limits::max(), std::numeric_limits::max()); + add_obstacles(bed_shape); } void JPSPathFinder::add_obstacles(const Lines &obstacles) { auto store_obstacle = [&](coord_t x, coord_t y) { - obstacle_max.x() = std::max(obstacle_max.x(), x); - obstacle_max.y() = std::max(obstacle_max.y(), y); - obstacle_min.x() = std::min(obstacle_min.x(), x); - obstacle_min.y() = std::min(obstacle_min.y(), y); + max_search_box.max.x() = std::max(max_search_box.max.x(), x); + max_search_box.max.y() = std::max(max_search_box.max.y(), y); + max_search_box.min.x() = std::min(max_search_box.min.x(), x); + max_search_box.min.y() = std::min(max_search_box.min.y(), y); inpassable.insert(Pixel{x, y}); return true; }; @@ -240,9 +242,9 @@ Polyline JPSPathFinder::find_path(const Point &p0, const Point &p1) }); } - BoundingBox search_box({start, end, obstacle_max, obstacle_min}); - search_box.max += Pixel(1, 1); - search_box.min -= Pixel(1, 1); + BoundingBox search_box = max_search_box; + search_box.max -= Pixel(1, 1); + search_box.min += Pixel(1, 1); BoundingBox bounding_square(Points{start, end}); bounding_square.max += Pixel(5, 5); diff --git a/src/libslic3r/JumpPointSearch.hpp b/src/libslic3r/JumpPointSearch.hpp index b09cc77477..5f3b5fee21 100644 --- a/src/libslic3r/JumpPointSearch.hpp +++ b/src/libslic3r/JumpPointSearch.hpp @@ -2,6 +2,7 @@ #define SRC_LIBSLIC3R_JUMPPOINTSEARCH_HPP_ #include "BoundingBox.hpp" +#include "Polygon.hpp" #include "libslic3r/Layer.hpp" #include "libslic3r/Point.hpp" #include "libslic3r/Polyline.hpp" @@ -16,18 +17,19 @@ class JPSPathFinder using Pixel = Point; std::unordered_set inpassable; coordf_t print_z; - Pixel obstacle_min; - Pixel obstacle_max; + BoundingBox max_search_box; + Lines bed_shape; const coord_t resolution = scaled(1.5); Pixel pixelize(const Point &p) { return p / resolution; } Point unpixelize(const Pixel &p) { return p * resolution; } public: - JPSPathFinder() { clear(); }; - void clear(); - void add_obstacles(const Lines &obstacles); - void add_obstacles(const Layer* layer, const Point& global_origin); + JPSPathFinder() = default; + void init_bed_shape(const Points &bed_shape) { this->bed_shape = (to_lines(Polygon{bed_shape})); }; + void clear(); + void add_obstacles(const Lines &obstacles); + void add_obstacles(const Layer *layer, const Point &global_origin); Polyline find_path(const Point &start, const Point &end); }; diff --git a/src/libslic3r/SupportSpotsGenerator.cpp b/src/libslic3r/SupportSpotsGenerator.cpp index e5f58f91e3..d45f82db87 100644 --- a/src/libslic3r/SupportSpotsGenerator.cpp +++ b/src/libslic3r/SupportSpotsGenerator.cpp @@ -1043,6 +1043,7 @@ void estimate_supports_malformations(SupportLayerPtrs &layers, float flow_width, AABBTreeLines::LinesDistancer prev_layer_lines{}; for (SupportLayer *l : layers) { + l->malformed_lines.clear(); std::vector current_layer_lines; for (const ExtrusionEntity *extrusion : l->support_fills.flatten().entities) { @@ -1114,6 +1115,7 @@ void estimate_malformations(LayerPtrs &layers, const Params ¶ms) LD prev_layer_lines{}; for (Layer *l : layers) { + l->malformed_lines.clear(); std::vector boundary_lines = l->lower_layer != nullptr ? to_unscaled_linesf(l->lower_layer->lslices) : std::vector(); AABBTreeLines::LinesDistancer prev_layer_boundary{std::move(boundary_lines)}; std::vector current_layer_lines; From 4e32b7ea5a54685d46c3afac0e0eb48f519b97eb Mon Sep 17 00:00:00 2001 From: David Kocik Date: Fri, 17 Feb 2023 15:05:32 +0100 Subject: [PATCH 06/16] Fix of Config wizard "no filaments selected for a printer" --- src/slic3r/GUI/ConfigWizard.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 35292d803b..b0e68dffff 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -2785,7 +2785,7 @@ bool ConfigWizard::priv::check_and_install_missing_materials(Technology technolo { // Walk over all installed Printer presets and verify whether there is a filament or SLA material profile installed at the same PresetBundle, // which is compatible with it. - const auto printer_models_missing_materials = [this, only_for_model_id](PrinterTechnology technology, const std::string §ion) + const auto printer_models_missing_materials = [this, only_for_model_id](PrinterTechnology technology, const std::string §ion, bool no_templates) { const std::map &appconfig_presets = appconfig_new.has_section(section) ? appconfig_new.get_section(section) : std::map(); std::set printer_models_without_material; @@ -2805,15 +2805,16 @@ bool ConfigWizard::priv::check_and_install_missing_materials(Technology technolo has_material = true; break; } - // find if preset.first is part of the templates profile (up is searching if preset.first is part of printer vendor preset) - for (const auto& bp : bundles) { - if (!bp.second.preset_bundle->vendors.empty() && bp.second.preset_bundle->vendors.begin()->second.templates_profile) { - const PresetCollection& template_materials = bp.second.preset_bundle->materials(technology); - const Preset* template_material = template_materials.find_preset(preset.first, false); - if (template_material && is_compatible_with_printer(PresetWithVendorProfile(*template_material, &bp.second.preset_bundle->vendors.begin()->second), PresetWithVendorProfile(printer, nullptr))) { - has_material = true; - break; + if (!no_templates) { + for (const auto& bp : bundles) { + if (!bp.second.preset_bundle->vendors.empty() && bp.second.preset_bundle->vendors.begin()->second.templates_profile) { + const PresetCollection& template_materials = bp.second.preset_bundle->materials(technology); + const Preset* template_material = template_materials.find_preset(preset.first, false); + if (template_material && is_compatible_with_printer(PresetWithVendorProfile(*template_material, &bp.second.preset_bundle->vendors.begin()->second), PresetWithVendorProfile(printer, nullptr))) { + has_material = true; + break; + } } } } @@ -2872,8 +2873,10 @@ bool ConfigWizard::priv::check_and_install_missing_materials(Technology technolo return out; }; + bool no_templates = wxGetApp().app_config->get("no_templates") == "1"; + if (any_fff_selected && (technology & T_FFF)) { - std::set printer_models_without_material = printer_models_missing_materials(ptFFF, AppConfig::SECTION_FILAMENTS); + std::set printer_models_without_material = printer_models_missing_materials(ptFFF, AppConfig::SECTION_FILAMENTS, no_templates); if (! printer_models_without_material.empty()) { if (only_for_model_id.empty()) ask_and_select_default_materials( @@ -2891,7 +2894,7 @@ bool ConfigWizard::priv::check_and_install_missing_materials(Technology technolo } if (any_sla_selected && (technology & T_SLA)) { - std::set printer_models_without_material = printer_models_missing_materials(ptSLA, AppConfig::SECTION_MATERIALS); + std::set printer_models_without_material = printer_models_missing_materials(ptSLA, AppConfig::SECTION_MATERIALS, no_templates); if (! printer_models_without_material.empty()) { if (only_for_model_id.empty()) ask_and_select_default_materials( From a41dd8eeed50b9bfbb9f37769569f091512d8124 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 21 Feb 2023 12:43:55 +0100 Subject: [PATCH 07/16] =?UTF-8?q?Follow-up=20dc0275f70d4c5d163e1906828cfc0?= =?UTF-8?q?8ee46b6d081=20-=20Cut:=20Next=20performance=C2=A0fix.=20Refacto?= =?UTF-8?q?r=20a=20code=20to=20avoid=20redundant=20recalculation=20of=20an?= =?UTF-8?q?=20object=20bounding=20box=20and=20transformed=20bounding=20box?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 106 +++++++++------------------ src/slic3r/GUI/Gizmos/GLGizmoCut.hpp | 8 +- 2 files changed, 39 insertions(+), 75 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 8c33c3e037..d8064bd043 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -453,15 +453,9 @@ void GLGizmoCut3D::update_clipper() update_raycasters_for_picking_transform(); } -void GLGizmoCut3D::update_clipper_on_render() +void GLGizmoCut3D::set_center(const Vec3d& center, bool update_tbb /*=false*/) { - update_clipper(); - force_update_clipper_on_render = false; -} - -void GLGizmoCut3D::set_center(const Vec3d& center) -{ - set_center_pos(center); + set_center_pos(center, update_tbb); update_clipper(); } @@ -584,7 +578,7 @@ void GLGizmoCut3D::render_move_center_input(int axis) if (in_val != val) { move[axis] = val; - set_center(move); + set_center(move, true); } } @@ -888,21 +882,17 @@ bool GLGizmoCut3D::on_init() void GLGizmoCut3D::on_load(cereal::BinaryInputArchive& ar) { - ar( m_keep_upper, m_keep_lower, m_rotate_lower, m_rotate_upper, m_hide_cut_plane, m_mode, m_connectors_editing,//m_selected, - // m_connector_depth_ratio, m_connector_size, m_connector_mode, m_connector_type, m_connector_style, m_connector_shape_id, + ar( m_keep_upper, m_keep_lower, m_rotate_lower, m_rotate_upper, m_hide_cut_plane, m_mode, m_connectors_editing, m_ar_plane_center, m_rotation_m); set_center_pos(m_ar_plane_center, true); - force_update_clipper_on_render = true; - m_parent.request_extra_frame(); } void GLGizmoCut3D::on_save(cereal::BinaryOutputArchive& ar) const { - ar( m_keep_upper, m_keep_lower, m_rotate_lower, m_rotate_upper, m_hide_cut_plane, m_mode, m_connectors_editing,//m_selected, - // m_connector_depth_ratio, m_connector_size, m_connector_mode, m_connector_type, m_connector_style, m_connector_shape_id, + ar( m_keep_upper, m_keep_lower, m_rotate_lower, m_rotate_upper, m_hide_cut_plane, m_mode, m_connectors_editing, m_ar_plane_center, m_start_dragging_m); } @@ -923,6 +913,7 @@ void GLGizmoCut3D::on_set_state() // initiate archived values m_ar_plane_center = m_plane_center; m_start_dragging_m = m_rotation_m; + m_transformed_bounding_box = transformed_bounding_box(m_plane_center); m_parent.request_extra_frame(); } @@ -934,7 +925,6 @@ void GLGizmoCut3D::on_set_state() m_selected.clear(); m_parent.set_use_color_clip_plane(false); } - force_update_clipper_on_render = m_state == On; } void GLGizmoCut3D::on_register_raycasters_for_picking() @@ -1146,7 +1136,7 @@ void GLGizmoCut3D::dragging_grabber_z(const GLGizmoBase::UpdateData &data) const Vec3d shift = starting_vec * projection; // move cut plane center - set_center(m_plane_center + shift); + set_center(m_plane_center + shift, true); m_was_cut_plane_dragged = true; } @@ -1247,16 +1237,19 @@ void GLGizmoCut3D::on_stop_dragging() } } -void GLGizmoCut3D::set_center_pos(const Vec3d& center_pos, bool force/* = false*/) +void GLGizmoCut3D::set_center_pos(const Vec3d& center_pos, bool update_tbb /*=false*/) { - if (m_plane_center == center_pos) - return; + BoundingBoxf3 tbb = m_transformed_bounding_box; + if (update_tbb) { + Vec3d normal = m_rotation_m.inverse() * Vec3d(m_plane_center - center_pos); + tbb.translate(normal.z() * Vec3d::UnitZ()); + } + const Vec3d& instance_offset = m_parent.get_selection().get_first_volume()->get_instance_offset(); + const Vec3d trans_center_pos = (m_rotation_m.inverse() * (center_pos - instance_offset)) + tbb.center(); - bool can_set_center_pos = force; - BoundingBoxf3 tbb; + bool can_set_center_pos = tbb.contains(trans_center_pos); if (!can_set_center_pos) { - tbb = transformed_bounding_box(center_pos); - if (tbb.max.z() > -1. && tbb.min.z() < 1.) + if (tbb.max.z() > -.5 && tbb.min.z() < .5) can_set_center_pos = true; else { const double old_dist = (m_bb_center - m_plane_center).norm(); @@ -1290,55 +1283,31 @@ BoundingBoxf3 GLGizmoCut3D::bounding_box() const BoundingBoxf3 GLGizmoCut3D::transformed_bounding_box(const Vec3d& plane_center) const { - // #ysFIXME !!! - BoundingBoxf3 ret; - - const CommonGizmosDataObjects::SelectionInfo* sel_info = m_c->selection_info(); - if (!sel_info) - return ret; - const ModelObject* mo = sel_info->model_object(); - if (!mo) - return ret; - const int instance_idx = sel_info->get_active_instance(); - if (instance_idx < 0 || mo->instances.empty()) - return ret; - const ModelInstance* mi = mo->instances[instance_idx]; - - const Vec3d& instance_offset = mi->get_offset(); - Vec3d cut_center_offset = plane_center - instance_offset; - cut_center_offset[Z] -= sel_info->get_sla_shift(); - - const auto cut_matrix = Transform3d::Identity() * m_rotation_m.inverse() * translation_transform(-cut_center_offset); - const Selection& selection = m_parent.get_selection(); + + const Vec3d& instance_offset = selection.get_first_volume()->get_instance_offset(); + const auto cut_matrix = Transform3d::Identity() * m_rotation_m.inverse() * translation_transform(instance_offset - plane_center); + const Selection::IndicesList& idxs = selection.get_volume_idxs(); + BoundingBoxf3 ret; for (unsigned int i : idxs) { const GLVolume* volume = selection.get_volume(i); // respect just to the solid parts for FFF and ignore pad and supports for SLA if (!volume->is_modifier && !volume->is_sla_pad() && !volume->is_sla_support()) { -#if ENABLE_WORLD_COORDINATE const auto instance_matrix = volume->get_instance_transformation().get_matrix_no_offset(); -#else - const auto instance_matrix = assemble_transform( - Vec3d::Zero(), // don't apply offset - volume->get_instance_rotation().cwiseProduct(Vec3d(1.0, 1.0, 1.0)), - volume->get_instance_scaling_factor(), - volume->get_instance_mirror() - ); -#endif // ENABLE_WORLD_COORDINATE - auto volume_trafo = instance_matrix * volume->get_volume_transformation().get_matrix(); - ret.merge(volume->transformed_convex_hull_bounding_box(cut_matrix * volume_trafo)); } } return ret; } -bool GLGizmoCut3D::update_bb() +void GLGizmoCut3D::update_bb() { const BoundingBoxf3 box = bounding_box(); + if (!box.defined) + return; if (m_max_pos != box.max || m_min_pos != box.min) { m_bounding_box = box; @@ -1348,10 +1317,11 @@ bool GLGizmoCut3D::update_bb() m_max_pos = box.max; m_min_pos = box.min; m_bb_center = box.center(); + m_transformed_bounding_box = transformed_bounding_box(m_bb_center); if (box.contains(m_center_offset)) - set_center_pos(m_bb_center + m_center_offset, true); + set_center_pos(m_bb_center + m_center_offset); else - set_center_pos(m_bb_center, true); + set_center_pos(m_bb_center); m_radius = box.radius(); m_grabber_connection_len = 0.5 * m_radius;// std::min(0.75 * m_radius, 35.0); @@ -1376,10 +1346,7 @@ bool GLGizmoCut3D::update_bb() clear_selection(); if (CommonGizmosDataObjects::SelectionInfo* selection = m_c->selection_info()) m_selected.resize(selection->model_object()->cut_connectors.size(), false); - - return true; } - return false; } void GLGizmoCut3D::init_picking_models() @@ -1435,12 +1402,7 @@ void GLGizmoCut3D::render_clipper_cut() void GLGizmoCut3D::on_render() { - if (update_bb() || force_update_clipper_on_render) { - update_clipper_on_render(); - m_c->object_clipper()->set_behavior(m_connectors_editing, m_connectors_editing, 0.4); - } - else - update_clipper(); + update_clipper(); init_picking_models(); @@ -1653,10 +1615,10 @@ void GLGizmoCut3D::render_build_size() void GLGizmoCut3D::reset_cut_plane() { - set_center(m_bb_center); m_rotation_m = Transform3d::Identity(); m_angle_arc.reset(); - update_clipper(); + m_transformed_bounding_box = transformed_bounding_box(m_bb_center); + set_center(m_bb_center); } void GLGizmoCut3D::invalidate_cut_plane() @@ -1671,6 +1633,9 @@ void GLGizmoCut3D::invalidate_cut_plane() void GLGizmoCut3D::set_connectors_editing(bool connectors_editing) { + if (m_connectors_editing == connectors_editing) + return; + m_connectors_editing = connectors_editing; update_raycasters_for_picking(); @@ -2340,7 +2305,7 @@ bool GLGizmoCut3D::process_cut_line(SLAGizmoEventType action, const Vec2d& mouse m_rotation_m = m; m_angle_arc.reset(); - set_center(m_plane_center + cross_dir * (cross_dir.dot(pt - m_plane_center))); + set_center(m_plane_center + cross_dir * (cross_dir.dot(pt - m_plane_center)), true); discard_cut_line_processing(); } @@ -2542,6 +2507,7 @@ CommonGizmosDataID GLGizmoCut3D::on_get_requirements() const { void GLGizmoCut3D::data_changed() { + update_bb(); if (auto oc = m_c->object_clipper()) oc->set_behavior(m_connectors_editing, m_connectors_editing, double(m_contour_width)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index 569122d4ad..5e6e4146f0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -121,7 +121,6 @@ class GLGizmoCut3D : public GLGizmoBase float m_label_width{ 150.0 }; float m_control_width{ 200.0 }; bool m_imperial_units{ false }; - bool force_update_clipper_on_render{false}; float m_contour_width{ 0.4f }; float m_cut_plane_radius_koef{ 1.5f }; @@ -192,7 +191,6 @@ public: void rotate_vec3d_around_plane_center(Vec3d&vec); void put_connectors_on_cut_plane(const Vec3d& cp_normal, double cp_offset); void update_clipper(); - void update_clipper_on_render(); void invalidate_cut_plane(); BoundingBoxf3 bounding_box() const; @@ -258,7 +256,7 @@ protected: void data_changed() override; private: - void set_center(const Vec3d& center); + void set_center(const Vec3d& center, bool update_tbb = false); bool render_combo(const std::string& label, const std::vector& lines, size_t& selection_idx); bool render_double_input(const std::string& label, double& value_in); bool render_slider_double_input(const std::string& label, float& value_in, float& tolerance_in); @@ -284,8 +282,8 @@ private: void render_cut_plane_grabbers(); void render_cut_line(); void perform_cut(const Selection&selection); - void set_center_pos(const Vec3d¢er_pos, bool force = false); - bool update_bb(); + void set_center_pos(const Vec3d¢er_pos, bool update_tbb = false); + void update_bb(); void init_picking_models(); void init_rendering_items(); void render_clipper_cut(); From db60d23c1889e32767fba7587b27993826ba7b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Tue, 21 Feb 2023 13:48:16 +0100 Subject: [PATCH 08/16] Fix of #9809: Crash after splitting an object into parts. Now after splitting an object into parts, custom supports, seams, and multimaterial painting are removed, and the user is notified about it. Also, this commit fixed the text of the notification about removing custom supports, seams, and multimaterial painting by Simplify gizmo. And it also fixed that info about custom supports, seams, and multimaterial painting was still shown in the right panel after the model simplification event when custom supports, seams, and multimaterial were removed. --- src/slic3r/GUI/GUI_ObjectList.cpp | 11 ++++++++++- src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp | 6 +++++- src/slic3r/GUI/Plater.cpp | 9 ++++++--- src/slic3r/GUI/Plater.hpp | 2 +- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 1906d2c307..79ae5b8963 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2175,6 +2175,10 @@ void ObjectList::split() take_snapshot(_(L("Split to Parts"))); + // Before splitting volume we have to remove all custom supports, seams, and multimaterial painting. + wxGetApp().plater()->clear_before_change_mesh(obj_idx, _u8L("Custom supports, seams and multimaterial painting were " + "removed after splitting the object.")); + volume->split(nozzle_dmrs_cnt); (*m_objects)[obj_idx]->input_file.clear(); @@ -2186,6 +2190,10 @@ void ObjectList::split() changed_object(obj_idx); // update printable state for new volumes on canvas3D wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_object(obj_idx); + + // After removing custom supports, seams, and multimaterial painting, we have to update info about the object to remove information about + // custom supports, seams, and multimaterial painting in the right panel. + wxGetApp().obj_list()->update_info_items(obj_idx); } void ObjectList::merge(bool to_multipart_object) @@ -4682,7 +4690,8 @@ void ObjectList::fix_through_netfabb() msg += "\n"; } - plater->clear_before_change_mesh(obj_idx); + plater->clear_before_change_mesh(obj_idx, _u8L("Custom supports, seams and multimaterial painting were " + "removed after repairing the mesh.")); std::string res; if (!fix_model_by_win10_sdk_gui(*(object(obj_idx)), vol_idx, progress_dlg, msg, res)) return false; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp index 177d9d5a7b..90552c0a5d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp @@ -540,7 +540,11 @@ void GLGizmoSimplify::apply_simplify() { const Selection& selection = m_parent.get_selection(); auto plater = wxGetApp().plater(); plater->take_snapshot(_u8L("Simplify ") + create_volumes_name(m_volume_ids, selection)); - plater->clear_before_change_mesh(selection.get_object_idx()); + plater->clear_before_change_mesh(selection.get_object_idx(), _u8L("Custom supports, seams and multimaterial painting were " + "removed after simplifying the mesh.")); + // After removing custom supports, seams, and multimaterial painting, we have to update info about the object to remove information about + // custom supports, seams, and multimaterial painting in the right panel. + wxGetApp().obj_list()->update_info_items(selection.get_object_idx()); for (const auto &item: m_state.result) { const ObjectID &id = item.first; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d4e0b8fbd0..15c5400822 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3127,6 +3127,10 @@ void Plater::priv::split_object() Model new_model = model; ModelObject* current_model_object = new_model.objects[obj_idx]; + // Before splitting object we have to remove all custom supports, seams, and multimaterial painting. + wxGetApp().plater()->clear_before_change_mesh(obj_idx, _u8L("Custom supports, seams and multimaterial painting were " + "removed after splitting the object.")); + wxBusyCursor wait; ModelObjectPtrs new_objects; current_model_object->split(&new_objects); @@ -7338,7 +7342,7 @@ bool Plater::set_printer_technology(PrinterTechnology printer_technology) return ret; } -void Plater::clear_before_change_mesh(int obj_idx) +void Plater::clear_before_change_mesh(int obj_idx, const std::string ¬ification_msg) { ModelObject* mo = model().objects[obj_idx]; @@ -7356,8 +7360,7 @@ void Plater::clear_before_change_mesh(int obj_idx) get_notification_manager()->push_notification( NotificationType::CustomSupportsAndSeamRemovedAfterRepair, NotificationManager::NotificationLevel::PrintInfoNotificationLevel, - _u8L("Custom supports, seams and multimaterial painting were " - "removed after repairing the mesh.")); + notification_msg); // _u8L("Undo the repair"), // [this, snapshot_time](wxEvtHandler*){ // // Make sure the snapshot is still available and that diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 1ecbeb1906..3dcca746da 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -273,7 +273,7 @@ public: void reslice_FFF_until_step(PrintObjectStep step, const ModelObject &object, bool postpone_error_messages = false); void reslice_SLA_until_step(SLAPrintObjectStep step, const ModelObject &object, bool postpone_error_messages = false); - void clear_before_change_mesh(int obj_idx); + void clear_before_change_mesh(int obj_idx, const std::string ¬ification_msg); void changed_mesh(int obj_idx); void changed_object(int obj_idx); From e463979592d9e778fbc5632c5416fe37a6785db1 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 21 Feb 2023 15:25:08 +0100 Subject: [PATCH 09/16] Refactoring of dialog text --- src/slic3r/GUI/ConfigWizard.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index b0e68dffff..74f1ba19ee 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -2881,9 +2881,9 @@ bool ConfigWizard::priv::check_and_install_missing_materials(Technology technolo if (only_for_model_id.empty()) ask_and_select_default_materials( _L("The following FFF printer models have no filament selected:") + - "\n\n\t" + + "\n\n" + printer_model_list(printer_models_without_material) + - "\n\n\t" + + "\n\n" + _L("Do you want to select default filaments for these FFF printer models?"), printer_models_without_material, T_FFF); @@ -2899,9 +2899,9 @@ bool ConfigWizard::priv::check_and_install_missing_materials(Technology technolo if (only_for_model_id.empty()) ask_and_select_default_materials( _L("The following SLA printer models have no materials selected:") + - "\n\n\t" + + "\n\n" + printer_model_list(printer_models_without_material) + - "\n\n\t" + + "\n\n" + _L("Do you want to select default SLA materials for these printer models?"), printer_models_without_material, T_SLA); From beabf46e871dcc40a593f4d87daa968aabce5730 Mon Sep 17 00:00:00 2001 From: Pavel Mikus Date: Wed, 22 Feb 2023 11:01:12 +0100 Subject: [PATCH 10/16] Set cooling markers correctly - finally fix of cooperation between dynamic speed and pressure equalizer Fixes the following issues: 9769, 9485 and maybe others where presusre equalier is used with dynamic speeds --- src/libslic3r/GCode.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 460ddc1114..7088a158d8 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2930,19 +2930,19 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de + float_to_string_decimal_point(m_last_height) + "\n"; } - std::string comment; + std::string cooling_marker_setspeed_comments; if (m_enable_cooling_markers) { if (path.role().is_bridge()) gcode += ";_BRIDGE_FAN_START\n"; else - comment = ";_EXTRUDE_SET_SPEED"; + cooling_marker_setspeed_comments = ";_EXTRUDE_SET_SPEED"; if (path.role() == ExtrusionRole::ExternalPerimeter) - comment += ";_EXTERNAL_PERIMETER"; + cooling_marker_setspeed_comments += ";_EXTERNAL_PERIMETER"; } if (!variable_speed) { // F is mm per minute. - gcode += m_writer.set_speed(F, "", comment); + gcode += m_writer.set_speed(F, "", cooling_marker_setspeed_comments); double path_length = 0.; std::string comment; if (m_config.gcode_comments) { @@ -2966,7 +2966,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de marked_comment += description_bridge; } double last_set_speed = new_points[0].speed * 60.0; - gcode += m_writer.set_speed(last_set_speed, "", comment); + gcode += m_writer.set_speed(last_set_speed, "", cooling_marker_setspeed_comments); Vec2d prev = this->point_to_gcode_quantized(new_points[0].p); for (size_t i = 1; i < new_points.size(); i++) { const ProcessedPoint& processed_point = new_points[i]; @@ -2976,7 +2976,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de prev = p; double new_speed = processed_point.speed * 60.0; if (last_set_speed != new_speed) { - gcode += m_writer.set_speed(new_speed, "", comment); + gcode += m_writer.set_speed(new_speed, "", cooling_marker_setspeed_comments); last_set_speed = new_speed; } } From 17899adc6957dd5207eb288e36045c533da3f544 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 22 Feb 2023 11:33:39 +0100 Subject: [PATCH 11/16] #9823 - Fixed parsing of gcode generated by Simplify3D --- src/libslic3r/GCode/GCodeProcessor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 5664768242..6db0492d0e 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -472,7 +472,7 @@ const std::vector> GCodeProces { EProducer::Slic3r, "generated by Slic3r" }, { EProducer::SuperSlicer, "generated by SuperSlicer" }, { EProducer::Cura, "Cura_SteamEngine" }, - { EProducer::Simplify3D, "G-Code generated by Simplify3D(R)" }, + { EProducer::Simplify3D, "generated by Simplify3D(R)" }, { EProducer::CraftWare, "CraftWare" }, { EProducer::ideaMaker, "ideaMaker" }, { EProducer::KissSlicer, "KISSlicer" }, @@ -2025,10 +2025,10 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string_view comment) return true; } - // ; layer - tag = " layer"; + // ; layer | ;layer + tag = "layer"; pos = cmt.find(tag); - if (pos == 0) { + if (pos == 0 || pos == 1) { // skip lines "; layer end" const std::string_view data = cmt.substr(pos + tag.length()); size_t end_start = data.find("end"); From 6a722570f1afe857c083177fd1357e87961c4a9b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 22 Feb 2023 13:22:45 +0100 Subject: [PATCH 12/16] #9722 - GCodeViewer - Take in account z offset when setting the height of the toolpaths for the purge line in custom start gcode. --- src/libslic3r/GCode/GCodeProcessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 6db0492d0e..555aab0c15 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -2402,7 +2402,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line) if (m_forced_height > 0.0f) m_height = m_forced_height; else if (m_layer_id == 0) - m_height = (m_end_position[Z] <= double(m_first_layer_height)) ? m_end_position[Z] : m_first_layer_height; + m_height = std::min((float)m_end_position[Z], m_first_layer_height + m_z_offset); else if (line.comment() != INTERNAL_G2G3_TAG){ if (m_end_position[Z] > m_extruded_last_z + EPSILON && delta_pos[Z] == 0.0) m_height = m_end_position[Z] - m_extruded_last_z; From d6c731218102bfc4e6f1f432b74bc705b1e7bcef Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 22 Feb 2023 16:58:49 +0100 Subject: [PATCH 13/16] FOllow-up a41dd8eeed50b9bfbb9f37769569f091512d8124 - Fix for SPE-1521 - Use the arrows to move the cut plane out of the object --- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index d8064bd043..b7470a854b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -364,7 +364,7 @@ void GLGizmoCut3D::shift_cut_z(double delta) { Vec3d new_cut_center = m_plane_center; new_cut_center[Z] += delta; - set_center(new_cut_center); + set_center(new_cut_center, true); } void GLGizmoCut3D::rotate_vec3d_around_plane_center(Vec3d&vec) From be74338e534f3d29953c6372974acc487753bb64 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 23 Feb 2023 10:01:40 +0100 Subject: [PATCH 14/16] Follow-up a41dd8eeed50b9bfbb9f37769569f091512d8124 - Added missed updates for transformed bounding box + Fixed Arrow Up/Down action. Cut plane is moved during the its own normal instead of during the Z axes --- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 18 ++++++++++++------ src/slic3r/GUI/Gizmos/GLGizmoCut.hpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index b7470a854b..fb457f5f6e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -360,11 +360,12 @@ bool GLGizmoCut3D::on_mouse(const wxMouseEvent &mouse_event) return false; } -void GLGizmoCut3D::shift_cut_z(double delta) +void GLGizmoCut3D::shift_cut(double delta) { - Vec3d new_cut_center = m_plane_center; - new_cut_center[Z] += delta; - set_center(new_cut_center, true); + Vec3d starting_vec = m_rotation_m * Vec3d::UnitZ(); + if (starting_vec.norm() != 0.0) + starting_vec.normalize(); + set_center(m_plane_center + starting_vec * delta, true); } void GLGizmoCut3D::rotate_vec3d_around_plane_center(Vec3d&vec) @@ -1175,9 +1176,10 @@ void GLGizmoCut3D::dragging_grabber_xy(const GLGizmoBase::UpdateData &data) rotation[m_hover_id] = theta; const Transform3d rotation_tmp = m_start_dragging_m * rotation_transform(rotation); - if (m_rotation_m.rotation() != rotation_tmp.rotation()) - m_transformed_bounding_box = transformed_bounding_box(m_plane_center); + const bool update_tbb = m_rotation_m.rotation() != rotation_tmp.rotation(); m_rotation_m = rotation_tmp; + if (update_tbb) + m_transformed_bounding_box = transformed_bounding_box(m_plane_center); m_angle = theta; while (m_angle > two_pi) @@ -1647,6 +1649,8 @@ void GLGizmoCut3D::set_connectors_editing(bool connectors_editing) void GLGizmoCut3D::flip_cut_plane() { m_rotation_m = m_rotation_m * rotation_transform(PI * Vec3d::UnitX()); + m_transformed_bounding_box = transformed_bounding_box(m_plane_center); + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Flip cut plane"), UndoRedo::SnapshotType::GizmoAction); m_start_dragging_m = m_rotation_m; @@ -2303,6 +2307,8 @@ bool GLGizmoCut3D::process_cut_line(SLAGizmoEventType action, const Vec2d& mouse m.matrix().block(0, 0, 3, 3) = q.setFromTwoVectors(Vec3d::UnitZ(), cross_dir).toRotationMatrix(); m_rotation_m = m; + // update transformed bb + m_transformed_bounding_box = transformed_bounding_box(m_plane_center); m_angle_arc.reset(); set_center(m_plane_center + cross_dir * (cross_dir.dot(pt - m_plane_center)), true); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index 5e6e4146f0..1f07f561f8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -187,7 +187,7 @@ public: /// Return True when use the information otherwise False. bool on_mouse(const wxMouseEvent &mouse_event) override; - void shift_cut_z(double delta); + void shift_cut(double delta); void rotate_vec3d_around_plane_center(Vec3d&vec); void put_connectors_on_cut_plane(const Vec3d& cp_normal, double cp_offset); void update_clipper(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index d7d6f309da..af93c07df3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -623,7 +623,7 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt) else if (m_current == Cut) { auto do_move = [this, &processed](double delta_z) { GLGizmoCut3D* cut = dynamic_cast(get_current()); - cut->shift_cut_z(delta_z); + cut->shift_cut(delta_z); processed = true; }; From 575422c7b74c2fe71bedf0ea20a3d0b253d97418 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 23 Feb 2023 10:12:29 +0100 Subject: [PATCH 15/16] Follow-up of 3b174c37a0291d630df3ac37b292c3c1dd360197 - Fixed update of wipe tower brim width after loading a 3mf project --- src/slic3r/GUI/GCodeViewer.cpp | 6 +++--- src/slic3r/GUI/GLCanvas3D.cpp | 23 +++++++++++------------ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 186f1f4fff..24f692d114 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -2250,9 +2250,9 @@ void GCodeViewer::load_shells(const Print& print) const PrintConfig& config = print.config(); const size_t extruders_count = config.nozzle_diameter.size(); if (extruders_count > 1 && config.wipe_tower && !config.complete_objects) { - const float depth = print.wipe_tower_data(extruders_count).depth; - const float brim_width = print.wipe_tower_data(extruders_count).brim_width; - + const WipeTowerData& wipe_tower_data = print.wipe_tower_data(extruders_count); + const float depth = wipe_tower_data.depth; + const float brim_width = wipe_tower_data.brim_width; m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle, !print.is_step_done(psWipeTower), brim_width); } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 79ceae9ecc..427c0e99fc 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1972,31 +1972,30 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re // Should the wipe tower be visualized ? unsigned int extruders_count = (unsigned int)dynamic_cast(m_config->option("nozzle_diameter"))->values.size(); - bool wt = dynamic_cast(m_config->option("wipe_tower"))->value; - bool co = dynamic_cast(m_config->option("complete_objects"))->value; + const bool wt = dynamic_cast(m_config->option("wipe_tower"))->value; + const bool co = dynamic_cast(m_config->option("complete_objects"))->value; if (extruders_count > 1 && wt && !co) { // Height of a print (Show at least a slab) - double height = std::max(m_model->bounding_box().max(2), 10.0); + const double height = std::max(m_model->bounding_box().max.z(), 10.0); - float x = dynamic_cast(m_config->option("wipe_tower_x"))->value; - float y = dynamic_cast(m_config->option("wipe_tower_y"))->value; - float w = dynamic_cast(m_config->option("wipe_tower_width"))->value; - float a = dynamic_cast(m_config->option("wipe_tower_rotation_angle"))->value; + const float x = dynamic_cast(m_config->option("wipe_tower_x"))->value; + const float y = dynamic_cast(m_config->option("wipe_tower_y"))->value; + const float w = dynamic_cast(m_config->option("wipe_tower_width"))->value; + const float a = dynamic_cast(m_config->option("wipe_tower_rotation_angle"))->value; + const float bw = dynamic_cast(m_config->option("wipe_tower_brim_width"))->value; const Print *print = m_process->fff_print(); - - float depth = print->wipe_tower_data(extruders_count).depth; - float brim_width = print->wipe_tower_data(extruders_count).brim_width; + const float depth = print->wipe_tower_data(extruders_count).depth; #if ENABLE_OPENGL_ES int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), - brim_width, &m_wipe_tower_mesh); + bw, &m_wipe_tower_mesh); #else int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), - brim_width); + bw); #endif // ENABLE_OPENGL_ES if (volume_idx_wipe_tower_old != -1) map_glvolume_old_to_new[volume_idx_wipe_tower_old] = volume_idx_wipe_tower_new; From 923f7cf8d764d420e332d9034d1e397574a0d956 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 23 Feb 2023 18:39:35 +0100 Subject: [PATCH 16/16] Cut bug fixing: SPE-1511 and SPE-1525 * Fixed Cut by line * Added missed snapshots for Undo/Redo * Fix for set new position do the cut plane * Fixed update_clipper() --- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 85 ++++++++++++++++------------ src/slic3r/GUI/Gizmos/GLGizmoCut.hpp | 4 +- 2 files changed, 51 insertions(+), 38 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index fb457f5f6e..744ae2ff43 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -365,7 +365,9 @@ void GLGizmoCut3D::shift_cut(double delta) Vec3d starting_vec = m_rotation_m * Vec3d::UnitZ(); if (starting_vec.norm() != 0.0) starting_vec.normalize(); + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Move cut plane"), UndoRedo::SnapshotType::GizmoAction); set_center(m_plane_center + starting_vec * delta, true); + m_ar_plane_center = m_plane_center; } void GLGizmoCut3D::rotate_vec3d_around_plane_center(Vec3d&vec) @@ -402,12 +404,10 @@ bool GLGizmoCut3D::is_looking_forward() const void GLGizmoCut3D::update_clipper() { - BoundingBoxf3 box = m_bounding_box; - // update cut_normal - Vec3d beg, end = beg = m_plane_center; - beg[Z] = box.center().z() - m_radius; - end[Z] = box.center().z() + m_radius; + Vec3d beg, end = beg = m_bb_center; + beg[Z] -= m_radius; + end[Z] += m_radius; rotate_vec3d_around_plane_center(beg); rotate_vec3d_around_plane_center(end); @@ -416,19 +416,18 @@ void GLGizmoCut3D::update_clipper() Vec3d normal = m_cut_normal = end - beg; // calculate normal and offset for clipping plane - double dist = (m_plane_center - beg).norm(); - dist = std::clamp(dist, 0.0001, normal.norm()); normal.normalize(); - m_clp_normal = normal; - double offset = normal.dot(beg) + dist; + m_clp_normal = normal; + double offset = normal.dot(m_plane_center); + double dist = normal.dot(beg); m_parent.set_color_clip_plane(normal, offset); if (!is_looking_forward()) { // recalculate normal and offset for clipping plane, if camera is looking downward to cut plane - end = beg = m_plane_center; - beg[Z] = box.center().z() + m_radius; - end[Z] = box.center().z() - m_radius; + end = beg = m_bb_center; + beg[Z] += m_radius; + end[Z] -= m_radius; rotate_vec3d_around_plane_center(beg); rotate_vec3d_around_plane_center(end); @@ -436,12 +435,10 @@ void GLGizmoCut3D::update_clipper() normal = end - beg; if (normal == Vec3d::Zero()) return; - - dist = (m_plane_center - beg).norm(); - dist = std::clamp(dist, 0.0001, normal.norm()); normal.normalize(); m_clp_normal = normal; - offset = normal.dot(beg) + dist; + offset = normal.dot(m_plane_center); + dist = normal.dot(beg); } m_c->object_clipper()->set_range_and_pos(normal, offset, dist); @@ -579,7 +576,9 @@ void GLGizmoCut3D::render_move_center_input(int axis) if (in_val != val) { move[axis] = val; + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Move cut plane"), UndoRedo::SnapshotType::GizmoAction); set_center(move, true); + m_ar_plane_center = m_plane_center; } } @@ -886,7 +885,8 @@ void GLGizmoCut3D::on_load(cereal::BinaryInputArchive& ar) ar( m_keep_upper, m_keep_lower, m_rotate_lower, m_rotate_upper, m_hide_cut_plane, m_mode, m_connectors_editing, m_ar_plane_center, m_rotation_m); - set_center_pos(m_ar_plane_center, true); + m_transformed_bounding_box = transformed_bounding_box(m_ar_plane_center, m_rotation_m); + set_center_pos(m_ar_plane_center); m_parent.request_extra_frame(); } @@ -910,11 +910,11 @@ void GLGizmoCut3D::on_set_state() update_bb(); m_connectors_editing = !m_selected.empty(); + m_transformed_bounding_box = transformed_bounding_box(m_plane_center); // initiate archived values m_ar_plane_center = m_plane_center; m_start_dragging_m = m_rotation_m; - m_transformed_bounding_box = transformed_bounding_box(m_plane_center); m_parent.request_extra_frame(); } @@ -1179,7 +1179,7 @@ void GLGizmoCut3D::dragging_grabber_xy(const GLGizmoBase::UpdateData &data) const bool update_tbb = m_rotation_m.rotation() != rotation_tmp.rotation(); m_rotation_m = rotation_tmp; if (update_tbb) - m_transformed_bounding_box = transformed_bounding_box(m_plane_center); + m_transformed_bounding_box = transformed_bounding_box(m_plane_center, m_rotation_m); m_angle = theta; while (m_angle > two_pi) @@ -1246,11 +1246,9 @@ void GLGizmoCut3D::set_center_pos(const Vec3d& center_pos, bool update_tbb /*=fa Vec3d normal = m_rotation_m.inverse() * Vec3d(m_plane_center - center_pos); tbb.translate(normal.z() * Vec3d::UnitZ()); } - const Vec3d& instance_offset = m_parent.get_selection().get_first_volume()->get_instance_offset(); - const Vec3d trans_center_pos = (m_rotation_m.inverse() * (center_pos - instance_offset)) + tbb.center(); - bool can_set_center_pos = tbb.contains(trans_center_pos); - if (!can_set_center_pos) { + bool can_set_center_pos = false; + { if (tbb.max.z() > -.5 && tbb.min.z() < .5) can_set_center_pos = true; else { @@ -1283,12 +1281,12 @@ BoundingBoxf3 GLGizmoCut3D::bounding_box() const return ret; } -BoundingBoxf3 GLGizmoCut3D::transformed_bounding_box(const Vec3d& plane_center) const +BoundingBoxf3 GLGizmoCut3D::transformed_bounding_box(const Vec3d& plane_center, const Transform3d& rotation_m/* = Transform3d::Identity()*/) const { const Selection& selection = m_parent.get_selection(); const Vec3d& instance_offset = selection.get_first_volume()->get_instance_offset(); - const auto cut_matrix = Transform3d::Identity() * m_rotation_m.inverse() * translation_transform(instance_offset - plane_center); + const auto cut_matrix = Transform3d::Identity() * rotation_m.inverse() * translation_transform(instance_offset - plane_center); const Selection::IndicesList& idxs = selection.get_volume_idxs(); BoundingBoxf3 ret; @@ -1544,8 +1542,11 @@ void GLGizmoCut3D::render_connectors_input_window(CutConnectors &connectors) m_imgui->disabled_begin(connectors.empty()); ImGui::SameLine(m_label_width); - if (render_reset_button("connectors", _u8L("Remove connectors"))) + const wxString act_name = _L("Remove connectors"); + if (render_reset_button("connectors", into_u8(act_name))) { + Plater::TakeSnapshot snapshot(wxGetApp().plater(), act_name, UndoRedo::SnapshotType::GizmoAction); reset_connectors(); + } m_imgui->disabled_end(); render_flip_plane_button(m_connectors_editing && connectors.empty()); @@ -1617,10 +1618,11 @@ void GLGizmoCut3D::render_build_size() void GLGizmoCut3D::reset_cut_plane() { - m_rotation_m = Transform3d::Identity(); m_angle_arc.reset(); m_transformed_bounding_box = transformed_bounding_box(m_bb_center); set_center(m_bb_center); + m_start_dragging_m = m_rotation_m = Transform3d::Identity(); + m_ar_plane_center = m_plane_center; } void GLGizmoCut3D::invalidate_cut_plane() @@ -1649,7 +1651,7 @@ void GLGizmoCut3D::set_connectors_editing(bool connectors_editing) void GLGizmoCut3D::flip_cut_plane() { m_rotation_m = m_rotation_m * rotation_transform(PI * Vec3d::UnitX()); - m_transformed_bounding_box = transformed_bounding_box(m_plane_center); + m_transformed_bounding_box = transformed_bounding_box(m_plane_center, m_rotation_m); Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Flip cut plane"), UndoRedo::SnapshotType::GizmoAction); m_start_dragging_m = m_rotation_m; @@ -1724,8 +1726,11 @@ void GLGizmoCut3D::render_cut_plane_input_window(CutConnectors &connectors) const bool is_cut_plane_init = m_rotation_m.isApprox(Transform3d::Identity()) && m_bb_center == m_plane_center; m_imgui->disabled_begin(is_cut_plane_init); - if (render_reset_button("cut_plane", _u8L("Reset cutting plane"))) + wxString act_name = _L("Reset cutting plane"); + if (render_reset_button("cut_plane", into_u8(act_name))) { + Plater::TakeSnapshot snapshot(wxGetApp().plater(), act_name, UndoRedo::SnapshotType::GizmoAction); reset_cut_plane(); + } m_imgui->disabled_end(); // render_flip_plane_button(); @@ -1740,7 +1745,9 @@ void GLGizmoCut3D::render_cut_plane_input_window(CutConnectors &connectors) ImGui::SameLine(2.5f * m_label_width); m_imgui->disabled_begin(is_cut_plane_init && !has_connectors); - if (m_imgui->button(_L("Reset cut"), _L("Reset cutting plane and remove connectors"))) { + act_name = _L("Reset cut"); + if (m_imgui->button(act_name, _L("Reset cutting plane and remove connectors"))) { + Plater::TakeSnapshot snapshot(wxGetApp().plater(), act_name, UndoRedo::SnapshotType::GizmoAction); reset_cut_plane(); reset_connectors(); } @@ -2299,20 +2306,26 @@ bool GLGizmoCut3D::process_cut_line(SLAGizmoEventType action, const Vec2d& mouse Vec3d line_dir = m_line_end - m_line_beg; if (line_dir.norm() < 3.0) return true; - Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Cut by line"), UndoRedo::SnapshotType::GizmoAction); Vec3d cross_dir = line_dir.cross(dir).normalized(); Eigen::Quaterniond q; Transform3d m = Transform3d::Identity(); m.matrix().block(0, 0, 3, 3) = q.setFromTwoVectors(Vec3d::UnitZ(), cross_dir).toRotationMatrix(); - m_rotation_m = m; + const Vec3d new_plane_center = m_bb_center + cross_dir * cross_dir.dot(pt - m_bb_center); // update transformed bb - m_transformed_bounding_box = transformed_bounding_box(m_plane_center); + const auto new_tbb = transformed_bounding_box(new_plane_center, m); + const Vec3d& instance_offset = m_parent.get_selection().get_first_volume()->get_instance_offset(); + const Vec3d trans_center_pos = m.inverse() * (new_plane_center - instance_offset) + new_tbb.center(); + if (new_tbb.contains(trans_center_pos)) { + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Cut by line"), UndoRedo::SnapshotType::GizmoAction); + m_transformed_bounding_box = new_tbb; + set_center(new_plane_center); + m_start_dragging_m = m_rotation_m = m; + m_ar_plane_center = m_plane_center; + } + m_angle_arc.reset(); - - set_center(m_plane_center + cross_dir * (cross_dir.dot(pt - m_plane_center)), true); - discard_cut_line_processing(); } else if (action == SLAGizmoEventType::Moving) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index 1f07f561f8..ddacebae85 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -35,6 +35,7 @@ class GLGizmoCut3D : public GLGizmoBase // archived values Vec3d m_ar_plane_center { Vec3d::Zero() }; + Transform3d m_start_dragging_m{ Transform3d::Identity() }; Vec3d m_plane_center{ Vec3d::Zero() }; // data to check position of the cut palne center on gizmo activation @@ -57,7 +58,6 @@ class GLGizmoCut3D : public GLGizmoBase double m_snap_fine_out_radius{ 0.0 }; // dragging angel in hovered axes - Transform3d m_start_dragging_m{ Transform3d::Identity() }; double m_angle{ 0.0 }; TriangleMesh m_connector_mesh; @@ -194,7 +194,7 @@ public: void invalidate_cut_plane(); BoundingBoxf3 bounding_box() const; - BoundingBoxf3 transformed_bounding_box(const Vec3d& plane_center) const; + BoundingBoxf3 transformed_bounding_box(const Vec3d& plane_center, const Transform3d& rotation_m = Transform3d::Identity()) const; protected: bool on_init() override;