mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 12:11:15 -06:00 
			
		
		
		
	NEW:add paint tool in assembly view
Change-Id: I108e1e24ca9d033d2279c8153585166971a347a6
This commit is contained in:
		
							parent
							
								
									5236f17792
								
							
						
					
					
						commit
						ab0c6611c8
					
				
					 13 changed files with 265 additions and 108 deletions
				
			
		|  | @ -1288,6 +1288,15 @@ void GLCanvas3D::on_change_color_mode(bool is_dark, bool reinit) { | |||
|             m_gizmos.set_icon_dirty(); | ||||
|         } | ||||
|     } | ||||
|     if (m_canvas_type == CanvasAssembleView) { | ||||
|         m_gizmos.on_change_color_mode(is_dark); | ||||
|         if (reinit) { | ||||
|             // reset svg
 | ||||
|             m_gizmos.switch_gizmos_icon_filename(); | ||||
|             // set dirty to re-generate icon texture
 | ||||
|             m_gizmos.set_icon_dirty(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::set_as_dirty() | ||||
|  | @ -2369,9 +2378,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re | |||
|                     deleted_wipe_towers.emplace_back(volume, volume_id); | ||||
|                 delete volume; | ||||
|             } | ||||
| 
 | ||||
|             // BBS
 | ||||
|             m_explosion_ratio = 1.0; | ||||
|         } | ||||
|         else { | ||||
|             // This GLVolume will be reused.
 | ||||
|  | @ -3045,7 +3051,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) | |||
| #else /* __APPLE__ */ | ||||
|         case WXK_CONTROL_Y: | ||||
| #endif /* __APPLE__ */ | ||||
|             if (m_canvas_type == CanvasView3D) { | ||||
|             if (m_canvas_type == CanvasView3D || m_canvas_type == CanvasAssembleView) { | ||||
|                 post_event(SimpleEvent(EVT_GLCANVAS_REDO)); | ||||
|             } | ||||
|         break; | ||||
|  | @ -3056,7 +3062,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) | |||
|         case WXK_CONTROL_Z: | ||||
| #endif /* __APPLE__ */ | ||||
|             // only support redu/undo in CanvasView3D
 | ||||
|             if (m_canvas_type == CanvasView3D) { | ||||
|             if (m_canvas_type == CanvasView3D || m_canvas_type == CanvasAssembleView) { | ||||
|                 post_event(SimpleEvent(EVT_GLCANVAS_UNDO)); | ||||
|             } | ||||
|         break; | ||||
|  | @ -6229,7 +6235,7 @@ bool GLCanvas3D::_init_assemble_view_toolbar() | |||
|     item.tooltip = _utf8(L("Assembly View")); | ||||
|     item.sprite_id = 1; | ||||
|     item.left.toggable = false; | ||||
|     item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLVIEWTOOLBAR_ASSEMBLE)); }; | ||||
|     item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLVIEWTOOLBAR_ASSEMBLE)); m_gizmos.reset_all_states(); wxGetApp().plater()->get_assmeble_canvas3D()->get_gizmos_manager().reset_all_states(); }; | ||||
|     item.left.render_callback = GLToolbarItem::Default_Render_Callback; | ||||
|     item.visible = true; | ||||
|     item.visibility_callback = [this]()->bool { return true; }; | ||||
|  | @ -6742,7 +6748,10 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with | |||
|     else { | ||||
|         m_volumes.set_clipping_plane(m_camera_clipping_plane.get_data()); | ||||
|     } | ||||
|     m_volumes.set_show_sinking_contours(! m_gizmos.is_hiding_instances()); | ||||
|     if (m_canvas_type == CanvasAssembleView) | ||||
|         m_volumes.set_show_sinking_contours(false); | ||||
|     else | ||||
|         m_volumes.set_show_sinking_contours(!m_gizmos.is_hiding_instances()); | ||||
| 
 | ||||
|     GLShaderProgram* shader = wxGetApp().get_shader("gouraud"); | ||||
|     ECanvasType canvas_type = this->m_canvas_type; | ||||
|  | @ -7233,9 +7242,6 @@ void GLCanvas3D::_render_gizmos_overlay() | |||
|     const float size = int(GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale()); | ||||
|     m_gizmos.set_overlay_icon_size(size); //! #ys_FIXME_experiment
 | ||||
| #endif /* __WXMSW__ */ | ||||
|     if (m_canvas_type == CanvasAssembleView) | ||||
|         return; | ||||
| 
 | ||||
|     m_gizmos.render_overlay(); | ||||
| 
 | ||||
|     if (m_gizmo_highlighter.m_render_arrow) | ||||
|  | @ -7648,6 +7654,8 @@ void GLCanvas3D::_render_return_toolbar() const | |||
|     if (ImGui::ImageTextButton(real_size,_utf8(L("return")).c_str(), m_return_toolbar.get_return_texture_id(), button_icon_size, uv0, uv1, -1, bg_col, tint_col, margin)) { | ||||
|         if (m_canvas != nullptr) | ||||
|             wxPostEvent(m_canvas, SimpleEvent(EVT_GLVIEWTOOLBAR_3D)); | ||||
|         const_cast<GLGizmosManager*>(&m_gizmos)->reset_all_states(); | ||||
|         wxGetApp().plater()->get_view3D_canvas3D()->get_gizmos_manager().reset_all_states(); | ||||
|     } | ||||
|     ImGui::PopStyleColor(5); | ||||
|     ImGui::PopStyleVar(1); | ||||
|  | @ -7849,6 +7857,7 @@ void GLCanvas3D::_render_paint_toolbar() const | |||
|         ImGui::BBLRenderArrow(draw_list, right_arrow_button.GetCenter() - ImVec2(draw_list->_Data->FontSize, draw_list->_Data->FontSize) * 0.5f, arrow_color, ImGuiDir_Right, 2.0f); | ||||
|     } | ||||
| 
 | ||||
