diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index e34e4e5dda..d0c9962900 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -3610,7 +3610,7 @@ void GCodeProcessor::post_process() last_time_insertion = rev_it->time; const std::string out_line = line_inserter(i + 1, last_time_insertion, m_time - last_time_insertion); rev_it_dist = std::distance(m_lines.rbegin(), rev_it) + 1; - const auto new_it = m_lines.insert(rev_it.base(), { out_line, rev_it->time }); + m_lines.insert(rev_it.base(), { out_line, rev_it->time }); #ifndef NDEBUG m_statistics.add_line(out_line.length()); #endif // NDEBUG @@ -3984,7 +3984,7 @@ void GCodeProcessor::post_process() #if ENABLE_GCODE_POSTPROCESS_BACKTRACE // add lines XXX to exported gcode - auto process_line_T = [this, &export_lines](const std::string& gcode_line, const size_t g1_lines_counter, const ExportLines::Backtrace& backtrace) { + auto process_line_T = [this, &export_lines](const std::string& gcode_line, const size_t g1_lines_counter, const ExportLines::Backtrace& backtrace) { const std::string cmd = GCodeReader::GCodeLine::extract_cmd(gcode_line); if (cmd.size() >= 2) { std::stringstream ss(cmd.substr(1)); diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 97975404ff..b4e3936daf 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -593,7 +593,7 @@ void GLVolumeCollection::load_object_auxiliary( return; const Transform3d mesh_trafo_inv = print_object->trafo().inverse(); - auto add_volume = [this, &instances, timestamp](int obj_idx, int inst_idx, const ModelInstance& model_instance, SLAPrintObjectStep step, + auto add_volume = [this, timestamp](int obj_idx, int inst_idx, const ModelInstance& model_instance, SLAPrintObjectStep step, const TriangleMesh& mesh, const ColorRGBA& color, std::optional convex_hull = std::nullopt) { if (mesh.empty()) return; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index d04fc7f985..72aaa59448 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3189,6 +3189,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_canvas->SetFocus(); if (evt.Entering()) { + if (m_mouse.dragging && !evt.LeftIsDown() && !evt.RightIsDown() && !evt.MiddleIsDown()) + // reset dragging state if the user released the mouse button outside the 3D scene + m_mouse.dragging = false; + //#if defined(__WXMSW__) || defined(__linux__) // // On Windows and Linux needs focus in order to catch key events // Set focus in order to remove it from object list diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp index 398aebb52f..98058ee17b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp @@ -60,11 +60,13 @@ void GLGizmoFlatten::data_changed(bool is_serializing) { const Selection & selection = m_parent.get_selection(); const ModelObject *model_object = nullptr; + int instance_id = -1; if (selection.is_single_full_instance() || selection.is_from_single_object() ) { model_object = selection.get_model()->objects[selection.get_object_idx()]; + instance_id = selection.get_instance_idx(); } - set_flattening_data(model_object); + set_flattening_data(model_object, instance_id); } bool GLGizmoFlatten::on_init() @@ -156,9 +158,9 @@ void GLGizmoFlatten::on_unregister_raycasters_for_picking() m_planes_casters.clear(); } -void GLGizmoFlatten::set_flattening_data(const ModelObject* model_object) +void GLGizmoFlatten::set_flattening_data(const ModelObject* model_object, int instance_id) { - if (model_object != m_old_model_object) { + if (model_object != m_old_model_object || instance_id != m_old_instance_id) { m_planes.clear(); on_unregister_raycasters_for_picking(); } @@ -363,6 +365,7 @@ void GLGizmoFlatten::update_planes() m_first_instance_scale = mo->instances.front()->get_scaling_factor(); m_first_instance_mirror = mo->instances.front()->get_mirror(); m_old_model_object = mo; + m_old_instance_id = m_c->selection_info()->get_active_instance(); // And finally create respective VBOs. The polygon is convex with // the vertices in order, so triangulation is trivial. diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp index 1701b76a5c..ff44fcd2d0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.hpp @@ -39,6 +39,7 @@ private: std::vector> m_planes_casters; bool m_mouse_left_down = false; // for detection left_up of this gizmo const ModelObject* m_old_model_object = nullptr; + int m_old_instance_id{ -1 }; void update_planes(); bool is_plane_update_necessary() const; @@ -46,7 +47,7 @@ private: public: GLGizmoFlatten(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); - void set_flattening_data(const ModelObject* model_object); + void set_flattening_data(const ModelObject* model_object, int instance_id); /// /// Apply rotation on select plane diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp index 785c660766..e0d2cdb68d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp @@ -294,7 +294,7 @@ protected: private: int m_print_object_idx = -1; - int m_print_objects_count = 0; +// int m_print_objects_count = 0; std::unique_ptr m_supports_clipper; std::unique_ptr m_pad_clipper; }; diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 4cce6e2632..0754c35cc9 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -460,7 +460,7 @@ bool ImGuiWrapper::button(const wxString &label, const wxString& tooltip) if (!tooltip.IsEmpty() && ImGui::IsItemHovered()) { auto tooltip_utf8 = into_u8(tooltip); - ImGui::SetTooltip(tooltip_utf8.c_str()); + ImGui::SetTooltip(tooltip_utf8.c_str(), nullptr); } return ret; diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 8115136a57..2828fc8003 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -231,8 +231,10 @@ coord_t get_skirt_offset(const Plater* plater) { // Try to subtract the skirt from the bed shape so we don't arrange outside of it. if (plater->printer_technology() == ptFFF && plater->fff_print().has_skirt()) { const auto& print = plater->fff_print(); - skirt_inset = print.config().skirts.value * print.skirt_flow().width() + - print.config().skirt_distance.value; + if (!print.objects().empty()) { + skirt_inset = print.config().skirts.value * print.skirt_flow().width() + + print.config().skirt_distance.value; + } } return scaled(skirt_inset); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 5808b196d0..6adabb7d68 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -6057,7 +6057,7 @@ void Plater::remove_selected() p->view3D->delete_selected(); } -void Plater::increase_instances(size_t num, int obj_idx/* = -1*/) +void Plater::increase_instances(size_t num, int obj_idx, std::optional selection_map) { if (! can_increase_instances()) { return; } @@ -6067,14 +6067,26 @@ void Plater::increase_instances(size_t num, int obj_idx/* = -1*/) obj_idx = p->get_selected_object_idx(); if (obj_idx < 0) { - if (const auto obj_idxs = get_selection().get_object_idxs(); !obj_idxs.empty()) - for (const size_t obj_id : obj_idxs) - increase_instances(1, int(obj_id)); + if (const auto obj_idxs = get_selection().get_object_idxs(); !obj_idxs.empty()) { + // we need a copy made here because the selection changes at every call of increase_instances() + const Selection::ObjectIdxsToInstanceIdxsMap content = selection_map.has_value() ? *selection_map : p->get_selection().get_content(); + for (const size_t obj_id : obj_idxs) { + increase_instances(1, int(obj_id), content); + } + } return; } ModelObject* model_object = p->model.objects[obj_idx]; - const int inst_idx = p->get_selected_instance_idx(); + int inst_idx = -1; + if (selection_map.has_value()) { + auto obj_it = selection_map->find(obj_idx); + if (obj_it != selection_map->end() && obj_it->second.size() == 1) + inst_idx = *obj_it->second.begin(); + } + else + inst_idx = p->get_selected_instance_idx(); + ModelInstance* model_instance = (inst_idx >= 0) ? model_object->instances[inst_idx] : model_object->instances.back(); bool was_one_instance = model_object->instances.size()==1; diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index fa2ec65080..a76ef6f1cb 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -250,7 +250,7 @@ public: void reset_with_confirm(); bool delete_object_from_model(size_t obj_idx); void remove_selected(); - void increase_instances(size_t num = 1, int obj_idx = -1); + void increase_instances(size_t num = 1, int obj_idx = -1, std::optional selection_map = std::nullopt); void decrease_instances(size_t num = 1, int obj_idx = -1); void set_number_of_copies(); void fill_bed_with_instances(); diff --git a/src/slic3r/GUI/SceneRaycaster.cpp b/src/slic3r/GUI/SceneRaycaster.cpp index 1f44a07d6d..64493d86b4 100644 --- a/src/slic3r/GUI/SceneRaycaster.cpp +++ b/src/slic3r/GUI/SceneRaycaster.cpp @@ -117,7 +117,7 @@ SceneRaycaster::HitResult SceneRaycaster::hit(const Vec2d& mouse_pos, const Came return false; if (hit.type == SceneRaycaster::EType::Volume) - m_selected_volume_already_found = *m_selected_volume_id == decode_id(hit.type, hit.raycaster_id); + m_selected_volume_already_found = *m_selected_volume_id == (unsigned int)decode_id(hit.type, hit.raycaster_id); m_closest_hit_pos = hit.position; return true;