diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 16696e49a3..7088a158d8 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); + } } } @@ -2922,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) { @@ -2958,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]; @@ -2968,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; } } diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index eb7c46861f..555aab0c15 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"); @@ -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; @@ -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); 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; 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(); diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 35292d803b..74f1ba19ee 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,15 +2873,17 @@ 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( _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); @@ -2891,14 +2894,14 @@ 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( _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); 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; 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/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 8c33c3e037..744ae2ff43 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -360,11 +360,14 @@ 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); + 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) @@ -401,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); @@ -415,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); @@ -435,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); @@ -453,15 +451,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 +576,9 @@ void GLGizmoCut3D::render_move_center_input(int axis) if (in_val != val) { move[axis] = val; - set_center(move); + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Move cut plane"), UndoRedo::SnapshotType::GizmoAction); + set_center(move, true); + m_ar_plane_center = m_plane_center; } } @@ -888,21 +882,18 @@ 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_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(); } 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); } @@ -919,6 +910,7 @@ 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; @@ -934,7 +926,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 +1137,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; } @@ -1185,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_rotation_m); m_angle = theta; while (m_angle > two_pi) @@ -1247,16 +1239,17 @@ 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()); + } - bool can_set_center_pos = force; - BoundingBoxf3 tbb; - if (!can_set_center_pos) { - tbb = transformed_bounding_box(center_pos); - if (tbb.max.z() > -1. && tbb.min.z() < 1.) + bool can_set_center_pos = false; + { + 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(); @@ -1288,57 +1281,33 @@ 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 { - // #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() * 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(); @@ -1580,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()); @@ -1653,10 +1618,11 @@ 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); + m_start_dragging_m = m_rotation_m = Transform3d::Identity(); + m_ar_plane_center = m_plane_center; } void GLGizmoCut3D::invalidate_cut_plane() @@ -1671,6 +1637,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(); @@ -1682,6 +1651,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, m_rotation_m); + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Flip cut plane"), UndoRedo::SnapshotType::GizmoAction); m_start_dragging_m = m_rotation_m; @@ -1755,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(); @@ -1771,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(); } @@ -2330,18 +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 + 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))); - discard_cut_line_processing(); } else if (action == SLAGizmoEventType::Moving) @@ -2542,6 +2526,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..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; @@ -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 }; @@ -188,15 +187,14 @@ 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(); - void update_clipper_on_render(); 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; @@ -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(); 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/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; }; 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); 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); 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")