|     m_paint_toolbar_width = (ImGui::GetWindowWidth() + 50.0f * em_unit * f_scale); | ||||
|     imgui.end(); | ||||
|     ImGui::PopStyleVar(3); | ||||
|     ImGui::PopStyleColor(); | ||||
|  | @ -7861,6 +7870,10 @@ void GLCanvas3D::_render_assemble_control() const | |||
|         GLVolume::explosion_ratio = m_explosion_ratio = 1.0; | ||||
|         return; | ||||
|     } | ||||
|     if (m_gizmos.get_current_type() == GLGizmosManager::EType::MmuSegmentation) { | ||||
|         m_gizmos.m_assemble_view_data->model_objects_clipper()->set_position(0.0, true); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     ImGuiWrapper* imgui = wxGetApp().imgui(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -520,6 +520,7 @@ private: | |||
|     mutable IMToolbar m_sel_plate_toolbar; | ||||
|     mutable GLToolbar m_assemble_view_toolbar; | ||||
|     mutable IMReturnToolbar m_return_toolbar; | ||||
|     mutable float m_paint_toolbar_width; | ||||
| 
 | ||||
|     //BBS: add canvas type for assemble view usage
 | ||||
|     ECanvasType m_canvas_type; | ||||
|  | @ -713,6 +714,7 @@ public: | |||
|     bool init(); | ||||
|     void post_event(wxEvent &&event); | ||||
| 
 | ||||
|     void reset_explosion_ratio() { m_explosion_ratio = 1.0; } | ||||
|     void on_change_color_mode(bool is_dark, bool reinit = true); | ||||
|     const bool get_dark_mode_status() { return m_is_dark; } | ||||
|     void set_as_dirty(); | ||||
|  | @ -819,6 +821,7 @@ public: | |||
|     float get_main_toolbar_width() { return m_main_toolbar.get_width();} | ||||
|     float get_assemble_view_toolbar_width() { return m_assemble_view_toolbar.get_width(); } | ||||
|     float get_assemble_view_toolbar_height() { return m_assemble_view_toolbar.get_height(); } | ||||
|     float get_assembly_paint_toolbar_width() { return m_paint_toolbar_width; } | ||||
|     float get_separator_toolbar_width() { return m_separator_toolbar.get_width(); } | ||||
|     float get_separator_toolbar_height() { return m_separator_toolbar.get_height(); } | ||||
|     float get_collapse_toolbar_width(); | ||||
|  |  | |||
|  | @ -1194,13 +1194,15 @@ void ObjectList::list_manipulation(const wxPoint& mouse_pos, bool evt_context_me | |||
|             } | ||||
|         } | ||||
|         else if (col_num == colColorPaint) { | ||||
|             ObjectDataViewModelNode* node = (ObjectDataViewModelNode*)item.GetID(); | ||||
|             if (node->HasColorPainting()) { | ||||
|                 GLGizmosManager& gizmos_mgr = wxGetApp().plater()->get_view3D_canvas3D()->get_gizmos_manager(); | ||||
|                 if (gizmos_mgr.get_current_type() != GLGizmosManager::EType::MmuSegmentation) | ||||
|                     gizmos_mgr.open_gizmo(GLGizmosManager::EType::MmuSegmentation); | ||||
|                 else | ||||
|                     gizmos_mgr.reset_all_states(); | ||||
|             if (wxGetApp().plater()->get_current_canvas3D()->get_canvas_type() != GLCanvas3D::CanvasAssembleView) { | ||||
|                 ObjectDataViewModelNode* node = (ObjectDataViewModelNode*)item.GetID(); | ||||
|                 if (node->HasColorPainting()) { | ||||
|                     GLGizmosManager& gizmos_mgr = wxGetApp().plater()->get_view3D_canvas3D()->get_gizmos_manager(); | ||||
|                     if (gizmos_mgr.get_current_type() != GLGizmosManager::EType::MmuSegmentation) | ||||
|                         gizmos_mgr.open_gizmo(GLGizmosManager::EType::MmuSegmentation); | ||||
|                     else | ||||
|                         gizmos_mgr.reset_all_states(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         else if (col_num == colSinking) { | ||||
|  | @ -2775,6 +2777,9 @@ void ObjectList::merge(bool to_multipart_object) | |||
|         new_object->center_around_origin(); | ||||
|         new_object->translate_instances(-new_object->origin_translation); | ||||
|         new_object->origin_translation = Vec3d::Zero(); | ||||
|         //BBS init asssmble transformation
 | ||||
|         Geometry::Transformation t = new_object->instances[0]->get_transformation(); | ||||
|         new_object->instances[0]->set_assemble_transformation(t); | ||||
|         //BBS: notify it before remove
 | ||||
|         notify_instance_updated(m_objects->size() - 1); | ||||
| 
 | ||||
|  | @ -4457,12 +4462,12 @@ void ObjectList::update_selections() | |||
| 
 | ||||
| void ObjectList::update_selections_on_canvas() | ||||
| { | ||||
|     Selection& selection = wxGetApp().plater()->get_view3D_canvas3D()->get_selection(); | ||||
|     Selection& selection = wxGetApp().plater()->get_current_canvas3D()->get_selection(); | ||||
| 
 | ||||
|     const int sel_cnt = GetSelectedItemsCount(); | ||||
|     if (sel_cnt == 0) { | ||||
|         selection.remove_all(); | ||||
|         wxGetApp().plater()->get_view3D_canvas3D()->update_gizmos_on_off_state(); | ||||
|         wxGetApp().plater()->get_current_canvas3D()->update_gizmos_on_off_state(); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|  | @ -4566,7 +4571,7 @@ void ObjectList::update_selections_on_canvas() | |||
|         selection.add_volumes(mode, volume_idxs, single_selection); | ||||
|     } | ||||
| 
 | ||||
|     wxGetApp().plater()->get_view3D_canvas3D()->update_gizmos_on_off_state(); | ||||
|     wxGetApp().plater()->get_current_canvas3D()->update_gizmos_on_off_state(); | ||||
|     wxGetApp().plater()->canvas3D()->render(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -212,7 +212,14 @@ void GLGizmoMmuSegmentation::render_triangles(const Selection &selection) const | |||
| 
 | ||||
|         ++mesh_id; | ||||
| 
 | ||||
|         const Transform3d trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix(); | ||||
|         Transform3d trafo_matrix; | ||||
|         if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) { | ||||
|             trafo_matrix = mo->instances[selection.get_instance_idx()]->get_assemble_transformation().get_matrix() * mv->get_matrix(); | ||||
|             trafo_matrix.translate(mv->get_transformation().get_offset() * (GLVolume::explosion_ratio - 1.0) + mo->instances[selection.get_instance_idx()]->get_offset_to_assembly() * (GLVolume::explosion_ratio - 1.0)); | ||||
|         } | ||||
|         else { | ||||
|             trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix()* mv->get_matrix(); | ||||
|         } | ||||
| 
 | ||||
|         bool is_left_handed = trafo_matrix.matrix().determinant() < 0.; | ||||
|         if (is_left_handed) | ||||
|  |  | |||
|  | @ -85,10 +85,15 @@ void GLGizmoPainterBase::render_triangles(const Selection& selection) const | |||
|             continue; | ||||
| 
 | ||||
|         ++mesh_id; | ||||
| 
 | ||||
|         const Transform3d trafo_matrix = | ||||
|             mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * | ||||
|             mv->get_matrix(); | ||||
|          | ||||
|         Transform3d trafo_matrix; | ||||
|         if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) { | ||||
|             trafo_matrix = mo->instances[selection.get_instance_idx()]->get_assemble_transformation().get_matrix() * mv->get_matrix(); | ||||
|             trafo_matrix.translate(mv->get_transformation().get_offset() * (GLVolume::explosion_ratio - 1.0) + mo->instances[selection.get_instance_idx()]->get_offset_to_assembly() * (GLVolume::explosion_ratio - 1.0)); | ||||
|         } | ||||
|         else { | ||||
|             trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix()* mv->get_matrix(); | ||||
|         } | ||||
| 
 | ||||
|         bool is_left_handed = trafo_matrix.matrix().determinant() < 0.; | ||||
|         if (is_left_handed) | ||||
|  | @ -124,7 +129,16 @@ void GLGizmoPainterBase::render_cursor() const | |||
|     std::vector<Transform3d> trafo_matrices; | ||||
|     for (const ModelVolume* mv : mo->volumes) { | ||||
|         if (mv->is_model_part()) | ||||
|             trafo_matrices.emplace_back(mi->get_transformation().get_matrix() * mv->get_matrix()); | ||||
|         { | ||||
|             if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) { | ||||
|                 Transform3d temp = mi->get_assemble_transformation().get_matrix() * mv->get_matrix(); | ||||
|                 temp.translate(mv->get_transformation().get_offset() * (GLVolume::explosion_ratio - 1.0) + mi->get_offset_to_assembly() * (GLVolume::explosion_ratio - 1.0)); | ||||
|                 trafo_matrices.emplace_back(temp); | ||||
|             } | ||||
|             else { | ||||
|                 trafo_matrices.emplace_back(mi->get_transformation().get_matrix() * mv->get_matrix()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     // Raycast and return if there's no hit.
 | ||||
|     update_raycast_cache(m_parent.get_local_mouse_position(), camera, trafo_matrices); | ||||
|  | @ -230,17 +244,35 @@ void GLGizmoPainterBase::render_cursor_height_range(const Transform3d& trafo) co | |||
|     const BoundingBoxf3 box = bounding_box(); | ||||
|     Vec3d hit_world = trafo * Vec3d(m_rr.hit(0), m_rr.hit(1), m_rr.hit(2)); | ||||
|     float max_z = (float)box.max.z(); | ||||
|     float min_z = (float)box.min.z(); | ||||
| 
 | ||||
|     float cursor_z = std::clamp((float)hit_world.z(), 0.f, max_z); | ||||
|     std::array<float, 2> zs = { cursor_z, std::clamp(cursor_z + m_cursor_height, 0.f, max_z) }; | ||||
|     for (int i = 0; i < zs.size(); i++) { | ||||
|         update_contours(zs[i], max_z); | ||||
|     float cursor_z = std::clamp((float)hit_world.z(), min_z, max_z); | ||||
|     std::array<float, 2> zs = { cursor_z, std::clamp(cursor_z + m_cursor_height, min_z, max_z) }; | ||||
| 
 | ||||
|     const Selection& selection = m_parent.get_selection(); | ||||
|     const ModelObject* model_object = wxGetApp().model().objects[selection.get_object_idx()]; | ||||
|     const ModelInstance* mi = model_object->instances[selection.get_instance_idx()]; | ||||
|     for (const ModelVolume* mv : model_object->volumes) { | ||||
|         TriangleMesh vol_mesh = mv->mesh(); | ||||
|         if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) { | ||||
|             Transform3d temp = mi->get_assemble_transformation().get_matrix() * mv->get_matrix(); | ||||
|             temp.translate(mv->get_transformation().get_offset() * (GLVolume::explosion_ratio - 1.0) + mi->get_offset_to_assembly() * (GLVolume::explosion_ratio - 1.0)); | ||||
|             vol_mesh.transform(temp); | ||||
|         } | ||||
|         else { | ||||
|             vol_mesh.transform(mi->get_transformation().get_matrix() * mv->get_matrix()); | ||||
|         } | ||||
| 
 | ||||
|         for (int i = 0; i < zs.size(); i++) { | ||||
|             update_contours(vol_mesh, zs[i], max_z, min_z); | ||||
| 
 | ||||
|             glsafe(::glPushMatrix()); | ||||
|             glsafe(::glTranslated(m_cut_contours.shift.x(), m_cut_contours.shift.y(), m_cut_contours.shift.z())); | ||||
|             glsafe(::glLineWidth(2.0f)); | ||||
|             m_cut_contours.contours.render(); | ||||
|             glsafe(::glPopMatrix()); | ||||
|         } | ||||
| 
 | ||||
|         glsafe(::glPushMatrix()); | ||||
|         glsafe(::glTranslated(m_cut_contours.shift.x(), m_cut_contours.shift.y(), m_cut_contours.shift.z())); | ||||
|         glsafe(::glLineWidth(2.0f)); | ||||
|         m_cut_contours.contours.render(); | ||||
|         glsafe(::glPopMatrix()); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -257,7 +289,7 @@ BoundingBoxf3 GLGizmoPainterBase::bounding_box() const | |||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| void GLGizmoPainterBase::update_contours(float cursor_z, float max_z) const | ||||
| void GLGizmoPainterBase::update_contours(const TriangleMesh& vol_mesh, float cursor_z, float max_z, float min_z) const | ||||
| { | ||||
|     const Selection& selection = m_parent.get_selection(); | ||||
|     const GLVolume* first_glvolume = selection.get_volume(*selection.get_volume_idxs().begin()); | ||||
|  | @ -266,33 +298,32 @@ void GLGizmoPainterBase::update_contours(float cursor_z, float max_z) const | |||
|     const ModelObject* model_object = wxGetApp().model().objects[selection.get_object_idx()]; | ||||
|     const int instance_idx = selection.get_instance_idx(); | ||||
| 
 | ||||
|     if (0.0 < cursor_z && cursor_z < max_z) { | ||||
|         if (m_cut_contours.cut_z != cursor_z || m_cut_contours.object_id != model_object->id() || m_cut_contours.instance_idx != instance_idx) { | ||||
|             m_cut_contours.cut_z = cursor_z; | ||||
|         if (min_z < cursor_z && cursor_z < max_z) { | ||||
|             if (m_cut_contours.cut_z != cursor_z || m_cut_contours.object_id != model_object->id() || m_cut_contours.instance_idx != instance_idx) { | ||||
|                 m_cut_contours.cut_z = cursor_z; | ||||
| 
 | ||||
|             if (m_cut_contours.object_id != model_object->id()) | ||||
|                 m_cut_contours.mesh = model_object->raw_mesh(); | ||||
|                 m_cut_contours.mesh = vol_mesh; | ||||
| 
 | ||||
|             m_cut_contours.position = box.center(); | ||||
|             m_cut_contours.shift = Vec3d::Zero(); | ||||
|             m_cut_contours.object_id = model_object->id(); | ||||
|             m_cut_contours.instance_idx = instance_idx; | ||||
|             m_cut_contours.contours.reset(); | ||||
|                 m_cut_contours.position = box.center(); | ||||
|                 m_cut_contours.shift = Vec3d::Zero(); | ||||
|                 m_cut_contours.object_id = model_object->id(); | ||||
|                 m_cut_contours.instance_idx = instance_idx; | ||||
|                 m_cut_contours.contours.reset(); | ||||
| 
 | ||||
|             MeshSlicingParams slicing_params; | ||||
|             slicing_params.trafo = first_glvolume->get_instance_transformation().get_matrix(); | ||||
|             const Polygons polys = slice_mesh(m_cut_contours.mesh.its, cursor_z, slicing_params); | ||||
|             if (!polys.empty()) { | ||||
|                 m_cut_contours.contours.init_from(polys, static_cast<float>(cursor_z)); | ||||
|                 m_cut_contours.contours.set_color(-1, { 1.0f, 1.0f, 1.0f, 1.0f }); | ||||
|                 MeshSlicingParams slicing_params; | ||||
|                 slicing_params.trafo = Transform3d::Identity().matrix(); | ||||
|                 const Polygons polys = slice_mesh(m_cut_contours.mesh.its, cursor_z, slicing_params); | ||||
|                 if (!polys.empty()) { | ||||
|                     m_cut_contours.contours.init_from(polys, static_cast<float>(cursor_z)); | ||||
|                     m_cut_contours.contours.set_color(-1, { 1.0f, 1.0f, 1.0f, 1.0f }); | ||||
|                 } | ||||
|             } | ||||
|             else if (box.center() != m_cut_contours.position) { | ||||
|                 m_cut_contours.shift = box.center() - m_cut_contours.position; | ||||
|             } | ||||
|         } | ||||
|         else if (box.center() != m_cut_contours.position) { | ||||
|             m_cut_contours.shift = box.center() - m_cut_contours.position; | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|         m_cut_contours.contours.reset(); | ||||
|         else | ||||
|             m_cut_contours.contours.reset(); | ||||
| } | ||||
| 
 | ||||
| bool GLGizmoPainterBase::is_mesh_point_clipped(const Vec3d& point, const Transform3d& trafo) const | ||||
|  | @ -451,8 +482,12 @@ std::vector<GLGizmoPainterBase::ProjectedHeightRange> GLGizmoPainterBase::get_pr | |||
|     const Selection& selection = m_parent.get_selection(); | ||||
|     const ModelObject* mo = m_c->selection_info()->model_object(); | ||||
|     const ModelInstance* mi = mo->instances[selection.get_instance_idx()]; | ||||
|     const Transform3d   instance_trafo = mi->get_transformation().get_matrix(); | ||||
|     const Transform3d   instance_trafo_not_translate = mi->get_transformation().get_matrix(true); | ||||
|     const Transform3d   instance_trafo = m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView ? | ||||
|         mi->get_assemble_transformation().get_matrix() : | ||||
|         mi->get_transformation().get_matrix(); | ||||
|     const Transform3d   instance_trafo_not_translate = m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView ? | ||||
|         mi->get_assemble_transformation().get_matrix(true) : | ||||
|         mi->get_transformation().get_matrix(true); | ||||
| 
 | ||||
|     for (int mesh_idx = 0; mesh_idx < part_volumes.size(); mesh_idx++) { | ||||
|         if (mesh_idx == m_rr.mesh_id) | ||||
|  | @ -518,8 +553,12 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous | |||
|                     const Selection     &selection                 = m_parent.get_selection(); | ||||
|                     const ModelObject   *mo                        = m_c->selection_info()->model_object(); | ||||
|                     const ModelInstance *mi                        = mo->instances[selection.get_instance_idx()]; | ||||
|                     const Transform3d   trafo_matrix_not_translate = mi->get_transformation().get_matrix(true) * mo->volumes[m_rr.mesh_id]->get_matrix(true); | ||||
|                     const Transform3d   trafo_matrix = mi->get_transformation().get_matrix() * mo->volumes[m_rr.mesh_id]->get_matrix(); | ||||
|                     const Transform3d   trafo_matrix_not_translate = m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView ? | ||||
|                         mi->get_assemble_transformation().get_matrix(true) * mo->volumes[m_rr.mesh_id]->get_matrix(true) : | ||||
|                         mi->get_transformation().get_matrix(true) * mo->volumes[m_rr.mesh_id]->get_matrix(true); | ||||
|                     const Transform3d   trafo_matrix = m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView ? | ||||
|                         mi->get_assemble_transformation().get_matrix() * mo->volumes[m_rr.mesh_id]->get_matrix() : | ||||
|                         mi->get_transformation().get_matrix() * mo->volumes[m_rr.mesh_id]->get_matrix(); | ||||
|                     m_triangle_selectors[m_rr.mesh_id]->seed_fill_select_triangles(m_rr.hit, int(m_rr.facet), trafo_matrix_not_translate, this->get_clipping_plane_in_volume_coordinates(trafo_matrix), m_smart_fill_angle, | ||||
|                                                                                    m_paint_on_overhangs_only ? m_highlight_by_angle_threshold_deg : 0.f, true); | ||||
|                     m_triangle_selectors[m_rr.mesh_id]->request_update_render_data(); | ||||
|  | @ -581,8 +620,12 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous | |||
|         const Selection     &selection                   = m_parent.get_selection(); | ||||
|         const ModelObject   *mo                          = m_c->selection_info()->model_object(); | ||||
|         const ModelInstance *mi                          = mo->instances[selection.get_instance_idx()]; | ||||
|         const Transform3d   instance_trafo               = mi->get_transformation().get_matrix(); | ||||
|         const Transform3d   instance_trafo_not_translate = mi->get_transformation().get_matrix(true); | ||||
|         Transform3d   instance_trafo = m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView ? | ||||
|             mi->get_assemble_transformation().get_matrix() : | ||||
|             mi->get_transformation().get_matrix(); | ||||
|         Transform3d   instance_trafo_not_translate = m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView ? | ||||
|             mi->get_assemble_transformation().get_matrix(true) : | ||||
|             mi->get_transformation().get_matrix(true); | ||||
|         std::vector<const ModelVolume*> part_volumes; | ||||
| 
 | ||||
|         // Precalculate transformations of individual meshes.
 | ||||
|  | @ -590,7 +633,14 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous | |||
|         std::vector<Transform3d> trafo_matrices_not_translate; | ||||
|         for (const ModelVolume *mv : mo->volumes) | ||||
|             if (mv->is_model_part()) { | ||||
|                 trafo_matrices.emplace_back(instance_trafo * mv->get_matrix()); | ||||
|                 if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) { | ||||
|                     Transform3d temp = instance_trafo * mv->get_matrix(); | ||||
|                     temp.translate(mv->get_transformation().get_offset() * (GLVolume::explosion_ratio - 1.0) + mi->get_offset_to_assembly() * (GLVolume::explosion_ratio - 1.0)); | ||||
|                     trafo_matrices.emplace_back(temp); | ||||
|                 } | ||||
|                 else { | ||||
|                     trafo_matrices.emplace_back(instance_trafo* mv->get_matrix()); | ||||
|                 } | ||||
|                 trafo_matrices_not_translate.emplace_back(instance_trafo_not_translate * mv->get_matrix(true)); | ||||
|                 part_volumes.push_back(mv); | ||||
|             } | ||||
|  | @ -713,15 +763,26 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous | |||
|         const Selection     &selection                    = m_parent.get_selection(); | ||||
|         const ModelObject   *mo                           = m_c->selection_info()->model_object(); | ||||
|         const ModelInstance *mi                           = mo->instances[selection.get_instance_idx()]; | ||||
|         const Transform3d    instance_trafo               = mi->get_transformation().get_matrix(); | ||||
|         const Transform3d    instance_trafo_not_translate = mi->get_transformation().get_matrix(true); | ||||
|         const Transform3d    instance_trafo = m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView ? | ||||
|             mi->get_assemble_transformation().get_matrix() : | ||||
|             mi->get_transformation().get_matrix(); | ||||
|         const Transform3d    instance_trafo_not_translate = m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView ? | ||||
|             mi->get_assemble_transformation().get_matrix(true) : | ||||
|             mi->get_transformation().get_matrix(true); | ||||
| 
 | ||||
|         // Precalculate transformations of individual meshes.
 | ||||
|         std::vector<Transform3d> trafo_matrices; | ||||
|         std::vector<Transform3d> trafo_matrices_not_translate; | ||||
|         for (const ModelVolume *mv : mo->volumes) | ||||
|             if (mv->is_model_part()) { | ||||
|                 trafo_matrices.emplace_back(instance_trafo * mv->get_matrix()); | ||||
|                 if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) { | ||||
|                     Transform3d temp = instance_trafo * mv->get_matrix(); | ||||
|                     temp.translate(mv->get_transformation().get_offset() * (GLVolume::explosion_ratio - 1.0) + mi->get_offset_to_assembly() * (GLVolume::explosion_ratio - 1.0)); | ||||
|                     trafo_matrices.emplace_back(temp); | ||||
|                 } | ||||
|                 else { | ||||
|                     trafo_matrices.emplace_back(instance_trafo * mv->get_matrix()); | ||||
|                 } | ||||
|                 trafo_matrices_not_translate.emplace_back(instance_trafo_not_translate * mv->get_matrix(true)); | ||||
|             } | ||||
| 
 | ||||
|  | @ -811,7 +872,8 @@ void GLGizmoPainterBase::update_raycast_cache(const Vec2d& mouse_position, | |||
|                    hit, | ||||
|                    normal, | ||||
|                    m_c->object_clipper()->get_clipping_plane(), | ||||
|                    &facet)) | ||||
|                    &facet, | ||||
|                    m_parent.get_canvas_type() != GLCanvas3D::CanvasAssembleView)) | ||||
|         { | ||||
|             // In case this hit is clipped, skip it.
 | ||||
|             if (is_mesh_point_clipped(hit.cast<double>(), trafo_matrices[mesh_id])) | ||||
|  |  | |||
|  | @ -368,7 +368,7 @@ private: | |||
|     mutable CutContours m_cut_contours; | ||||
| 
 | ||||
|     BoundingBoxf3 bounding_box() const; | ||||
|     void update_contours(float cursor_z, float max_z) const; | ||||
|     void update_contours(const TriangleMesh& vol_mesh, float cursor_z, float max_z, float min_z) const; | ||||
| 
 | ||||
| protected: | ||||
|     void on_set_state() override; | ||||
|  |  | |||
|  | @ -145,6 +145,11 @@ void InstancesHider::on_update() | |||
|     const ModelObject* mo = get_pool()->selection_info()->model_object(); | ||||
|     int active_inst = get_pool()->selection_info()->get_active_instance(); | ||||
|     GLCanvas3D* canvas = get_pool()->get_canvas(); | ||||
|     double z_min; | ||||
|     if (canvas->get_canvas_type() == GLCanvas3D::CanvasAssembleView) | ||||
|         z_min = std::numeric_limits<double>::max(); | ||||
|     else | ||||
|         z_min = -SINKING_Z_THRESHOLD; | ||||
| 
 | ||||
|     if (mo && active_inst != -1) { | ||||
|         canvas->toggle_model_objects_visibility(false); | ||||
|  | @ -152,7 +157,7 @@ void InstancesHider::on_update() | |||
|         canvas->toggle_sla_auxiliaries_visibility(m_show_supports, mo, active_inst); | ||||
|         canvas->set_use_clipping_planes(true); | ||||
|         // Some objects may be sinking, do not show whatever is below the bed.
 | ||||
|         canvas->set_clipping_plane(0, ClippingPlane(Vec3d::UnitZ(), -SINKING_Z_THRESHOLD)); | ||||
|         canvas->set_clipping_plane(0, ClippingPlane(Vec3d::UnitZ(), z_min)); | ||||
|         canvas->set_clipping_plane(1, ClippingPlane(-Vec3d::UnitZ(), std::numeric_limits<double>::max())); | ||||
| 
 | ||||
| 
 | ||||
|  | @ -164,7 +169,7 @@ void InstancesHider::on_update() | |||
|             m_clippers.clear(); | ||||
|             for (const TriangleMesh* mesh : meshes) { | ||||
|                 m_clippers.emplace_back(new MeshClipper); | ||||
|                 m_clippers.back()->set_plane(ClippingPlane(-Vec3d::UnitZ(), -SINKING_Z_THRESHOLD)); | ||||
|                 m_clippers.back()->set_plane(ClippingPlane(-Vec3d::UnitZ(), z_min)); | ||||
|                 m_clippers.back()->set_mesh(*mesh); | ||||
|             } | ||||
|             m_old_meshes = meshes; | ||||
|  | @ -404,18 +409,30 @@ void ObjectClipper::render_cut() const | |||
|         return; | ||||
|     const SelectionInfo* sel_info = get_pool()->selection_info(); | ||||
|     const ModelObject* mo = sel_info->model_object(); | ||||
|     Geometry::Transformation inst_trafo = mo->instances[sel_info->get_active_instance()]->get_transformation(); | ||||
|     Geometry::Transformation inst_trafo; | ||||
|     bool is_assem_cnv = get_pool()->get_canvas()->get_canvas_type() == GLCanvas3D::CanvasAssembleView; | ||||
|     inst_trafo = is_assem_cnv ? | ||||
|         mo->instances[sel_info->get_active_instance()]->get_assemble_transformation() : | ||||
|         mo->instances[sel_info->get_active_instance()]->get_transformation(); | ||||
|     auto offset_to_assembly = mo->instances[0]->get_offset_to_assembly(); | ||||
| 
 | ||||
|     size_t clipper_id = 0; | ||||
|     for (const ModelVolume* mv : mo->volumes) { | ||||
|         Geometry::Transformation vol_trafo  = mv->get_transformation(); | ||||
|         Geometry::Transformation trafo = inst_trafo * vol_trafo; | ||||
|         trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., sel_info->get_sla_shift())); | ||||
| 
 | ||||
|         if (is_assem_cnv) { | ||||
|             trafo.set_offset(trafo.get_offset() + offset_to_assembly * (GLVolume::explosion_ratio - 1.0) + vol_trafo.get_offset() * (GLVolume::explosion_ratio - 1.0)); | ||||
|         } | ||||
|         else { | ||||
|             trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., sel_info->get_sla_shift())); | ||||
|         } | ||||
|         auto& clipper = m_clippers[clipper_id]; | ||||
|         clipper->set_plane(*m_clp); | ||||
|         clipper->set_transformation(trafo); | ||||
|         clipper->set_limiting_plane(ClippingPlane(Vec3d::UnitZ(), -SINKING_Z_THRESHOLD)); | ||||
|         if (is_assem_cnv) | ||||
|             clipper->set_limiting_plane(ClippingPlane(Vec3d::UnitZ(), std::numeric_limits<double>::max())); | ||||
|         else | ||||
|             clipper->set_limiting_plane(ClippingPlane(Vec3d::UnitZ(), -SINKING_Z_THRESHOLD)); | ||||
|         glsafe(::glPushMatrix()); | ||||
|         // BBS
 | ||||
|         glsafe(::glColor3f(0.25f, 0.25f, 0.25f)); | ||||
|  | @ -438,14 +455,27 @@ void ObjectClipper::set_position(double pos, bool keep_normal) | |||
|     //    camera_dir(2) = 0;
 | ||||
| 
 | ||||
|     Vec3d normal = (keep_normal && m_clp) ? m_clp->get_normal() : /*-camera_dir;*/ -wxGetApp().plater()->get_camera().get_dir_forward(); | ||||
|     const Vec3d& center = mo->instances[active_inst]->get_offset() + Vec3d(0., 0., z_shift); | ||||
|     Vec3d center; | ||||
| 
 | ||||
|     if (get_pool()->get_canvas()->get_canvas_type() == GLCanvas3D::CanvasAssembleView) { | ||||
|         const SelectionInfo* sel_info = get_pool()->selection_info(); | ||||
|         auto trafo = mo->instances[sel_info->get_active_instance()]->get_assemble_transformation(); | ||||
|         auto offset_to_assembly = mo->instances[0]->get_offset_to_assembly(); | ||||
|         center = trafo.get_offset() + offset_to_assembly * (GLVolume::explosion_ratio - 1.0); | ||||
|     } | ||||
|     else { | ||||
|         center = mo->instances[active_inst]->get_offset() + Vec3d(0., 0., z_shift); | ||||
|     } | ||||
| 
 | ||||
|     float dist = normal.dot(center); | ||||
| 
 | ||||
|     if (pos < 0.) | ||||
|         pos = m_clp_ratio; | ||||
| 
 | ||||
|     m_clp_ratio = pos; | ||||
|     m_clp.reset(new ClippingPlane(normal, (dist - (-m_active_inst_bb_radius) - m_clp_ratio * 2*m_active_inst_bb_radius))); | ||||
| 
 | ||||
|     m_clp.reset(new ClippingPlane(normal, (dist - (-m_active_inst_bb_radius) - m_clp_ratio * 2 * m_active_inst_bb_radius))); | ||||
| 
 | ||||
|     get_pool()->get_canvas()->set_as_dirty(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -54,9 +54,16 @@ GLGizmosManager::GLGizmosManager(GLCanvas3D& parent) | |||
| std::vector<size_t> GLGizmosManager::get_selectable_idxs() const | ||||
| { | ||||
|     std::vector<size_t> out; | ||||
|     for (size_t i=0; i<m_gizmos.size(); ++i) | ||||
|         if (m_gizmos[i]->is_selectable()) | ||||
|             out.push_back(i); | ||||
|     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) | ||||
|                 out.push_back(i); | ||||
|     } | ||||
|     else { | ||||
|         for (size_t i = 0; i < m_gizmos.size(); ++i) | ||||
|             if (m_gizmos[i]->is_selectable()) | ||||
|                 out.push_back(i); | ||||
|     } | ||||
|     return out; | ||||
| } | ||||
| 
 | ||||
|  | @ -78,6 +85,8 @@ size_t GLGizmosManager::get_gizmo_idx_from_mouse(const Vec2d& mouse_pos) const | |||
| #if BBS_TOOLBAR_ON_TOP | ||||
|     //float space_width = GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale();;
 | ||||
|     float top_x = std::max(m_parent.get_main_toolbar_width() + border, 0.5f * (cnv_w - width + m_parent.get_main_toolbar_width() + m_parent.get_collapse_toolbar_width() - m_parent.get_assemble_view_toolbar_width()) + border); | ||||
|     if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) | ||||
|         top_x = 0.5f * cnv_w + 0.5f * (m_parent.get_assembly_paint_toolbar_width()); | ||||
|     float top_y = 0; | ||||
|     float stride_x = m_layout.scaled_stride_x(); | ||||
| 
 | ||||
|  | @ -1372,17 +1381,23 @@ void GLGizmosManager::do_render_overlay() const | |||
|     float width = get_scaled_total_width(); | ||||
|     float zoomed_border = m_layout.scaled_border() * inv_zoom; | ||||
| 
 | ||||
|     //BBS: GUI refactor: GLToolbar&&Gizmo adjust
 | ||||
|     float zoomed_top_x; | ||||
|     if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) { | ||||
|         zoomed_top_x = 0.5f * m_parent.get_assembly_paint_toolbar_width() * inv_zoom; | ||||
|     } | ||||
|     else { | ||||
|         //BBS: GUI refactor: GLToolbar&&Gizmo adjust
 | ||||
| #if BBS_TOOLBAR_ON_TOP | ||||
|     float main_toolbar_width =  (float)m_parent.get_main_toolbar_width(); | ||||
|     float assemble_view_width = (float)m_parent.get_assemble_view_toolbar_width(); | ||||
|     float collapse_width = (float)m_parent.get_collapse_toolbar_width(); | ||||
|     //float space_width = GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale();
 | ||||
|     //float zoomed_top_x = 0.5f *(cnv_w + main_toolbar_width - 2 * space_width - width) * inv_zoom;
 | ||||
|         float main_toolbar_width = (float)m_parent.get_main_toolbar_width(); | ||||
|         float assemble_view_width = (float)m_parent.get_assemble_view_toolbar_width(); | ||||
|         float collapse_width = (float)m_parent.get_collapse_toolbar_width(); | ||||
|         //float space_width = GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale();
 | ||||
|         //float zoomed_top_x = 0.5f *(cnv_w + main_toolbar_width - 2 * space_width - width) * inv_zoom;
 | ||||
| 
 | ||||
|     float main_toolbar_left = std::max(-0.5f * cnv_w, -0.5f * (main_toolbar_width + get_scaled_total_width() + assemble_view_width - collapse_width)) * inv_zoom; | ||||
|     //float zoomed_top_x = 0.5f *(main_toolbar_width + collapse_width - width - assemble_view_width) * inv_zoom;
 | ||||
|     float zoomed_top_x = main_toolbar_left + (main_toolbar_width) *inv_zoom; | ||||
|         float main_toolbar_left = std::max(-0.5f * cnv_w, -0.5f * (main_toolbar_width + get_scaled_total_width() + assemble_view_width - collapse_width)) * inv_zoom; | ||||
|         //float zoomed_top_x = 0.5f *(main_toolbar_width + collapse_width - width - assemble_view_width) * inv_zoom;
 | ||||
|         zoomed_top_x = main_toolbar_left + (main_toolbar_width)*inv_zoom; | ||||
|     } | ||||
|     float zoomed_top_y = 0.5f * cnv_h * inv_zoom; | ||||
| #else | ||||
|     //float zoomed_top_x = (-0.5f * cnv_w) * inv_zoom;
 | ||||
|  |  | |||
|  | @ -241,7 +241,7 @@ void MeshRaycaster::line_from_mouse_pos(const Vec2d& mouse_pos, const Transform3 | |||
| 
 | ||||
| bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera, | ||||
|                                       Vec3f& position, Vec3f& normal, const ClippingPlane* clipping_plane, | ||||
|                                       size_t* facet_idx) const | ||||
|                                       size_t* facet_idx, bool sinking_limit) const | ||||
| { | ||||
|     Vec3d point; | ||||
|     Vec3d direction; | ||||
|  | @ -258,8 +258,8 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& | |||
|     // Also, remove anything below the bed (sinking objects).
 | ||||
|     for (i=0; i<hits.size(); ++i) { | ||||
|         Vec3d transformed_hit = trafo * hits[i].position(); | ||||
|         if (transformed_hit.z() >= SINKING_Z_THRESHOLD && | ||||
|             (! clipping_plane || ! clipping_plane->is_point_clipped(transformed_hit))) | ||||
|         if (transformed_hit.z() >= sinking_limit ? SINKING_Z_THRESHOLD : -std::numeric_limits<double>::max() && | ||||
|             (!clipping_plane || !clipping_plane->is_point_clipped(transformed_hit))) | ||||
|             break; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -150,7 +150,8 @@ public: | |||
|         Vec3f& position, // where to save the positibon of the hit (mesh coords)
 | ||||
|         Vec3f& normal, // normal of the triangle that was hit
 | ||||
|         const ClippingPlane* clipping_plane = nullptr, // clipping plane (if active)
 | ||||
|         size_t* facet_idx = nullptr // index of the facet hit
 | ||||
|         size_t* facet_idx = nullptr, // index of the facet hit
 | ||||
|         bool sinking_limit = true | ||||
|     ) const; | ||||
| 
 | ||||
|     // Given a vector of points in woorld coordinates, this returns vector
 | ||||
|  |  | |||
|  | @ -2481,6 +2481,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) | |||
|         assemble_canvas->Bind(EVT_GLCANVAS_OBJECT_SELECT, &priv::on_object_select, this); | ||||
|         assemble_canvas->Bind(EVT_GLVIEWTOOLBAR_3D, [q](SimpleEvent&) { q->select_view_3D("3D"); }); | ||||
|         assemble_canvas->Bind(EVT_GLCANVAS_RIGHT_CLICK, &priv::on_right_click, this); | ||||
|         assemble_canvas->Bind(EVT_GLCANVAS_UNDO, [this](SimpleEvent&) { this->undo(); }); | ||||
|         assemble_canvas->Bind(EVT_GLCANVAS_REDO, [this](SimpleEvent&) { this->redo(); }); | ||||
|     } | ||||
| 
 | ||||
|     if (wxGetApp().is_editor()) { | ||||
|  | @ -4158,6 +4160,7 @@ void Plater::priv::reset(bool apply_presets_change) | |||
|     // Stop and reset the Print content.
 | ||||
|     this->background_process.reset(); | ||||
|     model.clear_objects(); | ||||
|     assemble_view->get_canvas3d()->reset_explosion_ratio(); | ||||
|     update(); | ||||
| 
 | ||||
|     //BBS
 | ||||
|  | @ -7263,18 +7266,19 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name, const UndoRed | |||
|             tower.rotation = proj_cfg.opt_float("wipe_tower_rotation_angle"); | ||||
|         } | ||||
|     } | ||||
|     const GLGizmosManager& gizmos = view3D->get_canvas3d()->get_gizmos_manager(); | ||||
|     const GLGizmosManager& gizmos = get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_gizmos_manager() : view3D->get_canvas3d()->get_gizmos_manager(); | ||||
| 
 | ||||
|     if (snapshot_type == UndoRedo::SnapshotType::ProjectSeparator) | ||||
|         this->undo_redo_stack().clear(); | ||||
|     this->undo_redo_stack().take_snapshot(snapshot_name, model, view3D->get_canvas3d()->get_selection(), view3D->get_canvas3d()->get_gizmos_manager(), partplate_list, snapshot_data); | ||||
|     this->undo_redo_stack().take_snapshot(snapshot_name, model, get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_selection() : view3D->get_canvas3d()->get_selection(), gizmos, partplate_list, snapshot_data); | ||||
|     if (snapshot_type == UndoRedo::SnapshotType::LeavingGizmoWithAction) { | ||||
|         // Filter all but the last UndoRedo::SnapshotType::GizmoAction in a row between the last UndoRedo::SnapshotType::EnteringGizmo and UndoRedo::SnapshotType::LeavingGizmoWithAction.
 | ||||
|         // The remaining snapshot will be renamed to a more generic name,
 | ||||
|         // depending on what gizmo is being left.
 | ||||
|         assert(gizmos.get_current() != nullptr); | ||||
|         std::string new_name = gizmos.get_current()->get_action_snapshot_name(); | ||||
|         this->undo_redo_stack().reduce_noisy_snapshots(new_name); | ||||
|         if (gizmos.get_current() != nullptr) { | ||||
|             std::string new_name = gizmos.get_current()->get_action_snapshot_name(); | ||||
|             this->undo_redo_stack().reduce_noisy_snapshots(new_name); | ||||
|         } | ||||
|     } else if (snapshot_type == UndoRedo::SnapshotType::ProjectSeparator) { | ||||
|         // Reset the "dirty project" flag.
 | ||||
|         m_undo_redo_stack_main.mark_current_as_saved(); | ||||
|  | @ -7296,6 +7300,13 @@ void Plater::priv::undo() | |||
|     // BBS: undo-redo until modify record
 | ||||
|     while (--it_current != snapshots.begin() && !snapshot_modifies_project(*it_current)); | ||||
|     if (it_current == snapshots.begin()) return; | ||||
|     if (get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView) { | ||||
|         if (it_current->snapshot_data.snapshot_type != UndoRedo::SnapshotType::GizmoAction && | ||||
|             it_current->snapshot_data.snapshot_type != UndoRedo::SnapshotType::EnteringGizmo && | ||||
|             it_current->snapshot_data.snapshot_type != UndoRedo::SnapshotType::LeavingGizmoNoAction && | ||||
|             it_current->snapshot_data.snapshot_type != UndoRedo::SnapshotType::LeavingGizmoWithAction) | ||||
|             return; | ||||
|     } | ||||
|     this->undo_redo_to(it_current); | ||||
| } | ||||
| 
 | ||||
|  | @ -7398,8 +7409,8 @@ void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator | |||
|     const UndoRedo::Snapshot snapshot_copy = *it_snapshot; | ||||
|     // Do the jump in time.
 | ||||
|     if (it_snapshot->timestamp < this->undo_redo_stack().active_snapshot_time() ? | ||||
|         this->undo_redo_stack().undo(model, this->view3D->get_canvas3d()->get_selection(), this->view3D->get_canvas3d()->get_gizmos_manager(), this->partplate_list, top_snapshot_data, it_snapshot->timestamp) : | ||||
|         this->undo_redo_stack().redo(model, this->view3D->get_canvas3d()->get_gizmos_manager(), this->partplate_list, it_snapshot->timestamp)) { | ||||
|         this->undo_redo_stack().undo(model, get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_selection() : this->view3D->get_canvas3d()->get_selection(), get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_gizmos_manager() : this->view3D->get_canvas3d()->get_gizmos_manager(), this->partplate_list, top_snapshot_data, it_snapshot->timestamp) : | ||||
|         this->undo_redo_stack().redo(model, get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_gizmos_manager() : this->view3D->get_canvas3d()->get_gizmos_manager(), this->partplate_list, it_snapshot->timestamp)) { | ||||
|         if (printer_technology_changed) { | ||||
|             // Switch to the other printer technology. Switch to the last printer active for that particular technology.
 | ||||
|             AppConfig *app_config = wxGetApp().app_config; | ||||
|  | @ -7476,7 +7487,7 @@ void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator | |||
| 
 | ||||
| void Plater::priv::update_after_undo_redo(const UndoRedo::Snapshot& snapshot, bool /* temp_snapshot_was_taken */) | ||||
| { | ||||
|     this->view3D->get_canvas3d()->get_selection().clear(); | ||||
|     get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_selection().clear() : this->view3D->get_canvas3d()->get_selection().clear(); | ||||
|     // Update volumes from the deserializd model, always stop / update the background processing (for both the SLA and FFF technologies).
 | ||||
|     this->update((unsigned int)UpdateParams::FORCE_BACKGROUND_PROCESSING_UPDATE | (unsigned int)UpdateParams::POSTPONE_VALIDATION_ERROR_MESSAGE); | ||||
|     // Release old snapshots if the memory allocated is excessive. This may remove the top most snapshot if jumping to the very first snapshot.
 | ||||
|  | @ -7485,8 +7496,12 @@ void Plater::priv::update_after_undo_redo(const UndoRedo::Snapshot& snapshot, bo | |||
|     // triangle meshes may have gotten released from the scene or the background processing, therefore now being calculated into the Undo / Redo stack size.
 | ||||
|         this->undo_redo_stack().release_least_recently_used(); | ||||
|     //YS_FIXME update obj_list from the deserialized model (maybe store ObjectIDs into the tree?) (no selections at this point of time)
 | ||||
|     this->view3D->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack().selection_deserialized().mode), this->undo_redo_stack().selection_deserialized().volumes_and_instances); | ||||
|     this->view3D->get_canvas3d()->get_gizmos_manager().update_after_undo_redo(snapshot); | ||||
|         get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ?  | ||||
|             assemble_view->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack().selection_deserialized().mode), this->undo_redo_stack().selection_deserialized().volumes_and_instances) : | ||||
|             this->view3D->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack().selection_deserialized().mode), this->undo_redo_stack().selection_deserialized().volumes_and_instances); | ||||
|     get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ?  | ||||
|         assemble_view->get_canvas3d()->get_gizmos_manager().update_after_undo_redo(snapshot) : | ||||
|         this->view3D->get_canvas3d()->get_gizmos_manager().update_after_undo_redo(snapshot); | ||||
| 
 | ||||
|     wxGetApp().obj_list()->update_after_undo_redo(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -2712,9 +2712,14 @@ void Selection::paste_objects_from_clipboard() | |||
|             displacement      = {empty_cell.x() + point_offset.x(), empty_cell.y() + point_offset.y(), start_offset(2)}; | ||||
|         } | ||||
| 
 | ||||
|         for (ModelInstance* inst : dst_object->instances) | ||||
|         for (ModelInstance* inst : dst_object->instances) { | ||||
|             inst->set_offset(displacement); | ||||
| 
 | ||||
|             //BBS init asssmble transformation
 | ||||
|             Geometry::Transformation t = inst->get_transformation(); | ||||
|             inst->set_assemble_transformation(t); | ||||
|         } | ||||
| 
 | ||||
|         object_idxs.push_back(m_model->objects.size() - 1); | ||||
| #ifdef _DEBUG | ||||
| 	    check_model_ids_validity(*m_model); | ||||
|  |  | |||
|  | @ -479,10 +479,11 @@ public: | |||
| 		assert(! m_history.empty()); | ||||
| 		auto it = std::lower_bound(m_history.begin(), m_history.end(), MutableHistoryInterval(timestamp, timestamp)); | ||||
| 		if (it == m_history.end() || it->begin() > timestamp) { | ||||
| 			assert(it != m_history.begin()); | ||||
| 			-- it; | ||||
| 			//assert(it != m_history.begin());
 | ||||
| 			if (it != m_history.begin()) | ||||
| 				--it; | ||||
| 		} | ||||
| 		assert(timestamp >= it->begin() && timestamp < it->end()); | ||||
| 		//assert(timestamp >= it->begin() && timestamp < it->end());
 | ||||
| 		return std::string(it->data(), it->data() + it->size()); | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 liz.li
						liz.li