From e8c08d8f915364706213068d81e248b4b3e49fc6 Mon Sep 17 00:00:00 2001 From: Enrico Turri <enricoturri@seznam.cz> Date: Tue, 16 Apr 2019 08:50:46 +0200 Subject: [PATCH 1/4] Switch to regular shading when manipulating an object with gizmos while layers editing is active --- src/slic3r/GUI/GLCanvas3D.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 43e91064f..2c86bfd97 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3657,7 +3657,7 @@ void GLCanvas3D::_render_objects() const m_volumes.set_clipping_plane(m_camera_clipping_plane.get_data()); m_shader.start_using(); - if (m_picking_enabled && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) { + if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) { int object_id = m_layers_editing.last_object_id; m_volumes.render_VBOs(GLVolumeCollection::Opaque, false, m_camera.get_view_matrix(), [object_id](const GLVolume &volume) { // Which volume to paint without the layer height profile shader? From a177a7e1da19be236de27d53c01fa3124e5ffb0e Mon Sep 17 00:00:00 2001 From: Lukas Matena <lukasmatena@seznam.cz> Date: Mon, 15 Apr 2019 16:20:29 +0200 Subject: [PATCH 2/4] SLA gizmo clipping now also triangulates the cuts on support structure --- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 93 ++++++++++++++++++-- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 7 +- 2 files changed, 92 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index aa88f9dd5..569684a15 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -51,6 +51,9 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const S return; } + if (m_model_object != model_object) + m_print_object_idx = -1; + m_model_object = model_object; m_active_instance = selection.get_instance_idx(); @@ -111,32 +114,91 @@ void GLGizmoSlaSupports::render_clipping_plane(const Selection& selection, const if (m_clipping_plane_distance == 0.f) return; + // First cache instance transformation to be used later. const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin()); Transform3f instance_matrix = vol->get_instance_transformation().get_matrix().cast<float>(); Transform3f instance_matrix_no_translation_no_scaling = vol->get_instance_transformation().get_matrix(true,false,true).cast<float>(); Vec3f scaling = vol->get_instance_scaling_factor().cast<float>(); + Vec3d instance_offset = vol->get_instance_offset(); + // Calculate distance from mesh origin to the clipping plane (in mesh coordinates). Vec3f up_noscale = instance_matrix_no_translation_no_scaling.inverse() * direction_to_camera.cast<float>(); Vec3f up = Vec3f(up_noscale(0)*scaling(0), up_noscale(1)*scaling(1), up_noscale(2)*scaling(2)); float height_mesh = (m_active_instance_bb_radius - m_clipping_plane_distance * 2*m_active_instance_bb_radius) * (up_noscale.norm()/up.norm()); + // Get transformation of the supports and calculate how far from its origin the clipping plane is. + Transform3d supports_trafo = Transform3d::Identity(); + supports_trafo = supports_trafo.rotate(Eigen::AngleAxisd(vol->get_instance_rotation()(2), Vec3d::UnitZ())); + Vec3f up_supports = (supports_trafo.inverse() * direction_to_camera).cast<float>(); + supports_trafo = supports_trafo.pretranslate(Vec3d(instance_offset(0), instance_offset(1), vol->get_sla_shift_z())); + // Instance and supports origin do not coincide, so the following is quite messy: + float height_supports = height_mesh * (up.norm() / up_supports.norm()) + instance_offset(2) * (direction_to_camera(2) / direction_to_camera.norm()); + + // In case either of these was recently changed, the cached triangulated ExPolygons are invalid now. + // We are gonna recalculate them both for the object and for the support structures. if (m_clipping_plane_distance != m_old_clipping_plane_distance || m_old_direction_to_camera != direction_to_camera) { - std::vector<ExPolygons> list_of_expolys; + m_old_direction_to_camera = direction_to_camera; + m_old_clipping_plane_distance = m_clipping_plane_distance; + + // Now initialize the TMS for the object, perform the cut and save the result. if (! m_tms) { m_tms.reset(new TriangleMeshSlicer); m_tms->init(const_cast<TriangleMesh*>(&m_mesh), [](){}); } - + std::vector<ExPolygons> list_of_expolys; m_tms->set_up_direction(up); m_tms->slice(std::vector<float>{height_mesh}, 0.f, &list_of_expolys, [](){}); m_triangles = triangulate_expolygons_2f(list_of_expolys[0]); - m_old_direction_to_camera = direction_to_camera; - m_old_clipping_plane_distance = m_clipping_plane_distance; + + + // 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; + for (const SLAPrintObject* po : m_parent.sla_print()->objects()) { + ++m_print_object_idx; + if (po->model_object()->id() == 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 (print_object->is_step_done(slaposSupportTree)) { + // 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_tms || (int)timestamp != m_old_timestamp) { + // The timestamp has changed - stash the mesh and initialize the TMS. + m_supports_mesh = print_object->support_mesh(); + m_supports_tms.reset(new TriangleMeshSlicer); + m_supports_tms->init(const_cast<TriangleMesh*>(&m_supports_mesh), [](){}); + m_old_timestamp = timestamp; + } + + // The TMS is initialized - let's do the cutting: + list_of_expolys.clear(); + m_supports_tms->set_up_direction(up_supports); + m_supports_tms->slice(std::vector<float>{height_supports}, 0.f, &list_of_expolys, [](){}); + m_supports_triangles = triangulate_expolygons_2f(list_of_expolys[0]); + } + else { + // The supports are not valid. We better dump the cached data. + m_supports_tms.reset(); + m_supports_triangles.clear(); + } + } } + // At this point we have the triangulated cuts for both the object and supports - let's render. + ::glColor3f(1.0f, 0.37f, 0.0f); + if (! m_triangles.empty()) { ::glPushMatrix(); ::glTranslated(0.0, 0.0, m_z_shift); @@ -146,11 +208,26 @@ void GLGizmoSlaSupports::render_clipping_plane(const Selection& selection, const Eigen::AngleAxisf aa(q); ::glRotatef(aa.angle() * (180./M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2)); ::glTranslatef(0.f, 0.f, -0.001f); // to make sure the cut is safely beyond the near clipping plane - ::glColor3f(1.0f, 0.37f, 0.0f); ::glBegin(GL_TRIANGLES); - ::glColor3f(1.0f, 0.37f, 0.0f); for (const Vec2f& point : m_triangles) ::glVertex3f(point(0), point(1), height_mesh); + + ::glEnd(); + ::glPopMatrix(); + } + + if (! m_supports_triangles.empty()) { + ::glPushMatrix(); + ::glMultMatrixd(supports_trafo.data()); + Eigen::Quaternionf q; + q.setFromTwoVectors(Vec3f::UnitZ(), up_supports); + Eigen::AngleAxisf aa(q); + ::glRotatef(aa.angle() * (180./M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2)); + ::glTranslatef(0.f, 0.f, -0.001f); // to make sure the cut is safely beyond the near clipping plane + ::glBegin(GL_TRIANGLES); + for (const Vec2f& point : m_supports_triangles) + ::glVertex3f(point(0), point(1), height_supports); + ::glEnd(); ::glPopMatrix(); } @@ -974,10 +1051,12 @@ void GLGizmoSlaSupports::on_set_state() m_clipping_plane_distance = 0.f; // Release copy of the mesh, triangle slicer and the AABB spatial search structure. m_mesh.clear(); + m_supports_mesh.clear(); m_AABB.deinit(); m_V = Eigen::MatrixXf(); m_F = Eigen::MatrixXi(); - m_tms.reset(nullptr); + m_tms.reset(); + m_supports_tms.reset(); }); } m_old_state = m_state; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index c74559e2f..41dd117d6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -37,7 +37,12 @@ private: Eigen::MatrixXi m_F; // facets indices igl::AABB<Eigen::MatrixXf,3> m_AABB; TriangleMesh m_mesh; + mutable TriangleMesh m_supports_mesh; mutable std::vector<Vec2f> m_triangles; + mutable std::vector<Vec2f> m_supports_triangles; + mutable int m_old_timestamp = -1; + mutable int m_print_object_idx = -1; + mutable int m_print_objects_count = -1; class CacheEntry { public: @@ -79,7 +84,6 @@ private: bool m_old_editing_state = false; // To keep track of whether the user toggled between the modes (needed for imgui refreshes). float m_new_point_head_diameter; // Size of a new point. float m_minimal_point_distance = 20.f; - float m_density = 100.f; mutable std::vector<CacheEntry> m_editing_mode_cache; // a support point and whether it is currently selected float m_clipping_plane_distance = 0.f; mutable float m_old_clipping_plane_distance = 0.f; @@ -101,6 +105,7 @@ private: int m_canvas_height; mutable std::unique_ptr<TriangleMeshSlicer> m_tms; + mutable std::unique_ptr<TriangleMeshSlicer> m_supports_tms; std::vector<const ConfigOption*> get_config_options(const std::vector<std::string>& keys) const; bool is_point_clipped(const Vec3d& point, const Vec3d& direction_to_camera) const; From f33e9bf6095eb4d54fce5946a75e2780fb1502d5 Mon Sep 17 00:00:00 2001 From: Lukas Matena <lukasmatena@seznam.cz> Date: Mon, 15 Apr 2019 21:58:13 +0200 Subject: [PATCH 3/4] TriangleMeshSlicer is now initialized by const-pointer to the mesh, responsibility for calling require_shared_vertices is left to the caller --- src/libslic3r/Model.cpp | 1 + src/libslic3r/PrintObject.cpp | 2 ++ src/libslic3r/SLA/SLABasePool.cpp | 1 + src/libslic3r/SLA/SLASupportTree.cpp | 2 ++ src/libslic3r/SLAPrint.cpp | 1 + src/libslic3r/TriangleMesh.cpp | 6 ++++-- src/libslic3r/TriangleMesh.hpp | 12 +++++------- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 2 ++ 8 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 6b16855e8..5a0558977 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -1189,6 +1189,7 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, bool keep_upper, b volume->mesh.transform(instance_matrix * volume_matrix, true); // Perform cut + volume->mesh.require_shared_vertices(); // TriangleMeshSlicer needs this TriangleMeshSlicer tms(&volume->mesh); tms.cut(float(z), &upper_mesh, &lower_mesh); diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 0b51f36ec..bb03d1e9d 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1813,6 +1813,7 @@ std::vector<ExPolygons> PrintObject::_slice_volumes(const std::vector<float> &z, TriangleMeshSlicer mslicer; const Print *print = this->print(); auto callback = TriangleMeshSlicer::throw_on_cancel_callback_type([print](){print->throw_if_canceled();}); + mesh.require_shared_vertices(); // TriangleMeshSlicer needs this mslicer.init(&mesh, callback); mslicer.slice(z, float(m_config.slice_closing_radius.value), &layers, callback); m_print->throw_if_canceled(); @@ -1840,6 +1841,7 @@ std::vector<ExPolygons> PrintObject::_slice_volume(const std::vector<float> &z, TriangleMeshSlicer mslicer; const Print *print = this->print(); auto callback = TriangleMeshSlicer::throw_on_cancel_callback_type([print](){print->throw_if_canceled();}); + mesh.require_shared_vertices(); // TriangleMeshSlicer needs this mslicer.init(&mesh, callback); mslicer.slice(z, float(m_config.slice_closing_radius.value), &layers, callback); m_print->throw_if_canceled(); diff --git a/src/libslic3r/SLA/SLABasePool.cpp b/src/libslic3r/SLA/SLABasePool.cpp index 2aabaa590..94b6c7d9b 100644 --- a/src/libslic3r/SLA/SLABasePool.cpp +++ b/src/libslic3r/SLA/SLABasePool.cpp @@ -552,6 +552,7 @@ void base_plate(const TriangleMesh &mesh, ExPolygons &output, float h, float layerh, ThrowOnCancel thrfn) { TriangleMesh m = mesh; + m.require_shared_vertices(); // TriangleMeshSlicer needs this TriangleMeshSlicer slicer(&m); auto bb = mesh.bounding_box(); diff --git a/src/libslic3r/SLA/SLASupportTree.cpp b/src/libslic3r/SLA/SLASupportTree.cpp index bb0e5e007..37a6bae4b 100644 --- a/src/libslic3r/SLA/SLASupportTree.cpp +++ b/src/libslic3r/SLA/SLASupportTree.cpp @@ -2231,6 +2231,7 @@ SlicedSupports SLASupportTree::slice(float layerh, float init_layerh) const TriangleMesh fullmesh = m_impl->merged_mesh(); fullmesh.merge(get_pad()); + fullmesh.require_shared_vertices(); // TriangleMeshSlicer needs this TriangleMeshSlicer slicer(&fullmesh); SlicedSupports ret; slicer.slice(heights, 0.f, &ret, get().ctl().cancelfn); @@ -2243,6 +2244,7 @@ SlicedSupports SLASupportTree::slice(const std::vector<float> &heights, { TriangleMesh fullmesh = m_impl->merged_mesh(); fullmesh.merge(get_pad()); + fullmesh.require_shared_vertices(); // TriangleMeshSlicer needs this TriangleMeshSlicer slicer(&fullmesh); SlicedSupports ret; slicer.slice(heights, cr, &ret, get().ctl().cancelfn); diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index e5a574463..b7191970d 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -706,6 +706,7 @@ void SLAPrint::process() po.m_model_height_levels.emplace_back(it->slice_level()); } + mesh.require_shared_vertices(); // TriangleMeshSlicer needs this TriangleMeshSlicer slicer(&mesh); po.m_model_slices.clear(); diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index 2d603661d..f449ac2b4 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -607,10 +607,12 @@ void TriangleMesh::require_shared_vertices() BOOST_LOG_TRIVIAL(trace) << "TriangleMeshSlicer::require_shared_vertices - end"; } -void TriangleMeshSlicer::init(TriangleMesh *_mesh, throw_on_cancel_callback_type throw_on_cancel) +void TriangleMeshSlicer::init(const TriangleMesh *_mesh, throw_on_cancel_callback_type throw_on_cancel) { mesh = _mesh; - _mesh->require_shared_vertices(); + if (! mesh->has_shared_vertices()) + throw std::invalid_argument("TriangleMeshSlicer was passed a mesh without shared vertices."); + throw_on_cancel(); facets_edges.assign(_mesh->stl.stats.number_of_facets * 3, -1); v_scaled_shared.assign(_mesh->stl.v_shared, _mesh->stl.v_shared + _mesh->stl.stats.shared_vertices); diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index 4bf5ce039..60ddcca08 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -67,18 +67,17 @@ public: TriangleMesh convex_hull_3d() const; void reset_repair_stats(); bool needed_repair() const; + void require_shared_vertices(); + bool has_shared_vertices() const { return stl.v_shared != NULL; } size_t facets_count() const { return this->stl.stats.number_of_facets; } bool empty() const { return this->facets_count() == 0; } - bool is_splittable() const; stl_file stl; bool repaired; - + private: - void require_shared_vertices(); std::deque<uint32_t> find_unvisited_neighbors(std::vector<unsigned char> &facet_visited) const; - friend class TriangleMeshSlicer; }; enum FacetEdgeType { @@ -159,9 +158,8 @@ class TriangleMeshSlicer public: typedef std::function<void()> throw_on_cancel_callback_type; TriangleMeshSlicer() : mesh(nullptr) {} - // Not quite nice, but the constructor and init() methods require non-const mesh pointer to be able to call mesh->require_shared_vertices() - TriangleMeshSlicer(TriangleMesh* mesh) { this->init(mesh, [](){}); } - void init(TriangleMesh *mesh, throw_on_cancel_callback_type throw_on_cancel); + TriangleMeshSlicer(const TriangleMesh* mesh) { this->init(mesh, [](){}); } + void init(const TriangleMesh *mesh, throw_on_cancel_callback_type throw_on_cancel); void slice(const std::vector<float> &z, std::vector<Polygons>* layers, throw_on_cancel_callback_type throw_on_cancel) const; void slice(const std::vector<float> &z, const float closing_radius, std::vector<ExPolygons>* layers, throw_on_cancel_callback_type throw_on_cancel) const; enum FacetSliceType { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 569684a15..af27c2f9f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -178,6 +178,7 @@ void GLGizmoSlaSupports::render_clipping_plane(const Selection& selection, const // The timestamp has changed - stash the mesh and initialize the TMS. m_supports_mesh = print_object->support_mesh(); m_supports_tms.reset(new TriangleMeshSlicer); + m_supports_mesh.require_shared_vertices(); // TriangleMeshSlicer needs this m_supports_tms->init(const_cast<TriangleMesh*>(&m_supports_mesh), [](){}); m_old_timestamp = timestamp; } @@ -411,6 +412,7 @@ void GLGizmoSlaSupports::update_mesh() Eigen::MatrixXi& F = m_F; // This mesh does not account for the possible Z up SLA offset. m_mesh = m_model_object->raw_mesh(); + m_mesh.require_shared_vertices(); // TriangleMeshSlicer needs this const stl_file& stl = m_mesh.stl; V.resize(3 * stl.stats.number_of_facets, 3); F.resize(stl.stats.number_of_facets, 3); From 63ce3c3150fcf8bf4d068894857acdce49fbc5c6 Mon Sep 17 00:00:00 2001 From: Lukas Matena <lukasmatena@seznam.cz> Date: Mon, 15 Apr 2019 22:24:10 +0200 Subject: [PATCH 4/4] SLA gizmo now does not make redundant copies of the object and supports meshes --- src/libslic3r/SLA/SLASupportTree.cpp | 4 ++++ src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 20 ++++++++++---------- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 4 ++-- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/libslic3r/SLA/SLASupportTree.cpp b/src/libslic3r/SLA/SLASupportTree.cpp index 37a6bae4b..75f9b0140 100644 --- a/src/libslic3r/SLA/SLASupportTree.cpp +++ b/src/libslic3r/SLA/SLASupportTree.cpp @@ -817,6 +817,10 @@ public: meshcache = mesh(merged); + // The mesh will be passed by const-pointer to TriangleMeshSlicer, + // which will need this. + meshcache.require_shared_vertices(); + // TODO: Is this necessary? //meshcache.repair(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index af27c2f9f..2285e2520 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -145,7 +145,7 @@ void GLGizmoSlaSupports::render_clipping_plane(const Selection& selection, const // Now initialize the TMS for the object, perform the cut and save the result. if (! m_tms) { m_tms.reset(new TriangleMeshSlicer); - m_tms->init(const_cast<TriangleMesh*>(&m_mesh), [](){}); + m_tms->init(m_mesh, [](){}); } std::vector<ExPolygons> list_of_expolys; m_tms->set_up_direction(up); @@ -176,10 +176,10 @@ void GLGizmoSlaSupports::render_clipping_plane(const Selection& selection, const if (!m_supports_tms || (int)timestamp != m_old_timestamp) { // The timestamp has changed - stash the mesh and initialize the TMS. - m_supports_mesh = print_object->support_mesh(); + m_supports_mesh = &print_object->support_mesh(); m_supports_tms.reset(new TriangleMeshSlicer); - m_supports_mesh.require_shared_vertices(); // TriangleMeshSlicer needs this - m_supports_tms->init(const_cast<TriangleMesh*>(&m_supports_mesh), [](){}); + // The mesh should already have the shared vertices calculated. + m_supports_tms->init(m_supports_mesh, [](){}); m_old_timestamp = timestamp; } @@ -410,10 +410,12 @@ void GLGizmoSlaSupports::update_mesh() wxBusyCursor wait; Eigen::MatrixXf& V = m_V; Eigen::MatrixXi& F = m_F; + // We rely on SLA model object having a single volume, + // 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->raw_mesh(); - m_mesh.require_shared_vertices(); // TriangleMeshSlicer needs this - const stl_file& stl = m_mesh.stl; + m_mesh = &m_model_object->volumes.front()->mesh; + const_cast<TriangleMesh*>(m_mesh)->require_shared_vertices(); // TriangleMeshSlicer needs this + const stl_file& stl = m_mesh->stl; V.resize(3 * stl.stats.number_of_facets, 3); F.resize(stl.stats.number_of_facets, 3); for (unsigned int i=0; i<stl.stats.number_of_facets; ++i) { @@ -1051,9 +1053,7 @@ void GLGizmoSlaSupports::on_set_state() m_editing_mode = false; // so it is not active next time the gizmo opens m_editing_mode_cache.clear(); m_clipping_plane_distance = 0.f; - // Release copy of the mesh, triangle slicer and the AABB spatial search structure. - m_mesh.clear(); - m_supports_mesh.clear(); + // Release triangle mesh slicer and the AABB spatial search structure. m_AABB.deinit(); m_V = Eigen::MatrixXf(); m_F = Eigen::MatrixXi(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index 41dd117d6..a06a3502c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -36,8 +36,8 @@ private: Eigen::MatrixXf m_V; // vertices Eigen::MatrixXi m_F; // facets indices igl::AABB<Eigen::MatrixXf,3> m_AABB; - TriangleMesh m_mesh; - mutable TriangleMesh m_supports_mesh; + const TriangleMesh* m_mesh; + mutable const TriangleMesh* m_supports_mesh; mutable std::vector<Vec2f> m_triangles; mutable std::vector<Vec2f> m_supports_triangles; mutable int m_old_timestamp = -1;