diff --git a/src/libslic3r/SLAPrintSteps.cpp b/src/libslic3r/SLAPrintSteps.cpp index f16aa7cfa..e0c92a71c 100644 --- a/src/libslic3r/SLAPrintSteps.cpp +++ b/src/libslic3r/SLAPrintSteps.cpp @@ -225,8 +225,7 @@ void SLAPrint::Steps::slice_model(SLAPrintObject &po) if(po.m_config.supports_enable.getBool() || po.m_config.pad_enable.getBool()) { - po.m_supportdata.reset( - new SLAPrintObject::SupportData(po.transformed_mesh()) ); + po.m_supportdata.reset(new SLAPrintObject::SupportData(mesh)); } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index cb18bdb16..7dce249f2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -135,7 +135,7 @@ void GLGizmoBase::Grabber::render_face(float half_size) const } -GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) +GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id, CommonGizmosData* common_data_ptr) : m_parent(parent) , m_group_id(-1) , m_state(Off) @@ -146,6 +146,7 @@ GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, u , m_dragging(false) , m_imgui(wxGetApp().imgui()) , m_first_input_window_render(true) + , m_c(common_data_ptr) { ::memcpy((void*)m_base_color, (const void*)DEFAULT_BASE_COLOR, 4 * sizeof(float)); ::memcpy((void*)m_drag_color, (const void*)DEFAULT_DRAG_COLOR, 4 * sizeof(float)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index da3042779..9479174fb 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -30,7 +30,7 @@ static const float CONSTRAINED_COLOR[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; class ImGuiWrapper; - +class CommonGizmosData; class GLGizmoBase { @@ -99,9 +99,13 @@ protected: mutable std::vector m_grabbers; ImGuiWrapper* m_imgui; bool m_first_input_window_render; + CommonGizmosData* m_c = nullptr; public: - GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); + GLGizmoBase(GLCanvas3D& parent, + const std::string& icon_filename, + unsigned int sprite_id, + CommonGizmosData* common_data = nullptr); virtual ~GLGizmoBase() {} bool init() { return on_init(); } @@ -179,6 +183,34 @@ protected: // were not interpolated by alpha blending or multi sampling. extern unsigned char picking_checksum_alpha_channel(unsigned char red, unsigned char green, unsigned char blue); +class MeshRaycaster; +class MeshClipper; + +class CommonGizmosData { +public: + const TriangleMesh* mesh() const { + return (! m_mesh ? nullptr : (m_cavity_mesh ? m_cavity_mesh.get() : m_mesh)); + } + + + + ModelObject* m_model_object = nullptr; + const TriangleMesh* m_mesh; + std::unique_ptr m_mesh_raycaster; + std::unique_ptr m_object_clipper; + std::unique_ptr m_supports_clipper; + + std::unique_ptr m_cavity_mesh; + std::unique_ptr m_volume_with_cavity; + + int m_active_instance = -1; + float m_active_instance_bb_radius = 0; + ObjectID m_model_object_id = 0; + int m_print_object_idx = -1; + int m_print_objects_count = -1; + int m_old_timestamp = -1; +}; + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index cad0243f0..75a21057a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -18,8 +18,8 @@ namespace Slic3r { namespace GUI { -GLGizmoHollow::GLGizmoHollow(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) - : GLGizmoBase(parent, icon_filename, sprite_id) +GLGizmoHollow::GLGizmoHollow(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id, CommonGizmosData* cd) + : GLGizmoBase(parent, icon_filename, sprite_id, cd) , m_quadric(nullptr) { m_clipping_plane.reset(new ClippingPlane(Vec3d::Zero(), 0.)); @@ -58,23 +58,23 @@ bool GLGizmoHollow::on_init() void GLGizmoHollow::set_sla_support_data(ModelObject* model_object, const Selection& selection) { if (! model_object || selection.is_empty()) { - m_model_object = nullptr; + m_c->m_model_object = nullptr; return; } - if (m_model_object != model_object || m_model_object_id != model_object->id()) { - m_model_object = model_object; - m_print_object_idx = -1; + if (m_c->m_model_object != model_object || m_c->m_model_object_id != model_object->id()) { + m_c->m_model_object = model_object; + m_c->m_print_object_idx = -1; } - m_active_instance = selection.get_instance_idx(); + m_c->m_active_instance = selection.get_instance_idx(); if (model_object && selection.is_from_single_instance()) { // Cache the bb - it's needed for dealing with the clipping plane quite often // It could be done inside update_mesh but one has to account for scaling of the instance. //FIXME calling ModelObject::instance_bounding_box() is expensive! - m_active_instance_bb_radius = m_model_object->instance_bounding_box(m_active_instance).radius(); + m_c->m_active_instance_bb_radius = m_c->m_model_object->instance_bounding_box(m_c->m_active_instance).radius(); if (is_mesh_update_necessary()) { update_mesh(); @@ -83,7 +83,7 @@ void GLGizmoHollow::set_sla_support_data(ModelObject* model_object, const Select if (m_state == On) { m_parent.toggle_model_objects_visibility(false); - m_parent.toggle_model_objects_visibility(true, m_model_object, m_active_instance); + m_parent.toggle_model_objects_visibility(true, m_c->m_model_object, m_c->m_active_instance); } else m_parent.toggle_model_objects_visibility(true, nullptr, -1); @@ -96,26 +96,37 @@ void GLGizmoHollow::on_render() const { const Selection& selection = m_parent.get_selection(); - // If current m_model_object does not match selection, ask GLCanvas3D to turn us off + // If current m_c->m_model_object does not match selection, ask GLCanvas3D to turn us off if (m_state == On - && (m_model_object != selection.get_model()->objects[selection.get_object_idx()] - || m_active_instance != selection.get_instance_idx() - || m_model_object_id != m_model_object->id())) { + && (m_c->m_model_object != selection.get_model()->objects[selection.get_object_idx()] + || m_c->m_active_instance != selection.get_instance_idx() + || m_c->m_model_object_id != m_c->m_model_object->id())) { m_parent.post_event(SimpleEvent(EVT_GLCANVAS_RESETGIZMOS)); return; } - if (! m_mesh) + if (! m_c->m_mesh) const_cast(this)->update_mesh(); glsafe(::glEnable(GL_BLEND)); glsafe(::glEnable(GL_DEPTH_TEST)); - if (m_volume_with_cavity) { + if (m_c->m_volume_with_cavity) { + m_c->m_volume_with_cavity->set_sla_shift_z(m_z_shift); m_parent.get_shader().start_using(); - m_volume_with_cavity->render(); + + GLint current_program_id; + glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); + GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; + GLint print_box_detection_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.volume_detection") : -1; + GLint print_box_worldmatrix_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.volume_world_matrix") : -1; + glcheck(); + m_c->m_volume_with_cavity->set_render_color(); + m_c->m_volume_with_cavity->render(color_id, print_box_detection_id, print_box_worldmatrix_id); m_parent.get_shader().stop_using(); } + // Show/hide the original object + m_parent.toggle_model_objects_visibility(! m_c->m_cavity_mesh, m_c->m_model_object, m_c->m_active_instance); m_z_shift = selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z(); @@ -132,7 +143,7 @@ void GLGizmoHollow::on_render() const void GLGizmoHollow::render_clipping_plane(const Selection& selection) const { - if (m_clipping_plane_distance == 0.f || mesh()->empty()) + if (m_clipping_plane_distance == 0.f || m_c->mesh()->empty()) return; // Get transformation of the instance @@ -150,65 +161,65 @@ void GLGizmoHollow::render_clipping_plane(const Selection& selection) const 1.)); // Now initialize the TMS for the object, perform the cut and save the result. - if (! m_object_clipper) { - m_object_clipper.reset(new MeshClipper); - m_object_clipper->set_mesh(*mesh()); + if (! m_c->m_object_clipper) { + m_c->m_object_clipper.reset(new MeshClipper); + m_c->m_object_clipper->set_mesh(*m_c->mesh()); } - m_object_clipper->set_plane(*m_clipping_plane); - m_object_clipper->set_transformation(trafo); + m_c->m_object_clipper->set_plane(*m_clipping_plane); + m_c->m_object_clipper->set_transformation(trafo); // Next, ask the backend if supports are already calculated. If so, we are gonna cut them too. // First we need a pointer to the respective SLAPrintObject. The index into objects vector is // cached so we don't have todo it on each render. We only search for the po if needed: - if (m_print_object_idx < 0 || (int)m_parent.sla_print()->objects().size() != m_print_objects_count) { - m_print_objects_count = m_parent.sla_print()->objects().size(); - m_print_object_idx = -1; + if (m_c->m_print_object_idx < 0 || (int)m_parent.sla_print()->objects().size() != m_c->m_print_objects_count) { + m_c->m_print_objects_count = m_parent.sla_print()->objects().size(); + m_c->m_print_object_idx = -1; for (const SLAPrintObject* po : m_parent.sla_print()->objects()) { - ++m_print_object_idx; - if (po->model_object()->id() == m_model_object->id()) + ++m_c->m_print_object_idx; + if (po->model_object()->id() == m_c->m_model_object->id()) break; } } - if (m_print_object_idx >= 0) { - const SLAPrintObject* print_object = m_parent.sla_print()->objects()[m_print_object_idx]; + if (m_c->m_print_object_idx >= 0) { + const SLAPrintObject* print_object = m_parent.sla_print()->objects()[m_c->m_print_object_idx]; if (print_object->is_step_done(slaposSupportTree) && !print_object->get_mesh(slaposSupportTree).empty()) { // If the supports are already calculated, save the timestamp of the respective step // so we can later tell they were recalculated. size_t timestamp = print_object->step_state_with_timestamp(slaposSupportTree).timestamp; - if (! m_supports_clipper || (int)timestamp != m_old_timestamp) { + if (! m_c->m_supports_clipper || (int)timestamp != m_c->m_old_timestamp) { // The timestamp has changed. - m_supports_clipper.reset(new MeshClipper); + m_c->m_supports_clipper.reset(new MeshClipper); // The mesh should already have the shared vertices calculated. - m_supports_clipper->set_mesh(print_object->support_mesh()); - m_old_timestamp = timestamp; + m_c->m_supports_clipper->set_mesh(print_object->support_mesh()); + m_c->m_old_timestamp = timestamp; } - m_supports_clipper->set_plane(*m_clipping_plane); - m_supports_clipper->set_transformation(supports_trafo); + m_c->m_supports_clipper->set_plane(*m_clipping_plane); + m_c->m_supports_clipper->set_transformation(supports_trafo); } else // The supports are not valid. We better dump the cached data. - m_supports_clipper.reset(); + m_c->m_supports_clipper.reset(); } // At this point we have the triangulated cuts for both the object and supports - let's render. - if (! m_object_clipper->get_triangles().empty()) { + if (! m_c->m_object_clipper->get_triangles().empty()) { ::glPushMatrix(); ::glColor3f(1.0f, 0.37f, 0.0f); ::glBegin(GL_TRIANGLES); - for (const Vec3f& point : m_object_clipper->get_triangles()) + for (const Vec3f& point : m_c->m_object_clipper->get_triangles()) ::glVertex3f(point(0), point(1), point(2)); ::glEnd(); ::glPopMatrix(); } - if (m_show_supports && m_supports_clipper && ! m_supports_clipper->get_triangles().empty()) { + if (m_show_supports && m_c->m_supports_clipper && ! m_c->m_supports_clipper->get_triangles().empty()) { ::glPushMatrix(); ::glColor3f(1.0f, 0.f, 0.37f); ::glBegin(GL_TRIANGLES); - for (const Vec3f& point : m_supports_clipper->get_triangles()) + for (const Vec3f& point : m_c->m_supports_clipper->get_triangles()) ::glVertex3f(point(0), point(1), point(2)); ::glEnd(); ::glPopMatrix(); @@ -241,10 +252,10 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons glsafe(::glMultMatrixd(instance_matrix.data())); float render_color[4]; - size_t cache_size = m_model_object->sla_drain_holes.size(); + size_t cache_size = m_c->m_model_object->sla_drain_holes.size(); for (size_t i = 0; i < cache_size; ++i) { - const sla::DrainHole& drain_hole = m_model_object->sla_drain_holes[i]; + const sla::DrainHole& drain_hole = m_c->m_model_object->sla_drain_holes[i]; const bool& point_selected = m_selected[i]; if (is_mesh_point_clipped((drain_hole.pos+HoleStickOutLength*drain_hole.normal).cast())) @@ -324,7 +335,7 @@ bool GLGizmoHollow::is_mesh_point_clipped(const Vec3d& point) const if (m_clipping_plane_distance == 0.f) return false; - Vec3d transformed_point = m_model_object->instances[m_active_instance]->get_transformation().get_matrix() * point; + Vec3d transformed_point = m_c->m_model_object->instances[m_c->m_active_instance]->get_transformation().get_matrix() * point; transformed_point(2) += m_z_shift; return m_clipping_plane->is_point_clipped(transformed_point); } @@ -333,34 +344,34 @@ bool GLGizmoHollow::is_mesh_point_clipped(const Vec3d& point) const bool GLGizmoHollow::is_mesh_update_necessary() const { - return ((m_state == On) && (m_model_object != nullptr) && !m_model_object->instances.empty()) - && ((m_model_object->id() != m_model_object_id) || ! m_mesh); + return ((m_state == On) && (m_c->m_model_object != nullptr) && !m_c->m_model_object->instances.empty()) + && ((m_c->m_model_object->id() != m_c->m_model_object_id) || ! m_c->m_mesh); } void GLGizmoHollow::update_mesh() { - if (! m_model_object) + if (! m_c->m_model_object) return; wxBusyCursor wait; // this way we can use that mesh directly. // This mesh does not account for the possible Z up SLA offset. - m_mesh = &m_model_object->volumes.front()->mesh(); + m_c->m_mesh = &m_c->m_model_object->volumes.front()->mesh(); // If this is different mesh than last time - if (m_model_object_id != m_model_object->id()) { - m_cavity_mesh.reset(); // dump the cavity - m_volume_with_cavity.reset(); - m_parent.toggle_model_objects_visibility(true, m_model_object, m_active_instance); - m_mesh_raycaster.reset(); + if (m_c->m_model_object_id != m_c->m_model_object->id()) { + m_c->m_cavity_mesh.reset(); // dump the cavity + m_c->m_volume_with_cavity.reset(); + m_parent.toggle_model_objects_visibility(true, m_c->m_model_object, m_c->m_active_instance); + m_c->m_mesh_raycaster.reset(); } - if (! m_mesh_raycaster) - m_mesh_raycaster.reset(new MeshRaycaster(*m_mesh)); + if (! m_c->m_mesh_raycaster) + m_c->m_mesh_raycaster.reset(new MeshRaycaster(*m_c->mesh())); - m_model_object_id = m_model_object->id(); + m_c->m_model_object_id = m_c->m_model_object->id(); } @@ -370,7 +381,7 @@ void GLGizmoHollow::update_mesh() bool GLGizmoHollow::unproject_on_mesh(const Vec2d& mouse_pos, std::pair& pos_and_normal) { // if the gizmo doesn't have the V, F structures for igl, calculate them first: - if (! m_mesh_raycaster) + if (! m_c->m_mesh_raycaster) update_mesh(); const Camera& camera = m_parent.get_camera(); @@ -382,7 +393,7 @@ bool GLGizmoHollow::unproject_on_mesh(const Vec2d& mouse_pos, std::pairunproject_on_mesh(mouse_pos, trafo.get_matrix(), camera, hit, normal, m_clipping_plane.get())) { + if (m_c->m_mesh_raycaster->unproject_on_mesh(mouse_pos, trafo.get_matrix(), camera, hit, normal, m_clipping_plane.get())) { // Return both the point and the facet normal. pos_and_normal = std::make_pair(hit, normal); return true; @@ -427,10 +438,10 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos std::pair pos_and_normal; if (unproject_on_mesh(mouse_position, pos_and_normal)) { // we got an intersection Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Add drainage hole"))); - m_model_object->sla_drain_holes.emplace_back(pos_and_normal.first + HoleStickOutLength * pos_and_normal.second, + m_c->m_model_object->sla_drain_holes.emplace_back(pos_and_normal.first + HoleStickOutLength * pos_and_normal.second, -pos_and_normal.second, m_new_hole_radius, m_new_hole_height+HoleStickOutLength); m_selected.push_back(false); - assert(m_selected.size() == m_model_object->sla_drain_holes.size()); + assert(m_selected.size() == m_c->m_model_object->sla_drain_holes.size()); m_parent.set_as_dirty(); m_wait_for_up_event = true; } @@ -449,11 +460,11 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos GLSelectionRectangle::EState rectangle_status = m_selection_rectangle.get_state(); // First collect positions of all the points in world coordinates. - Geometry::Transformation trafo = m_model_object->instances[m_active_instance]->get_transformation(); + Geometry::Transformation trafo = m_c->m_model_object->instances[m_c->m_active_instance]->get_transformation(); trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_z_shift)); std::vector points; - for (unsigned int i=0; isla_drain_holes.size(); ++i) - points.push_back(trafo.get_matrix() * m_model_object->sla_drain_holes[i].pos.cast()); + for (unsigned int i=0; im_model_object->sla_drain_holes.size(); ++i) + points.push_back(trafo.get_matrix() * m_c->m_model_object->sla_drain_holes[i].pos.cast()); // Now ask the rectangle which of the points are inside. std::vector points_inside; @@ -462,7 +473,7 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos points_inside.push_back(points[idx].cast()); // Only select/deselect points that are actually visible - for (size_t idx : m_mesh_raycaster->get_unobscured_idxs(trafo, m_parent.get_camera(), points_inside, m_clipping_plane.get())) + for (size_t idx : m_c->m_mesh_raycaster->get_unobscured_idxs(trafo, m_parent.get_camera(), points_inside, m_clipping_plane.get())) { if (rectangle_status == GLSelectionRectangle::Deselect) unselect_point(points_idxs[idx]); @@ -539,10 +550,10 @@ void GLGizmoHollow::delete_selected_points() { Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Delete drainage hole"))); - for (unsigned int idx=0; idxsla_drain_holes.size(); ++idx) { + for (unsigned int idx=0; idxm_model_object->sla_drain_holes.size(); ++idx) { if (m_selected[idx]) { m_selected.erase(m_selected.begin()+idx); - m_model_object->sla_drain_holes.erase(m_model_object->sla_drain_holes.begin() + (idx--)); + m_c->m_model_object->sla_drain_holes.erase(m_c->m_model_object->sla_drain_holes.begin() + (idx--)); } } @@ -555,8 +566,8 @@ void GLGizmoHollow::on_update(const UpdateData& data) std::pair pos_and_normal; if (! unproject_on_mesh(data.mouse_pos.cast(), pos_and_normal)) return; - m_model_object->sla_drain_holes[m_hover_id].pos = pos_and_normal.first + HoleStickOutLength * pos_and_normal.second; - m_model_object->sla_drain_holes[m_hover_id].normal = -pos_and_normal.second; + m_c->m_model_object->sla_drain_holes[m_hover_id].pos = pos_and_normal.first + HoleStickOutLength * pos_and_normal.second; + m_c->m_model_object->sla_drain_holes[m_hover_id].normal = -pos_and_normal.second; } } @@ -568,14 +579,14 @@ std::pair GLGizmoHollow::get_hollowi double offset = static_cast(opts[0])->value; double quality = static_cast(opts[1])->value; double closing_d = static_cast(opts[2])->value; - return std::make_pair(m_mesh, sla::HollowingConfig{offset, quality, closing_d}); + return std::make_pair(m_c->m_mesh, sla::HollowingConfig{offset, quality, closing_d}); } void GLGizmoHollow::update_mesh_raycaster(std::unique_ptr &&rc) { - m_mesh_raycaster = std::move(rc); - m_object_clipper.reset(); - m_volume_with_cavity.reset(); + m_c->m_mesh_raycaster = std::move(rc); + m_c->m_object_clipper.reset(); + m_c->m_volume_with_cavity.reset(); } void GLGizmoHollow::hollow_mesh() @@ -588,13 +599,13 @@ void GLGizmoHollow::hollow_mesh() void GLGizmoHollow::update_hollowed_mesh(std::unique_ptr &&mesh) { // Called from Plater when the UI job finishes - m_cavity_mesh = std::move(mesh); + m_c->m_cavity_mesh = std::move(mesh); - if(m_cavity_mesh) { + if(m_c->m_cavity_mesh) { // First subtract the holes: - if (! m_model_object->sla_drain_holes.empty()) { + if (! m_c->m_model_object->sla_drain_holes.empty()) { TriangleMesh holes_mesh; - for (const sla::DrainHole& hole : m_model_object->sla_drain_holes) { + for (const sla::DrainHole& hole : m_c->m_model_object->sla_drain_holes) { TriangleMesh hole_mesh = make_cylinder(hole.radius, hole.height, 2*M_PI/8); Eigen::Quaternionf q; Transform3f m = Transform3f::Identity(); @@ -602,22 +613,22 @@ void GLGizmoHollow::update_hollowed_mesh(std::unique_ptr &&mesh) hole_mesh.transform(m.cast()); hole_mesh.translate(hole.pos); holes_mesh.merge(hole_mesh); - //MeshBoolean::minus(*m_cavity_mesh.get(), hole_mesh); + holes_mesh.repair(); } - MeshBoolean::minus(*m_cavity_mesh.get(), holes_mesh); + MeshBoolean::minus(*m_c->m_cavity_mesh.get(), holes_mesh); } - // create a new GLVolume that only has the cavity inside - Geometry::Transformation volume_trafo = m_model_object->volumes.front()->get_transformation(); + Geometry::Transformation volume_trafo = m_c->m_model_object->volumes.front()->get_transformation(); volume_trafo.set_offset(volume_trafo.get_offset() + Vec3d(0., 0., m_z_shift)); - m_volume_with_cavity.reset(new GLVolume(1.f, 0.f, 0.f, 0.5f)); - m_volume_with_cavity->indexed_vertex_array.load_mesh(*m_cavity_mesh.get()); - m_volume_with_cavity->finalize_geometry(true); - m_volume_with_cavity->set_volume_transformation(volume_trafo); - m_volume_with_cavity->set_instance_transformation(m_model_object->instances[size_t(m_active_instance)]->get_transformation()); + m_c->m_volume_with_cavity.reset(new GLVolume(GLVolume::MODEL_COLOR[2])); + m_c->m_volume_with_cavity->indexed_vertex_array.load_mesh(*m_c->m_cavity_mesh.get()); + m_c->m_volume_with_cavity->finalize_geometry(true); + m_c->m_volume_with_cavity->set_volume_transformation(volume_trafo); + m_c->m_volume_with_cavity->set_instance_transformation(m_c->m_model_object->instances[size_t(m_c->m_active_instance)]->get_transformation()); + m_c->m_volume_with_cavity->force_transparent = false; } - m_parent.toggle_model_objects_visibility(! m_cavity_mesh, m_model_object, m_active_instance); + if (m_clipping_plane_distance == 0.f) { m_clipping_plane_distance = 0.5f; update_clipping_plane(); @@ -628,10 +639,10 @@ std::vector GLGizmoHollow::get_config_options(const std::ve { std::vector out; - if (!m_model_object) + if (!m_c->m_model_object) return out; - const DynamicPrintConfig& object_cfg = m_model_object->config; + const DynamicPrintConfig& object_cfg = m_c->m_model_object->config; const DynamicPrintConfig& print_cfg = wxGetApp().preset_bundle->sla_prints.get_edited_preset().config; std::unique_ptr default_cfg = nullptr; @@ -654,7 +665,7 @@ std::vector GLGizmoHollow::get_config_options(const std::ve ClippingPlane GLGizmoHollow::get_sla_clipping_plane() const { - if (!m_model_object || m_state == Off || m_clipping_plane_distance == 0.f) + if (!m_c->m_model_object || m_state == Off || m_clipping_plane_distance == 0.f) return ClippingPlane::ClipsNothing(); else return ClippingPlane(-m_clipping_plane->get_normal(), m_clipping_plane->get_data()[3]); @@ -663,7 +674,7 @@ ClippingPlane GLGizmoHollow::get_sla_clipping_plane() const void GLGizmoHollow::on_render_input_window(float x, float y, float bottom_limit) { - if (! m_model_object) + if (! m_c->m_model_object) return; bool first_run = true; // This is a hack to redraw the button when all points are removed, @@ -672,7 +683,7 @@ RENDER_AGAIN: const float approx_height = m_imgui->scaled(20.0f); y = std::min(y, bottom_limit - approx_height); m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); - m_imgui->set_next_window_bg_alpha(0.5f); + m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: @@ -694,7 +705,7 @@ RENDER_AGAIN: std::vector opts = get_config_options({"hollowing_enable"}); m_enable_hollowing = static_cast(opts[0])->value; if (m_imgui->checkbox(m_desc["enable"], m_enable_hollowing)) { - m_model_object->config.opt("hollowing_enable", true)->value = m_enable_hollowing; + m_c->m_model_object->config.opt("hollowing_enable", true)->value = m_enable_hollowing; wxGetApp().obj_list()->update_and_show_object_settings_item(); } } @@ -738,14 +749,14 @@ RENDER_AGAIN: } if (slider_edited || slider_released) { if (slider_released) { - m_model_object->config.opt("hollowing_min_thickness", true)->value = m_offset_stash; - m_model_object->config.opt("hollowing_quality", true)->value = m_quality_stash; - m_model_object->config.opt("hollowing_closing_distance", true)->value = m_closing_d_stash; + m_c->m_model_object->config.opt("hollowing_min_thickness", true)->value = m_offset_stash; + m_c->m_model_object->config.opt("hollowing_quality", true)->value = m_quality_stash; + m_c->m_model_object->config.opt("hollowing_closing_distance", true)->value = m_closing_d_stash; Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Hollowing parameter change"))); } - m_model_object->config.opt("hollowing_min_thickness", true)->value = offset; - m_model_object->config.opt("hollowing_quality", true)->value = quality; - m_model_object->config.opt("hollowing_closing_distance", true)->value = closing_d; + m_c->m_model_object->config.opt("hollowing_min_thickness", true)->value = offset; + m_c->m_model_object->config.opt("hollowing_quality", true)->value = quality; + m_c->m_model_object->config.opt("hollowing_closing_distance", true)->value = closing_d; if (slider_released) wxGetApp().obj_list()->update_and_show_object_settings_item(); } @@ -756,7 +767,8 @@ RENDER_AGAIN: bool remove_selected = false; bool remove_all = false; - m_imgui->text(" "); // vertical gap + // m_imgui->text(" "); // vertical gap + ImGui::Separator(); float diameter_upper_cap = 20.f; //static_cast(wxGetApp().preset_bundle->sla_prints.get_edited_preset().config.option("support_pillar_diameter"))->value; if (m_new_hole_radius > diameter_upper_cap) @@ -786,19 +798,19 @@ RENDER_AGAIN: // - take correct undo/redo snapshot after the user is done with moving the slider if (! m_selection_empty) { if (clicked) { - m_holes_stash = m_model_object->sla_drain_holes; + m_holes_stash = m_c->m_model_object->sla_drain_holes; } if (edited) { for (size_t idx=0; idxsla_drain_holes[idx].radius = m_new_hole_radius; - m_model_object->sla_drain_holes[idx].height = m_new_hole_height; + m_c->m_model_object->sla_drain_holes[idx].radius = m_new_hole_radius; + m_c->m_model_object->sla_drain_holes[idx].height = m_new_hole_height; } } if (deactivated) { // momentarily restore the old value to take snapshot - sla::DrainHoles new_holes = m_model_object->sla_drain_holes; - m_model_object->sla_drain_holes = m_holes_stash; + sla::DrainHoles new_holes = m_c->m_model_object->sla_drain_holes; + m_c->m_model_object->sla_drain_holes = m_holes_stash; float backup_rad = m_new_hole_radius; float backup_hei = m_new_hole_height; for (size_t i=0; isla_drain_holes = new_holes; + m_c->m_model_object->sla_drain_holes = new_holes; } } @@ -819,12 +831,13 @@ RENDER_AGAIN: remove_selected = m_imgui->button(m_desc.at("remove_selected")); m_imgui->disabled_end(); - m_imgui->disabled_begin(m_model_object->sla_drain_holes.empty()); + m_imgui->disabled_begin(m_c->m_model_object->sla_drain_holes.empty()); remove_all = m_imgui->button(m_desc.at("remove_all")); m_imgui->disabled_end(); // Following is rendered in both editing and non-editing mode: - m_imgui->text(""); + // m_imgui->text(""); + ImGui::Separator(); if (m_clipping_plane_distance == 0.f) m_imgui->text(m_desc.at("clipping_of_view")); else { @@ -842,7 +855,7 @@ RENDER_AGAIN: // make sure supports are shown/hidden as appropriate m_imgui->checkbox(m_desc["show_supports"], m_show_supports); - force_refresh = m_parent.toggle_sla_auxiliaries_visibility(m_show_supports, m_model_object, m_active_instance); + force_refresh = m_parent.toggle_sla_auxiliaries_visibility(m_show_supports, m_c->m_model_object, m_c->m_active_instance); m_imgui->end(); @@ -896,19 +909,19 @@ std::string GLGizmoHollow::on_get_name() const } -const TriangleMesh* GLGizmoHollow::mesh() const { - return (! m_mesh ? nullptr : (m_cavity_mesh ? m_cavity_mesh.get() : m_mesh)); -} +//const TriangleMesh* GLGizmoHollow::mesh() const { +// return (! m_c->m_mesh ? nullptr : (m_c->m_cavity_mesh ? m_c->m_cavity_mesh.get() : m_c->m_mesh)); +//} void GLGizmoHollow::on_set_state() { - // m_model_object pointer can be invalid (for instance because of undo/redo action), + // m_c->m_model_object pointer can be invalid (for instance because of undo/redo action), // we should recover it from the object id - m_model_object = nullptr; + m_c->m_model_object = nullptr; for (const auto mo : wxGetApp().model().objects) { - if (mo->id() == m_model_object_id) { - m_model_object = mo; + if (mo->id() == m_c->m_model_object_id) { + m_c->m_model_object = mo; break; } } @@ -922,12 +935,12 @@ void GLGizmoHollow::on_set_state() update_mesh(); // we'll now reload support points: - if (m_model_object) + if (m_c->m_model_object) reload_cache(); m_parent.toggle_model_objects_visibility(false); - if (m_model_object) - m_parent.toggle_model_objects_visibility(true, m_model_object, m_active_instance); + if (m_c->m_model_object) + m_parent.toggle_model_objects_visibility(true, m_c->m_model_object, m_c->m_active_instance); // Set default head diameter from config. const DynamicPrintConfig& cfg = wxGetApp().preset_bundle->sla_prints.get_edited_preset().config; @@ -938,11 +951,11 @@ void GLGizmoHollow::on_set_state() m_parent.toggle_model_objects_visibility(true); m_clipping_plane_distance = 0.f; // Release clippers and the AABB raycaster. - m_object_clipper.reset(); - m_supports_clipper.reset(); - m_mesh_raycaster.reset(); - m_cavity_mesh.reset(); - m_volume_with_cavity.reset(); + m_c->m_object_clipper.reset(); + m_c->m_supports_clipper.reset(); + //m_c->m_mesh_raycaster.reset(); + //m_c->m_cavity_mesh.reset(); + //m_c->m_volume_with_cavity.reset(); } m_old_state = m_state; } @@ -954,7 +967,7 @@ void GLGizmoHollow::on_start_dragging() if (m_hover_id != -1) { select_point(NoPoints); select_point(m_hover_id); - m_hole_before_drag = m_model_object->sla_drain_holes[m_hover_id].pos; + m_hole_before_drag = m_c->m_model_object->sla_drain_holes[m_hover_id].pos; } else m_hole_before_drag = Vec3f::Zero(); @@ -964,14 +977,14 @@ void GLGizmoHollow::on_start_dragging() void GLGizmoHollow::on_stop_dragging() { if (m_hover_id != -1) { - Vec3f backup = m_model_object->sla_drain_holes[m_hover_id].pos; + Vec3f backup = m_c->m_model_object->sla_drain_holes[m_hover_id].pos; if (m_hole_before_drag != Vec3f::Zero() // some point was touched && backup != m_hole_before_drag) // and it was moved, not just selected { - m_model_object->sla_drain_holes[m_hover_id].pos = m_hole_before_drag; + m_c->m_model_object->sla_drain_holes[m_hover_id].pos = m_hole_before_drag; Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Move drainage hole"))); - m_model_object->sla_drain_holes[m_hover_id].pos = backup; + m_c->m_model_object->sla_drain_holes[m_hover_id].pos = backup; } } m_hole_before_drag = Vec3f::Zero(); @@ -983,7 +996,7 @@ void GLGizmoHollow::on_load(cereal::BinaryInputArchive& ar) { ar(m_clipping_plane_distance, *m_clipping_plane, - m_model_object_id, + m_c->m_model_object_id, m_new_hole_radius, m_new_hole_height, m_selected, @@ -997,7 +1010,7 @@ void GLGizmoHollow::on_save(cereal::BinaryOutputArchive& ar) const { ar(m_clipping_plane_distance, *m_clipping_plane, - m_model_object_id, + m_c->m_model_object_id, m_new_hole_radius, m_new_hole_height, m_selected, @@ -1014,8 +1027,8 @@ void GLGizmoHollow::select_point(int i) m_selection_empty = (i == NoPoints); if (i == AllPoints) { - m_new_hole_radius = m_model_object->sla_drain_holes[0].radius; - m_new_hole_height = m_model_object->sla_drain_holes[0].height; + m_new_hole_radius = m_c->m_model_object->sla_drain_holes[0].radius; + m_new_hole_height = m_c->m_model_object->sla_drain_holes[0].height; } } else { @@ -1023,8 +1036,8 @@ void GLGizmoHollow::select_point(int i) m_selected.push_back(false); m_selected[i] = true; m_selection_empty = false; - m_new_hole_radius = m_model_object->sla_drain_holes[i].radius; - m_new_hole_height = m_model_object->sla_drain_holes[i].height; + m_new_hole_radius = m_c->m_model_object->sla_drain_holes[i].radius; + m_new_hole_height = m_c->m_model_object->sla_drain_holes[i].height; } } @@ -1044,7 +1057,7 @@ void GLGizmoHollow::unselect_point(int i) void GLGizmoHollow::reload_cache() { m_selected.clear(); - m_selected.assign(m_model_object->sla_drain_holes.size(), false); + m_selected.assign(m_c->m_model_object->sla_drain_holes.size(), false); } void GLGizmoHollow::update_clipping_plane(bool keep_normal) const @@ -1052,9 +1065,9 @@ void GLGizmoHollow::update_clipping_plane(bool keep_normal) const Vec3d normal = (keep_normal && m_clipping_plane->get_normal() != Vec3d::Zero() ? m_clipping_plane->get_normal() : -m_parent.get_camera().get_dir_forward()); - const Vec3d& center = m_model_object->instances[m_active_instance]->get_offset() + Vec3d(0., 0., m_z_shift); + const Vec3d& center = m_c->m_model_object->instances[m_c->m_active_instance]->get_offset() + Vec3d(0., 0., m_z_shift); float dist = normal.dot(center); - *m_clipping_plane = ClippingPlane(normal, (dist - (-m_active_instance_bb_radius) - m_clipping_plane_distance * 2*m_active_instance_bb_radius)); + *m_clipping_plane = ClippingPlane(normal, (dist - (-m_c->m_active_instance_bb_radius) - m_clipping_plane_distance * 2*m_c->m_active_instance_bb_radius)); m_parent.set_as_dirty(); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp index 8e022eb1e..bea396097 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.hpp @@ -21,10 +21,10 @@ enum class SLAGizmoEventType : unsigned char; class GLGizmoHollow : public GLGizmoBase { private: - ModelObject* m_model_object = nullptr; - ObjectID m_model_object_id = 0; - int m_active_instance = -1; - float m_active_instance_bb_radius; // to cache the bb + //ModelObject* m_model_object = nullptr; + //ObjectID m_model_object_id = 0; + //int m_active_instance = -1; + //float m_active_instance_bb_radius; // to cache the bb mutable double m_z_shift = 0.; bool unproject_on_mesh(const Vec2d& mouse_pos, std::pair& pos_and_normal); @@ -32,19 +32,16 @@ private: GLUquadricObj* m_quadric; - std::unique_ptr m_mesh_raycaster; - std::unique_ptr m_cavity_mesh; - std::unique_ptr m_volume_with_cavity; - const TriangleMesh* m_mesh; - mutable const TriangleMesh* m_supports_mesh; - mutable std::vector m_triangles; - mutable std::vector m_supports_triangles; - mutable int m_old_timestamp = -1; - mutable int m_print_object_idx = -1; - mutable int m_print_objects_count = -1; + //std::unique_ptr m_mesh_raycaster; + //std::unique_ptr m_cavity_mesh; + //std::unique_ptr m_volume_with_cavity; + //const TriangleMesh* m_mesh; + //mutable int m_old_timestamp = -1; + //mutable int m_print_object_idx = -1; + //mutable int m_print_objects_count = -1; public: - GLGizmoHollow(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); + GLGizmoHollow(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id, CommonGizmosData* cd); ~GLGizmoHollow() override; void set_sla_support_data(ModelObject* model_object, const Selection& selection); bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down); @@ -70,7 +67,6 @@ private: void update_mesh(); void hollow_mesh(); bool unsaved_changes() const; - const TriangleMesh* mesh() const; bool m_show_supports = true; float m_new_hole_radius; // Size of a new hole. @@ -104,8 +100,8 @@ private: bool m_selection_empty = true; EState m_old_state = Off; // to be able to see that the gizmo has just been closed (see on_set_state) - mutable std::unique_ptr m_object_clipper; - mutable std::unique_ptr m_supports_clipper; + //mutable std::unique_ptr m_object_clipper; + //mutable std::unique_ptr m_supports_clipper; std::vector get_config_options(const std::vector& keys) const; bool is_mesh_point_clipped(const Vec3d& point) const; @@ -126,7 +122,7 @@ protected: void on_set_hover_id() override { - if (int(m_model_object->sla_drain_holes.size()) <= m_hover_id) + if (int(m_c->m_model_object->sla_drain_holes.size()) <= m_hover_id) m_hover_id = -1; } void on_start_dragging() override; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index b10f57108..ddde79c52 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -22,8 +22,8 @@ namespace Slic3r { namespace GUI { -GLGizmoSlaSupports::GLGizmoSlaSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) - : GLGizmoBase(parent, icon_filename, sprite_id) +GLGizmoSlaSupports::GLGizmoSlaSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id, CommonGizmosData* cd) + : GLGizmoBase(parent, icon_filename, sprite_id, cd) , m_quadric(nullptr) , m_its(nullptr) { @@ -64,23 +64,23 @@ bool GLGizmoSlaSupports::on_init() void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const Selection& selection) { if (! model_object || selection.is_empty()) { - m_model_object = nullptr; + m_c->m_model_object = nullptr; return; } - if (m_model_object != model_object || m_model_object_id != model_object->id()) { - m_model_object = model_object; - m_print_object_idx = -1; + if (m_c->m_model_object != model_object || m_c->m_model_object_id != model_object->id()) { + m_c->m_model_object = model_object; + m_c->m_print_object_idx = -1; } - m_active_instance = selection.get_instance_idx(); + m_c->m_active_instance = selection.get_instance_idx(); if (model_object && selection.is_from_single_instance()) { // Cache the bb - it's needed for dealing with the clipping plane quite often // It could be done inside update_mesh but one has to account for scaling of the instance. //FIXME calling ModelObject::instance_bounding_box() is expensive! - m_active_instance_bb_radius = m_model_object->instance_bounding_box(m_active_instance).radius(); + m_c->m_active_instance_bb_radius = m_c->m_model_object->instance_bounding_box(m_c->m_active_instance).radius(); if (is_mesh_update_necessary()) { update_mesh(); @@ -88,12 +88,12 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const S } // If we triggered autogeneration before, check backend and fetch results if they are there - if (m_model_object->sla_points_status == sla::PointsStatus::Generating) + if (m_c->m_model_object->sla_points_status == sla::PointsStatus::Generating) get_data_from_backend(); if (m_state == On) { m_parent.toggle_model_objects_visibility(false); - m_parent.toggle_model_objects_visibility(true, m_model_object, m_active_instance); + m_parent.toggle_model_objects_visibility(true, m_c->m_model_object, m_c->m_active_instance); } else m_parent.toggle_model_objects_visibility(true, nullptr, -1); @@ -106,21 +106,38 @@ void GLGizmoSlaSupports::on_render() const { const Selection& selection = m_parent.get_selection(); - // If current m_model_object does not match selection, ask GLCanvas3D to turn us off + // If current m_c->m_model_object does not match selection, ask GLCanvas3D to turn us off if (m_state == On - && (m_model_object != selection.get_model()->objects[selection.get_object_idx()] - || m_active_instance != selection.get_instance_idx() - || m_model_object_id != m_model_object->id())) { + && (m_c->m_model_object != selection.get_model()->objects[selection.get_object_idx()] + || m_c->m_active_instance != selection.get_instance_idx() + || m_c->m_model_object_id != m_c->m_model_object->id())) { m_parent.post_event(SimpleEvent(EVT_GLCANVAS_RESETGIZMOS)); return; } - if (! m_its || ! m_mesh) + if (! m_its || ! m_c->m_mesh) const_cast(this)->update_mesh(); glsafe(::glEnable(GL_BLEND)); glsafe(::glEnable(GL_DEPTH_TEST)); + if (m_c->m_volume_with_cavity) { + m_c->m_volume_with_cavity->set_sla_shift_z(m_z_shift); + m_parent.get_shader().start_using(); + + GLint current_program_id; + glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id)); + GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1; + GLint print_box_detection_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.volume_detection") : -1; + GLint print_box_worldmatrix_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.volume_world_matrix") : -1; + glcheck(); + m_c->m_volume_with_cavity->set_render_color(); + m_c->m_volume_with_cavity->render(color_id, print_box_detection_id, print_box_worldmatrix_id); + m_parent.get_shader().stop_using(); + } + // Show/hide the original object + m_parent.toggle_model_objects_visibility(! m_c->m_cavity_mesh, m_c->m_model_object, m_c->m_active_instance); + m_z_shift = selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z(); if (m_quadric != nullptr && selection.is_from_single_instance()) @@ -136,7 +153,7 @@ void GLGizmoSlaSupports::on_render() const void GLGizmoSlaSupports::render_clipping_plane(const Selection& selection) const { - if (m_clipping_plane_distance == 0.f || m_mesh->empty()) + if (m_clipping_plane_distance == 0.f || m_c->m_mesh->empty()) return; // Get transformation of the instance @@ -154,66 +171,66 @@ void GLGizmoSlaSupports::render_clipping_plane(const Selection& selection) const 1.)); // Now initialize the TMS for the object, perform the cut and save the result. - if (! m_object_clipper) { - m_object_clipper.reset(new MeshClipper); - m_object_clipper->set_mesh(*m_mesh); + if (! m_c->m_object_clipper) { + m_c->m_object_clipper.reset(new MeshClipper); + m_c->m_object_clipper->set_mesh(*m_c->mesh()); } - m_object_clipper->set_plane(*m_clipping_plane); - m_object_clipper->set_transformation(trafo); + m_c->m_object_clipper->set_plane(*m_clipping_plane); + m_c->m_object_clipper->set_transformation(trafo); // Next, ask the backend if supports are already calculated. If so, we are gonna cut them too. // First we need a pointer to the respective SLAPrintObject. The index into objects vector is // cached so we don't have todo it on each render. We only search for the po if needed: - if (m_print_object_idx < 0 || (int)m_parent.sla_print()->objects().size() != m_print_objects_count) { - m_print_objects_count = m_parent.sla_print()->objects().size(); - m_print_object_idx = -1; + if (m_c->m_print_object_idx < 0 || (int)m_parent.sla_print()->objects().size() != m_c->m_print_objects_count) { + m_c->m_print_objects_count = m_parent.sla_print()->objects().size(); + m_c->m_print_object_idx = -1; for (const SLAPrintObject* po : m_parent.sla_print()->objects()) { - ++m_print_object_idx; - if (po->model_object()->id() == m_model_object->id()) + ++m_c->m_print_object_idx; + if (po->model_object()->id() == m_c->m_model_object->id()) break; } } - if (m_print_object_idx >= 0) { - const SLAPrintObject* print_object = m_parent.sla_print()->objects()[m_print_object_idx]; + if (m_c->m_print_object_idx >= 0) { + const SLAPrintObject* print_object = m_parent.sla_print()->objects()[m_c->m_print_object_idx]; if (print_object->is_step_done(slaposSupportTree) && !print_object->get_mesh(slaposSupportTree).empty()) { // If the supports are already calculated, save the timestamp of the respective step // so we can later tell they were recalculated. size_t timestamp = print_object->step_state_with_timestamp(slaposSupportTree).timestamp; - if (! m_supports_clipper || (int)timestamp != m_old_timestamp) { + if (! m_c->m_supports_clipper || (int)timestamp != m_c->m_old_timestamp) { // The timestamp has changed. - m_supports_clipper.reset(new MeshClipper); + m_c->m_supports_clipper.reset(new MeshClipper); // The mesh should already have the shared vertices calculated. - m_supports_clipper->set_mesh(print_object->support_mesh()); - m_old_timestamp = timestamp; + m_c->m_supports_clipper->set_mesh(print_object->support_mesh()); + m_c->m_old_timestamp = timestamp; } - m_supports_clipper->set_plane(*m_clipping_plane); - m_supports_clipper->set_transformation(supports_trafo); + m_c->m_supports_clipper->set_plane(*m_clipping_plane); + m_c->m_supports_clipper->set_transformation(supports_trafo); } else // The supports are not valid. We better dump the cached data. - m_supports_clipper.reset(); + m_c->m_supports_clipper.reset(); } // At this point we have the triangulated cuts for both the object and supports - let's render. - if (! m_object_clipper->get_triangles().empty()) { + if (! m_c->m_object_clipper->get_triangles().empty()) { ::glPushMatrix(); ::glColor3f(1.0f, 0.37f, 0.0f); ::glBegin(GL_TRIANGLES); - for (const Vec3f& point : m_object_clipper->get_triangles()) + for (const Vec3f& point : m_c->m_object_clipper->get_triangles()) ::glVertex3f(point(0), point(1), point(2)); ::glEnd(); ::glPopMatrix(); } - if (m_supports_clipper && ! m_supports_clipper->get_triangles().empty() && !m_editing_mode) { + if (m_c->m_supports_clipper && ! m_c->m_supports_clipper->get_triangles().empty() && !m_editing_mode) { // The supports are hidden in the editing mode, so it makes no sense to render the cuts. ::glPushMatrix(); ::glColor3f(1.0f, 0.f, 0.37f); ::glBegin(GL_TRIANGLES); - for (const Vec3f& point : m_supports_clipper->get_triangles()) + for (const Vec3f& point : m_c->m_supports_clipper->get_triangles()) ::glVertex3f(point(0), point(1), point(2)); ::glEnd(); ::glPopMatrix(); @@ -298,7 +315,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) if (m_editing_mode) { // in case the normal is not yet cached, find and cache it if (m_editing_cache[i].normal == Vec3f::Zero()) - m_mesh_raycaster->get_closest_point(m_editing_cache[i].support_point.pos, &m_editing_cache[i].normal); + m_c->m_mesh_raycaster->get_closest_point(m_editing_cache[i].support_point.pos, &m_editing_cache[i].normal); Eigen::Quaterniond q; q.setFromTwoVectors(Vec3d{0., 0., 1.}, instance_scaling_matrix_inverse * m_editing_cache[i].normal.cast()); @@ -328,41 +345,41 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) } // Now render the drain holes: - render_color[0] = 0.7f; - render_color[1] = 0.7f; - render_color[2] = 0.7f; - render_color[3] = 0.7f; - glsafe(::glColor4fv(render_color)); - for (const sla::DrainHole& drain_hole : m_model_object->sla_drain_holes) { - // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object. - glsafe(::glPushMatrix()); - glsafe(::glTranslatef(drain_hole.pos(0), drain_hole.pos(1), drain_hole.pos(2))); - glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data())); +// render_color[0] = 0.7f; +// render_color[1] = 0.7f; +// render_color[2] = 0.7f; +// render_color[3] = 0.7f; +// glsafe(::glColor4fv(render_color)); +// for (const sla::DrainHole& drain_hole : m_c->m_model_object->sla_drain_holes) { +// // Inverse matrix of the instance scaling is applied so that the mark does not scale with the object. +// glsafe(::glPushMatrix()); +// glsafe(::glTranslatef(drain_hole.pos(0), drain_hole.pos(1), drain_hole.pos(2))); +// glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data())); - if (vol->is_left_handed()) - glFrontFace(GL_CW); +// if (vol->is_left_handed()) +// glFrontFace(GL_CW); - // Matrices set, we can render the point mark now. +// // Matrices set, we can render the point mark now. - Eigen::Quaterniond q; - q.setFromTwoVectors(Vec3d{0., 0., 1.}, instance_scaling_matrix_inverse * (-drain_hole.normal).cast()); - Eigen::AngleAxisd aa(q); - glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2))); - glsafe(::glPushMatrix()); - glsafe(::glTranslated(0., 0., -drain_hole.height)); - ::gluCylinder(m_quadric, drain_hole.radius, drain_hole.radius, drain_hole.height, 24, 1); - glsafe(::glTranslated(0., 0., drain_hole.height)); - ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1); - glsafe(::glTranslated(0., 0., -drain_hole.height)); - glsafe(::glRotatef(180.f, 1.f, 0.f, 0.f)); - ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1); - glsafe(::glPopMatrix()); +// Eigen::Quaterniond q; +// q.setFromTwoVectors(Vec3d{0., 0., 1.}, instance_scaling_matrix_inverse * (-drain_hole.normal).cast()); +// Eigen::AngleAxisd aa(q); +// glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2))); +// glsafe(::glPushMatrix()); +// glsafe(::glTranslated(0., 0., -drain_hole.height)); +// ::gluCylinder(m_quadric, drain_hole.radius, drain_hole.radius, drain_hole.height, 24, 1); +// glsafe(::glTranslated(0., 0., drain_hole.height)); +// ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1); +// glsafe(::glTranslated(0., 0., -drain_hole.height)); +// glsafe(::glRotatef(180.f, 1.f, 0.f, 0.f)); +// ::gluDisk(m_quadric, 0.0, drain_hole.radius, 24, 1); +// glsafe(::glPopMatrix()); - if (vol->is_left_handed()) - glFrontFace(GL_CCW); - glsafe(::glPopMatrix()); +// if (vol->is_left_handed()) +// glFrontFace(GL_CCW); +// glsafe(::glPopMatrix()); - } +// } if (!picking) glsafe(::glDisable(GL_LIGHTING)); @@ -377,7 +394,7 @@ bool GLGizmoSlaSupports::is_mesh_point_clipped(const Vec3d& point) const if (m_clipping_plane_distance == 0.f) return false; - Vec3d transformed_point = m_model_object->instances[m_active_instance]->get_transformation().get_matrix() * point; + Vec3d transformed_point = m_c->m_model_object->instances[m_c->m_active_instance]->get_transformation().get_matrix() * point; transformed_point(2) += m_z_shift; return m_clipping_plane->is_point_clipped(transformed_point); } @@ -386,28 +403,28 @@ bool GLGizmoSlaSupports::is_mesh_point_clipped(const Vec3d& point) const bool GLGizmoSlaSupports::is_mesh_update_necessary() const { - return ((m_state == On) && (m_model_object != nullptr) && !m_model_object->instances.empty()) - && ((m_model_object->id() != m_model_object_id) || m_its == nullptr); + return ((m_state == On) && (m_c->m_model_object != nullptr) && !m_c->m_model_object->instances.empty()) + && ((m_c->m_model_object->id() != m_c->m_model_object_id) || m_its == nullptr); } void GLGizmoSlaSupports::update_mesh() { - if (! m_model_object) + if (! m_c->m_model_object) return; wxBusyCursor wait; // this way we can use that mesh directly. // This mesh does not account for the possible Z up SLA offset. - m_mesh = &m_model_object->volumes.front()->mesh(); - m_its = &m_mesh->its; + m_c->m_mesh = &m_c->m_model_object->volumes.front()->mesh(); + m_its = &m_c->m_mesh->its; // If this is different mesh than last time or if the AABB tree is uninitialized, recalculate it. - if (m_model_object_id != m_model_object->id() || ! m_mesh_raycaster) - m_mesh_raycaster.reset(new MeshRaycaster(*m_mesh)); + if (m_c->m_model_object_id != m_c->m_model_object->id() || ! m_c->m_mesh_raycaster) + m_c->m_mesh_raycaster.reset(new MeshRaycaster(*m_c->mesh())); - m_model_object_id = m_model_object->id(); + m_c->m_model_object_id = m_c->m_model_object->id(); disable_editing_mode(); } @@ -417,7 +434,7 @@ void GLGizmoSlaSupports::update_mesh() bool GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pair& pos_and_normal) { // if the gizmo doesn't have the V, F structures for igl, calculate them first: - if (! m_mesh_raycaster) + if (! m_c->m_mesh_raycaster) update_mesh(); const Camera& camera = m_parent.get_camera(); @@ -429,10 +446,10 @@ bool GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pairunproject_on_mesh(mouse_pos, trafo.get_matrix(), camera, hit, normal, m_clipping_plane.get())) { + if (m_c->m_mesh_raycaster->unproject_on_mesh(mouse_pos, trafo.get_matrix(), camera, hit, normal, m_clipping_plane.get())) { // Check whether the hit is in a hole bool in_hole = false; - for (const sla::DrainHole& hole : m_model_object->sla_drain_holes) { + for (const sla::DrainHole& hole : m_c->m_model_object->sla_drain_holes) { if (hole.is_inside(hit)) { in_hole = true; break; @@ -505,7 +522,7 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous GLSelectionRectangle::EState rectangle_status = m_selection_rectangle.get_state(); // First collect positions of all the points in world coordinates. - Geometry::Transformation trafo = m_model_object->instances[m_active_instance]->get_transformation(); + Geometry::Transformation trafo = m_c->m_model_object->instances[m_c->m_active_instance]->get_transformation(); trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., m_z_shift)); std::vector points; for (unsigned int i=0; i()); // Only select/deselect points that are actually visible - for (size_t idx : m_mesh_raycaster->get_unobscured_idxs(trafo, m_parent.get_camera(), points_inside, m_clipping_plane.get())) + for (size_t idx : m_c->m_mesh_raycaster->get_unobscured_idxs(trafo, m_parent.get_camera(), points_inside, m_clipping_plane.get())) { if (rectangle_status == GLSelectionRectangle::Deselect) unselect_point(points_idxs[idx]); @@ -656,10 +673,10 @@ std::vector GLGizmoSlaSupports::get_config_options(const st { std::vector out; - if (!m_model_object) + if (!m_c->m_model_object) return out; - const DynamicPrintConfig& object_cfg = m_model_object->config; + const DynamicPrintConfig& object_cfg = m_c->m_model_object->config; const DynamicPrintConfig& print_cfg = wxGetApp().preset_bundle->sla_prints.get_edited_preset().config; std::unique_ptr default_cfg = nullptr; @@ -682,7 +699,7 @@ std::vector GLGizmoSlaSupports::get_config_options(const st ClippingPlane GLGizmoSlaSupports::get_sla_clipping_plane() const { - if (!m_model_object || m_state == Off || m_clipping_plane_distance == 0.f) + if (!m_c->m_model_object || m_state == Off || m_clipping_plane_distance == 0.f) return ClippingPlane::ClipsNothing(); else return ClippingPlane(-m_clipping_plane->get_normal(), m_clipping_plane->get_data()[3]); @@ -711,7 +728,7 @@ void GLGizmoSlaSupports::find_intersecting_facets(const igl::AABBvolumes.front()->mesh); + TriangleMeshSlicer tms(&m_c->m_model_object->volumes.front()->mesh); Vec3f normal(0.f, 1.f, 1.f); double d = 0.; @@ -732,7 +749,7 @@ void GLGizmoSlaSupports::make_line_segments() const void GLGizmoSlaSupports::on_render_input_window(float x, float y, float bottom_limit) { - if (!m_model_object) + if (!m_c->m_model_object) return; bool first_run = true; // This is a hack to redraw the button when all points are removed, @@ -853,15 +870,15 @@ RENDER_AGAIN: m_density_stash = density; } if (slider_edited) { - m_model_object->config.opt("support_points_minimal_distance", true)->value = minimal_point_distance; - m_model_object->config.opt("support_points_density_relative", true)->value = (int)density; + m_c->m_model_object->config.opt("support_points_minimal_distance", true)->value = minimal_point_distance; + m_c->m_model_object->config.opt("support_points_density_relative", true)->value = (int)density; } if (slider_released) { - m_model_object->config.opt("support_points_minimal_distance", true)->value = m_minimal_point_distance_stash; - m_model_object->config.opt("support_points_density_relative", true)->value = (int)m_density_stash; + m_c->m_model_object->config.opt("support_points_minimal_distance", true)->value = m_minimal_point_distance_stash; + m_c->m_model_object->config.opt("support_points_density_relative", true)->value = (int)m_density_stash; Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Support parameter change"))); - m_model_object->config.opt("support_points_minimal_distance", true)->value = minimal_point_distance; - m_model_object->config.opt("support_points_density_relative", true)->value = (int)density; + m_c->m_model_object->config.opt("support_points_minimal_distance", true)->value = minimal_point_distance; + m_c->m_model_object->config.opt("support_points_density_relative", true)->value = (int)density; wxGetApp().obj_list()->update_and_show_object_settings_item(); } @@ -879,10 +896,10 @@ RENDER_AGAIN: m_imgui->disabled_end(); // m_imgui->text(""); - // m_imgui->text(m_model_object->sla_points_status == sla::PointsStatus::NoPoints ? _(L("No points (will be autogenerated)")) : - // (m_model_object->sla_points_status == sla::PointsStatus::AutoGenerated ? _(L("Autogenerated points (no modifications)")) : - // (m_model_object->sla_points_status == sla::PointsStatus::UserModified ? _(L("User-modified points")) : - // (m_model_object->sla_points_status == sla::PointsStatus::Generating ? _(L("Generation in progress...")) : "UNKNOWN STATUS")))); + // m_imgui->text(m_c->m_model_object->sla_points_status == sla::PointsStatus::NoPoints ? _(L("No points (will be autogenerated)")) : + // (m_c->m_model_object->sla_points_status == sla::PointsStatus::AutoGenerated ? _(L("Autogenerated points (no modifications)")) : + // (m_c->m_model_object->sla_points_status == sla::PointsStatus::UserModified ? _(L("User-modified points")) : + // (m_c->m_model_object->sla_points_status == sla::PointsStatus::Generating ? _(L("Generation in progress...")) : "UNKNOWN STATUS")))); } @@ -920,7 +937,7 @@ RENDER_AGAIN: // is done on each refresh because the user can switch the editing mode // before background process finishes. force_refresh = m_parent.toggle_sla_auxiliaries_visibility( - ! m_editing_mode, m_model_object, m_active_instance); + ! m_editing_mode, m_c->m_model_object, m_c->m_active_instance); if (remove_selected || remove_all) { force_refresh = false; @@ -978,12 +995,12 @@ std::string GLGizmoSlaSupports::on_get_name() const void GLGizmoSlaSupports::on_set_state() { - // m_model_object pointer can be invalid (for instance because of undo/redo action), + // m_c->m_model_object pointer can be invalid (for instance because of undo/redo action), // we should recover it from the object id - m_model_object = nullptr; + m_c->m_model_object = nullptr; for (const auto mo : wxGetApp().model().objects) { - if (mo->id() == m_model_object_id) { - m_model_object = mo; + if (mo->id() == m_c->m_model_object_id) { + m_c->m_model_object = mo; break; } } @@ -997,19 +1014,19 @@ void GLGizmoSlaSupports::on_set_state() update_mesh(); // we'll now reload support points: - if (m_model_object) + if (m_c->m_model_object) reload_cache(); m_parent.toggle_model_objects_visibility(false); - if (m_model_object) - m_parent.toggle_model_objects_visibility(true, m_model_object, m_active_instance); + if (m_c->m_model_object) + m_parent.toggle_model_objects_visibility(true, m_c->m_model_object, m_c->m_active_instance); // Set default head diameter from config. const DynamicPrintConfig& cfg = wxGetApp().preset_bundle->sla_prints.get_edited_preset().config; m_new_point_head_diameter = static_cast(cfg.option("support_head_front_diameter"))->value; } if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off - bool will_ask = m_model_object && m_editing_mode && unsaved_changes(); + bool will_ask = m_c->m_model_object && m_editing_mode && unsaved_changes(); if (will_ask) { wxGetApp().CallAfter([this]() { // Following is called through CallAfter, because otherwise there was a problem @@ -1033,9 +1050,9 @@ void GLGizmoSlaSupports::on_set_state() m_clipping_plane_distance = 0.f; // Release clippers and the AABB raycaster. m_its = nullptr; - m_object_clipper.reset(); - m_supports_clipper.reset(); - m_mesh_raycaster.reset(); + m_c->m_object_clipper.reset(); + m_c->m_supports_clipper.reset(); + m_c->m_mesh_raycaster.reset(); } } m_old_state = m_state; @@ -1077,7 +1094,7 @@ void GLGizmoSlaSupports::on_load(cereal::BinaryInputArchive& ar) { ar(m_clipping_plane_distance, *m_clipping_plane, - m_model_object_id, + m_c->m_model_object_id, m_new_point_head_diameter, m_normal_cache, m_editing_cache, @@ -1091,7 +1108,7 @@ void GLGizmoSlaSupports::on_save(cereal::BinaryOutputArchive& ar) const { ar(m_clipping_plane_distance, *m_clipping_plane, - m_model_object_id, + m_c->m_model_object_id, m_new_point_head_diameter, m_normal_cache, m_editing_cache, @@ -1169,9 +1186,9 @@ void GLGizmoSlaSupports::editing_mode_apply_changes() for (const CacheEntry& ce : m_editing_cache) m_normal_cache.push_back(ce.support_point); - m_model_object->sla_points_status = sla::PointsStatus::UserModified; - m_model_object->sla_support_points.clear(); - m_model_object->sla_support_points = m_normal_cache; + m_c->m_model_object->sla_points_status = sla::PointsStatus::UserModified; + m_c->m_model_object->sla_support_points.clear(); + m_c->m_model_object->sla_support_points = m_normal_cache; reslice_SLA_supports(); } @@ -1182,10 +1199,10 @@ void GLGizmoSlaSupports::editing_mode_apply_changes() void GLGizmoSlaSupports::reload_cache() { m_normal_cache.clear(); - if (m_model_object->sla_points_status == sla::PointsStatus::AutoGenerated || m_model_object->sla_points_status == sla::PointsStatus::Generating) + if (m_c->m_model_object->sla_points_status == sla::PointsStatus::AutoGenerated || m_c->m_model_object->sla_points_status == sla::PointsStatus::Generating) get_data_from_backend(); else - for (const sla::SupportPoint& point : m_model_object->sla_support_points) + for (const sla::SupportPoint& point : m_c->m_model_object->sla_support_points) m_normal_cache.emplace_back(point); } @@ -1194,7 +1211,7 @@ bool GLGizmoSlaSupports::has_backend_supports() const { // find SlaPrintObject with this ID for (const SLAPrintObject* po : m_parent.sla_print()->objects()) { - if (po->model_object()->id() == m_model_object->id()) + if (po->model_object()->id() == m_c->m_model_object->id()) return po->is_step_done(slaposSupportPoints); } return false; @@ -1202,7 +1219,7 @@ bool GLGizmoSlaSupports::has_backend_supports() const void GLGizmoSlaSupports::reslice_SLA_supports(bool postpone_error_messages) const { - wxGetApp().CallAfter([this, postpone_error_messages]() { wxGetApp().plater()->reslice_SLA_supports(*m_model_object, postpone_error_messages); }); + wxGetApp().CallAfter([this, postpone_error_messages]() { wxGetApp().plater()->reslice_SLA_supports(*m_c->m_model_object, postpone_error_messages); }); } void GLGizmoSlaSupports::get_data_from_backend() @@ -1212,14 +1229,14 @@ void GLGizmoSlaSupports::get_data_from_backend() // find the respective SLAPrintObject, we need a pointer to it for (const SLAPrintObject* po : m_parent.sla_print()->objects()) { - if (po->model_object()->id() == m_model_object->id()) { + if (po->model_object()->id() == m_c->m_model_object->id()) { m_normal_cache.clear(); const std::vector& points = po->get_support_points(); auto mat = po->trafo().inverse().cast(); for (unsigned int i=0; isla_points_status = sla::PointsStatus::AutoGenerated; + m_c->m_model_object->sla_points_status = sla::PointsStatus::AutoGenerated; break; } } @@ -1236,10 +1253,10 @@ void GLGizmoSlaSupports::auto_generate() _(L("Are you sure you want to do it?")) + "\n", _(L("Warning")), wxICON_WARNING | wxYES | wxNO); - if (m_model_object->sla_points_status != sla::PointsStatus::UserModified || m_normal_cache.empty() || dlg.ShowModal() == wxID_YES) { + if (m_c->m_model_object->sla_points_status != sla::PointsStatus::UserModified || m_normal_cache.empty() || dlg.ShowModal() == wxID_YES) { Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Autogenerate support points"))); wxGetApp().CallAfter([this]() { reslice_SLA_supports(); }); - m_model_object->sla_points_status = sla::PointsStatus::Generating; + m_c->m_model_object->sla_points_status = sla::PointsStatus::Generating; } } @@ -1284,9 +1301,9 @@ void GLGizmoSlaSupports::update_clipping_plane(bool keep_normal) const Vec3d normal = (keep_normal && m_clipping_plane->get_normal() != Vec3d::Zero() ? m_clipping_plane->get_normal() : -m_parent.get_camera().get_dir_forward()); - const Vec3d& center = m_model_object->instances[m_active_instance]->get_offset() + Vec3d(0., 0., m_z_shift); + const Vec3d& center = m_c->m_model_object->instances[m_c->m_active_instance]->get_offset() + Vec3d(0., 0., m_z_shift); float dist = normal.dot(center); - *m_clipping_plane = ClippingPlane(normal, (dist - (-m_active_instance_bb_radius) - m_clipping_plane_distance * 2*m_active_instance_bb_radius)); + *m_clipping_plane = ClippingPlane(normal, (dist - (-m_c->m_active_instance_bb_radius) - m_clipping_plane_distance * 2*m_c->m_active_instance_bb_radius)); m_parent.set_as_dirty(); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index 1de241a53..7700ad3a6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -21,10 +21,10 @@ enum class SLAGizmoEventType : unsigned char; class GLGizmoSlaSupports : public GLGizmoBase { private: - ModelObject* m_model_object = nullptr; - ObjectID m_model_object_id = 0; - int m_active_instance = -1; - float m_active_instance_bb_radius; // to cache the bb + //ModelObject* m_model_object = nullptr; + //ObjectID m_model_object_id = 0; + //int m_active_instance = -1; + //float m_active_instance_bb_radius; // to cache the bb mutable double m_z_shift = 0.f; bool unproject_on_mesh(const Vec2d& mouse_pos, std::pair& pos_and_normal); @@ -34,15 +34,12 @@ private: typedef Eigen::Map> MapMatrixXfUnaligned; typedef Eigen::Map> MapMatrixXiUnaligned; - std::unique_ptr m_mesh_raycaster; - const TriangleMesh* m_mesh; + //std::unique_ptr m_mesh_raycaster; + //const TriangleMesh* m_mesh; const indexed_triangle_set* m_its; - mutable const TriangleMesh* m_supports_mesh; - mutable std::vector m_triangles; - mutable std::vector m_supports_triangles; - mutable int m_old_timestamp = -1; - mutable int m_print_object_idx = -1; - mutable int m_print_objects_count = -1; + //mutable int m_old_timestamp = -1; + //mutable int m_print_object_idx = -1; + //mutable int m_print_objects_count = -1; class CacheEntry { public: @@ -72,7 +69,7 @@ private: }; public: - GLGizmoSlaSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); + GLGizmoSlaSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id, CommonGizmosData* cd); ~GLGizmoSlaSupports() override; void set_sla_support_data(ModelObject* model_object, const Selection& selection); bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down); @@ -120,8 +117,8 @@ private: bool m_selection_empty = true; EState m_old_state = Off; // to be able to see that the gizmo has just been closed (see on_set_state) - mutable std::unique_ptr m_object_clipper; - mutable std::unique_ptr m_supports_clipper; + //mutable std::unique_ptr m_object_clipper; + //mutable std::unique_ptr m_supports_clipper; std::vector get_config_options(const std::vector& keys) const; bool is_mesh_point_clipped(const Vec3d& point) const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 89a313445..e089de3fc 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -88,13 +88,15 @@ bool GLGizmosManager::init() return false; } + m_common_gizmos_data.reset(new CommonGizmosData()); + m_gizmos.emplace_back(new GLGizmoMove3D(m_parent, "move.svg", 0)); m_gizmos.emplace_back(new GLGizmoScale3D(m_parent, "scale.svg", 1)); m_gizmos.emplace_back(new GLGizmoRotate3D(m_parent, "rotate.svg", 2)); m_gizmos.emplace_back(new GLGizmoFlatten(m_parent, "place.svg", 3)); m_gizmos.emplace_back(new GLGizmoCut(m_parent, "cut.svg", 4)); - m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", 5)); - m_gizmos.emplace_back(new GLGizmoHollow(m_parent, "hollow.svg", 6)); + m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", 5, m_common_gizmos_data.get())); + m_gizmos.emplace_back(new GLGizmoHollow(m_parent, "hollow.svg", 6, m_common_gizmos_data.get())); for (auto& gizmo : m_gizmos) { if (! gizmo->init()) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 2c4d71316..f816056a0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -101,6 +101,7 @@ private: MouseCapture m_mouse_capture; std::string m_tooltip; bool m_serializing; + std::unique_ptr m_common_gizmos_data; public: explicit GLGizmosManager(GLCanvas3D& parent);