diff --git a/src/admesh/stl.h b/src/admesh/stl.h index 1ca75c95d4..33e2b9c946 100644 --- a/src/admesh/stl.h +++ b/src/admesh/stl.h @@ -244,9 +244,15 @@ inline void stl_transform(stl_file *stl, const Eigen::Matrix +inline void its_translate(indexed_triangle_set &its, const V v) +{ + for (stl_vertex &v_dst : its.vertices) + v_dst += v; +} template -extern void its_transform(indexed_triangle_set &its, T *trafo3x4) +inline void its_transform(indexed_triangle_set &its, T *trafo3x4) { for (stl_vertex &v_dst : its.vertices) { stl_vertex v_src = v_dst; diff --git a/src/libslic3r/SlicingAdaptive.cpp b/src/libslic3r/SlicingAdaptive.cpp index 77f41d7bfd..30ff67bba5 100644 --- a/src/libslic3r/SlicingAdaptive.cpp +++ b/src/libslic3r/SlicingAdaptive.cpp @@ -84,7 +84,7 @@ void SlicingAdaptive::prepare(const ModelObject &object) m_faces.reserve(mesh.facets_count()); for (stl_triangle_vertex_indices face : mesh.its.indices) { stl_vertex vertex[3] = { mesh.its.vertices[face[0]], mesh.its.vertices[face[1]], mesh.its.vertices[face[2]] }; - stl_vertex n = (vertex[2] - vertex[1]).cross(vertex[3] - vertex[2]).normalized(); + stl_vertex n = face_normal_normalized(vertex); std::pair face_z_span { std::min(std::min(vertex[0].z(), vertex[1].z()), vertex[2].z()), std::max(std::max(vertex[0].z(), vertex[1].z()), vertex[2].z()) diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index ff85110907..d289fca141 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -1133,15 +1133,17 @@ TriangleMesh make_cylinder(double r, double h, double fa) return mesh; } - -TriangleMesh make_cone(double r, double h, double fa) +indexed_triangle_set its_make_cone(double r, double h, double fa) { - Pointf3s vertices; - std::vector facets; - vertices.reserve(3+size_t(2*PI/fa)); - vertices.reserve(3+2*size_t(2*PI/fa)); + indexed_triangle_set mesh; + auto& vertices = mesh.vertices; + auto& facets = mesh.indices; + vertices.reserve(3 + 2 * size_t(2 * PI / fa)); + + // base center and top vertex + vertices.emplace_back(Vec3f::Zero()); + vertices.emplace_back(Vec3f(0., 0., h)); - vertices = { Vec3d::Zero(), Vec3d(0., 0., h) }; // base center and top vertex size_t i = 0; for (double angle=0; angle<2*PI; angle+=fa) { vertices.emplace_back(r*std::cos(angle), r*std::sin(angle), 0.); @@ -1154,11 +1156,15 @@ TriangleMesh make_cone(double r, double h, double fa) facets.emplace_back(0, 2, i+1); // close the shape facets.emplace_back(1, i+1, 2); - TriangleMesh mesh(std::move(vertices), std::move(facets)); - mesh.repair(); return mesh; } +TriangleMesh make_cone(double radius, double fa) +{ + TriangleMesh mesh(its_make_cone(radius, fa)); + mesh.repair(); + return mesh; +} // Generates mesh for a sphere centered about the origin, using the generated angle // to determine the granularity. @@ -1222,7 +1228,6 @@ TriangleMesh make_sphere(double radius, double fa) { TriangleMesh mesh(its_make_sphere(radius, fa)); mesh.repair(); - return mesh; } @@ -1343,10 +1348,8 @@ std::vector its_face_normals(const indexed_triangle_set &its) { std::vector normals; normals.reserve(its.indices.size()); - for (stl_triangle_vertex_indices face : its.indices) { - stl_vertex vertex[3] = { its.vertices[face[0]], its.vertices[face[1]], its.vertices[face[2]] }; - normals.push_back((vertex[2] - vertex[1]).cross(vertex[3] - vertex[2]).normalized()); - } + for (stl_triangle_vertex_indices face : its.indices) + normals.push_back(its_face_normal(its, face)); return normals; } diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index 1a3d1fae09..60ab975c4c 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -209,17 +209,21 @@ void its_merge(indexed_triangle_set &A, const std::vector &triangles); void its_merge(indexed_triangle_set &A, const Pointf3s &triangles); std::vector its_face_normals(const indexed_triangle_set &its); +inline Vec3f face_normal(const stl_vertex vertex[3]) { return (vertex[1] - vertex[0]).cross(vertex[2] - vertex[1]).normalized(); } +inline Vec3f face_normal_normalized(const stl_vertex vertex[3]) { return face_normal(vertex).normalized(); } +inline Vec3f its_face_normal(const indexed_triangle_set &its, const stl_triangle_vertex_indices face) + { const stl_vertex vertices[3] { its.vertices[face[0]], its.vertices[face[1]], its.vertices[face[2]] }; return face_normal_normalized(vertices); } +inline Vec3f its_face_normal(const indexed_triangle_set &its, const int face_idx) + { return its_face_normal(its, its.indices[face_idx]); } -indexed_triangle_set its_make_cube(double x, double y, double z); -TriangleMesh make_cube(double x, double y, double z); - -// Generate a TriangleMesh of a cylinder -indexed_triangle_set its_make_cylinder(double r, double h, double fa=(2*PI/360)); -TriangleMesh make_cylinder(double r, double h, double fa=(2*PI/360)); - -indexed_triangle_set its_make_sphere(double rho, double fa=(2*PI/360)); -TriangleMesh make_cone(double r, double h, double fa=(2*PI/360)); -TriangleMesh make_sphere(double rho, double fa=(2*PI/360)); +indexed_triangle_set its_make_cube(double x, double y, double z); +TriangleMesh make_cube(double x, double y, double z); +indexed_triangle_set its_make_cylinder(double r, double h, double fa=(2*PI/360)); +TriangleMesh make_cylinder(double r, double h, double fa=(2*PI/360)); +indexed_triangle_set its_make_cone(double r, double h, double fa=(2*PI/360)); +TriangleMesh make_cone(double r, double h, double fa=(2*PI/360)); +indexed_triangle_set its_make_sphere(double radius, double fa); +TriangleMesh make_sphere(double rho, double fa=(2*PI/360)); inline BoundingBoxf3 bounding_box(const TriangleMesh &m) { return m.bounding_box(); } inline BoundingBoxf3 bounding_box(const indexed_triangle_set& its) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index b4258e7818..c758468300 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -171,7 +171,7 @@ void GLIndexedVertexArray::load_its_flat_shading(const indexed_triangle_set &its for (int i = 0; i < int(its.indices.size()); ++ i) { stl_triangle_vertex_indices face = its.indices[i]; stl_vertex vertex[3] = { its.vertices[face[0]], its.vertices[face[1]], its.vertices[face[2]] }; - stl_vertex n = (vertex[2] - vertex[1]).cross(vertex[3] - vertex[2]).normalized(); + stl_vertex n = face_normal_normalized(vertex); for (int j = 0; j < 3; ++j) this->push_geometry(vertex[j](0), vertex[j](1), vertex[j](2), n(0), n(1), n(2)); this->push_triangle(vertices_count, vertices_count + 1, vertices_count + 2); diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 6e58a3231b..0fe6c8546c 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -93,7 +93,7 @@ void GLModel::init_from(const indexed_triangle_set& its, const BoundingBoxf3 &bb for (uint32_t i = 0; i < its.indices.size(); ++i) { stl_triangle_vertex_indices face = its.indices[i]; stl_vertex vertex[3] = { its.vertices[face[0]], its.vertices[face[1]], its.vertices[face[2]] }; - stl_vertex n = (vertex[2] - vertex[1]).cross(vertex[3] - vertex[2]).normalized(); + stl_vertex n = face_normal_normalized(vertex); for (size_t j = 0; j < 3; ++ j) { size_t offset = i * 18 + j * 6; ::memcpy(static_cast(&vertices[offset]), static_cast(vertex[j].data()), 3 * sizeof(float)); @@ -111,6 +111,11 @@ void GLModel::init_from(const indexed_triangle_set& its, const BoundingBoxf3 &bb m_render_data.emplace_back(data); } +void GLModel::init_from(const indexed_triangle_set& its) +{ + this->init_from(its, bounding_box(its)); +} + #if ENABLE_SINKING_CONTOURS void GLModel::init_from(const Polygons& polygons, float z) { @@ -158,7 +163,9 @@ bool GLModel::init_from_file(const std::string& filename) return false; } - init_from(model.mesh()); + TriangleMesh mesh = model.mesh(); + mesh.require_shared_vertices(); + init_from(mesh.its, mesh.bounding_box()); m_filename = filename; diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index c57faa9e89..95be6dca1f 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -70,8 +70,8 @@ namespace GUI { virtual ~GLModel() { reset(); } void init_from(const InitializationData& data); - void init_from(const TriangleMesh& mesh) { this->init_from(mesh.its, mesh.bounding_box()); } void init_from(const indexed_triangle_set& its, const BoundingBoxf3& bbox); + void init_from(const indexed_triangle_set& its); #if ENABLE_SINKING_CONTOURS void init_from(const Polygons& polygons, float z); #endif // ENABLE_SINKING_CONTOURS diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index 64479a39e2..7353288811 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -53,9 +53,9 @@ void GLGizmoBase::Grabber::render(float size, const std::array& render if (! cube_initialized) { // This cannot be done in constructor, OpenGL is not yet // initialized at that point (on Linux at least). - TriangleMesh mesh = make_cube(1., 1., 1.); - mesh.translate(Vec3f(-0.5, -0.5, -0.5)); - const_cast(cube).init_from(mesh); + indexed_triangle_set mesh = its_make_cube(1., 1., 1.); + its_translate(mesh, Vec3f(-0.5, -0.5, -0.5)); + const_cast(cube).init_from(mesh, BoundingBoxf3{ { -0.5, -0.5, -0.5 }, { 0.5, 0.5, 0.5 } }); const_cast(cube_initialized) = true; } @@ -90,9 +90,9 @@ GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, u m_base_color = DEFAULT_BASE_COLOR; m_drag_color = DEFAULT_DRAG_COLOR; m_highlight_color = DEFAULT_HIGHLIGHT_COLOR; - m_cone.init_from(make_cone(1., 1., 2 * PI / 24)); - m_sphere.init_from(make_sphere(1., (2 * M_PI) / 24.)); - m_cylinder.init_from(make_cylinder(1., 1., 2 * PI / 24.)); + m_cone.init_from(its_make_cone(1., 1., 2 * PI / 24)); + m_sphere.init_from(its_make_sphere(1., (2 * M_PI) / 24.)); + m_cylinder.init_from(its_make_cylinder(1., 1., 2 * PI / 24.)); } void GLGizmoBase::set_hover_id(int id) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 5270087be4..01eeebe107 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -287,16 +287,14 @@ void GLGizmoFdmSupports::select_facets_by_angle(float threshold_deg, bool block) float dot_limit = limit.dot(down); // Now calculate dot product of vert_direction and facets' normals. - int idx = -1; + int idx = 0; const indexed_triangle_set &its = mv->mesh().its; for (stl_triangle_vertex_indices face : its.indices) { - stl_vertex vertex[3] = { its.vertices[face[0]], its.vertices[face[1]], its.vertices[face[2]] }; - stl_vertex n = (vertex[2] - vertex[1]).cross(vertex[3] - vertex[2]).normalized(); - ++ idx; - if (n.dot(down) > dot_limit) { + if (its_face_normal(its, face).dot(down) > dot_limit) { m_triangle_selectors[mesh_id]->set_facet(idx, block ? EnforcerBlockerType::BLOCKER : EnforcerBlockerType::ENFORCER); m_triangle_selectors.back()->request_update_render_data(); } + ++ idx; } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index f405f457d1..17630e5c68 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -20,7 +20,7 @@ namespace GUI { GLGizmoHollow::GLGizmoHollow(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) { - m_vbo_cylinder.init_from(make_cylinder(1., 1.)); + m_vbo_cylinder.init_from(its_make_cylinder(1., 1.)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index e7b6a0ad6e..e73a85647e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -20,7 +20,7 @@ GLGizmoMove3D::GLGizmoMove3D(GLCanvas3D& parent, const std::string& icon_filenam , m_starting_box_center(Vec3d::Zero()) , m_starting_box_bottom_center(Vec3d::Zero()) { - m_vbo_cone.init_from(make_cone(1., 1., 2*PI/36)); + m_vbo_cone.init_from(its_make_cone(1., 1., 2*PI/36)); } std::string GLGizmoMove3D::get_tooltip() const