From d9e47bd9a9d534bcc25b44247fc74b8ccdd02eb3 Mon Sep 17 00:00:00 2001 From: "zhou.xu" Date: Mon, 18 Mar 2024 11:20:59 +0800 Subject: [PATCH] NEW:add move and rotate gizmo in assemble view Jira: STUDIO-6545 Change-Id: I30ab8155f5288953b36cd9a301ce3596d6edc0c6 --- src/libslic3r/Model.hpp | 3 +- src/slic3r/GUI/3DScene.cpp | 16 +++++---- src/slic3r/GUI/3DScene.hpp | 12 ++++--- src/slic3r/GUI/GLCanvas3D.cpp | 33 +++++++++++++++---- src/slic3r/GUI/GLCanvas3D.hpp | 8 ++--- src/slic3r/GUI/GUI_Preview.cpp | 6 ++-- src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp | 9 ++--- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 22 ++++++++++--- .../GUI/Gizmos/GizmoObjectManipulation.cpp | 16 +++++---- src/slic3r/GUI/Plater.cpp | 12 ++++--- src/slic3r/GUI/Selection.cpp | 17 +++++++--- 11 files changed, 105 insertions(+), 49 deletions(-) diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 62696f8c7..e942faa1c 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -1276,13 +1276,14 @@ public: m_assemble_transformation.set_from_transform(transform); } void set_assemble_offset(const Vec3d& offset) { m_assemble_transformation.set_offset(offset); } + void set_assemble_rotation(const Vec3d &rotation) { m_assemble_transformation.set_rotation(rotation); } void rotate_assemble(double angle, const Vec3d& axis) { m_assemble_transformation.set_rotation(m_assemble_transformation.get_rotation() + Geometry::extract_euler_angles(Eigen::Quaterniond(Eigen::AngleAxisd(angle, axis)).toRotationMatrix())); } // BBS void set_offset_to_assembly(const Vec3d& offset) { m_offset_to_assembly = offset; } - Vec3d get_offset_to_assembly() const { return m_offset_to_assembly; } + const Vec3d& get_offset_to_assembly() const { return m_offset_to_assembly; } const Vec3d& get_offset() const { return m_transformation.get_offset(); } double get_offset(Axis axis) const { return m_transformation.get_offset(axis); } diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index bf36690dd..97486424d 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -678,7 +678,7 @@ void GLVolume::set_range(double min_z, double max_z) //BBS: add outline related logic //static unsigned char stencil_data[1284][2944]; -void GLVolume::render(bool with_outline) const +void GLVolume::render(bool with_outline, const std::array& body_color) const { if (!is_active) return; @@ -880,7 +880,6 @@ void GLVolume::render(bool with_outline) const glStencilFunc(GL_NOTEQUAL, 0xff, 0xFF); glStencilMask(0x00); float scale = 1.02f; - std::array body_color = { 1.0f, 1.0f, 1.0f, 1.0f }; //red shader->set_uniform("uniform_color", body_color); shader->set_uniform("is_outline", true); @@ -1336,8 +1335,13 @@ int GLVolumeCollection::get_selection_support_threshold_angle(bool &enable_suppo } //BBS: add outline drawing logic -void GLVolumeCollection::render( - GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d &view_matrix, std::function filter_func, bool with_outline) const +void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, + bool disable_cullface, + const Transform3d & view_matrix, + std::function filter_func, + bool with_outline, + const std::array & body_color, + bool partly_inside_enable) const { GLVolumeWithIdAndZList to_render = volumes_to_render(volumes, type, view_matrix, filter_func); if (to_render.empty()) @@ -1396,7 +1400,7 @@ void GLVolumeCollection::render( //shader->set_uniform("print_volume.xy_data", m_render_volume.data); //shader->set_uniform("print_volume.z_data", m_render_volume.zs); - if (volume.first->partly_inside) { + if (volume.first->partly_inside && partly_inside_enable) { //only partly inside volume need to be painted with boundary check shader->set_uniform("print_volume.type", static_cast(m_print_volume.type)); shader->set_uniform("print_volume.xy_data", m_print_volume.data); @@ -1427,7 +1431,7 @@ void GLVolumeCollection::render( glcheck(); //BBS: add outline related logic - volume.first->render(with_outline && volume.first->selected); + volume.first->render(with_outline && volume.first->selected, body_color); #if ENABLE_ENVIRONMENT_MAP if (use_environment_texture) diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index e1f5c3165..a4bce5232 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -497,7 +497,7 @@ public: void set_convex_hull(TriangleMesh &&convex_hull) { m_convex_hull = std::make_shared(std::move(convex_hull)); } void set_offset_to_assembly(const Vec3d& offset) { m_offset_to_assembly = offset; set_bounding_boxes_as_dirty(); } - Vec3d get_offset_to_assembly() { return m_offset_to_assembly; } + const Vec3d& get_offset_to_assembly() { return m_offset_to_assembly; } int object_idx() const { return this->composite_id.object_id; } int volume_idx() const { return this->composite_id.volume_id; } @@ -523,7 +523,8 @@ public: void set_range(double low, double high); //BBS: add outline related logic and add virtual specifier - virtual void render(bool with_outline = false) const; + virtual void render(bool with_outline = false, + const std::array &body_color = {1.0f, 1.0f, 1.0f, 1.0f} ) const; //BBS: add simple render function for thumbnail void simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_objects, std::vector>& extruder_colors) const; @@ -667,8 +668,11 @@ public: void render(ERenderType type, bool disable_cullface, const Transform3d & view_matrix, - std::function filter_func = std::function(), - bool with_outline = true) const; + std::function filter_func = std::function(), + bool with_outline = true, + const std::array& body_color = {1.0f, 1.0f, 1.0f, 1.0f}, + bool partly_inside_enable =true + ) const; // Finalize the initialization of the geometry & indices, // upload the geometry and indices to OpenGL VBO objects diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e946c8f6f..36007d250 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -14,7 +14,7 @@ #include "libslic3r/Technologies.hpp" #include "libslic3r/Tesselate.hpp" #include "libslic3r/PresetBundle.hpp" -#include "slic3r/GUI/3DBed.hpp" + #include "slic3r/GUI/3DScene.hpp" #include "slic3r/GUI/BackgroundSlicingProcess.hpp" #include "slic3r/GUI/GLShader.hpp" @@ -1946,6 +1946,9 @@ void GLCanvas3D::render(bool only_init) /* assemble render*/ else if (m_canvas_type == ECanvasType::CanvasAssembleView) { //BBS: add outline logic + if (m_show_world_axes) { + m_axes.render(); + } _render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running()); //_render_bed(!camera.is_looking_downward(), show_axes); _render_plane(); @@ -4569,8 +4572,13 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) // Move instances/volumes ModelObject* model_object = m_model->objects[object_idx]; if (model_object != nullptr) { - if (selection_mode == Selection::Instance) - model_object->instances[instance_idx]->set_offset(v->get_instance_offset()); + if (selection_mode == Selection::Instance) { + if (m_canvas_type == GLCanvas3D::ECanvasType::CanvasAssembleView) { + model_object->instances[instance_idx]->set_assemble_offset(v->get_instance_offset()); + } else { + model_object->instances[instance_idx]->set_offset(v->get_instance_offset()); + } + } else if (selection_mode == Selection::Volume) { if (model_object->volumes[volume_idx]->get_offset() != v->get_volume_offset()) { model_object->volumes[volume_idx]->set_offset(v->get_volume_offset()); @@ -4677,8 +4685,13 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type) ModelObject* model_object = m_model->objects[object_idx]; if (model_object != nullptr) { if (selection_mode == Selection::Instance) { - model_object->instances[instance_idx]->set_rotation(v->get_instance_rotation()); - model_object->instances[instance_idx]->set_offset(v->get_instance_offset()); + if (m_canvas_type == GLCanvas3D::ECanvasType::CanvasAssembleView) { + model_object->instances[instance_idx]->set_assemble_rotation(v->get_instance_rotation()); + model_object->instances[instance_idx]->set_assemble_offset(v->get_instance_offset()); + } else { + model_object->instances[instance_idx]->set_rotation(v->get_instance_rotation()); + model_object->instances[instance_idx]->set_offset(v->get_instance_offset()); + } } else if (selection_mode == Selection::Volume) { if (model_object->volumes[volume_idx]->get_rotation() != v->get_volume_rotation()) { @@ -6974,6 +6987,9 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with GLShaderProgram* shader = wxGetApp().get_shader("gouraud"); ECanvasType canvas_type = this->m_canvas_type; + std::array body_color = canvas_type == ECanvasType::CanvasAssembleView ? std::array({1.0f, 1.0f, 0.0f, 1.0f}) ://yellow + std::array({1.0f, 1.0f, 1.0f, 1.0f});//white + bool partly_inside_enable = canvas_type == ECanvasType::CanvasAssembleView ? false : true; if (shader != nullptr) { shader->start_using(); @@ -7009,7 +7025,8 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with else { return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0); } - }, with_outline); + }, + with_outline, body_color, partly_inside_enable); } } else { @@ -7042,7 +7059,8 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with else { return true; } - }, with_outline); + }, + with_outline, body_color, partly_inside_enable); if (m_canvas_type == CanvasAssembleView && m_gizmos.m_assemble_view_data->model_objects_clipper()->get_position() > 0) { const GLGizmosManager& gm = get_gizmos_manager(); shader->stop_using(); @@ -7908,6 +7926,7 @@ void GLCanvas3D::_render_return_toolbar() wxPostEvent(m_canvas, SimpleEvent(EVT_GLVIEWTOOLBAR_3D)); const_cast(&m_gizmos)->reset_all_states(); wxGetApp().plater()->get_view3D_canvas3D()->get_gizmos_manager().reset_all_states(); + wxGetApp().plater()->get_view3D_canvas3D()->reload_scene(true); { GLCanvas3D * view_3d = wxGetApp().plater()->get_view3D_canvas3D(); GLToolbarItem * assembly_item = view_3d->m_assemble_view_toolbar.get_item("assembly_view"); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index d85cec801..94ca1a34f 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -17,7 +17,7 @@ #include "GCodeViewer.hpp" #include "Camera.hpp" #include "IMToolbar.hpp" - +#include "slic3r/GUI/3DBed.hpp" #include "libslic3r/Slicing.hpp" #include @@ -53,7 +53,6 @@ namespace CustomGCode { struct Item; } namespace GUI { -class Bed3D; class PartPlateList; #if ENABLE_RETINA_GL @@ -609,8 +608,8 @@ private: PrinterTechnology current_printer_technology() const; - - + bool m_show_world_axes{false}; + Bed3D::Axes m_axes; //BBS:record key botton frequency int auto_orient_count = 0; int auto_arrange_count = 0; @@ -773,6 +772,7 @@ public: void set_color_by(const std::string& value); + void set_show_world_axes(bool flag) { m_show_world_axes = flag; } void refresh_camera_scene_box(); BoundingBoxf3 volumes_bounding_box() const; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index c17dcea7c..534e14fb2 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -811,10 +811,10 @@ bool AssembleView::init(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrint m_canvas->enable_assemble_view_toolbar(false); m_canvas->enable_return_toolbar(true); m_canvas->enable_separator_toolbar(false); - + m_canvas->set_show_world_axes(true); // BBS: set volume_selection_mode to Volume - m_canvas->get_selection().set_volume_selection_mode(Selection::Volume); - m_canvas->get_selection().lock_volume_selection_mode(); + //same to 3d //m_canvas->get_selection().set_volume_selection_mode(Selection::Instance); + //m_canvas->get_selection().lock_volume_selection_mode(); wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); main_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index aa93d4981..22b13ef05 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -3,7 +3,7 @@ #include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/Plater.hpp" #include "slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp" - +#include "slic3r/Utils/UndoRedo.hpp" #include "libslic3r/PresetBundle.hpp" #include "libslic3r/MeasureUtils.hpp" @@ -1322,7 +1322,8 @@ void GLGizmoMeasure::render_dimensioning() m_imgui->text(txt); if (m_hit_different_volumes.size() < 2) { ImGui::SameLine(); - if (m_imgui->image_button(ImGui::SliderFloatEditBtnIcon, _L("Edit to scale"))) { + if (m_imgui->image_button(ImGui::SliderFloatEditBtnIcon, _L("Edit to scale")) && + wxGetApp().plater()->canvas3D()->get_canvas_type() == GLCanvas3D::ECanvasType::CanvasView3D) { m_editing_distance = true; edit_value = curr_value; m_imgui->requires_extra_frame(); @@ -1345,7 +1346,7 @@ void GLGizmoMeasure::render_dimensioning() return; const double ratio = new_value / old_value; - wxGetApp().plater()->take_snapshot(_u8L("Scale")); + wxGetApp().plater()->take_snapshot(_u8L("Scale"), UndoRedo::SnapshotType::GizmoAction); // apply scale TransformationType type; type.set_world(); @@ -2024,7 +2025,7 @@ void GLGizmoMeasure::on_render_input_window(float x, float y, float bottom_limit distance[2] = m_buffered_distance[2]; } if (displacement.norm() > 0.0f) { - wxGetApp().plater()->take_snapshot(_u8L("MoveInMeasure"));// avoid storing another snapshot + wxGetApp().plater()->take_snapshot(_u8L("MoveInMeasure"), UndoRedo::SnapshotType::GizmoAction); // avoid storing another snapshot selection->set_mode(same_model_object ? Selection::Volume : Selection::Instance); auto llo = selection->get_mode(); if (same_model_object == false) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 8e300c4ab..d5889665c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -59,7 +59,9 @@ std::vector GLGizmosManager::get_selectable_idxs() const std::vector out; if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) { for (size_t i = 0; i < m_gizmos.size(); ++i) - if (m_gizmos[i]->get_sprite_id() == (unsigned int)MmuSegmentation) + if (m_gizmos[i]->get_sprite_id() == (unsigned int) Move || + m_gizmos[i]->get_sprite_id() == (unsigned int) Rotate || + m_gizmos[i]->get_sprite_id() == (unsigned int) MmuSegmentation) out.push_back(i); } else { @@ -877,9 +879,21 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) } else if (is_dragging()) { switch (m_current) { - case Move: { m_parent.do_move(("Tool-Move")); break; } - case Scale: { m_parent.do_scale(("Tool-Scale")); break; } - case Rotate: { m_parent.do_rotate(("Tool-Rotate")); break; } + case Move: { + wxGetApp().plater()->take_snapshot(_u8L("Tool-Move"), UndoRedo::SnapshotType::GizmoAction); + m_parent.do_move(""); + break; + } + case Scale: { + wxGetApp().plater()->take_snapshot(_u8L("Tool-Scale"), UndoRedo::SnapshotType::GizmoAction); + m_parent.do_scale(""); + break; + } + case Rotate: { + wxGetApp().plater()->take_snapshot(_u8L("Tool-Rotate"), UndoRedo::SnapshotType::GizmoAction); + m_parent.do_rotate(""); + break; + } default: break; } diff --git a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp index 7d58d5d73..577e93399 100644 --- a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp +++ b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp @@ -6,8 +6,8 @@ //#include "I18N.hpp" #include "GLGizmosManager.hpp" #include "slic3r/GUI/GLCanvas3D.hpp" - #include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/Utils/UndoRedo.hpp" #include "libslic3r/AppConfig.hpp" #include "libslic3r/Model.hpp" @@ -275,7 +275,8 @@ void GizmoObjectManipulation::change_position_value(int axis, double value) Selection& selection = m_glcanvas.get_selection(); selection.start_dragging(); selection.translate(position - m_cache.position, selection.requires_local_axes()); - m_glcanvas.do_move(L("Set Position")); + wxGetApp().plater()->take_snapshot(_u8L("Set Position"), UndoRedo::SnapshotType::GizmoAction); + m_glcanvas.do_move(""); m_cache.position = position; m_cache.position_rounded(axis) = DBL_MAX; @@ -303,9 +304,10 @@ void GizmoObjectManipulation::change_rotation_value(int axis, double value) selection.start_dragging(); selection.rotate( - (M_PI / 180.0) * (transformation_type.absolute() ? rotation : rotation - m_cache.rotation), + (M_PI / 180.0) * (transformation_type.absolute() ? rotation : rotation - m_cache.rotation), transformation_type); - m_glcanvas.do_rotate(L("Set Orientation")); + wxGetApp().plater()->take_snapshot(_u8L("Set Orientation"), UndoRedo::SnapshotType::GizmoAction); + m_glcanvas.do_rotate(""); m_cache.rotation = rotation; m_cache.rotation_rounded(axis) = DBL_MAX; @@ -422,7 +424,8 @@ void GizmoObjectManipulation::reset_position_value() return; // Copy position values from GLVolumes into Model (ModelInstance / ModelVolume), trigger background processing. - m_glcanvas.do_move(L("Reset Position")); + wxGetApp().plater()->take_snapshot(_u8L("Reset Position"), UndoRedo::SnapshotType::GizmoAction); + m_glcanvas.do_move(""); UpdateAndShow(true); } @@ -448,7 +451,8 @@ void GizmoObjectManipulation::reset_rotation_value() selection.synchronize_unselected_instances(Selection::SYNC_ROTATION_GENERAL); selection.synchronize_unselected_volumes(); // Copy rotation values from GLVolumes into Model (ModelInstance / ModelVolume), trigger background processing. - m_glcanvas.do_rotate(L("Reset Rotation")); + wxGetApp().plater()->take_snapshot(_u8L("Reset Rotation"), UndoRedo::SnapshotType::GizmoAction); + m_glcanvas.do_rotate(""); UpdateAndShow(true); } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 3ae47d5e7..bcd815a7e 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3137,11 +3137,13 @@ void Plater::priv::update(unsigned int flags) // Update the SLAPrint from the current Model, so that the reload_scene() // pulls the correct data. update_status = this->update_background_process(false, flags & (unsigned int)UpdateParams::POSTPONE_VALIDATION_ERROR_MESSAGE); - //BBS TODO reload_scene - this->view3D->reload_scene(false, flags & (unsigned int)UpdateParams::FORCE_FULL_SCREEN_REFRESH); - this->preview->reload_print(); - //BBS assemble view - this->assemble_view->reload_scene(false, flags); + //BBS reload_scene + if (wxGetApp().plater() && wxGetApp().plater()->canvas3D()->get_canvas_type() == GLCanvas3D::ECanvasType::CanvasAssembleView) { // BBS assemble view + this->assemble_view->reload_scene(false, flags); + } else { + this->view3D->reload_scene(false, flags & (unsigned int) UpdateParams::FORCE_FULL_SCREEN_REFRESH); + this->preview->reload_print(); + } if (current_panel && q->is_preview_shown()) { q->force_update_all_plate_thumbnails(); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 454d5390c..6977fa79a 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1071,10 +1071,13 @@ void Selection::translate(const Vec3d &displacement, bool local) else if (translation_type == Volume) synchronize_unselected_volumes(); #endif // !DISABLE_INSTANCES_SYNCH - - ensure_not_below_bed(); + if (wxGetApp().plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasAssembleView) { + ensure_not_below_bed(); + } set_bounding_boxes_dirty(); - wxGetApp().plater()->canvas3D()->requires_check_outside_state(); + if (wxGetApp().plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasAssembleView) { + wxGetApp().plater()->canvas3D()->requires_check_outside_state(); + } } // Rotate an object around one of the axes. Only one rotation component is expected to be changing. @@ -1188,7 +1191,9 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ } set_bounding_boxes_dirty(); - wxGetApp().plater()->canvas3D()->requires_check_outside_state(); + if (wxGetApp().plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasAssembleView) { + wxGetApp().plater()->canvas3D()->requires_check_outside_state(); + } } void Selection::flattening_rotate(const Vec3d& normal) @@ -1303,7 +1308,9 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type ensure_on_bed(); set_bounding_boxes_dirty(); - wxGetApp().plater()->canvas3D()->requires_check_outside_state(); + if (wxGetApp().plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasAssembleView) { + wxGetApp().plater()->canvas3D()->requires_check_outside_state(); + } } #if ENABLE_ENHANCED_PRINT_VOLUME_FIT