diff --git a/src/libslic3r/ObjectID.hpp b/src/libslic3r/ObjectID.hpp index 6be19c88f..4f34572d2 100644 --- a/src/libslic3r/ObjectID.hpp +++ b/src/libslic3r/ObjectID.hpp @@ -2,6 +2,7 @@ #define slic3r_ObjectID_hpp_ #include +#include namespace Slic3r { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 793ab1e51..56dd56462 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -568,6 +568,42 @@ bool GLGizmoCut3D::render_reset_button(const std::string& label_id, const std::s return revert; } +void GLGizmoCut3D::render_cut_plane_line() +{ + if (cut_line_processing()) + return; + + glsafe(::glEnable(GL_DEPTH_TEST)); + glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); + + const Camera& camera = wxGetApp().plater()->get_camera(); + + Vec3d unit_dir = m_rotation_m * Vec3d::UnitZ(); + unit_dir.normalize(); + + Vec3d camera_dir = camera.get_dir_forward(); + camera_dir.normalize(); + + if (std::abs(unit_dir.dot(camera_dir)) <= 0.025) { + GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); + if (shader) { + m_circle.reset(); + init_from_circle(m_circle, m_radius * 1.25); + + const Transform3d view_model_matrix = camera.get_view_matrix() * translation_transform(m_plane_center) * m_rotation_m; + + shader->start_using(); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + shader->set_uniform("view_model_matrix", view_model_matrix); + shader->set_uniform("width", 0.1f); + + m_circle.render(); + + shader->stop_using(); + } + } +} + void GLGizmoCut3D::render_cut_plane() { if (cut_line_processing()) @@ -986,7 +1022,7 @@ bool GLGizmoCut3D::on_is_activable() const // This is assumed in GLCanvas3D::do_rotate, do not change this // without updating that function too. - return selection.is_single_full_instance() && !is_dowel_object; + return selection.is_single_full_instance() && !is_dowel_object && !m_parent.is_layers_editing_enabled(); } bool GLGizmoCut3D::on_is_selectable() const @@ -1153,7 +1189,15 @@ void GLGizmoCut3D::on_stop_dragging() void GLGizmoCut3D::set_center_pos(const Vec3d& center_pos, bool force/* = false*/) { - if (force || transformed_bounding_box(true).contains(center_pos)) { + bool can_set_center_pos = force || transformed_bounding_box(true).contains(center_pos); + if (!can_set_center_pos) { + const double old_dist = (m_bb_center - m_plane_center).norm(); + const double new_dist = (m_bb_center - center_pos).norm(); + // check if forcing is reasonable + if ( new_dist < old_dist) + can_set_center_pos = true; + } + if (can_set_center_pos) { m_plane_center = center_pos; m_center_offset = m_plane_center - m_bb_center; } @@ -1178,17 +1222,20 @@ BoundingBoxf3 GLGizmoCut3D::transformed_bounding_box(bool revert_move /*= false* // #ysFIXME !!! BoundingBoxf3 ret; - const ModelObject* mo = m_c->selection_info()->model_object(); + 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 = m_c->selection_info()->get_active_instance(); + const int instance_idx = sel_info->get_active_instance(); if (instance_idx < 0) return ret; const ModelInstance* mi = mo->instances[instance_idx]; const Vec3d& instance_offset = mi->get_offset(); Vec3d cut_center_offset = m_plane_center - instance_offset; - cut_center_offset[Z] -= m_c->selection_info()->get_sla_shift(); + cut_center_offset[Z] -= sel_info->get_sla_shift(); const auto move = assemble_transform(-cut_center_offset); const auto move2 = assemble_transform(m_plane_center); @@ -1330,6 +1377,8 @@ void GLGizmoCut3D::on_render() render_cut_line(); + render_cut_plane_line(); + m_selection_rectangle.render(m_parent); } @@ -1935,7 +1984,7 @@ void GLGizmoCut3D::clear_selection() void GLGizmoCut3D::reset_connectors() { m_c->selection_info()->model_object()->cut_connectors.clear(); - update_model_object(); + update_raycasters_for_picking(); clear_selection(); } @@ -1960,17 +2009,6 @@ void GLGizmoCut3D::update_connector_shape() m_connector_mesh = TriangleMesh(its); } -void GLGizmoCut3D::update_model_object() -{ - const ModelObjectPtrs& mos = wxGetApp().model().objects; - ModelObject* mo = m_c->selection_info()->model_object(); - wxGetApp().obj_list()->update_info_items(std::find(mos.begin(), mos.end(), mo) - mos.begin()); - - m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); - - update_raycasters_for_picking(); -} - bool GLGizmoCut3D::cut_line_processing() const { return m_line_beg != Vec3d::Zero(); @@ -2053,7 +2091,7 @@ bool GLGizmoCut3D::add_connector(CutConnectors& connectors, const Vec2d& mouse_p m_selected.push_back(true); m_selected_count = 1; assert(m_selected.size() == connectors.size()); - update_model_object(); + update_raycasters_for_picking(); m_parent.set_as_dirty(); } else { @@ -2084,7 +2122,7 @@ bool GLGizmoCut3D::delete_selected_connectors(CutConnectors& connectors) m_selected_count = 0; assert(m_selected.size() == connectors.size()); - update_model_object(); + update_raycasters_for_picking(); m_parent.set_as_dirty(); return true; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index 86e14705b..941d01660 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -237,6 +237,7 @@ private: void render_grabber_connection(const ColorRGBA& color, Transform3d view_matrix); void render_cut_plane_grabbers(); void render_cut_line(); + void render_cut_plane_line(); void perform_cut(const Selection&selection); void set_center_pos(const Vec3d¢er_pos, bool force = false); bool update_bb(); @@ -248,7 +249,6 @@ private: void init_connector_shapes(); void update_connector_shape(); void validate_connector_settings(); - void update_model_object(); bool process_cut_line(SLAGizmoEventType action, const Vec2d& mouse_position); }; diff --git a/src/slic3r/GUI/ObjectDataViewModel.cpp b/src/slic3r/GUI/ObjectDataViewModel.cpp index e2fca5fae..50577771b 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.cpp +++ b/src/slic3r/GUI/ObjectDataViewModel.cpp @@ -34,6 +34,14 @@ void ObjectDataViewModelNode::init_container() #endif //__WXGTK__ } +void ObjectDataViewModelNode::invalidate_container() +{ +#ifndef __WXGTK__ + if (this->GetChildCount() == 0) + this->m_container = false; +#endif //__WXGTK__ +} + static constexpr char LayerRootIcon[] = "edit_layers_all"; static constexpr char LayerIcon[] = "edit_layers_some"; static constexpr char WarningIcon[] = "exclamation"; @@ -724,10 +732,7 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item) delete node_parent; ret_item = wxDataViewItem(obj_node); -#ifndef __WXGTK__ - if (obj_node->GetChildCount() == 0) - obj_node->m_container = false; -#endif //__WXGTK__ + obj_node->invalidate_container(); ItemDeleted(ret_item, wxDataViewItem(node_parent)); return ret_item; } @@ -743,10 +748,7 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item) delete node_parent; ret_item = wxDataViewItem(obj_node); -#ifndef __WXGTK__ - if (obj_node->GetChildCount() == 0) - obj_node->m_container = false; -#endif //__WXGTK__ + obj_node->invalidate_container(); ItemDeleted(ret_item, wxDataViewItem(node_parent)); return ret_item; } @@ -768,10 +770,7 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item) node_parent->m_volumes_cnt = 0; delete last_child_node; -#ifndef __WXGTK__ - if (node_parent->GetChildCount() == 0) - node_parent->m_container = false; -#endif //__WXGTK__ + node_parent->invalidate_container(); ItemDeleted(parent, wxDataViewItem(last_child_node)); wxCommandEvent event(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED); @@ -806,10 +805,7 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item) // set m_containet to FALSE if parent has no child if (node_parent) { -#ifndef __WXGTK__ - if (node_parent->GetChildCount() == 0) - node_parent->m_container = false; -#endif //__WXGTK__ + node_parent->invalidate_container(); ret_item = parent; } @@ -851,10 +847,7 @@ wxDataViewItem ObjectDataViewModel::DeleteLastInstance(const wxDataViewItem &par parent_node->set_printable_icon(last_inst_printable); ItemDeleted(parent_item, inst_root_item); ItemChanged(parent_item); -#ifndef __WXGTK__ - if (parent_node->GetChildCount() == 0) - parent_node->m_container = false; -#endif //__WXGTK__ + parent_node->invalidate_container(); } // update object_node printable property @@ -899,10 +892,7 @@ void ObjectDataViewModel::DeleteChildren(wxDataViewItem& parent) ItemDeleted(parent, item); } - // set m_containet to FALSE if parent has no child -#ifndef __WXGTK__ - root->m_container = false; -#endif //__WXGTK__ + root->invalidate_container(); } void ObjectDataViewModel::DeleteVolumeChildren(wxDataViewItem& parent) @@ -932,11 +922,7 @@ void ObjectDataViewModel::DeleteVolumeChildren(wxDataViewItem& parent) ItemDeleted(parent, item); } root->m_volumes_cnt = 0; - - // set m_containet to FALSE if parent has no child -#ifndef __WXGTK__ - root->m_container = false; -#endif //__WXGTK__ + root->invalidate_container(); } void ObjectDataViewModel::DeleteSettings(const wxDataViewItem& parent) diff --git a/src/slic3r/GUI/ObjectDataViewModel.hpp b/src/slic3r/GUI/ObjectDataViewModel.hpp index 55dbaafe2..6f2d1519c 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.hpp +++ b/src/slic3r/GUI/ObjectDataViewModel.hpp @@ -128,7 +128,9 @@ public: } void init_container(); - bool IsContainer() const + void invalidate_container(); + + bool IsContainer() const { return m_container; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 15ed60a99..d3bd704d2 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4470,7 +4470,10 @@ void Plater::priv::on_action_split_volumes(SimpleEvent&) void Plater::priv::on_action_layersediting(SimpleEvent&) { - view3D->enable_layers_editing(!view3D->is_layers_editing_enabled()); + const bool enable_layersediting = !view3D->is_layers_editing_enabled(); + view3D->enable_layers_editing(enable_layersediting); + if (enable_layersediting) + view3D->get_canvas3d()->reset_all_gizmos(); notification_manager->set_move_from_overlay(view3D->is_layers_editing_enabled()); } @@ -4513,7 +4516,7 @@ void Plater::priv::on_right_click(RBtnEvent& evt) selection.is_single_full_object() || selection.is_multiple_full_instance(); #if ENABLE_WORLD_COORDINATE - const bool is_part = selection.is_single_volume_or_modifier(); + const bool is_part = selection.is_single_volume_or_modifier() && ! selection.is_any_connector(); #else const bool is_part = selection.is_single_volume() || selection.is_single_modifier(); #endif // ENABLE_WORLD_COORDINATE