diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 56f3af2d1d..aa21c3adeb 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -1424,6 +1424,7 @@ static void add_cut_volume(TriangleMesh& mesh, ModelObject* object, const ModelV assert(vol->config.id().valid()); assert(vol->config.id() != src_volume->config.id()); vol->set_material(src_volume->material_id(), *src_volume->material()); + vol->cut_info = src_volume->cut_info; } void ModelObject::process_solid_part_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix, diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 2b58758158..c83e3f9703 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3529,7 +3529,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) const int volume_idx = get_first_hover_volume_idx(); BoundingBoxf3 volume_bbox = m_volumes.volumes[volume_idx]->transformed_bounding_box(); volume_bbox.offset(1.0); - if ((!any_gizmo_active || !evt.CmdDown()) && volume_bbox.contains(m_mouse.scene_position)) { + const bool is_cut_connector_selected = m_selection.is_any_connector(); + if ((!any_gizmo_active || !evt.CmdDown()) && volume_bbox.contains(m_mouse.scene_position) && !is_cut_connector_selected) { m_volumes.volumes[volume_idx]->hover = GLVolume::HS_None; // The dragging operation is initiated. m_mouse.drag.move_volume_idx = volume_idx; diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index ff9113c684..6ffe19218d 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -1080,6 +1080,9 @@ wxMenu* MenuFactory::multi_selection_menu() wxDataViewItemArray sels; obj_list()->GetSelections(sels); + if (sels.IsEmpty()) + return nullptr; + for (const wxDataViewItem& item : sels) if (!(list_model()->GetItemType(item) & (itVolume | itObject | itInstance))) // show this menu only for Objects(Instances mixed with Objects)/Volumes selection diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index d9cc1b1cac..ac96029855 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -3806,6 +3806,8 @@ void ObjectList::update_selections_on_canvas() if (sel_cnt == 1) { wxDataViewItem item = GetSelection(); + if (m_objects_model->GetInfoItemType(item) == InfoItemType::CutConnectors) + selection.remove_all(); if (m_objects_model->GetItemType(item) & (itSettings | itInstanceRoot | itLayerRoot | itLayer)) add_to_selection(m_objects_model->GetParent(item), selection, instance_idx, mode); else diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 9965e48460..793ab1e512 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -963,9 +963,30 @@ void GLGizmoCut3D::on_set_hover_id() bool GLGizmoCut3D::on_is_activable() const { + const Selection& selection = m_parent.get_selection(); + const int object_idx = selection.get_object_idx(); + if (object_idx < 0) + return false; + + bool is_dowel_object = false; + if (const ModelObject* mo = wxGetApp().plater()->model().objects[object_idx]; mo->is_cut()) { + int solid_connector_cnt = 0; + int connectors_cnt = 0; + for (const ModelVolume* volume : mo->volumes) { + if (volume->is_cut_connector()) { + connectors_cnt++; + if (volume->is_model_part()) + solid_connector_cnt++; + } + if (connectors_cnt > 1) + break; + } + is_dowel_object = connectors_cnt == 1 && solid_connector_cnt == 1; + } + // This is assumed in GLCanvas3D::do_rotate, do not change this // without updating that function too. - return m_parent.get_selection().is_single_full_instance(); + return selection.is_single_full_instance() && !is_dowel_object; } bool GLGizmoCut3D::on_is_selectable() const @@ -1200,6 +1221,9 @@ bool GLGizmoCut3D::update_bb() { const BoundingBoxf3 box = bounding_box(); if (m_max_pos != box.max || m_min_pos != box.min) { + + invalidate_cut_plane(); + m_max_pos = box.max; m_min_pos = box.min; m_bb_center = box.center(); @@ -1412,8 +1436,14 @@ void GLGizmoCut3D::render_connectors_input_window(CutConnectors &connectors) if (type_changed) apply_selected_connectors([this, &connectors] (size_t idx) { connectors[idx].attribs.type = CutConnectorType(m_connector_type); }); + m_imgui->disabled_begin(m_connector_type == CutConnectorType::Dowel); + if (type_changed && m_connector_type == CutConnectorType::Dowel) { + m_connector_style = size_t(CutConnectorStyle::Prizm); + apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.style = CutConnectorStyle(m_connector_style); }); + } if (render_combo(_u8L("Style"), m_connector_styles, m_connector_style)) apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.style = CutConnectorStyle(m_connector_style); }); + m_imgui->disabled_end(); if (render_combo(_u8L("Shape"), m_connector_shapes, m_connector_shape_id)) apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.shape = CutConnectorShape(m_connector_shape_id); }); @@ -1850,8 +1880,6 @@ void GLGizmoCut3D::perform_cut(const Selection& selection) else { // the object is SLA-elevated and the plane is under it. } - - invalidate_cut_plane(); } @@ -2136,7 +2164,7 @@ bool GLGizmoCut3D::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_posi return true; } - if (action == SLAGizmoEventType::LeftUp) { + if (action == SLAGizmoEventType::LeftUp && !m_selection_rectangle.is_dragging()) { if ((m_ldown_mouse_position - mouse_position).norm() < 5.) unselect_all_connectors(); return is_selection_changed(alt_down, shift_down); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 2051192ee4..15ed60a99a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2976,9 +2976,6 @@ void Plater::priv::object_list_changed() const bool model_fits = view3D->get_canvas3d()->check_volumes_outside_state() == ModelInstancePVS_Inside; sidebar->enable_buttons(!model.objects.empty() && !export_in_progress && model_fits); - - // invalidate CutGizmo after changes in ObjectList - static_cast(q->canvas3D()->get_gizmos_manager().get_gizmo(GLGizmosManager::Cut))->invalidate_cut_plane(); } void Plater::priv::select_all() @@ -4930,8 +4927,12 @@ bool Plater::priv::can_fix_through_netfabb() const bool Plater::priv::can_simplify() const { + const int obj_idx = get_selected_object_idx(); // is object for simplification selected - if (get_selected_object_idx() < 0) return false; + // cut object can't be simplify + if (obj_idx < 0 || model.objects[obj_idx]->is_cut()) + return false; + // is already opened? if (q->canvas3D()->get_gizmos_manager().get_current_type() == GLGizmosManager::EType::Simplify)