diff --git a/src/admesh/shared.cpp b/src/admesh/shared.cpp index e9f075498..7da2841b0 100644 --- a/src/admesh/shared.cpp +++ b/src/admesh/shared.cpp @@ -29,19 +29,13 @@ #include "stl.h" -void stl_invalidate_shared_vertices(stl_file *stl) -{ - stl->v_indices.clear(); - stl->v_shared.clear(); -} - -void stl_generate_shared_vertices(stl_file *stl) +void stl_generate_shared_vertices(stl_file *stl, indexed_triangle_set &its) { // 3 indices to vertex per face - stl->v_indices.assign(stl->stats.number_of_facets, v_indices_struct()); + its.indices.assign(stl->stats.number_of_facets, v_indices_struct()); // Shared vertices (3D coordinates) - stl->v_shared.clear(); - stl->v_shared.reserve(stl->stats.number_of_facets / 2); + its.vertices.clear(); + its.vertices.reserve(stl->stats.number_of_facets / 2); // A degenerate mesh may contain loops: Traversing a fan will end up in an endless loop // while never reaching the starting face. To avoid these endless loops, traversed faces at each fan traversal @@ -51,11 +45,11 @@ void stl_generate_shared_vertices(stl_file *stl) for (uint32_t facet_idx = 0; facet_idx < stl->stats.number_of_facets; ++ facet_idx) { for (int j = 0; j < 3; ++ j) { - if (stl->v_indices[facet_idx].vertex[j] != -1) + if (its.indices[facet_idx].vertex[j] != -1) // Shared vertex was already assigned. continue; // Create a new shared vertex. - stl->v_shared.emplace_back(stl->facet_start[facet_idx].vertex[j]); + its.vertices.emplace_back(stl->facet_start[facet_idx].vertex[j]); // Traverse the fan around the j-th vertex of the i-th face, assign the newly created shared vertex index to all the neighboring triangles in the triangle fan. int facet_in_fan_idx = facet_idx; bool edge_direction = false; @@ -89,7 +83,7 @@ void stl_generate_shared_vertices(stl_file *stl) next_edge = pivot_vertex; } } - stl->v_indices[facet_in_fan_idx].vertex[pivot_vertex] = stl->v_shared.size() - 1; + its.indices[facet_in_fan_idx].vertex[pivot_vertex] = its.vertices.size() - 1; fan_traversal_facet_visited[facet_in_fan_idx] = fan_traversal_stamp; // next_edge is an index of the starting vertex of the edge, not an index of the opposite vertex to the edge! @@ -130,7 +124,7 @@ void stl_generate_shared_vertices(stl_file *stl) } } -bool stl_write_off(stl_file *stl, const char *file) +bool its_write_off(const indexed_triangle_set &its, const char *file) { /* Open the file */ FILE *fp = boost::nowide::fopen(file, "w"); @@ -143,16 +137,16 @@ bool stl_write_off(stl_file *stl, const char *file) } fprintf(fp, "OFF\n"); - fprintf(fp, "%d %d 0\n", stl->v_shared.size(), stl->stats.number_of_facets); - for (int i = 0; i < stl->v_shared.size(); ++ i) - fprintf(fp, "\t%f %f %f\n", stl->v_shared[i](0), stl->v_shared[i](1), stl->v_shared[i](2)); - for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) - fprintf(fp, "\t3 %d %d %d\n", stl->v_indices[i].vertex[0], stl->v_indices[i].vertex[1], stl->v_indices[i].vertex[2]); + fprintf(fp, "%d %d 0\n", (int)its.vertices.size(), (int)its.indices.size()); + for (int i = 0; i < its.vertices.size(); ++ i) + fprintf(fp, "\t%f %f %f\n", its.vertices[i](0), its.vertices[i](1), its.vertices[i](2)); + for (uint32_t i = 0; i < its.indices.size(); ++ i) + fprintf(fp, "\t3 %d %d %d\n", its.indices[i].vertex[0], its.indices[i].vertex[1], its.indices[i].vertex[2]); fclose(fp); return true; } -bool stl_write_vrml(stl_file *stl, const char *file) +bool its_write_vrml(const indexed_triangle_set &its, const char *file) { /* Open the file */ FILE *fp = boost::nowide::fopen(file, "w"); @@ -180,16 +174,16 @@ bool stl_write_vrml(stl_file *stl, const char *file) fprintf(fp, "\t\t\tpoint [\n"); int i = 0; - for (; i + 1 < stl->v_shared.size(); ++ i) - fprintf(fp, "\t\t\t\t%f %f %f,\n", stl->v_shared[i](0), stl->v_shared[i](1), stl->v_shared[i](2)); - fprintf(fp, "\t\t\t\t%f %f %f]\n", stl->v_shared[i](0), stl->v_shared[i](1), stl->v_shared[i](2)); + for (; i + 1 < its.vertices.size(); ++ i) + fprintf(fp, "\t\t\t\t%f %f %f,\n", its.vertices[i](0), its.vertices[i](1), its.vertices[i](2)); + fprintf(fp, "\t\t\t\t%f %f %f]\n", its.vertices[i](0), its.vertices[i](1), its.vertices[i](2)); fprintf(fp, "\t\t}\n"); fprintf(fp, "\t\tDEF STLTriangles IndexedFaceSet {\n"); fprintf(fp, "\t\t\tcoordIndex [\n"); - for (int i = 0; i + 1 < (int)stl->stats.number_of_facets; ++ i) - fprintf(fp, "\t\t\t\t%d, %d, %d, -1,\n", stl->v_indices[i].vertex[0], stl->v_indices[i].vertex[1], stl->v_indices[i].vertex[2]); - fprintf(fp, "\t\t\t\t%d, %d, %d, -1]\n", stl->v_indices[i].vertex[0], stl->v_indices[i].vertex[1], stl->v_indices[i].vertex[2]); + for (size_t i = 0; i + 1 < its.indices.size(); ++ i) + fprintf(fp, "\t\t\t\t%d, %d, %d, -1,\n", its.indices[i].vertex[0], its.indices[i].vertex[1], its.indices[i].vertex[2]); + fprintf(fp, "\t\t\t\t%d, %d, %d, -1]\n", its.indices[i].vertex[0], its.indices[i].vertex[1], its.indices[i].vertex[2]); fprintf(fp, "\t\t}\n"); fprintf(fp, "\t}\n"); fprintf(fp, "}\n"); @@ -197,7 +191,7 @@ bool stl_write_vrml(stl_file *stl, const char *file) return true; } -bool stl_write_obj(stl_file *stl, const char *file) +bool its_write_obj(const indexed_triangle_set &its, const char *file) { FILE *fp = boost::nowide::fopen(file, "w"); @@ -209,10 +203,65 @@ bool stl_write_obj(stl_file *stl, const char *file) return false; } - for (size_t i = 0; i < stl->v_shared.size(); ++ i) - fprintf(fp, "v %f %f %f\n", stl->v_shared[i](0), stl->v_shared[i](1), stl->v_shared[i](2)); - for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) - fprintf(fp, "f %d %d %d\n", stl->v_indices[i].vertex[0]+1, stl->v_indices[i].vertex[1]+1, stl->v_indices[i].vertex[2]+1); + for (size_t i = 0; i < its.vertices.size(); ++ i) + fprintf(fp, "v %f %f %f\n", its.vertices[i](0), its.vertices[i](1), its.vertices[i](2)); + for (size_t i = 0; i < its.indices.size(); ++ i) + fprintf(fp, "f %d %d %d\n", its.indices[i].vertex[0]+1, its.indices[i].vertex[1]+1, its.indices[i].vertex[2]+1); fclose(fp); return true; } + + +// Check validity of the mesh, assert on error. +bool stl_validate(const stl_file *stl, const indexed_triangle_set &its) +{ + assert(! stl->facet_start.empty()); + assert(stl->facet_start.size() == stl->stats.number_of_facets); + assert(stl->neighbors_start.size() == stl->stats.number_of_facets); + assert(stl->facet_start.size() == stl->neighbors_start.size()); + assert(! stl->neighbors_start.empty()); + assert((its.indices.empty()) == (its.vertices.empty())); + assert(stl->stats.number_of_facets > 0); + assert(its.vertices.empty() || its.indices.size() == stl->stats.number_of_facets); + +#ifdef _DEBUG + // Verify validity of neighborship data. + for (int facet_idx = 0; facet_idx < (int)stl->stats.number_of_facets; ++ facet_idx) { + const stl_neighbors &nbr = stl->neighbors_start[facet_idx]; + const int *vertices = (its.indices.empty()) ? nullptr : its.indices[facet_idx].vertex; + for (int nbr_idx = 0; nbr_idx < 3; ++ nbr_idx) { + int nbr_face = stl->neighbors_start[facet_idx].neighbor[nbr_idx]; + assert(nbr_face < (int)stl->stats.number_of_facets); + if (nbr_face != -1) { + int nbr_vnot = nbr.which_vertex_not[nbr_idx]; + assert(nbr_vnot >= 0 && nbr_vnot < 6); + // Neighbor of the neighbor is the original face. + assert(stl->neighbors_start[nbr_face].neighbor[(nbr_vnot + 1) % 3] == facet_idx); + int vnot_back = stl->neighbors_start[nbr_face].which_vertex_not[(nbr_vnot + 1) % 3]; + assert(vnot_back >= 0 && vnot_back < 6); + assert((nbr_vnot < 3) == (vnot_back < 3)); + assert(vnot_back % 3 == (nbr_idx + 2) % 3); + if (vertices != nullptr) { + // Has shared vertices. + if (nbr_vnot < 3) { + // Faces facet_idx and nbr_face share two vertices accross the common edge. Faces are correctly oriented. + assert((its.indices[nbr_face].vertex[(nbr_vnot + 1) % 3] == vertices[(nbr_idx + 1) % 3] && its.indices[nbr_face].vertex[(nbr_vnot + 2) % 3] == vertices[nbr_idx])); + } else { + // Faces facet_idx and nbr_face share two vertices accross the common edge. Faces are incorrectly oriented, one of them is flipped. + assert((its.indices[nbr_face].vertex[(nbr_vnot + 2) % 3] == vertices[(nbr_idx + 1) % 3] && its.indices[nbr_face].vertex[(nbr_vnot + 1) % 3] == vertices[nbr_idx])); + } + } + } + } + } +#endif /* _DEBUG */ + + return true; +} + +// Check validity of the mesh, assert on error. +bool stl_validate(const stl_file *stl) +{ + indexed_triangle_set its; + return stl_validate(stl, its); +} diff --git a/src/admesh/stl.h b/src/admesh/stl.h index 4aee6048f..bb5d25296 100644 --- a/src/admesh/stl.h +++ b/src/admesh/stl.h @@ -130,21 +130,22 @@ struct stl_stats { struct stl_file { std::vector facet_start; std::vector neighbors_start; - // Indexed face set - std::vector v_indices; - std::vector v_shared; // Statistics stl_stats stats; }; +struct indexed_triangle_set +{ + void clear() { indices.clear(); vertices.clear(); } + std::vector indices; + std::vector vertices; +}; + extern bool stl_open(stl_file *stl, const char *file); extern void stl_stats_out(stl_file *stl, FILE *file, char *input_file); extern bool stl_print_neighbors(stl_file *stl, char *file); -extern void stl_put_little_int(FILE *fp, int value_in); -extern void stl_put_little_float(FILE *fp, float value_in); extern bool stl_write_ascii(stl_file *stl, const char *file, const char *label); extern bool stl_write_binary(stl_file *stl, const char *file, const char *label); -extern void stl_write_binary_block(stl_file *stl, FILE *fp); extern void stl_check_facets_exact(stl_file *stl); extern void stl_check_facets_nearby(stl_file *stl, float tolerance); extern void stl_remove_unconnected_facets(stl_file *stl); @@ -219,12 +220,12 @@ inline void stl_transform(stl_file *stl, const Eigen::Matrixvertex[1] - facet->vertex[0]).cross(facet->vertex[2] - facet->vertex[0]); } @@ -251,6 +252,7 @@ extern void stl_reallocate(stl_file *stl); extern void stl_add_facet(stl_file *stl, const stl_facet *new_facet); // Validate the mesh, assert on error. -extern bool stl_validate(stl_file *stl); +extern bool stl_validate(const stl_file *stl); +extern bool stl_validate(const stl_file *stl, const indexed_triangle_set &its); #endif diff --git a/src/admesh/stlinit.cpp b/src/admesh/stlinit.cpp index 088842d51..44477511f 100644 --- a/src/admesh/stlinit.cpp +++ b/src/admesh/stlinit.cpp @@ -253,8 +253,6 @@ void stl_reset(stl_file *stl) { stl->facet_start.clear(); stl->neighbors_start.clear(); - stl->v_indices.clear(); - stl->v_shared.clear(); memset(&stl->stats, 0, sizeof(stl_stats)); stl->stats.volume = -1.0; } diff --git a/src/admesh/util.cpp b/src/admesh/util.cpp index 685b641b4..f4e4dbf0a 100644 --- a/src/admesh/util.cpp +++ b/src/admesh/util.cpp @@ -73,7 +73,6 @@ void stl_translate(stl_file *stl, float x, float y, float z) stl->facet_start[i].vertex[j] += shift; stl->stats.min = new_min; stl->stats.max += shift; - stl_invalidate_shared_vertices(stl); } /* Translates the stl by x,y,z, relatively from wherever it is currently */ @@ -85,7 +84,6 @@ void stl_translate_relative(stl_file *stl, float x, float y, float z) stl->facet_start[i].vertex[j] += shift; stl->stats.min += shift; stl->stats.max += shift; - stl_invalidate_shared_vertices(stl); } void stl_scale_versor(stl_file *stl, const stl_vertex &versor) @@ -103,7 +101,6 @@ void stl_scale_versor(stl_file *stl, const stl_vertex &versor) for (int i = 0; i < stl->stats.number_of_facets; ++ i) for (int j = 0; j < 3; ++ j) stl->facet_start[i].vertex[j].array() *= s; - stl_invalidate_shared_vertices(stl); } static void calculate_normals(stl_file *stl) @@ -414,50 +411,3 @@ All facets connected. No further nearby check necessary.\n"); stl_verify_neighbors(stl); } } - -// Check validity of the mesh, assert on error. -bool stl_validate(stl_file *stl) -{ - assert(! stl->facet_start.empty()); - assert(stl->facet_start.size() == stl->stats.number_of_facets); - assert(stl->neighbors_start.size() == stl->stats.number_of_facets); - assert(stl->facet_start.size() == stl->neighbors_start.size()); - assert(! stl->neighbors_start.empty()); - assert((stl->v_indices.empty()) == (stl->v_shared.empty())); - assert(stl->stats.number_of_facets > 0); - assert(stl->v_shared.empty() || stl->v_indices.size() == stl->stats.number_of_facets); - -#ifdef _DEBUG - // Verify validity of neighborship data. - for (int facet_idx = 0; facet_idx < (int)stl->stats.number_of_facets; ++ facet_idx) { - const stl_neighbors &nbr = stl->neighbors_start[facet_idx]; - const int *vertices = (stl->v_indices.empty()) ? nullptr : stl->v_indices[facet_idx].vertex; - for (int nbr_idx = 0; nbr_idx < 3; ++ nbr_idx) { - int nbr_face = stl->neighbors_start[facet_idx].neighbor[nbr_idx]; - assert(nbr_face < (int)stl->stats.number_of_facets); - if (nbr_face != -1) { - int nbr_vnot = nbr.which_vertex_not[nbr_idx]; - assert(nbr_vnot >= 0 && nbr_vnot < 6); - // Neighbor of the neighbor is the original face. - assert(stl->neighbors_start[nbr_face].neighbor[(nbr_vnot + 1) % 3] == facet_idx); - int vnot_back = stl->neighbors_start[nbr_face].which_vertex_not[(nbr_vnot + 1) % 3]; - assert(vnot_back >= 0 && vnot_back < 6); - assert((nbr_vnot < 3) == (vnot_back < 3)); - assert(vnot_back % 3 == (nbr_idx + 2) % 3); - if (vertices != nullptr) { - // Has shared vertices. - if (nbr_vnot < 3) { - // Faces facet_idx and nbr_face share two vertices accross the common edge. Faces are correctly oriented. - assert((stl->v_indices[nbr_face].vertex[(nbr_vnot + 1) % 3] == vertices[(nbr_idx + 1) % 3] && stl->v_indices[nbr_face].vertex[(nbr_vnot + 2) % 3] == vertices[nbr_idx])); - } else { - // Faces facet_idx and nbr_face share two vertices accross the common edge. Faces are incorrectly oriented, one of them is flipped. - assert((stl->v_indices[nbr_face].vertex[(nbr_vnot + 2) % 3] == vertices[(nbr_idx + 1) % 3] && stl->v_indices[nbr_face].vertex[(nbr_vnot + 1) % 3] == vertices[nbr_idx])); - } - } - } - } - } -#endif /* _DEBUG */ - - return true; -} diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index d67106656..8298fe222 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -1881,27 +1881,23 @@ namespace Slic3r { volumes_offsets.insert(VolumeToOffsetsMap::value_type(volume, Offsets(vertices_count))).first; - if (!volume->mesh.repaired) - volume->mesh.repair(); + volume->mesh.require_shared_vertices(); - stl_file& stl = volume->mesh.stl; - if (stl.v_shared.empty()) - stl_generate_shared_vertices(&stl); - - if (stl.v_shared.empty()) + const indexed_triangle_set &its = volume->mesh.its; + if (its.vertices.empty()) { add_error("Found invalid mesh"); return false; } - vertices_count += stl.v_shared.size(); + vertices_count += its.vertices.size(); const Transform3d& matrix = volume->get_matrix(); - for (size_t i = 0; i < stl.v_shared.size(); ++i) + for (size_t i = 0; i < its.vertices.size(); ++i) { stream << " <" << VERTEX_TAG << " "; - Vec3f v = (matrix * stl.v_shared[i].cast()).cast(); + Vec3f v = (matrix * its.vertices[i].cast()).cast(); stream << "x=\"" << v(0) << "\" "; stream << "y=\"" << v(1) << "\" "; stream << "z=\"" << v(2) << "\" />\n"; @@ -1920,19 +1916,19 @@ namespace Slic3r { VolumeToOffsetsMap::iterator volume_it = volumes_offsets.find(volume); assert(volume_it != volumes_offsets.end()); - stl_file& stl = volume->mesh.stl; + const indexed_triangle_set &its = volume->mesh.its; // updates triangle offsets volume_it->second.first_triangle_id = triangles_count; - triangles_count += stl.stats.number_of_facets; + triangles_count += its.indices.size(); volume_it->second.last_triangle_id = triangles_count - 1; - for (uint32_t i = 0; i < stl.stats.number_of_facets; ++i) + for (size_t i = 0; i < its.indices.size(); ++ i) { stream << " <" << TRIANGLE_TAG << " "; for (int j = 0; j < 3; ++j) { - stream << "v" << j + 1 << "=\"" << stl.v_indices[i].vertex[j] + volume_it->second.first_vertex_id << "\" "; + stream << "v" << j + 1 << "=\"" << its.indices[i].vertex[j] + volume_it->second.first_vertex_id << "\" "; } stream << "/>\n"; } diff --git a/src/libslic3r/Format/AMF.cpp b/src/libslic3r/Format/AMF.cpp index e81ced3ad..dcd913864 100644 --- a/src/libslic3r/Format/AMF.cpp +++ b/src/libslic3r/Format/AMF.cpp @@ -923,23 +923,22 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config) int num_vertices = 0; for (ModelVolume *volume : object->volumes) { vertices_offsets.push_back(num_vertices); - if (! volume->mesh.repaired) + if (! volume->mesh.repaired) throw std::runtime_error("store_amf() requires repair()"); - auto &stl = volume->mesh.stl; - if (stl.v_shared.empty()) - stl_generate_shared_vertices(&stl); + volume->mesh.require_shared_vertices(); + const indexed_triangle_set &its = volume->mesh.its; const Transform3d& matrix = volume->get_matrix(); - for (size_t i = 0; i < stl.v_shared.size(); ++i) { + for (size_t i = 0; i < its.vertices.size(); ++i) { stream << " \n"; stream << " \n"; - Vec3f v = (matrix * stl.v_shared[i].cast()).cast(); + Vec3f v = (matrix * its.vertices[i].cast()).cast(); stream << " " << v(0) << "\n"; stream << " " << v(1) << "\n"; stream << " " << v(2) << "\n"; stream << " \n"; stream << " \n"; } - num_vertices += stl.v_shared.size(); + num_vertices += its.vertices.size(); } stream << " \n"; for (size_t i_volume = 0; i_volume < object->volumes.size(); ++i_volume) { @@ -956,10 +955,10 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config) if (volume->is_modifier()) stream << " 1\n"; stream << " " << ModelVolume::type_to_string(volume->type()) << "\n"; - for (int i = 0; i < (int)volume->mesh.stl.stats.number_of_facets; ++i) { + for (size_t i = 0; i < (int)volume->mesh.its.indices.size(); ++i) { stream << " \n"; for (int j = 0; j < 3; ++j) - stream << " " << volume->mesh.stl.v_indices[i].vertex[j] + vertices_offset << "\n"; + stream << " " << volume->mesh.its.indices[i].vertex[j] + vertices_offset << "\n"; stream << " \n"; } stream << " \n"; diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 6da7fc0c3..770581c03 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -908,10 +908,11 @@ Polygon ModelObject::convex_hull_2d(const Transform3d &trafo_instance) const Points pts; for (const ModelVolume *v : this->volumes) if (v->is_model_part()) { - const stl_file &stl = v->mesh.stl; Transform3d trafo = trafo_instance * v->get_matrix(); - if (stl.v_shared.empty()) { + const indexed_triangle_set &its = v->mesh.its; + if (its.vertices.empty()) { // Using the STL faces. + const stl_file& stl = v->mesh.stl; for (const stl_facet &facet : stl.facet_start) for (size_t j = 0; j < 3; ++ j) { Vec3d p = trafo * facet.vertex[j].cast(); @@ -919,8 +920,8 @@ Polygon ModelObject::convex_hull_2d(const Transform3d &trafo_instance) const } } else { // Using the shared vertices should be a bit quicker than using the STL faces. - for (size_t i = 0; i < stl.v_shared.size(); ++ i) { - Vec3d p = trafo * stl.v_shared[i].cast(); + for (size_t i = 0; i < its.vertices.size(); ++ i) { + Vec3d p = trafo * its.vertices[i].cast(); pts.emplace_back(coord_t(scale_(p.x())), coord_t(scale_(p.y()))); } } diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index 003affc27..ae35c8a5b 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -238,20 +238,20 @@ bool TriangleMesh::needed_repair() const void TriangleMesh::WriteOBJFile(const char* output_file) { - stl_generate_shared_vertices(&stl); - stl_write_obj(&stl, output_file); + stl_generate_shared_vertices(&stl, its); + its_write_obj(its, output_file); } void TriangleMesh::scale(float factor) { stl_scale(&(this->stl), factor); - stl_invalidate_shared_vertices(&this->stl); + this->its.clear(); } void TriangleMesh::scale(const Vec3d &versor) { stl_scale_versor(&this->stl, versor.cast()); - stl_invalidate_shared_vertices(&this->stl); + this->its.clear(); } void TriangleMesh::translate(float x, float y, float z) @@ -259,7 +259,7 @@ void TriangleMesh::translate(float x, float y, float z) if (x == 0.f && y == 0.f && z == 0.f) return; stl_translate_relative(&(this->stl), x, y, z); - stl_invalidate_shared_vertices(&this->stl); + this->its.clear(); } void TriangleMesh::translate(const Vec3f &displacement) @@ -282,7 +282,7 @@ void TriangleMesh::rotate(float angle, const Axis &axis) } else if (axis == Z) { stl_rotate_z(&(this->stl), angle); } - stl_invalidate_shared_vertices(&this->stl); + this->its.clear(); } void TriangleMesh::rotate(float angle, const Vec3d& axis) @@ -305,13 +305,13 @@ void TriangleMesh::mirror(const Axis &axis) } else if (axis == Z) { stl_mirror_xy(&this->stl); } - stl_invalidate_shared_vertices(&this->stl); + this->its.clear(); } void TriangleMesh::transform(const Transform3d& t, bool fix_left_handed) { stl_transform(&stl, t); - stl_invalidate_shared_vertices(&stl); + this->its.clear(); if (fix_left_handed && t.matrix().block(0, 0, 3, 3).determinant() < 0.) { // Left handed transformation is being applied. It is a good idea to flip the faces and their normals. this->repair(); @@ -322,7 +322,7 @@ void TriangleMesh::transform(const Transform3d& t, bool fix_left_handed) void TriangleMesh::transform(const Matrix3d& m, bool fix_left_handed) { stl_transform(&stl, m); - stl_invalidate_shared_vertices(&stl); + this->its.clear(); if (fix_left_handed && m.determinant() < 0.) { // Left handed transformation is being applied. It is a good idea to flip the faces and their normals. this->repair(); @@ -443,7 +443,7 @@ void TriangleMesh::merge(const TriangleMesh &mesh) { // reset stats and metadata int number_of_facets = this->stl.stats.number_of_facets; - stl_invalidate_shared_vertices(&this->stl); + this->its.clear(); this->repaired = false; // update facet count and allocate more memory @@ -484,9 +484,9 @@ Polygon TriangleMesh::convex_hull() { this->require_shared_vertices(); Points pp; - pp.reserve(this->stl.v_shared.size()); - for (size_t i = 0; i < this->stl.v_shared.size(); ++ i) { - const stl_vertex &v = this->stl.v_shared[i]; + pp.reserve(this->its.vertices.size()); + for (size_t i = 0; i < this->its.vertices.size(); ++ i) { + const stl_vertex &v = this->its.vertices[i]; pp.emplace_back(Point::new_scale(v(0), v(1))); } return Slic3r::Geometry::convex_hull(pp); @@ -504,14 +504,14 @@ BoundingBoxf3 TriangleMesh::bounding_box() const BoundingBoxf3 TriangleMesh::transformed_bounding_box(const Transform3d &trafo) const { BoundingBoxf3 bbox; - if (stl.v_shared.empty()) { + if (this->its.vertices.empty()) { // Using the STL faces. for (const stl_facet &facet : this->stl.facet_start) for (size_t j = 0; j < 3; ++ j) bbox.merge(trafo * facet.vertex[j].cast()); } else { // Using the shared vertices should be a bit quicker than using the STL faces. - for (const stl_vertex &v : this->stl.v_shared) + for (const stl_vertex &v : this->its.vertices) bbox.merge(trafo * v.cast()); } return bbox; @@ -576,11 +576,11 @@ void TriangleMesh::require_shared_vertices() assert(stl_validate(&this->stl)); if (! this->repaired) this->repair(); - if (this->stl.v_shared.empty()) { + if (this->its.vertices.empty()) { BOOST_LOG_TRIVIAL(trace) << "TriangleMeshSlicer::require_shared_vertices - stl_generate_shared_vertices"; - stl_generate_shared_vertices(&(this->stl)); + stl_generate_shared_vertices(&this->stl, this->its); } - assert(stl_validate(&this->stl)); + assert(stl_validate(&this->stl, this->its)); BOOST_LOG_TRIVIAL(trace) << "TriangleMeshSlicer::require_shared_vertices - end"; } @@ -592,9 +592,9 @@ void TriangleMeshSlicer::init(const TriangleMesh *_mesh, throw_on_cancel_callbac throw_on_cancel(); facets_edges.assign(_mesh->stl.stats.number_of_facets * 3, -1); - v_scaled_shared.assign(_mesh->stl.v_shared.size(), stl_vertex()); + v_scaled_shared.assign(_mesh->its.vertices.size(), stl_vertex()); for (size_t i = 0; i < v_scaled_shared.size(); ++ i) - this->v_scaled_shared[i] = _mesh->stl.v_shared[i] / float(SCALING_FACTOR); + this->v_scaled_shared[i] = _mesh->its.vertices[i] / float(SCALING_FACTOR); // Create a mapping from triangle edge into face. struct EdgeToFace { @@ -614,8 +614,8 @@ void TriangleMeshSlicer::init(const TriangleMesh *_mesh, throw_on_cancel_callbac for (uint32_t facet_idx = 0; facet_idx < this->mesh->stl.stats.number_of_facets; ++ facet_idx) for (int i = 0; i < 3; ++ i) { EdgeToFace &e2f = edges_map[facet_idx*3+i]; - e2f.vertex_low = this->mesh->stl.v_indices[facet_idx].vertex[i]; - e2f.vertex_high = this->mesh->stl.v_indices[facet_idx].vertex[(i + 1) % 3]; + e2f.vertex_low = this->mesh->its.indices[facet_idx].vertex[i]; + e2f.vertex_high = this->mesh->its.indices[facet_idx].vertex[(i + 1) % 3]; e2f.face = facet_idx; // 1 based indexing, to be always strictly positive. e2f.face_edge = i + 1; @@ -852,7 +852,7 @@ TriangleMeshSlicer::FacetSliceType TriangleMeshSlicer::slice_facet( // Reorder vertices so that the first one is the one with lowest Z. // This is needed to get all intersection lines in a consistent order // (external on the right of the line) - const int *vertices = this->mesh->stl.v_indices[facet_idx].vertex; + const int *vertices = this->mesh->its.indices[facet_idx].vertex; int i = (facet.vertex[1].z() == min_z) ? 1 : ((facet.vertex[2].z() == min_z) ? 2 : 0); // These are used only if the cut plane is tilted: diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index c16f4a664..75082cfdb 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -69,12 +69,13 @@ public: void reset_repair_stats(); bool needed_repair() const; void require_shared_vertices(); - bool has_shared_vertices() const { return ! stl.v_shared.empty(); } + bool has_shared_vertices() const { return ! this->its.vertices.empty(); } 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; + indexed_triangle_set its; bool repaired; private: diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index fb3b6f7a4..45092f257 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -781,7 +781,7 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool if (i == 0) suffix[0] = 0; else - sprintf(suffix, "%d", i); + sprintf(suffix, "%d", (int)i); std::string new_name = name + suffix; loaded = &this->filaments.load_preset(this->filaments.path_from_name(new_name), new_name, std::move(cfg), i == 0); @@ -1379,7 +1379,7 @@ void PresetBundle::export_configbundle(const std::string &path, bool export_syst for (size_t i = 0; i < this->filament_presets.size(); ++ i) { char suffix[64]; if (i > 0) - sprintf(suffix, "_%d", i); + sprintf(suffix, "_%d", (int)i); else suffix[0] = 0; c << "filament" << suffix << " = " << this->filament_presets[i] << std::endl; diff --git a/xs/xsp/TriangleMesh.xsp b/xs/xsp/TriangleMesh.xsp index 53b052027..3e90bfefd 100644 --- a/xs/xsp/TriangleMesh.xsp +++ b/xs/xsp/TriangleMesh.xsp @@ -98,20 +98,18 @@ SV* TriangleMesh::vertices() CODE: if (!THIS->repaired) CONFESS("vertices() requires repair()"); - - if (THIS->stl.v_shared.empty()) - stl_generate_shared_vertices(&(THIS->stl)); + THIS->require_shared_vertices(); // vertices AV* vertices = newAV(); - av_extend(vertices, THIS->stl.v_shared.size()); - for (size_t i = 0; i < THIS->stl.v_shared.size(); i++) { + av_extend(vertices, THIS->its.vertices.size()); + for (size_t i = 0; i < THIS->its.vertices.size(); i++) { AV* vertex = newAV(); av_store(vertices, i, newRV_noinc((SV*)vertex)); av_extend(vertex, 2); - av_store(vertex, 0, newSVnv(THIS->stl.v_shared[i](0))); - av_store(vertex, 1, newSVnv(THIS->stl.v_shared[i](1))); - av_store(vertex, 2, newSVnv(THIS->stl.v_shared[i](2))); + av_store(vertex, 0, newSVnv(THIS->its.vertices[i](0))); + av_store(vertex, 1, newSVnv(THIS->its.vertices[i](1))); + av_store(vertex, 2, newSVnv(THIS->its.vertices[i](2))); } RETVAL = newRV_noinc((SV*)vertices); @@ -122,9 +120,7 @@ SV* TriangleMesh::facets() CODE: if (!THIS->repaired) CONFESS("facets() requires repair()"); - - if (THIS->stl.v_shared.empty()) - stl_generate_shared_vertices(&(THIS->stl)); + THIS->require_shared_vertices(); // facets AV* facets = newAV(); @@ -133,9 +129,9 @@ TriangleMesh::facets() AV* facet = newAV(); av_store(facets, i, newRV_noinc((SV*)facet)); av_extend(facet, 2); - av_store(facet, 0, newSVnv(THIS->stl.v_indices[i].vertex[0])); - av_store(facet, 1, newSVnv(THIS->stl.v_indices[i].vertex[1])); - av_store(facet, 2, newSVnv(THIS->stl.v_indices[i].vertex[2])); + av_store(facet, 0, newSVnv(THIS->its.indices[i].vertex[0])); + av_store(facet, 1, newSVnv(THIS->its.indices[i].vertex[1])); + av_store(facet, 2, newSVnv(THIS->its.indices[i].vertex[2])); } RETVAL = newRV_noinc((SV*)facets);