diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 2e96910f4..c0e7e907d 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -257,8 +257,6 @@ struct CutConnector static constexpr size_t steps = 32; }; -using CutConnectors = std::vector; - // Declared outside of ModelVolume, so it could be forward declared. enum class ModelVolumeType : int { INVALID = -1, @@ -269,6 +267,27 @@ enum class ModelVolumeType : int { SUPPORT_ENFORCER, }; +using CutConnectors = std::vector; + +enum class CutConnectorType : int { + Plug + , Dowel +}; + +enum class CutConnectorStyle : int { + Prizm + , Frustrum + //,Claw +}; + +enum class CutConnectorShape : int { + Triangle + , Square + , Hexagon + , Circle + //,D-shape +}; + enum class ModelObjectCutAttribute : int { KeepUpper, KeepLower, FlipLower }; using ModelObjectCutAttributes = enum_bitmask; ENABLE_ENUM_BITMASK_OPERATORS(ModelObjectCutAttribute); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 27c374b3f..7462e8153 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1841,6 +1841,12 @@ void ObjectList::del_info_item(const int obj_idx, InfoItemType type) mv->seam_facets.reset(); break; + case InfoItemType::Cut: + cnv->get_gizmos_manager().reset_all_states(); + Plater::TakeSnapshot(plater, _L("Remove cut connectors")); + (*m_objects)[obj_idx]->cut_connectors.clear(); + break; + case InfoItemType::MmuSegmentation: cnv->get_gizmos_manager().reset_all_states(); Plater::TakeSnapshot(plater, _L("Remove Multi Material painting")); @@ -2464,10 +2470,12 @@ void ObjectList::part_selection_changed() } case InfoItemType::CustomSupports: case InfoItemType::CustomSeam: + case InfoItemType::Cut: case InfoItemType::MmuSegmentation: { - GLGizmosManager::EType gizmo_type = info_type == InfoItemType::CustomSupports ? GLGizmosManager::EType::FdmSupports : - info_type == InfoItemType::CustomSeam ? GLGizmosManager::EType::Seam : + GLGizmosManager::EType gizmo_type = info_type == InfoItemType::CustomSupports ? GLGizmosManager::EType::FdmSupports : + info_type == InfoItemType::CustomSeam ? GLGizmosManager::EType::Seam : + info_type == InfoItemType::Cut ? GLGizmosManager::EType::Cut : GLGizmosManager::EType::MmuSegmentation; GLGizmosManager& gizmos_mgr = wxGetApp().plater()->canvas3D()->get_gizmos_manager(); if (gizmos_mgr.get_current_type() != gizmo_type) @@ -2604,6 +2612,7 @@ void ObjectList::update_info_items(size_t obj_idx, wxDataViewItemArray* selectio for (InfoItemType type : {InfoItemType::CustomSupports, InfoItemType::CustomSeam, + InfoItemType::Cut, InfoItemType::MmuSegmentation, InfoItemType::Sinking, InfoItemType::VariableLayerHeight}) { @@ -2624,6 +2633,9 @@ void ObjectList::update_info_items(size_t obj_idx, wxDataViewItemArray* selectio }); break; + case InfoItemType::Cut : + should_show = !model_object->cut_connectors.empty(); + break; case InfoItemType::VariableLayerHeight : should_show = printer_technology() == ptFFF && ! model_object->layer_height_profile.empty(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 0e3dd3067..9c5074a45 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -26,6 +26,9 @@ static const ColorRGBA GRABBER_COLOR = ColorRGBA::ORANGE(); GLGizmoCut3D::GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) + , m_connector_type (CutConnectorType::Plug) + , m_connector_style (size_t(CutConnectorStyle::Prizm)) + , m_connector_shape_id (size_t(CutConnectorShape::Hexagon)) , m_rotation_gizmo(GLGizmoRotate3D(parent, "", -1)) , m_rotation_matrix( Eigen::AngleAxisd(0.0, Vec3d::UnitZ()) * Eigen::AngleAxisd(0.0, Vec3d::UnitY()) @@ -46,7 +49,7 @@ GLGizmoCut3D::GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename, // , _u8L("Claw") }; - m_connector_shapes = { _u8L("Triangle"), _u8L("Square"), _u8L("Circle"), _u8L("Hexagon") + m_connector_shapes = { _u8L("Triangle"), _u8L("Square"), _u8L("Hexagon"), _u8L("Circle") // , _u8L("D-shape") }; @@ -295,17 +298,17 @@ void GLGizmoCut3D::render_rotation_input(int axis) } } -void GLGizmoCut3D::render_connect_type_radio_button(ConnectorType type) +void GLGizmoCut3D::render_connect_type_radio_button(CutConnectorType type) { - ImGui::SameLine(type == ConnectorType::Plug ? m_label_width : 2*m_label_width); + ImGui::SameLine(type == CutConnectorType::Plug ? m_label_width : 2*m_label_width); ImGui::PushItemWidth(m_control_width); if (m_imgui->radio_button(m_connector_types[int(type)], m_connector_type == type)) m_connector_type = type; } -void GLGizmoCut3D::render_connect_mode_radio_button(ConnectorMode mode) +void GLGizmoCut3D::render_connect_mode_radio_button(CutConnectorMode mode) { - ImGui::SameLine(mode == ConnectorMode::Auto ? m_label_width : 2*m_label_width); + ImGui::SameLine(mode == CutConnectorMode::Auto ? m_label_width : 2*m_label_width); ImGui::PushItemWidth(m_control_width); if (m_imgui->radio_button(m_connector_modes[int(mode)], m_connector_mode == mode)) m_connector_mode = mode; @@ -517,8 +520,16 @@ std::string GLGizmoCut3D::on_get_name() const void GLGizmoCut3D::on_set_state() { - if (get_state() == On) + if (get_state() == On) { update_bb(); + + m_selected.clear(); + if (CommonGizmosDataObjects::SelectionInfo* selection = m_c->selection_info()) { + const CutConnectors& connectors = selection->model_object()->cut_connectors; + for (size_t i = 0; i < connectors.size(); ++i) + m_selected.push_back(false); + } + } m_rotation_gizmo.set_center(m_plane_center); m_rotation_gizmo.set_state(m_state); @@ -738,12 +749,12 @@ void GLGizmoCut3D::on_render_input_window(float x, float y, float bottom_limit) m_imgui->text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _L("Connectors")); m_imgui->text(_L("Mode")); - render_connect_mode_radio_button(ConnectorMode::Auto); - render_connect_mode_radio_button(ConnectorMode::Manual); + render_connect_mode_radio_button(CutConnectorMode::Auto); + render_connect_mode_radio_button(CutConnectorMode::Manual); m_imgui->text(_L("Type")); - render_connect_type_radio_button(ConnectorType::Plug); - render_connect_type_radio_button(ConnectorType::Dowel); + render_connect_type_radio_button(CutConnectorType::Plug); + render_connect_type_radio_button(CutConnectorType::Dowel); if (render_combo(_u8L("Style"), m_connector_styles, m_connector_style)) update_connector_shape(); @@ -854,7 +865,7 @@ void GLGizmoCut3D::render_connectors(bool picking) #if ENABLE_GL_SHADERS_ATTRIBUTES const Transform3d view_model_matrix = camera.get_view_matrix() * Geometry::assemble_transform( - Vec3d(connector.pos.x(), connector.pos.y(), connector.pos.z() - 0.5 * connector.height), + Vec3d(connector.pos.x(), connector.pos.y(), connector.pos.z()), m_rotation_gizmo.get_rotation(), Vec3d(connector.radius, connector.radius, connector.height), Vec3d::Ones() @@ -964,6 +975,7 @@ bool GLGizmoCut3D::unproject_on_cut_plane(const Vec2d& mouse_position, std::pair void GLGizmoCut3D::reset_connectors() { m_c->selection_info()->model_object()->cut_connectors.clear(); + update_model_object(); m_selected.clear(); } @@ -972,26 +984,35 @@ void GLGizmoCut3D::update_connector_shape() if (m_connector_shape.is_initialized()) m_connector_shape.reset(); - bool is_prizm = m_connector_style == size_t(Prizm); + bool is_prizm = m_connector_style == size_t(CutConnectorStyle::Prizm); const std::function& its_make_shape = is_prizm ? its_make_cylinder : its_make_cone; - switch (ConnectorShape(m_connector_shape_id)) { - case Triangle: + switch (CutConnectorShape(m_connector_shape_id)) { + case CutConnectorShape::Triangle: m_connector_shape.init_from(its_make_shape(1.0, 1.0, (2 * PI / 3))); break; - case Square: + case CutConnectorShape::Square: m_connector_shape.init_from(its_make_shape(1.0, 1.0, (2 * PI / 4))); break; - case Circle: + case CutConnectorShape::Circle: m_connector_shape.init_from(its_make_shape(1.0, 1.0, 2 * PI / 360)); break; - case Hexagon: + case CutConnectorShape::Hexagon: m_connector_shape.init_from(its_make_shape(1.0, 1.0, (2 * PI / 6))); break; } } +void GLGizmoCut3D::update_model_object() const +{ + 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)); +} + bool GLGizmoCut3D::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down) { if (is_dragging() || action != SLAGizmoEventType::LeftDown) @@ -1019,6 +1040,7 @@ bool GLGizmoCut3D::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_posi Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Add pin")); mo->cut_connectors.emplace_back(hit, -normal, float(m_connector_size * 0.5), float(m_connector_depth_ratio)); + update_model_object(); m_selected.push_back(false); assert(m_selected.size() == mo->cut_connectors.size()); m_parent.set_as_dirty(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index 8394dba60..1fedcd22e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -9,6 +9,9 @@ #include "libslic3r/ObjectID.hpp" namespace Slic3r { + +enum class CutConnectorType : int; + namespace GUI { class Selection; @@ -41,8 +44,8 @@ class GLGizmoCut3D : public GLGizmoBase bool m_hide_cut_plane{ false }; - double m_connector_depth_ratio{ 5.0 }; - double m_connector_size{ 2.0 }; + double m_connector_depth_ratio{ 3.0 }; + double m_connector_size{ 2.5 }; float m_label_width{ 150.0 }; float m_control_width{ 200.0 }; @@ -64,44 +67,25 @@ class GLGizmoCut3D : public GLGizmoBase //,cutModular }; - enum ConnectorMode { + enum CutConnectorMode { Auto , Manual }; - enum ConnectorType { - Plug - , Dowel - }; - - enum ConnectorStyle { - Prizm - , Frustrum - //,Claw - }; - - enum ConnectorShape { - Triangle - , Square - , Circle - , Hexagon - //,D-shape - }; - std::vector m_modes; size_t m_mode{ size_t(cutPlanar) }; std::vector m_connector_modes; - ConnectorMode m_connector_mode{ Auto }; + CutConnectorMode m_connector_mode{ Auto }; std::vector m_connector_types; - ConnectorType m_connector_type{ Plug }; + CutConnectorType m_connector_type; std::vector m_connector_styles; - size_t m_connector_style{ size_t(Prizm) }; + size_t m_connector_style; std::vector m_connector_shapes; - size_t m_connector_shape_id{ size_t(Hexagon) }; + size_t m_connector_shape_id; std::vector m_axis_names; @@ -147,9 +131,9 @@ private: bool render_double_input(const std::string& label, double& value_in); void render_move_center_input(int axis); void render_rotation_input(int axis); - void render_connect_mode_radio_button(ConnectorMode mode); + void render_connect_mode_radio_button(CutConnectorMode mode); bool render_revert_button(const std::string& label); - void render_connect_type_radio_button(ConnectorType type); + void render_connect_type_radio_button(CutConnectorType type); void render_connectors(bool picking); bool can_perform_cut() const; @@ -161,6 +145,7 @@ private: bool update_bb(); void reset_connectors(); void update_connector_shape(); + void update_model_object() const; }; } // namespace GUI diff --git a/src/slic3r/GUI/ObjectDataViewModel.cpp b/src/slic3r/GUI/ObjectDataViewModel.cpp index 496cdcfc7..908307125 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.cpp +++ b/src/slic3r/GUI/ObjectDataViewModel.cpp @@ -48,6 +48,7 @@ const std::map INFO_ITEMS{ // info_item Type info_item Name info_item BitmapName { InfoItemType::CustomSupports, {L("Paint-on supports"), "fdm_supports_" }, }, { InfoItemType::CustomSeam, {L("Paint-on seam"), "seam_" }, }, + { InfoItemType::Cut, {L("Cut connectors"), "cut_" }, }, { InfoItemType::MmuSegmentation, {L("Multimaterial painting"), "mmu_segmentation_"}, }, { InfoItemType::Sinking, {L("Sinking"), "sinking"}, }, { InfoItemType::VariableLayerHeight, {L("Variable layer height"), "layers"}, }, diff --git a/src/slic3r/GUI/ObjectDataViewModel.hpp b/src/slic3r/GUI/ObjectDataViewModel.hpp index f8885b206..8669a8fd0 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.hpp +++ b/src/slic3r/GUI/ObjectDataViewModel.hpp @@ -51,6 +51,7 @@ enum class InfoItemType Undef, CustomSupports, CustomSeam, + Cut, MmuSegmentation, Sinking, VariableLayerHeight