From ea5dcf79d2fa86b84dce2e4c001686a0261c1ee2 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Sun, 9 Jun 2024 01:29:52 +0800 Subject: [PATCH 01/24] fix comparison between integers with different signedness and implicit narrowing --- CMakeLists.txt | 4 +- bindings/c/conv.cpp | 6 +-- bindings/c/include/conv.h | 2 +- bindings/c/manifoldc.cpp | 6 +-- meshIO/src/meshIO.cpp | 14 +++---- src/collider/src/collider.cpp | 2 +- src/cross_section/src/cross_section.cpp | 50 +++++++++++-------------- src/manifold/include/manifold.h | 4 +- src/manifold/src/boolean3.cpp | 6 +-- src/manifold/src/boolean_result.cpp | 6 +-- src/manifold/src/constructors.cpp | 16 ++++---- src/manifold/src/csg_tree.cpp | 12 +++--- src/manifold/src/edge_op.cpp | 10 ++--- src/manifold/src/face_op.cpp | 2 +- src/manifold/src/impl.cpp | 34 ++++++++--------- src/manifold/src/impl.h | 10 ++--- src/manifold/src/manifold.cpp | 10 ++--- src/manifold/src/properties.cpp | 26 ++++++------- src/manifold/src/smoothing.cpp | 14 +++---- src/manifold/src/sort.cpp | 29 +++++++------- src/manifold/src/subdivision.cpp | 11 +++--- src/polygon/include/polygon.h | 2 +- src/polygon/src/polygon.cpp | 2 +- src/utilities/include/hashtable.h | 2 +- src/utilities/include/sparse.h | 2 +- src/utilities/include/vec.h | 4 ++ test/manifold_test.cpp | 16 +++++--- test/smooth_test.cpp | 10 ++--- test/test_main.cpp | 22 +++++------ 29 files changed, 167 insertions(+), 167 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index de328b85a..78eab0404 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,10 +86,10 @@ if (MSVC) set(MANIFOLD_FLAGS ${MANIFOLD_FLAGS} /DNOMINMAX) else() if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(WARNING_FLAGS -Werror -Wall -Wno-sign-compare -Wno-unused -Wno-array-bounds + set(WARNING_FLAGS -Werror -Wall -Wno-unused -Wno-array-bounds -Wno-stringop-overflow -Wno-alloc-size-larger-than) else() - set(WARNING_FLAGS -Werror -Wall -Wno-sign-compare -Wno-unused) + set(WARNING_FLAGS -Werror -Wall -Wno-unused) endif() set(MANIFOLD_FLAGS ${MANIFOLD_FLAGS} ${WARNING_FLAGS}) endif() diff --git a/bindings/c/conv.cpp b/bindings/c/conv.cpp index 4f074639e..253501dec 100644 --- a/bindings/c/conv.cpp +++ b/bindings/c/conv.cpp @@ -227,7 +227,7 @@ glm::vec4 from_c(ManifoldVec4 v) { return glm::vec4(v.x, v.y, v.z, v.w); } std::vector vector_of_vec_array(ManifoldVec3 *vs, size_t length) { auto vec = std::vector(); - for (int i = 0; i < length; ++i) { + for (size_t i = 0; i < length; ++i) { vec.push_back(from_c(vs[i])); } return vec; @@ -235,7 +235,7 @@ std::vector vector_of_vec_array(ManifoldVec3 *vs, size_t length) { std::vector vector_of_vec_array(ManifoldIVec3 *vs, size_t length) { auto vec = std::vector(); - for (int i = 0; i < length; ++i) { + for (size_t i = 0; i < length; ++i) { vec.push_back(from_c(vs[i])); } return vec; @@ -243,7 +243,7 @@ std::vector vector_of_vec_array(ManifoldIVec3 *vs, size_t length) { std::vector vector_of_vec_array(ManifoldVec4 *vs, size_t length) { auto vec = std::vector(); - for (int i = 0; i < length; ++i) { + for (size_t i = 0; i < length; ++i) { vec.push_back(from_c(vs[i])); } return vec; diff --git a/bindings/c/include/conv.h b/bindings/c/include/conv.h index fee7653a1..4635c4f78 100644 --- a/bindings/c/include/conv.h +++ b/bindings/c/include/conv.h @@ -67,7 +67,7 @@ std::vector vector_of_vec_array(ManifoldVec4 *vs, size_t length); template std::vector vector_of_array(T *ts, size_t length) { auto vec = std::vector(); - for (int i = 0; i < length; ++i) { + for (size_t i = 0; i < length; ++i) { vec.push_back(ts[i]); } return vec; diff --git a/bindings/c/manifoldc.cpp b/bindings/c/manifoldc.cpp index 28874a1ef..92d297b44 100644 --- a/bindings/c/manifoldc.cpp +++ b/bindings/c/manifoldc.cpp @@ -58,7 +58,7 @@ extern "C" { ManifoldSimplePolygon *manifold_simple_polygon(void *mem, ManifoldVec2 *ps, size_t length) { auto vec = new (mem) std::vector; - for (int i = 0; i < length; ++i) { + for (size_t i = 0; i < length; ++i) { vec->push_back({ps[i].x, ps[i].y}); } return to_c(vec); @@ -68,7 +68,7 @@ ManifoldPolygons *manifold_polygons(void *mem, ManifoldSimplePolygon **ps, size_t length) { auto vec = new (mem) std::vector; auto polys = reinterpret_cast(ps); - for (int i = 0; i < length; ++i) { + for (size_t i = 0; i < length; ++i) { vec->push_back(*polys[i]); } return to_c(vec); @@ -216,7 +216,7 @@ ManifoldManifold *manifold_batch_hull(void *mem, ManifoldManifoldVec *ms) { ManifoldManifold *manifold_hull_pts(void *mem, ManifoldVec3 *ps, size_t length) { std::vector vec(length); - for (int i = 0; i < length; ++i) { + for (size_t i = 0; i < length; ++i) { vec[i] = {ps[i].x, ps[i].y, ps[i].z}; } auto hulled = Manifold::Hull(vec); diff --git a/meshIO/src/meshIO.cpp b/meshIO/src/meshIO.cpp index 3e33d3fc6..3a36ebc8e 100644 --- a/meshIO/src/meshIO.cpp +++ b/meshIO/src/meshIO.cpp @@ -144,14 +144,14 @@ Mesh ImportMesh(const std::string& filename, bool forceCleanup) { ASSERT(scene, userErr, importer.GetErrorString()); Mesh mesh_out; - for (int i = 0; i < scene->mNumMeshes; ++i) { + for (size_t i = 0; i < scene->mNumMeshes; ++i) { const aiMesh* mesh_i = scene->mMeshes[i]; - for (int j = 0; j < mesh_i->mNumVertices; ++j) { + for (size_t j = 0; j < mesh_i->mNumVertices; ++j) { const aiVector3D vert = mesh_i->mVertices[j]; mesh_out.vertPos.push_back(isYup ? glm::vec3(vert.z, vert.x, vert.y) : glm::vec3(vert.x, vert.y, vert.z)); } - for (int j = 0; j < mesh_i->mNumFaces; ++j) { + for (size_t j = 0; j < mesh_i->mNumFaces; ++j) { const aiFace face = mesh_i->mFaces[j]; ASSERT(face.mNumIndices == 3, userErr, "Non-triangular face in " + filename); @@ -214,7 +214,7 @@ void ExportMesh(const std::string& filename, const MeshGL& mesh, ASSERT(validChannels, userErr, "Invalid colorChannels."); if (hasColor) mesh_out->mColors[0] = new aiColor4D[mesh_out->mNumVertices]; - for (int i = 0; i < mesh_out->mNumVertices; ++i) { + for (size_t i = 0; i < mesh_out->mNumVertices; ++i) { glm::vec3 v; for (int j : {0, 1, 2}) v[j] = mesh.vertProperties[i * mesh.numProp + j]; mesh_out->mVertices[i] = @@ -242,7 +242,7 @@ void ExportMesh(const std::string& filename, const MeshGL& mesh, mesh_out->mNumFaces = mesh.NumTri(); mesh_out->mFaces = new aiFace[mesh_out->mNumFaces]; - for (int i = 0; i < mesh_out->mNumFaces; ++i) { + for (size_t i = 0; i < mesh_out->mNumFaces; ++i) { aiFace& face = mesh_out->mFaces[i]; face.mNumIndices = 3; face.mIndices = new glm::uint[face.mNumIndices]; @@ -295,7 +295,7 @@ void ExportMesh(const std::string& filename, const Mesh& mesh, mesh_out->mColors[0] = new aiColor4D[mesh_out->mNumVertices]; } - for (int i = 0; i < mesh_out->mNumVertices; ++i) { + for (size_t i = 0; i < mesh_out->mNumVertices; ++i) { const glm::vec3& v = mesh.vertPos[i]; mesh_out->mVertices[i] = isYup ? aiVector3D(v.y, v.z, v.x) : aiVector3D(v.x, v.y, v.z); @@ -313,7 +313,7 @@ void ExportMesh(const std::string& filename, const Mesh& mesh, mesh_out->mNumFaces = mesh.triVerts.size(); mesh_out->mFaces = new aiFace[mesh_out->mNumFaces]; - for (int i = 0; i < mesh_out->mNumFaces; ++i) { + for (size_t i = 0; i < mesh_out->mNumFaces; ++i) { aiFace& face = mesh_out->mFaces[i]; face.mNumIndices = 3; face.mIndices = new glm::uint[face.mNumIndices]; diff --git a/src/collider/src/collider.cpp b/src/collider/src/collider.cpp index 7a4ed75f5..becc04401 100644 --- a/src/collider/src/collider.cpp +++ b/src/collider/src/collider.cpp @@ -84,7 +84,7 @@ struct CreateRadixTree { } int PrefixLength(int i, int j) const { - if (j < 0 || j >= leafMorton_.size()) { + if (j < 0 || j >= static_cast(leafMorton_.size())) { return -1; } else { int out; diff --git a/src/cross_section/src/cross_section.cpp b/src/cross_section/src/cross_section.cpp index a7bb15c29..d2f9b8402 100644 --- a/src/cross_section/src/cross_section.cpp +++ b/src/cross_section/src/cross_section.cpp @@ -101,7 +101,7 @@ C2::PathsD transform(const C2::PathsD ps, const glm::mat3x2 m) { for (auto path : ps) { auto sz = path.size(); auto s = C2::PathD(sz); - for (int i = 0; i < sz; ++i) { + for (size_t i = 0; i < sz; ++i) { auto idx = invert ? sz - 1 - i : i; s[idx] = v2_to_pd(m * glm::vec3(path[i].x, path[i].y, 1)); } @@ -117,10 +117,10 @@ std::shared_ptr shared_paths(const C2::PathsD& ps) { // forward declaration for mutual recursion void decompose_hole(const C2::PolyTreeD* outline, std::vector& polys, C2::PathsD& poly, - int n_holes, int j); + size_t n_holes, size_t j); void decompose_outline(const C2::PolyTreeD* tree, - std::vector& polys, int i) { + std::vector& polys, size_t i) { auto n_outlines = tree->Count(); if (i < n_outlines) { auto outline = tree->Child(i); @@ -137,7 +137,7 @@ void decompose_outline(const C2::PolyTreeD* tree, void decompose_hole(const C2::PolyTreeD* outline, std::vector& polys, C2::PathsD& poly, - int n_holes, int j) { + size_t n_holes, size_t j) { if (j < n_holes) { auto child = outline->Child(j); decompose_outline(child, polys, 0); @@ -146,7 +146,7 @@ void decompose_hole(const C2::PolyTreeD* outline, } } -void flatten(const C2::PolyTreeD* tree, C2::PathsD& polys, int i) { +void flatten(const C2::PolyTreeD* tree, C2::PathsD& polys, size_t i) { auto n_outlines = tree->Count(); if (i < n_outlines) { auto outline = tree->Child(i); @@ -177,33 +177,28 @@ void HullBacktrack(const glm::vec2& pt, std::vector& stack) { // https://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain // This is the same algorithm (Andrew, also called Montone Chain). C2::PathD HullImpl(SimplePolygon& pts) { - int len = pts.size(); + size_t len = pts.size(); if (len < 3) return C2::PathD(); // not enough points to create a polygon std::sort(pts.begin(), pts.end(), V2Lesser); auto lower = std::vector{}; - for (int i = 0; i < len; i++) { - HullBacktrack(pts[i], lower); - lower.push_back(pts[i]); + for (auto& pt : pts) { + HullBacktrack(pt, lower); + lower.push_back(pt); } auto upper = std::vector{}; - for (int i = len - 1; i >= 0; i--) { - HullBacktrack(pts[i], upper); - upper.push_back(pts[i]); + for (auto pt_iter = pts.rbegin(); pt_iter != pts.rend(); pt_iter++) { + HullBacktrack(*pt_iter, upper); + upper.push_back(*pt_iter); } upper.pop_back(); lower.pop_back(); - auto path = C2::PathD(lower.size() + upper.size()); - for (int i = 0; i < lower.size(); i++) { - path[i] = v2_to_pd(lower[i]); - } - auto llen = lower.size(); - int sz = upper.size(); // "fix" -Waggressive-loop-optimizations warning. - for (int i = 0; i < sz; i++) { - path[i + llen] = v2_to_pd(upper[i]); - } + auto path = C2::PathD(); + path.reserve(lower.size() + upper.size()); + for (const auto& l : lower) path.push_back(v2_to_pd(l)); + for (const auto& u : upper) path.push_back(v2_to_pd(u)); return path; } } // namespace @@ -381,12 +376,12 @@ CrossSection CrossSection::BatchBoolean( auto subjs = crossSections[0].GetPaths(); int n_clips = 0; - for (int i = 1; i < crossSections.size(); ++i) { + for (size_t i = 1; i < crossSections.size(); ++i) { n_clips += crossSections[i].GetPaths()->paths_.size(); } auto clips = C2::PathsD(); clips.reserve(n_clips); - for (int i = 1; i < crossSections.size(); ++i) { + for (size_t i = 1; i < crossSections.size(); ++i) { auto ps = crossSections[i].GetPaths(); clips.insert(clips.end(), ps->paths_.begin(), ps->paths_.end()); } @@ -471,12 +466,11 @@ std::vector CrossSection::Decompose() const { auto polys = std::vector(); decompose_outline(&tree, polys, 0); - auto n_polys = polys.size(); - auto comps = std::vector(n_polys); + auto comps = std::vector(); + comps.reserve(polys.size()); // reverse the stack while wrapping - for (int i = 0; i < n_polys; ++i) { - comps[n_polys - i - 1] = CrossSection(shared_paths(polys[i])); - } + for (auto poly = polys.rbegin(); poly != polys.rend(); ++poly) + comps.emplace_back(CrossSection(shared_paths(*poly))); return comps; } diff --git a/src/manifold/include/manifold.h b/src/manifold/include/manifold.h index fa9a0a45a..988b53206 100644 --- a/src/manifold/include/manifold.h +++ b/src/manifold/include/manifold.h @@ -47,13 +47,13 @@ class CsgLeafNode; struct MeshGL { /// Number of property vertices uint32_t NumVert() const { - if (vertProperties.size() / numProp >= std::numeric_limits::max()) + if (vertProperties.size() / numProp >= std::numeric_limits::max()) throw std::out_of_range("mesh too large"); return vertProperties.size() / numProp; }; /// Number of triangles uint32_t NumTri() const { - if (vertProperties.size() / numProp >= std::numeric_limits::max()) + if (vertProperties.size() / numProp >= std::numeric_limits::max()) throw std::out_of_range("mesh too large"); return triVerts.size() / 3; }; diff --git a/src/manifold/src/boolean3.cpp b/src/manifold/src/boolean3.cpp index 5ed8660d3..979f448de 100644 --- a/src/manifold/src/boolean3.cpp +++ b/src/manifold/src/boolean3.cpp @@ -137,7 +137,7 @@ inline thrust::pair Shadow01( // https://github.com/scandum/binary_search/blob/master/README.md // much faster than standard binary search on large arrays -size_t monobound_quaternary_search(VecView array, int64_t key) { +ssize_t monobound_quaternary_search(VecView array, int64_t key) { if (array.size() == 0) { return -1; } @@ -394,7 +394,7 @@ struct Kernel12 { for (int vert : {edge.startVert, edge.endVert}) { const int64_t key = forward ? SparseIndices::EncodePQ(vert, q2) : SparseIndices::EncodePQ(q2, vert); - const size_t idx = monobound_quaternary_search(p0q2, key); + const ssize_t idx = monobound_quaternary_search(p0q2, key); if (idx != -1) { const int s = s02[idx]; x12 += s * ((vert == edge.startVert) == forward ? 1 : -1); @@ -415,7 +415,7 @@ struct Kernel12 { const int q1F = edge.IsForward() ? q1 : edge.pairedHalfedge; const int64_t key = forward ? SparseIndices::EncodePQ(p1, q1F) : SparseIndices::EncodePQ(q1F, p1); - const size_t idx = monobound_quaternary_search(p1q1, key); + const ssize_t idx = monobound_quaternary_search(p1q1, key); if (idx != -1) { // s is implicitly zero for anything not found const int s = s11[idx]; x12 -= s * (edge.IsForward() ? 1 : -1); diff --git a/src/manifold/src/boolean_result.cpp b/src/manifold/src/boolean_result.cpp index c6750aca2..3da188824 100644 --- a/src/manifold/src/boolean_result.cpp +++ b/src/manifold/src/boolean_result.cpp @@ -603,10 +603,10 @@ void CreateProperties(Manifold::Impl &outR, const Manifold::Impl &inP, } else { auto &bin = propIdx[key.y]; bool bFound = false; - for (int k = 0; k < bin.size(); ++k) { - if (bin[k].first == glm::ivec3(key.x, key.z, key.w)) { + for (const auto &b : bin) { + if (b.first == glm::ivec3(key.x, key.z, key.w)) { bFound = true; - outR.meshRelation_.triProperties[tri][i] = bin[k].second; + outR.meshRelation_.triProperties[tri][i] = b.second; break; } } diff --git a/src/manifold/src/constructors.cpp b/src/manifold/src/constructors.cpp index 035020166..21ee2038d 100644 --- a/src/manifold/src/constructors.cpp +++ b/src/manifold/src/constructors.cpp @@ -271,13 +271,13 @@ Manifold Manifold::Extrude(const CrossSection& crossSection, float height, glm::vec2 scale = glm::mix(glm::vec2(1.0f), scaleTop, alpha); glm::mat2 rotation(cosd(phi), sind(phi), -sind(phi), cosd(phi)); glm::mat2 transform = glm::mat2(scale.x, 0.0f, 0.0f, scale.y) * rotation; - int j = 0; - int idx = 0; + size_t j = 0; + size_t idx = 0; for (const auto& poly : polygons) { - for (int vert = 0; vert < poly.size(); ++vert) { - int offset = idx + nCrossSection * i; - int thisVert = vert + offset; - int lastVert = (vert == 0 ? poly.size() : vert) - 1 + offset; + for (size_t vert = 0; vert < poly.size(); ++vert) { + size_t offset = idx + nCrossSection * i; + size_t thisVert = vert + offset; + size_t lastVert = (vert == 0 ? poly.size() : vert) - 1 + offset; if (i == nDivisions && isCone) { triVerts.push_back({nCrossSection * i + j, lastVert - nCrossSection, thisVert - nCrossSection}); @@ -294,7 +294,7 @@ Manifold Manifold::Extrude(const CrossSection& crossSection, float height, } } if (isCone) - for (int j = 0; j < polygons.size(); ++j) // Duplicate vertex for Genus + for (size_t j = 0; j < polygons.size(); ++j) // Duplicate vertex for Genus vertPos.push_back({0.0f, 0.0f, height}); std::vector top = TriangulateIdx(polygonsIndexed); for (const glm::ivec3& tri : top) { @@ -379,7 +379,7 @@ Manifold Manifold::Revolve(const CrossSection& crossSection, } } - for (int polyVert = 0; polyVert < poly.size(); ++polyVert) { + for (size_t polyVert = 0; polyVert < poly.size(); ++polyVert) { const int startPosIndex = vertPos.size(); if (!isFullRevolution) startPoses.push_back(startPosIndex); diff --git a/src/manifold/src/csg_tree.cpp b/src/manifold/src/csg_tree.cpp index 610d3e1e1..bf1950d73 100644 --- a/src/manifold/src/csg_tree.cpp +++ b/src/manifold/src/csg_tree.cpp @@ -74,7 +74,7 @@ struct UpdateMeshIDs { struct CheckOverlap { VecView boxes; const size_t i; - bool operator()(int j) { return boxes[i].DoesOverlap(boxes[j]); } + bool operator()(size_t j) { return boxes[i].DoesOverlap(boxes[j]); } }; using SharedImpl = std::variant, @@ -313,7 +313,7 @@ Manifold::Impl CsgLeafNode::Compose( UpdateMeshIDs({offset})); }); - for (int i = 0; i < nodes.size(); i++) { + for (size_t i = 0; i < nodes.size(); i++) { auto &node = nodes[i]; const int offset = i * Manifold::Impl::meshIDCounter_; @@ -546,11 +546,9 @@ void CsgOpNode::BatchUnion() const { : 0; Vec boxes; boxes.reserve(children_.size() - start); - for (int i = start; i < children_.size(); i++) { - boxes.push_back(std::dynamic_pointer_cast(children_[i]) - ->GetImpl() - ->bBox_); - } + for (const auto &child : children_) + boxes.push_back( + std::dynamic_pointer_cast(child)->GetImpl()->bBox_); // partition the children into a set of disjoint sets // each set contains a set of children that are pairwise disjoint std::vector> disjointSets; diff --git a/src/manifold/src/edge_op.cpp b/src/manifold/src/edge_op.cpp index 51460b911..0efb68588 100644 --- a/src/manifold/src/edge_op.cpp +++ b/src/manifold/src/edge_op.cpp @@ -112,7 +112,7 @@ struct SwappableEdge { struct SortEntry { int start; int end; - int index; + unsigned int index; inline bool operator<(const SortEntry& other) const { return start == other.start ? end < other.end : start < other.start; } @@ -156,14 +156,14 @@ void Manifold::Impl::SimplifyTopology() { ZoneScopedN("DedupeEdge"); Vec entries; entries.reserve(nbEdges / 2); - for (int i = 0; i < nbEdges; ++i) { + for (unsigned int i = 0; i < nbEdges; ++i) { if (halfedge_[i].IsForward()) { entries.push_back({halfedge_[i].startVert, halfedge_[i].endVert, i}); } } stable_sort(policy, entries.begin(), entries.end()); - for (int i = 0; i < entries.size() - 1; ++i) { + for (size_t i = 0; i < entries.size() - 1; ++i) { if (entries[i].start == entries[i + 1].start && entries[i].end == entries[i + 1].end) { DedupeEdge(entries[i].index); @@ -525,7 +525,7 @@ void Manifold::Impl::CollapseEdge(const int edge, std::vector& edges) { const int vert = halfedge_[current].endVert; const int next = halfedge_[current].pairedHalfedge; - for (int i = 0; i < edges.size(); ++i) { + for (size_t i = 0; i < edges.size(); ++i) { if (vert == halfedge_[edges[i]].endVert) { FormLoop(edges[i], current); start = next; @@ -659,7 +659,7 @@ void Manifold::Impl::SplitPinchedVerts() { ZoneScoped; std::vector vertProcessed(NumVert(), false); std::vector halfedgeProcessed(halfedge_.size(), false); - for (int i = 0; i < halfedge_.size(); ++i) { + for (size_t i = 0; i < halfedge_.size(); ++i) { if (halfedgeProcessed[i]) continue; int vert = halfedge_[i].startVert; if (vertProcessed[vert]) { diff --git a/src/manifold/src/face_op.cpp b/src/manifold/src/face_op.cpp index 29bc90488..32861b963 100644 --- a/src/manifold/src/face_op.cpp +++ b/src/manifold/src/face_op.cpp @@ -237,7 +237,7 @@ CrossSection Manifold::Impl::Slice(float height) const { collider_.Collisions(query.cview()); std::unordered_set tris; - for (int i = 0; i < collisions.size(); ++i) { + for (size_t i = 0; i < collisions.size(); ++i) { const int tri = collisions.Get(i, 1); float min = std::numeric_limits::infinity(); float max = -std::numeric_limits::infinity(); diff --git a/src/manifold/src/impl.cpp b/src/manifold/src/impl.cpp index eb0d0932f..9543d14df 100644 --- a/src/manifold/src/impl.cpp +++ b/src/manifold/src/impl.cpp @@ -327,13 +327,9 @@ void DedupePropVerts(manifold::Vec& triProp, const int numLabels = GetLabels(vertLabels, vert2vert, vert2vert.size()); std::vector label2vert(numLabels); - for (int v = 0; v < vert2vert.size(); ++v) { - label2vert[vertLabels[v]] = v; - } - for (int tri = 0; tri < triProp.size(); ++tri) { - for (int i : {0, 1, 2}) - triProp[tri][i] = label2vert[vertLabels[triProp[tri][i]]]; - } + for (size_t v = 0; v < vert2vert.size(); ++v) label2vert[vertLabels[v]] = v; + for (auto& prop : triProp) + for (int i : {0, 1, 2}) prop[i] = label2vert[vertLabels[prop[i]]]; } } // namespace @@ -349,8 +345,8 @@ Manifold::Impl::Impl(const MeshGL& meshGL, std::vector propertyTolerance) { Mesh mesh; mesh.precision = meshGL.precision; - const int numVert = meshGL.NumVert(); - const int numTri = meshGL.NumTri(); + const auto numVert = meshGL.NumVert(); + const auto numTri = meshGL.NumTri(); if (meshGL.numProp > 3 && static_cast(numVert) * static_cast(meshGL.numProp - 3) >= @@ -391,7 +387,7 @@ Manifold::Impl::Impl(const MeshGL& meshGL, for (size_t i = 0; i < meshGL.mergeFromVert.size(); ++i) { const int from = meshGL.mergeFromVert[i]; const int to = meshGL.mergeToVert[i]; - if (from >= numVert || to >= numVert) { + if (from >= static_cast(numVert) || to >= static_cast(numVert)) { MarkFailure(Error::MergeIndexOutOfBounds); return; } @@ -400,7 +396,7 @@ Manifold::Impl::Impl(const MeshGL& meshGL, for (size_t i = 0; i < numTri; ++i) { for (const size_t j : {0, 1, 2}) { const int vert = meshGL.triVerts[3 * i + j]; - if (vert < 0 || vert >= numVert) { + if (vert < 0 || vert >= static_cast(numVert)) { MarkFailure(Error::VertexOutOfBounds); return; } @@ -419,23 +415,23 @@ Manifold::Impl::Impl(const MeshGL& meshGL, } } - const int numProp = meshGL.numProp - 3; + const auto numProp = meshGL.numProp - 3; relation.numProp = numProp; relation.properties.resize(meshGL.NumVert() * numProp); // This will have unreferenced duplicate positions that will be removed by // Impl::RemoveUnreferencedVerts(). mesh.vertPos.resize(meshGL.NumVert()); - for (int i = 0; i < meshGL.NumVert(); ++i) { + for (size_t i = 0; i < meshGL.NumVert(); ++i) { for (const int j : {0, 1, 2}) mesh.vertPos[i][j] = meshGL.vertProperties[meshGL.numProp * i + j]; - for (int j = 0; j < numProp; ++j) + for (size_t j = 0; j < numProp; ++j) relation.properties[i * numProp + j] = meshGL.vertProperties[meshGL.numProp * i + 3 + j]; } mesh.halfedgeTangent.resize(meshGL.halfedgeTangent.size() / 4); - for (int i = 0; i < mesh.halfedgeTangent.size(); ++i) { + for (size_t i = 0; i < mesh.halfedgeTangent.size(); ++i) { for (const int j : {0, 1, 2, 3}) mesh.halfedgeTangent[i][j] = meshGL.halfedgeTangent[4 * i + j]; } @@ -452,10 +448,10 @@ Manifold::Impl::Impl(const MeshGL& meshGL, } relation.triRef.resize(meshGL.NumTri()); const int startID = Impl::ReserveIDs(meshGL.runOriginalID.size()); - for (int i = 0; i < meshGL.runOriginalID.size(); ++i) { + for (size_t i = 0; i < meshGL.runOriginalID.size(); ++i) { const int meshID = startID + i; const int originalID = meshGL.runOriginalID[i]; - for (int tri = runIndex[i] / 3; tri < runIndex[i + 1] / 3; ++tri) { + for (size_t tri = runIndex[i] / 3; tri < runIndex[i + 1] / 3; ++tri) { TriRef& ref = relation.triRef[tri]; ref.meshID = meshID; ref.originalID = originalID; @@ -652,7 +648,7 @@ void Manifold::Impl::CreateFaces(const std::vector& propertyTolerance) { const int numComponent = GetLabels(components, face2face, NumTri()); Vec comp2tri(numComponent, -1); - for (int tri = 0; tri < NumTri(); ++tri) { + for (size_t tri = 0; tri < NumTri(); ++tri) { const int comp = components[tri]; const int current = comp2tri[comp]; if (current < 0 || triArea[tri] > triArea[current]) { @@ -666,7 +662,7 @@ void Manifold::Impl::CreateFaces(const std::vector& propertyTolerance) { {comp2tri, halfedge_, vertPos_, &components, precision_})); Vec& triRef = meshRelation_.triRef; - for (int tri = 0; tri < NumTri(); ++tri) { + for (size_t tri = 0; tri < NumTri(); ++tri) { const int referenceTri = comp2tri[components[tri]]; if (referenceTri >= 0) { triRef[tri].tri = referenceTri; diff --git a/src/manifold/src/impl.h b/src/manifold/src/impl.h index 5c64b096f..47531fdc4 100644 --- a/src/manifold/src/impl.h +++ b/src/manifold/src/impl.h @@ -109,11 +109,11 @@ struct Manifold::Impl { bool inverted = false) const; bool IsEmpty() const { return NumVert() == 0; } - int NumVert() const { return vertPos_.size(); } - int NumEdge() const { return halfedge_.size() / 2; } - int NumTri() const { return halfedge_.size() / 3; } - int NumProp() const { return meshRelation_.numProp; } - int NumPropVert() const { + size_t NumVert() const { return vertPos_.size(); } + size_t NumEdge() const { return halfedge_.size() / 2; } + size_t NumTri() const { return halfedge_.size() / 3; } + size_t NumProp() const { return meshRelation_.numProp; } + size_t NumPropVert() const { return NumProp() == 0 ? NumVert() : meshRelation_.properties.size() / NumProp(); } diff --git a/src/manifold/src/manifold.cpp b/src/manifold/src/manifold.cpp index c0174e71e..e1e0a7abf 100644 --- a/src/manifold/src/manifold.cpp +++ b/src/manifold/src/manifold.cpp @@ -294,8 +294,8 @@ MeshGL Manifold::GetMeshGL(glm::ivec3 normalIdx) const { std::vector> vertPropPair(impl.NumVert()); out.vertProperties.reserve(numVert * static_cast(out.numProp)); - for (int run = 0; run < out.runOriginalID.size(); ++run) { - for (int tri = out.runIndex[run] / 3; tri < out.runIndex[run + 1] / 3; + for (size_t run = 0; run < out.runOriginalID.size(); ++run) { + for (size_t tri = out.runIndex[run] / 3; tri < out.runIndex[run + 1] / 3; ++tri) { const glm::ivec3 triProp = impl.meshRelation_.triProperties[triNew2Old[tri]]; @@ -305,10 +305,10 @@ MeshGL Manifold::GetMeshGL(glm::ivec3 normalIdx) const { auto& bin = vertPropPair[vert]; bool bFound = false; - for (int k = 0; k < bin.size(); ++k) { - if (bin[k].x == prop) { + for (const auto& b : bin) { + if (b.x == prop) { bFound = true; - out.triVerts[3 * tri + i] = bin[k].y; + out.triVerts[3 * tri + i] = b.y; break; } } diff --git a/src/manifold/src/properties.cpp b/src/manifold/src/properties.cpp index 17e89f842..7285077be 100644 --- a/src/manifold/src/properties.cpp +++ b/src/manifold/src/properties.cpp @@ -102,7 +102,7 @@ struct CurvatureAngles { VecView vertPos; VecView triNormal; - void operator()(int tri) { + void operator()(size_t tri) { glm::vec3 edge[3]; glm::vec3 edgeLength(0.0); for (int i : {0, 1, 2}) { @@ -161,9 +161,9 @@ struct UpdateProperties { const int meanIdx; // FIXME: race condition - void operator()(thrust::tuple inOut) { + void operator()(thrust::tuple inOut) { glm::ivec3& triProp = thrust::get<0>(inOut); - const int tri = thrust::get<1>(inOut); + const auto tri = thrust::get<1>(inOut); for (const int i : {0, 1, 2}) { const int vert = halfedge[3 * tri + i].startVert; @@ -201,7 +201,7 @@ struct CheckHalfedges { const Halfedge paired = halfedges[halfedge.pairedHalfedge]; bool good = true; - good &= paired.pairedHalfedge == edge; + good &= paired.pairedHalfedge == static_cast(edge); good &= halfedge.startVert != halfedge.endVert; good &= halfedge.startVert == paired.endVert; good &= halfedge.endVert == paired.startVert; @@ -212,7 +212,7 @@ struct CheckHalfedges { struct NoDuplicates { VecView halfedges; - bool operator()(int edge) { + bool operator()(size_t edge) { const Halfedge halfedge = halfedges[edge]; if (halfedge.startVert == -1 && halfedge.endVert == -1 && halfedge.pairedHalfedge == -1) @@ -228,7 +228,7 @@ struct CheckCCW { VecView triNormal; const float tol; - bool operator()(int face) { + bool operator()(size_t face) { if (halfedges[3 * face].pairedHalfedge < 0) return true; const glm::mat3x2 projection = GetAxisAlignedProjection(triNormal[face]); @@ -293,7 +293,7 @@ bool Manifold::Impl::Is2Manifold() const { Vec halfedge(halfedge_); stable_sort(policy, halfedge.begin(), halfedge.end()); - return all_of(policy, countAt(0), countAt(2 * NumEdge() - 1), + return all_of(policy, countAt(0_z), countAt(2 * NumEdge() - 1), NoDuplicates({halfedge})); } @@ -302,7 +302,7 @@ bool Manifold::Impl::Is2Manifold() const { */ bool Manifold::Impl::MatchesTriNormals() const { if (halfedge_.size() == 0 || faceNormal_.size() != NumTri()) return true; - return all_of(autoPolicy(NumTri()), countAt(0), countAt(NumTri()), + return all_of(autoPolicy(NumTri()), countAt(0_z), countAt(NumTri()), CheckCCW({halfedge_, vertPos_, faceNormal_, 2 * precision_})); } @@ -312,7 +312,7 @@ bool Manifold::Impl::MatchesTriNormals() const { int Manifold::Impl::NumDegenerateTris() const { if (halfedge_.size() == 0 || faceNormal_.size() != NumTri()) return true; return count_if( - autoPolicy(NumTri()), countAt(0), countAt(NumTri()), + autoPolicy(NumTri()), countAt(0_z), countAt(NumTri()), CheckCCW({halfedge_, vertPos_, faceNormal_, -1 * precision_ / 2})); } @@ -324,7 +324,7 @@ Properties Manifold::Impl::GetProperties() const { float volume = 0; float areaCompensation = 0; float volumeCompensation = 0; - for (int i = 0; i < NumTri(); ++i) { + for (size_t i = 0; i < NumTri(); ++i) { auto [area1, volume1] = FaceAreaVolume({halfedge_, vertPos_, precision_})(i); const float t1 = area + area1; @@ -349,7 +349,7 @@ void Manifold::Impl::CalculateCurvature(int gaussianIdx, int meanIdx) { Vec vertArea(NumVert(), 0); Vec degree(NumVert(), 0); auto policy = autoPolicy(NumTri()); - for_each(policy, countAt(0), countAt(NumTri()), + for_each(policy, countAt(0_z), countAt(NumTri()), CurvatureAngles({vertMeanCurvature, vertGaussianCurvature, vertArea, degree, halfedge_, vertPos_, faceNormal_})); for_each_n(policy, @@ -367,7 +367,7 @@ void Manifold::Impl::CalculateCurvature(int gaussianIdx, int meanIdx) { } for_each_n( - policy, zip(meshRelation_.triProperties.begin(), countAt(0)), NumTri(), + policy, zip(meshRelation_.triProperties.begin(), countAt(0_z)), NumTri(), UpdateProperties({meshRelation_.properties, oldProperties, halfedge_, vertMeanCurvature, vertGaussianCurvature, oldNumProp, numProp, gaussianIdx, meanIdx})); @@ -414,7 +414,7 @@ bool Manifold::Impl::IsIndexInBounds(VecView triVerts) const { std::numeric_limits::min()), MinMax()); - return minmax[0] >= 0 && minmax[1] < NumVert(); + return minmax[0] >= 0 && minmax[1] < static_cast(NumVert()); } /* diff --git a/src/manifold/src/smoothing.cpp b/src/manifold/src/smoothing.cpp index 4dfc47be0..bfdc6544d 100644 --- a/src/manifold/src/smoothing.cpp +++ b/src/manifold/src/smoothing.cpp @@ -340,7 +340,7 @@ bool Manifold::Impl::IsMarkedInsideQuad(int halfedge) const { std::vector Manifold::Impl::UpdateSharpenedEdges( const std::vector& sharpenedEdges) const { std::unordered_map oldHalfedge2New; - for (int tri = 0; tri < NumTri(); ++tri) { + for (size_t tri = 0; tri < NumTri(); ++tri) { int oldTri = meshRelation_.triRef[tri].tri; for (int i : {0, 1, 2}) oldHalfedge2New[3 * oldTri + i] = 3 * tri + i; } @@ -388,7 +388,7 @@ Vec Manifold::Impl::FlatFaces() const { Vec Manifold::Impl::VertFlatFace(const Vec& flatFaces) const { Vec vertFlatFace(NumVert(), -1); Vec vertRef(NumVert(), {-1, -1, -1}); - for (int tri = 0; tri < NumTri(); ++tri) { + for (size_t tri = 0; tri < NumTri(); ++tri) { if (flatFaces[tri]) { for (const int j : {0, 1, 2}) { const int vert = halfedge_[3 * tri + j].startVert; @@ -418,7 +418,7 @@ std::vector Manifold::Impl::SharpenEdges( float minSharpAngle, float minSmoothness) const { std::vector sharpenedEdges; const float minRadians = glm::radians(minSharpAngle); - for (int e = 0; e < halfedge_.size(); ++e) { + for (int e = 0; e < static_cast(halfedge_.size()); ++e) { if (!halfedge_[e].IsForward()) continue; const int pair = halfedge_[e].pairedHalfedge; const float dihedral = @@ -457,7 +457,7 @@ void Manifold::Impl::SetNormals(int normalIdx, float minSharpAngle) { Vec triIsFlatFace = FlatFaces(); Vec vertFlatFace = VertFlatFace(triIsFlatFace); Vec vertNumSharp(NumVert(), 0); - for (int e = 0; e < halfedge_.size(); ++e) { + for (size_t e = 0; e < halfedge_.size(); ++e) { if (!halfedge_[e].IsForward()) continue; const int pair = halfedge_[e].pairedHalfedge; const int tri1 = e / 3; @@ -716,7 +716,7 @@ void Manifold::Impl::DistributeTangents(const Vec& fixedHalfedges) { const float scale = currentAngle.back() / desiredAngle.back(); float offset = 0; if (current == halfedge) { // only one - find average offset - for (int i = 0; i < currentAngle.size(); ++i) { + for (size_t i = 0; i < currentAngle.size(); ++i) { offset += currentAngle[i] - scale * desiredAngle[i]; } offset /= currentAngle.size(); @@ -843,7 +843,7 @@ void Manifold::Impl::CreateTangents(std::vector sharpenedEdges) { Vec triIsFlatFace = FlatFaces(); Vec vertFlatFace = VertFlatFace(triIsFlatFace); Vec vertNormal = vertNormal_; - for (int v = 0; v < NumVert(); ++v) { + for (size_t v = 0; v < NumVert(); ++v) { if (vertFlatFace[v] >= 0) { vertNormal[v] = faceNormal_[vertFlatFace[v]]; } @@ -856,7 +856,7 @@ void Manifold::Impl::CreateTangents(std::vector sharpenedEdges) { halfedgeTangent_.swap(tangent); // Add sharpened edges around faces, just on the face side. - for (int tri = 0; tri < NumTri(); ++tri) { + for (int tri = 0; tri < static_cast(NumTri()); ++tri) { if (!triIsFlatFace[tri]) continue; for (const int j : {0, 1, 2}) { const int tri2 = halfedge_[3 * tri + j].pairedHalfedge / 3; diff --git a/src/manifold/src/sort.cpp b/src/manifold/src/sort.cpp index a8a706356..d334ac7ef 100644 --- a/src/manifold/src/sort.cpp +++ b/src/manifold/src/sort.cpp @@ -288,7 +288,7 @@ void Manifold::Impl::Finish() { */ void Manifold::Impl::SortVerts() { ZoneScoped; - const int numVert = NumVert(); + const auto numVert = NumVert(); Vec vertMorton(numVert); auto policy = autoPolicy(numVert); for_each_n(policy, zip(vertMorton.begin(), vertPos_.cbegin()), numVert, @@ -328,8 +328,9 @@ void Manifold::Impl::SortVerts() { void Manifold::Impl::ReindexVerts(const Vec& vertNew2Old, int oldNumVert) { ZoneScoped; Vec vertOld2New(oldNumVert); - scatter(autoPolicy(oldNumVert), countAt(0), countAt(NumVert()), - vertNew2Old.begin(), vertOld2New.begin()); + scatter(autoPolicy(oldNumVert), countAt(0), + countAt(static_cast(NumVert())), vertNew2Old.begin(), + vertOld2New.begin()); for_each(autoPolicy(oldNumVert), halfedge_.begin(), halfedge_.end(), Reindex({vertOld2New})); } @@ -477,15 +478,15 @@ MeshGL::MeshGL(const Mesh& mesh) { numProp = 3; precision = mesh.precision; vertProperties.resize(numProp * mesh.vertPos.size()); - for (int i = 0; i < mesh.vertPos.size(); ++i) { + for (size_t i = 0; i < mesh.vertPos.size(); ++i) { for (int j : {0, 1, 2}) vertProperties[3 * i + j] = mesh.vertPos[i][j]; } triVerts.resize(3 * mesh.triVerts.size()); - for (int i = 0; i < mesh.triVerts.size(); ++i) { + for (size_t i = 0; i < mesh.triVerts.size(); ++i) { for (int j : {0, 1, 2}) triVerts[3 * i + j] = mesh.triVerts[i][j]; } halfedgeTangent.resize(4 * mesh.halfedgeTangent.size()); - for (int i = 0; i < mesh.halfedgeTangent.size(); ++i) { + for (size_t i = 0; i < mesh.halfedgeTangent.size(); ++i) { for (int j : {0, 1, 2, 3}) halfedgeTangent[4 * i + j] = mesh.halfedgeTangent[i][j]; } @@ -510,14 +511,14 @@ bool MeshGL::Merge() { std::vector merge(NumVert()); std::iota(merge.begin(), merge.end(), 0); - for (int i = 0; i < mergeFromVert.size(); ++i) { + for (size_t i = 0; i < mergeFromVert.size(); ++i) { merge[mergeFromVert[i]] = mergeToVert[i]; } - const int numVert = NumVert(); - const int numTri = NumTri(); + const auto numVert = NumVert(); + const auto numTri = NumTri(); const int next[3] = {1, 2, 0}; - for (int tri = 0; tri < numTri; ++tri) { + for (size_t tri = 0; tri < numTri; ++tri) { for (int i : {0, 1, 2}) { auto edge = std::make_pair(merge[triVerts[3 * tri + next[i]]], merge[triVerts[3 * tri + i]]); @@ -579,19 +580,19 @@ bool MeshGL::Merge() { SparseIndices toMerge = collider.Collisions(vertBox.cview()); UnionFind<> uf(numVert); - for (int i = 0; i < mergeFromVert.size(); ++i) { + for (size_t i = 0; i < mergeFromVert.size(); ++i) { uf.unionXY(static_cast(mergeFromVert[i]), static_cast(mergeToVert[i])); } - for (int i = 0; i < toMerge.size(); ++i) { + for (size_t i = 0; i < toMerge.size(); ++i) { uf.unionXY(openVerts[toMerge.Get(i, false)], openVerts[toMerge.Get(i, true)]); } mergeToVert.clear(); mergeFromVert.clear(); - for (int v = 0; v < numVert; ++v) { - const int mergeTo = uf.find(v); + for (size_t v = 0; v < numVert; ++v) { + const size_t mergeTo = uf.find(v); if (mergeTo != v) { mergeFromVert.push_back(v); mergeToVert.push_back(mergeTo); diff --git a/src/manifold/src/subdivision.cpp b/src/manifold/src/subdivision.cpp index 3c5995bb5..b9f40923d 100644 --- a/src/manifold/src/subdivision.cpp +++ b/src/manifold/src/subdivision.cpp @@ -125,9 +125,9 @@ class Partition { } } const int offset = interiorOffset - newVerts.size(); - for (int i = newVerts.size(); i < vertBary.size(); ++i) { - newVerts.push_back(i + offset); - } + size_t old = newVerts.size(); + newVerts.resize(vertBary.size()); + std::iota(newVerts.begin() + old, newVerts.end(), old + offset); const int numTri = triVert.size(); Vec newTriVert(numTri); @@ -577,8 +577,9 @@ Vec Manifold::Impl::Subdivide( Vec triOffset(numTri); auto numSubTris = thrust::make_transform_iterator( - subTris.begin(), - [](const Partition& part) { return part.triVert.size(); }); + subTris.begin(), [](const Partition& part) { + return static_cast(part.triVert.size()); + }); exclusive_scan(policy, numSubTris, numSubTris + numTri, triOffset.begin(), 0); Vec interiorOffset(numTri); diff --git a/src/polygon/include/polygon.h b/src/polygon/include/polygon.h index 8e5f11f0b..bee6a5b30 100644 --- a/src/polygon/include/polygon.h +++ b/src/polygon/include/polygon.h @@ -48,4 +48,4 @@ std::vector Triangulate(const Polygons &polygons, ExecutionParams &PolygonParams(); /** @} */ -} // namespace manifold \ No newline at end of file +} // namespace manifold diff --git a/src/polygon/src/polygon.cpp b/src/polygon/src/polygon.cpp index 239631260..1f2a45273 100644 --- a/src/polygon/src/polygon.cpp +++ b/src/polygon/src/polygon.cpp @@ -444,7 +444,7 @@ class EarClip { const int lid = left->mesh_idx; const int rid = right->mesh_idx; - for (int i = 0; i < toTest.size(); ++i) { + for (size_t i = 0; i < toTest.size(); ++i) { const VertItr test = collider.itr[toTest.Get(i, true)]; if (!Clipped(test) && test->mesh_idx != mesh_idx && test->mesh_idx != lid && diff --git a/src/utilities/include/hashtable.h b/src/utilities/include/hashtable.h index ed0f5538d..5f21aeb06 100644 --- a/src/utilities/include/hashtable.h +++ b/src/utilities/include/hashtable.h @@ -70,7 +70,7 @@ class HashTableD { int Size() const { return keys_.size(); } bool Full() const { - return used_.load(std::memory_order_relaxed) * 2 > Size(); + return used_.load(std::memory_order_relaxed) * 2 > static_cast(Size()); } void Insert(Uint64 key, const V& val) { diff --git a/src/utilities/include/sparse.h b/src/utilities/include/sparse.h index 05a711c44..a151b31e9 100644 --- a/src/utilities/include/sparse.h +++ b/src/utilities/include/sparse.h @@ -121,7 +121,7 @@ class SparseIndices { } inline void Add(int p, int q) { - for (int i = 0; i < sizeof(int64_t); ++i) data_.push_back(-1); + for (unsigned int i = 0; i < sizeof(int64_t); ++i) data_.push_back(-1); Set(size() - 1, p, q); } diff --git a/src/utilities/include/vec.h b/src/utilities/include/vec.h index 5409843d9..fcbfa9120 100644 --- a/src/utilities/include/vec.h +++ b/src/utilities/include/vec.h @@ -235,6 +235,10 @@ class Vec : public VecView { T *data() { return this->ptr_; } const T *data() const { return this->ptr_; } + size_t capacity() const { + return capacity_; + } + private: size_t capacity_ = 0; diff --git a/test/manifold_test.cpp b/test/manifold_test.cpp index 086812e80..d0ed65813 100644 --- a/test/manifold_test.cpp +++ b/test/manifold_test.cpp @@ -55,12 +55,12 @@ TEST(Manifold, GetMeshGL) { MeshGL meshGL_out = manifold.GetMeshGL(); ASSERT_EQ(meshGL_out.NumVert(), mesh_out.vertPos.size()); ASSERT_EQ(meshGL_out.NumTri(), mesh_out.triVerts.size()); - for (int i = 0; i < meshGL_out.NumVert(); ++i) { + for (size_t i = 0; i < meshGL_out.NumVert(); ++i) { for (const int j : {0, 1, 2}) { ASSERT_EQ(meshGL_out.vertProperties[3 * i + j], mesh_out.vertPos[i][j]); } } - for (int i = 0; i < meshGL_out.NumTri(); ++i) { + for (size_t i = 0; i < meshGL_out.NumTri(); ++i) { for (const int j : {0, 1, 2}) ASSERT_EQ(meshGL_out.triVerts[3 * i + j], mesh_out.triVerts[i][j]); } @@ -193,6 +193,12 @@ TEST(Manifold, Sphere) { EXPECT_EQ(sphere.NumTri(), n * n * 8); } +TEST(Manifold, Cylinder) { + int n = 10000; + Manifold cylinder = Manifold::Cylinder(2, 2, 2, n); + EXPECT_EQ(cylinder.NumTri(), 4 * n - 4); +} + TEST(Manifold, Normals) { Mesh cube = Manifold::Cube(glm::vec3(1), true).GetMesh(); const int nVert = cube.vertPos.size(); @@ -235,7 +241,7 @@ Polygons RotatePolygons(Polygons polys, const int index) { TEST(Manifold, Revolve) { Polygons polys = SquareHole(); Manifold vug; - for (int i = 0; i < polys[0].size(); i++) { + for (size_t i = 0; i < polys[0].size(); i++) { Polygons rotatedPolys = RotatePolygons(polys, i); vug = Manifold::Revolve(rotatedPolys, 48); EXPECT_EQ(vug.Genus(), -1); @@ -267,7 +273,7 @@ TEST(Manifold, PartialRevolveOnYAxis) { Polygons offsetPolys = SquareHole(10.0f); Manifold revolute; - for (int i = 0; i < polys[0].size(); i++) { + for (size_t i = 0; i < polys[0].size(); i++) { Polygons rotatedPolys = RotatePolygons(polys, i); revolute = Manifold::Revolve(rotatedPolys, 48, 180); EXPECT_EQ(revolute.Genus(), 1); @@ -284,7 +290,7 @@ TEST(Manifold, PartialRevolveOffset) { Polygons polys = SquareHole(10.0f); Manifold revolute; - for (int i = 0; i < polys[0].size(); i++) { + for (size_t i = 0; i < polys[0].size(); i++) { Polygons rotatedPolys = RotatePolygons(polys, i); revolute = Manifold::Revolve(rotatedPolys, 48, 180); auto prop = revolute.GetProperties(); diff --git a/test/smooth_test.cpp b/test/smooth_test.cpp index 2fd7852cf..acda48f59 100644 --- a/test/smooth_test.cpp +++ b/test/smooth_test.cpp @@ -35,7 +35,7 @@ TEST(Smooth, Tetrahedron) { MeshGL out = smooth.CalculateCurvature(-1, 0).GetMeshGL(); float maxMeanCurvature = 0; - for (int i = 3; i < out.vertProperties.size(); i += 4) { + for (size_t i = 3; i < out.vertProperties.size(); i += 4) { maxMeanCurvature = glm::max(maxMeanCurvature, glm::abs(out.vertProperties[i])); } @@ -59,7 +59,7 @@ TEST(Smooth, RefineQuads) { const MeshGL baseline = WithPositionColors(cylinder); float maxDiff = 0; - for (int i = 0; i < out.vertProperties.size(); ++i) { + for (size_t i = 0; i < out.vertProperties.size(); ++i) { maxDiff = glm::max( maxDiff, glm::abs(out.vertProperties[i] - baseline.vertProperties[i])); } @@ -108,7 +108,7 @@ TEST(Smooth, ToLength) { MeshGL out = smooth.CalculateCurvature(-1, 0).GetMeshGL(); float maxMeanCurvature = 0; - for (int i = 3; i < out.vertProperties.size(); i += 4) { + for (size_t i = 3; i < out.vertProperties.size(); i += 4) { maxMeanCurvature = glm::max(maxMeanCurvature, glm::abs(out.vertProperties[i])); } @@ -298,7 +298,7 @@ TEST(Smooth, Torus) { .CalculateNormals(1); MeshGL out = smooth.GetMeshGL(); float maxMeanCurvature = 0; - for (int i = 0; i < out.vertProperties.size(); i += 7) { + for (size_t i = 0; i < out.vertProperties.size(); i += 7) { glm::vec3 v(out.vertProperties[i], out.vertProperties[i + 1], out.vertProperties[i + 2]); glm::vec3 p(v.x, v.y, 0); @@ -361,4 +361,4 @@ TEST(Smooth, SineSurface) { ExportMesh("smoothSineSurface.glb", smoothed.GetMeshGL(), options2); } #endif -} \ No newline at end of file +} diff --git a/test/test_main.cpp b/test/test_main.cpp index d747ddea3..71c862030 100644 --- a/test/test_main.cpp +++ b/test/test_main.cpp @@ -176,7 +176,7 @@ MeshGL CubeSTL() { MeshGL cube; cube.numProp = 6; - for (int tri = 0, vert = 0; tri < cubeIn.NumTri(); tri++) { + for (size_t tri = 0, vert = 0; tri < cubeIn.NumTri(); tri++) { glm::mat3 triPos; for (const int i : {0, 1, 2}) { cube.triVerts.push_back(vert++); @@ -249,14 +249,14 @@ MeshGL WithNormals(const Manifold& in) { out.runOriginalID = {Manifold::ReserveIDs(1)}; out.numProp = 6; out.vertProperties.resize(out.numProp * mesh.vertPos.size()); - for (int i = 0; i < mesh.vertPos.size(); ++i) { + for (size_t i = 0; i < mesh.vertPos.size(); ++i) { for (int j : {0, 1, 2}) { out.vertProperties[6 * i + j] = mesh.vertPos[i][j]; out.vertProperties[6 * i + 3 + j] = mesh.vertNormal[i][j]; } } out.triVerts.resize(3 * mesh.triVerts.size()); - for (int i = 0; i < mesh.triVerts.size(); ++i) { + for (size_t i = 0; i < mesh.triVerts.size(); ++i) { for (int j : {0, 1, 2}) out.triVerts[3 * i + j] = mesh.triVerts[i][j]; } return out; @@ -319,12 +319,12 @@ void CheckFinite(const MeshGL& mesh) { void Identical(const Mesh& mesh1, const Mesh& mesh2) { ASSERT_EQ(mesh1.vertPos.size(), mesh2.vertPos.size()); - for (int i = 0; i < mesh1.vertPos.size(); ++i) + for (size_t i = 0; i < mesh1.vertPos.size(); ++i) for (int j : {0, 1, 2}) ASSERT_NEAR(mesh1.vertPos[i][j], mesh2.vertPos[i][j], 0.0001); ASSERT_EQ(mesh1.triVerts.size(), mesh2.triVerts.size()); - for (int i = 0; i < mesh1.triVerts.size(); ++i) + for (size_t i = 0; i < mesh1.triVerts.size(); ++i) ASSERT_EQ(mesh1.triVerts[i], mesh2.triVerts[i]); } @@ -334,21 +334,21 @@ void RelatedGL(const Manifold& out, const std::vector& originals, const glm::ivec3 normalIdx = updateNormals ? glm::ivec3(3, 4, 5) : glm::ivec3(0); MeshGL output = out.GetMeshGL(normalIdx); - for (int run = 0; run < output.runOriginalID.size(); ++run) { + for (size_t run = 0; run < output.runOriginalID.size(); ++run) { const float* m = output.runTransform.data() + 12 * run; const glm::mat4x3 transform = output.runTransform.empty() ? glm::mat4x3(1.0f) : glm::mat4x3(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11]); - int i = 0; + size_t i = 0; for (; i < originals.size(); ++i) { ASSERT_EQ(originals[i].runOriginalID.size(), 1); if (originals[i].runOriginalID[0] == output.runOriginalID[run]) break; } ASSERT_LT(i, originals.size()); const MeshGL& inMesh = originals[i]; - for (int tri = output.runIndex[run] / 3; tri < output.runIndex[run + 1] / 3; + for (uint32_t tri = output.runIndex[run] / 3; tri < output.runIndex[run + 1] / 3; ++tri) { if (!output.faceID.empty()) { ASSERT_LT(tri, output.faceID.size()); @@ -394,7 +394,7 @@ void RelatedGL(const Manifold& out, const std::vector& originals, ASSERT_NEAR(glm::length(normal), 1, 0.0001); ASSERT_GT(glm::dot(normal, outNormal), 0); } else { - for (int p = 3; p < inMesh.numProp; ++p) { + for (size_t p = 3; p < inMesh.numProp; ++p) { const float propOut = output.vertProperties[vert * output.numProp + p]; @@ -427,7 +427,7 @@ void ExpectMeshes(const Manifold& manifold, return a.NumVert() != b.NumVert() ? a.NumVert() > b.NumVert() : a.NumTri() > b.NumTri(); }); - for (int i = 0; i < manifolds.size(); ++i) { + for (size_t i = 0; i < manifolds.size(); ++i) { EXPECT_EQ(manifolds[i].NumVert(), meshSize[i].numVert); EXPECT_EQ(manifolds[i].NumTri(), meshSize[i].numTri); EXPECT_EQ(manifolds[i].NumProp(), meshSize[i].numProp); @@ -476,4 +476,4 @@ Manifold ReadMesh(const std::string& filename) { std::string dir = file.substr(0, file.rfind('/')); return Manifold(ImportMesh(dir + "/models/" + filename)); } -#endif \ No newline at end of file +#endif From 0ad9657bf8ee20a09bd9e543ac14ced5e0051a11 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Sun, 9 Jun 2024 01:51:28 +0800 Subject: [PATCH 02/24] fix compilation error and formatting --- bindings/c/manifoldc.cpp | 2 +- extras/minimize_testcase.cpp | 26 +++++++++++++------------- src/collider/include/collider.h | 4 ++-- src/manifold/include/manifold.h | 6 ++++-- src/manifold/src/boolean_result.cpp | 4 ++-- src/manifold/src/properties.cpp | 2 +- src/manifold/src/shared.h | 2 +- src/manifold/src/sort.cpp | 6 +++--- src/polygon/src/polygon.cpp | 10 +++++----- src/utilities/CMakeLists.txt | 6 ++++++ src/utilities/include/hashtable.h | 3 ++- src/utilities/include/vec.h | 4 +--- test/test_main.cpp | 4 ++-- 13 files changed, 43 insertions(+), 36 deletions(-) diff --git a/bindings/c/manifoldc.cpp b/bindings/c/manifoldc.cpp index 92d297b44..f88296cf1 100644 --- a/bindings/c/manifoldc.cpp +++ b/bindings/c/manifoldc.cpp @@ -68,7 +68,7 @@ ManifoldPolygons *manifold_polygons(void *mem, ManifoldSimplePolygon **ps, size_t length) { auto vec = new (mem) std::vector; auto polys = reinterpret_cast(ps); - for (size_t i = 0; i < length; ++i) { + for (size_t i = 0; i < length; ++i) { vec->push_back(*polys[i]); } return to_c(vec); diff --git a/extras/minimize_testcase.cpp b/extras/minimize_testcase.cpp index 7ccf60df9..fb81d0387 100644 --- a/extras/minimize_testcase.cpp +++ b/extras/minimize_testcase.cpp @@ -61,11 +61,11 @@ inline bool intersect(glm::vec2 p0, glm::vec2 p1, glm::vec2 q0, glm::vec2 q1, // check if removing point j in polygon i will introduce self-intersection // this checks if the new edge j-1 <-> j+1 intersects with any other edges, // assuming the original polygon does not contain self-intersection -bool safeToRemove(const Polygons &polys, int i, int j, float precision) { +bool safeToRemove(const Polygons &polys, size_t i, size_t j, float precision) { if (polys[i].size() == 3) return false; glm::vec2 prev = polys[i][j == 0 ? polys[i].size() - 1 : (j - 1)]; glm::vec2 next = polys[i][j == (polys[i].size() - 1) ? 0 : (j + 1)]; - for (int k = 0; k < polys.size(); k++) { + for (size_t k = 0; k < polys.size(); k++) { auto ll = [&](size_t l) { return l == (polys[k].size() - 1) ? 0 : (l + 1); }; @@ -74,7 +74,7 @@ bool safeToRemove(const Polygons &polys, int i, int j, float precision) { #if MANIFOLD_PAR == 'T' && __has_include() std::execution::par, #endif - countAt((size_t)0), countAt(polys[k].size()), [=](size_t l) { + countAt(0_z), countAt(polys[k].size()), [=](size_t l) { if (i == k && (l == j || ll(l) == j)) return true; return !intersect(prev, next, polysk[l], polysk[ll(l)], precision); @@ -84,8 +84,8 @@ bool safeToRemove(const Polygons &polys, int i, int j, float precision) { return true; } -std::pair findIndex(const Polygons &polys, int i) { - int outer = 0; +std::pair findIndex(const Polygons &polys, size_t i) { + size_t outer = 0; while (i >= polys[outer].size()) i -= polys[outer++].size(); return std::make_pair(outer, i); } @@ -139,9 +139,9 @@ bool rayHit(glm::vec2 point, glm::vec2 q0, glm::vec2 q1) { // this enumerates over the first point in all other polygons, // and check if they are inside the current polygon // this algorithm assumes that polygons are non-intersecting -std::vector getChildren(const Polygons &polys, int i) { +std::vector getChildren(const Polygons &polys, size_t i) { std::vector results; - for (int j = 0; j < polys.size(); j++) { + for (size_t j = 0; j < polys.size(); j++) { if (i == j) continue; glm::vec2 point = polys[j][0]; auto k1 = [&](size_t k) { @@ -173,7 +173,7 @@ void simplify(Polygons &polys, float precision = -1) { removedSomething = false; // try to remove simple polygons - for (int i = 0; i < polys.size(); i++) { + for (size_t i = 0; i < polys.size(); i++) { std::vector children = getChildren(polys, i); // if there are children, we can't remove it or we will mess up with // winding direction... @@ -195,9 +195,9 @@ void simplify(Polygons &polys, float precision = -1) { } } - for (int i = 0; i < polys.size(); i++) { + for (size_t i = 0; i < polys.size(); i++) { std::vector children = getChildren(polys, i); - for (int j = 0; j < polys[i].size(); j++) { + for (size_t j = 0; j < polys[i].size(); j++) { // removed vertex cannot change inclusion relation // we just check if the vertex // x: intersects with j0, j (original edge 1) @@ -205,8 +205,8 @@ void simplify(Polygons &polys, float precision = -1) { // z: intersects with j0, j1 (new edge) // if (x ^ y ^ z) is true, it means that the count % 2 is changed, // and we changed inclusion relation, so vertex j cannot be removed - int j0 = j == 0 ? polys[i].size() - 1 : j - 1; - int j1 = j == polys[i].size() - 1 ? 0 : j + 1; + size_t j0 = j == 0 ? polys[i].size() - 1 : j - 1; + size_t j1 = j == polys[i].size() - 1 ? 0 : j + 1; if (std::any_of(children.begin(), children.end(), [&](int k) { return rayHit(polys[k][0], polys[i][j0], polys[i][j]) ^ rayHit(polys[k][0], polys[i][j], polys[i][j1]) ^ @@ -318,7 +318,7 @@ int main(int argc, char **argv) { SimplePolygon poly; // search for precision first while (std::getline(fin, line)) { - int index = line.find("Precision = "); + size_t index = line.find("Precision = "); if (index != std::string::npos) { std::istringstream iss(line.substr(index + 12)); if (!(iss >> precision)) { diff --git a/src/collider/include/collider.h b/src/collider/include/collider.h index 97208abdb..bf5235445 100644 --- a/src/collider/include/collider.h +++ b/src/collider/include/collider.h @@ -38,8 +38,8 @@ class Collider { // even nodes are leaves, odd nodes are internal, root is 1 Vec> internalChildren_; - int NumInternal() const { return internalChildren_.size(); }; - int NumLeaves() const { + size_t NumInternal() const { return internalChildren_.size(); }; + size_t NumLeaves() const { return internalChildren_.empty() ? 0 : (NumInternal() + 1); }; }; diff --git a/src/manifold/include/manifold.h b/src/manifold/include/manifold.h index 988b53206..958c71830 100644 --- a/src/manifold/include/manifold.h +++ b/src/manifold/include/manifold.h @@ -47,13 +47,15 @@ class CsgLeafNode; struct MeshGL { /// Number of property vertices uint32_t NumVert() const { - if (vertProperties.size() / numProp >= std::numeric_limits::max()) + if (vertProperties.size() / numProp >= + std::numeric_limits::max()) throw std::out_of_range("mesh too large"); return vertProperties.size() / numProp; }; /// Number of triangles uint32_t NumTri() const { - if (vertProperties.size() / numProp >= std::numeric_limits::max()) + if (vertProperties.size() / numProp >= + std::numeric_limits::max()) throw std::out_of_range("mesh too large"); return triVerts.size() / 3; }; diff --git a/src/manifold/src/boolean_result.cpp b/src/manifold/src/boolean_result.cpp index 3da188824..b1a6be8bb 100644 --- a/src/manifold/src/boolean_result.cpp +++ b/src/manifold/src/boolean_result.cpp @@ -243,7 +243,7 @@ std::vector PairUp(std::vector &edgePos) { // a heuristic. ASSERT(edgePos.size() % 2 == 0, topologyErr, "Non-manifold edge! Not an even number of points."); - size_t nEdges = edgePos.size() / 2; + ssize_t nEdges = edgePos.size() / 2; auto middle = std::partition(edgePos.begin(), edgePos.end(), [](EdgePos x) { return x.isStart; }); ASSERT(middle - edgePos.begin() == nEdges, topologyErr, "Non-manifold edge!"); @@ -251,7 +251,7 @@ std::vector PairUp(std::vector &edgePos) { std::stable_sort(edgePos.begin(), middle, cmp); std::stable_sort(middle, edgePos.end(), cmp); std::vector edges; - for (size_t i = 0; i < nEdges; ++i) + for (ssize_t i = 0; i < nEdges; ++i) edges.push_back({edgePos[i].vert, edgePos[i + nEdges].vert, -1, -1}); return edges; } diff --git a/src/manifold/src/properties.cpp b/src/manifold/src/properties.cpp index 7285077be..e77a2c737 100644 --- a/src/manifold/src/properties.cpp +++ b/src/manifold/src/properties.cpp @@ -251,7 +251,7 @@ struct CheckCCW { glm::vec3 V2 = vertPos[halfedges[3 * face + 2].startVert]; glm::vec3 norm = glm::cross(V1 - V0, V2 - V0); printf( - "Tri %d does not match normal, approx height = %g, base = %g\n" + "Tri %ld does not match normal, approx height = %g, base = %g\n" "tol = %g, area2 = %g, base2*tol2 = %g\n" "normal = %g, %g, %g\n" "norm = %g, %g, %g\nverts: %d, %d, %d\n", diff --git a/src/manifold/src/shared.h b/src/manifold/src/shared.h index ed457dad5..f18c1fe48 100644 --- a/src/manifold/src/shared.h +++ b/src/manifold/src/shared.h @@ -192,7 +192,7 @@ Vec inline CreateTmpEdges(const Vec& halfedge) { for_each_n(autoPolicy(edges.size()), zip(edges.begin(), halfedge.begin(), countAt(0)), edges.size(), Halfedge2Tmp()); - int numEdge = + size_t numEdge = remove_if( autoPolicy(edges.size()), edges.begin(), edges.end(), TmpInvalid()) - edges.begin(); diff --git a/src/manifold/src/sort.cpp b/src/manifold/src/sort.cpp index d334ac7ef..24d641438 100644 --- a/src/manifold/src/sort.cpp +++ b/src/manifold/src/sort.cpp @@ -255,14 +255,14 @@ void Manifold::Impl::Finish() { #endif ASSERT(extrema.startVert >= 0, topologyErr, "Vertex index is negative!"); - ASSERT(extrema.endVert < NumVert(), topologyErr, + ASSERT(extrema.endVert < static_cast(NumVert()), topologyErr, "Vertex index exceeds number of verts!"); ASSERT(extrema.face >= 0, topologyErr, "Face index is negative!"); - ASSERT(extrema.face < NumTri(), topologyErr, + ASSERT(extrema.face < static_cast(NumTri()), topologyErr, "Face index exceeds number of faces!"); ASSERT(extrema.pairedHalfedge >= 0, topologyErr, "Halfedge index is negative!"); - ASSERT(extrema.pairedHalfedge < 2 * NumEdge(), topologyErr, + ASSERT(extrema.pairedHalfedge < 2 * static_cast(NumEdge()), topologyErr, "Halfedge index exceeds number of halfedges!"); ASSERT(meshRelation_.triRef.size() == NumTri() || meshRelation_.triRef.size() == 0, diff --git a/src/polygon/src/polygon.cpp b/src/polygon/src/polygon.cpp index 1f2a45273..060ab69da 100644 --- a/src/polygon/src/polygon.cpp +++ b/src/polygon/src/polygon.cpp @@ -42,7 +42,7 @@ struct PolyEdge { std::vector Polygons2Edges(const PolygonsIdx &polys) { std::vector halfedges; for (const auto &poly : polys) { - for (int i = 1; i < poly.size(); ++i) { + for (size_t i = 1; i < poly.size(); ++i) { halfedges.push_back({poly[i - 1].idx, poly[i].idx}); } halfedges.push_back({poly.back().idx, poly[0].idx}); @@ -64,7 +64,7 @@ std::vector Triangles2Edges( void CheckTopology(const std::vector &halfedges) { ASSERT(halfedges.size() % 2 == 0, topologyErr, "Odd number of halfedges."); - size_t n_edges = halfedges.size() / 2; + ssize_t n_edges = halfedges.size() / 2; std::vector forward(halfedges.size()), backward(halfedges.size()); auto end = std::copy_if(halfedges.begin(), halfedges.end(), forward.begin(), @@ -87,7 +87,7 @@ void CheckTopology(const std::vector &halfedges) { }; std::stable_sort(forward.begin(), forward.end(), cmp); std::stable_sort(backward.begin(), backward.end(), cmp); - for (int i = 0; i < n_edges; ++i) { + for (ssize_t i = 0; i < n_edges; ++i) { ASSERT(forward[i].startVert == backward[i].startVert && forward[i].endVert == backward[i].endVert, topologyErr, "Not manifold."); @@ -108,7 +108,7 @@ void CheckGeometry(const std::vector &triangles, const PolygonsIdx &polys, float precision) { std::unordered_map vertPos; for (const auto &poly : polys) { - for (int i = 0; i < poly.size(); ++i) { + for (size_t i = 0; i < poly.size(); ++i) { vertPos[poly[i].idx] = poly[i].pos; } } @@ -145,7 +145,7 @@ void PrintFailure(const std::exception &e, const PolygonsIdx &polys, std::cout << e.what() << std::endl; Dump(polys); std::cout << "produced this triangulation:" << std::endl; - for (int j = 0; j < triangles.size(); ++j) { + for (size_t j = 0; j < triangles.size(); ++j) { std::cout << triangles[j][0] << ", " << triangles[j][1] << ", " << triangles[j][2] << std::endl; } diff --git a/src/utilities/CMakeLists.txt b/src/utilities/CMakeLists.txt index 83e7b6ca2..413474678 100644 --- a/src/utilities/CMakeLists.txt +++ b/src/utilities/CMakeLists.txt @@ -75,6 +75,12 @@ target_compile_options(${PROJECT_NAME} INTERFACE -DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_${MANIFOLD_PAR} ) +if(MANIFOLD_EXCEPTIONS) + target_compile_options(${PROJECT_NAME} INTERFACE + -DMANIFOLD_EXCEPTIONS=1 + ) +endif() + if(MANIFOLD_DEBUG) target_compile_options(${PROJECT_NAME} INTERFACE -DMANIFOLD_DEBUG) diff --git a/src/utilities/include/hashtable.h b/src/utilities/include/hashtable.h index 5f21aeb06..7d971d015 100644 --- a/src/utilities/include/hashtable.h +++ b/src/utilities/include/hashtable.h @@ -70,7 +70,8 @@ class HashTableD { int Size() const { return keys_.size(); } bool Full() const { - return used_.load(std::memory_order_relaxed) * 2 > static_cast(Size()); + return used_.load(std::memory_order_relaxed) * 2 > + static_cast(Size()); } void Insert(Uint64 key, const V& val) { diff --git a/src/utilities/include/vec.h b/src/utilities/include/vec.h index fcbfa9120..521878f54 100644 --- a/src/utilities/include/vec.h +++ b/src/utilities/include/vec.h @@ -235,9 +235,7 @@ class Vec : public VecView { T *data() { return this->ptr_; } const T *data() const { return this->ptr_; } - size_t capacity() const { - return capacity_; - } + size_t capacity() const { return capacity_; } private: size_t capacity_ = 0; diff --git a/test/test_main.cpp b/test/test_main.cpp index 71c862030..ab7dba0ed 100644 --- a/test/test_main.cpp +++ b/test/test_main.cpp @@ -348,8 +348,8 @@ void RelatedGL(const Manifold& out, const std::vector& originals, } ASSERT_LT(i, originals.size()); const MeshGL& inMesh = originals[i]; - for (uint32_t tri = output.runIndex[run] / 3; tri < output.runIndex[run + 1] / 3; - ++tri) { + for (uint32_t tri = output.runIndex[run] / 3; + tri < output.runIndex[run + 1] / 3; ++tri) { if (!output.faceID.empty()) { ASSERT_LT(tri, output.faceID.size()); } From 58717527ae3afa4c242ae1c24642ef7b281ca537 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Sun, 9 Jun 2024 02:03:23 +0800 Subject: [PATCH 03/24] allow build with exception disabled --- CMakeLists.txt | 10 ++++++++-- src/manifold/include/manifold.h | 4 ++++ src/manifold/src/boolean3.cpp | 2 ++ src/manifold/src/boolean_result.cpp | 4 ++++ src/manifold/src/face_op.cpp | 2 ++ src/manifold/src/impl.cpp | 16 ++++++++++++++-- src/polygon/src/polygon.cpp | 4 ++++ src/utilities/include/vec.h | 26 ++++++++++++++++++++++++-- src/utilities/include/vec_view.h | 22 ++++++++++++++++------ 9 files changed, 78 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 78eab0404..6ed511de2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ option(MANIFOLD_DEBUG "Enable debug tracing/timing" OFF) option(MANIFOLD_PYBIND "Build python bindings" OFF) option(MANIFOLD_CBIND "Build C (FFI) bindings" ON) option(MANIFOLD_JSBIND "Build js binding" ${EMSCRIPTEN}) +option(MANIFOLD_EXCEPTIONS "Build manifold with exception enabled" ON) option(BUILD_SHARED_LIBS "Build shared library" ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) @@ -59,8 +60,13 @@ endif() if(EMSCRIPTEN) message("Building for Emscripten") - set(MANIFOLD_FLAGS -fexceptions -D_LIBCUDACXX_HAS_THREAD_API_EXTERNAL -D_LIBCUDACXX_HAS_THREAD_API_CUDA) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -sALLOW_MEMORY_GROWTH=1 -fexceptions -sDISABLE_EXCEPTION_CATCHING=0") + if(MANIFOLD_EXCEPTIONS) + set(MANIFOLD_FLAGS -fexceptions -D_LIBCUDACXX_HAS_THREAD_API_EXTERNAL -D_LIBCUDACXX_HAS_THREAD_API_CUDA) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -sALLOW_MEMORY_GROWTH=1 -fexceptions -sDISABLE_EXCEPTION_CATCHING=0") + else() + set(MANIFOLD_FLAGS -D_LIBCUDACXX_HAS_THREAD_API_EXTERNAL -D_LIBCUDACXX_HAS_THREAD_API_CUDA) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -sALLOW_MEMORY_GROWTH=1") + endif() set(MANIFOLD_PYBIND OFF) set(BUILD_SHARED_LIBS OFF) endif() diff --git a/src/manifold/include/manifold.h b/src/manifold/include/manifold.h index 958c71830..0c887d850 100644 --- a/src/manifold/include/manifold.h +++ b/src/manifold/include/manifold.h @@ -47,16 +47,20 @@ class CsgLeafNode; struct MeshGL { /// Number of property vertices uint32_t NumVert() const { +#if MANIFOLD_EXCEPTIONS if (vertProperties.size() / numProp >= std::numeric_limits::max()) throw std::out_of_range("mesh too large"); +#endif return vertProperties.size() / numProp; }; /// Number of triangles uint32_t NumTri() const { +#if MANIFOLD_EXCEPTIONS if (vertProperties.size() / numProp >= std::numeric_limits::max()) throw std::out_of_range("mesh too large"); +#endif return triVerts.size() / 3; }; diff --git a/src/manifold/src/boolean3.cpp b/src/manifold/src/boolean3.cpp index 979f448de..d3e17b63e 100644 --- a/src/manifold/src/boolean3.cpp +++ b/src/manifold/src/boolean3.cpp @@ -578,8 +578,10 @@ Boolean3::Boolean3(const Manifold::Impl &inP, const Manifold::Impl &inQ, Intersect12(inQ, inP, s20, p2q0, s11, p1q1, z20, xyzz11, p2q1_, false); PRINT("x21 size = " << x21_.size()); +#if MANIFOLD_EXCEPTIONS if (x12_.size() + x21_.size() >= std::numeric_limits::max()) throw std::out_of_range("mesh too large"); +#endif Vec p0 = p0q2.Copy(false); p0q2.Resize(0); diff --git a/src/manifold/src/boolean_result.cpp b/src/manifold/src/boolean_result.cpp index b1a6be8bb..929ed32a3 100644 --- a/src/manifold/src/boolean_result.cpp +++ b/src/manifold/src/boolean_result.cpp @@ -104,8 +104,10 @@ std::tuple, Vec> SizeOutput( ZoneScoped; Vec sidesPerFacePQ(inP.NumTri() + inQ.NumTri(), 0); // note: numFaceR <= facePQ2R.size() = sidesPerFacePQ.size() + 1 +#if MANIFOLD_EXCEPTIONS if (sidesPerFacePQ.size() + 1 >= std::numeric_limits::max()) throw std::out_of_range("boolean result too large"); +#endif auto sidesPerFaceP = sidesPerFacePQ.view(0, inP.NumTri()); auto sidesPerFaceQ = sidesPerFacePQ.view(inP.NumTri(), inQ.NumTri()); @@ -544,9 +546,11 @@ void CreateProperties(Manifold::Impl &outR, const Manifold::Impl &inP, propMissIdx[0].resize(inQ.NumPropVert(), -1); propMissIdx[1].resize(inP.NumPropVert(), -1); +#if MANIFOLD_EXCEPTIONS if (static_cast(outR.NumVert()) * static_cast(numProp) >= std::numeric_limits::max()) throw std::out_of_range("too many vertices"); +#endif outR.meshRelation_.properties.reserve(outR.NumVert() * numProp); int idx = 0; diff --git a/src/manifold/src/face_op.cpp b/src/manifold/src/face_op.cpp index 32861b963..0eceb4788 100644 --- a/src/manifold/src/face_op.cpp +++ b/src/manifold/src/face_op.cpp @@ -156,8 +156,10 @@ void Manifold::Impl::Face2Tri(const Vec& faceEdge, // prefix sum computation (assign unique index to each face) and preallocation exclusive_scan(autoPolicy(triCount.size()), triCount.begin(), triCount.end(), triCount.begin(), 0_z); +#if MANIFOLD_EXCEPTIONS if (triCount.back() >= std::numeric_limits::max()) throw std::out_of_range("too many triangles"); +#endif triVerts.resize(triCount.back()); triNormal.resize(triCount.back()); triRef.resize(triCount.back()); diff --git a/src/manifold/src/impl.cpp b/src/manifold/src/impl.cpp index 9543d14df..31fbfcb88 100644 --- a/src/manifold/src/impl.cpp +++ b/src/manifold/src/impl.cpp @@ -350,8 +350,14 @@ Manifold::Impl::Impl(const MeshGL& meshGL, if (meshGL.numProp > 3 && static_cast(numVert) * static_cast(meshGL.numProp - 3) >= - std::numeric_limits::max()) + std::numeric_limits::max()) { +#if MANIFOLD_EXCEPTIONS throw std::out_of_range("mesh too large"); +#else + MarkFailure(Error::InvalidConstruction); + return; +#endif + } if (meshGL.numProp < 3) { MarkFailure(Error::MissingPositionProperties); @@ -486,8 +492,14 @@ Manifold::Impl::Impl(const Mesh& mesh, const MeshRelationD& relation, const std::vector& propertyTolerance, bool hasFaceIDs) : vertPos_(mesh.vertPos), halfedgeTangent_(mesh.halfedgeTangent) { - if (mesh.triVerts.size() >= std::numeric_limits::max()) + if (mesh.triVerts.size() >= std::numeric_limits::max()) { +#if MANIFOLD_EXCEPTIONS throw std::out_of_range("mesh too large"); +#else + MarkFailure(Error::InvalidConstruction); + return; +#endif + } meshRelation_ = {relation.originalID, relation.numProp, relation.properties, relation.meshIDtransform}; diff --git a/src/polygon/src/polygon.cpp b/src/polygon/src/polygon.cpp index 060ab69da..f63439cec 100644 --- a/src/polygon/src/polygon.cpp +++ b/src/polygon/src/polygon.cpp @@ -875,9 +875,12 @@ namespace manifold { std::vector TriangulateIdx(const PolygonsIdx &polys, float precision) { std::vector triangles; +#if MANIFOLD_EXCEPTIONS try { +#endif EarClip triangulator(polys, precision); triangles = triangulator.Triangulate(); +#if MANIFOLD_EXCEPTIONS #ifdef MANIFOLD_DEBUG if (params.intermediateChecks) { CheckTopology(triangles, polys); @@ -897,6 +900,7 @@ std::vector TriangulateIdx(const PolygonsIdx &polys, } catch (const std::exception &e) { #endif } +#endif return triangles; } diff --git a/src/utilities/include/vec.h b/src/utilities/include/vec.h index 521878f54..8e5afef78 100644 --- a/src/utilities/include/vec.h +++ b/src/utilities/include/vec.h @@ -13,7 +13,9 @@ // limitations under the License. #pragma once +#if MANIFOLD_EXCEPTIONS #include +#endif #if TRACY_ENABLE && TRACY_MEMORY_USAGE #include "tracy/Tracy.hpp" #else @@ -62,7 +64,9 @@ class Vec : public VecView { auto policy = autoPolicy(this->size_); if (this->size_ != 0) { this->ptr_ = reinterpret_cast(malloc(this->size_ * sizeof(T))); +#if MANIFOLD_EXCEPTIONS if (this->ptr_ == nullptr) throw std::bad_alloc(); +#endif TracyAllocS(this->ptr_, this->size_ * sizeof(T), 3); uninitialized_copy(policy, vec.begin(), vec.end(), this->ptr_); } @@ -74,7 +78,9 @@ class Vec : public VecView { auto policy = autoPolicy(this->size_); if (this->size_ != 0) { this->ptr_ = reinterpret_cast(malloc(this->size_ * sizeof(T))); +#if MANIFOLD_EXCEPTIONS if (this->ptr_ == nullptr) throw std::bad_alloc(); +#endif TracyAllocS(this->ptr_, this->size_ * sizeof(T), 3); uninitialized_copy(policy, vec.begin(), vec.end(), this->ptr_); } @@ -113,7 +119,9 @@ class Vec : public VecView { auto policy = autoPolicy(this->size_); if (this->size_ != 0) { this->ptr_ = reinterpret_cast(malloc(this->size_ * sizeof(T))); +#if MANIFOLD_EXCEPTIONS if (this->ptr_ == nullptr) throw std::bad_alloc(); +#endif TracyAllocS(this->ptr_, this->size_ * sizeof(T), 3); uninitialized_copy(policy, other.begin(), other.end(), this->ptr_); } @@ -157,7 +165,9 @@ class Vec : public VecView { void reserve(size_t n) { if (n > capacity_) { T *newBuffer = reinterpret_cast(malloc(n * sizeof(T))); +#if MANIFOLD_EXCEPTIONS if (newBuffer == nullptr) throw std::bad_alloc(); +#endif TracyAllocS(newBuffer, n * sizeof(T), 3); if (this->size_ > 0) uninitialized_copy(autoPolicy(this->size_), this->ptr_, @@ -186,7 +196,9 @@ class Vec : public VecView { T *newBuffer = nullptr; if (this->size_ > 0) { newBuffer = reinterpret_cast(malloc(this->size_ * sizeof(T))); +#if MANIFOLD_EXCEPTIONS if (newBuffer == nullptr) throw std::bad_alloc(); +#endif TracyAllocS(newBuffer, this->size_ * sizeof(T), 3); uninitialized_copy(autoPolicy(this->size_), this->ptr_, this->ptr_ + this->size_, newBuffer); @@ -203,12 +215,17 @@ class Vec : public VecView { size_t length = std::numeric_limits::max()) { if (length == std::numeric_limits::max()) { length = this->size_ - offset; +#if MANIFOLD_EXCEPTIONS if (length < 0) throw std::out_of_range("Vec::view out of range"); - } else if (offset + length > this->size_ || offset < 0) { +#endif + } +#if MANIFOLD_EXCEPTIONS + else if (offset + length > this->size_ || offset < 0) { throw std::out_of_range("Vec::view out of range"); } else if (length < 0) { throw std::out_of_range("Vec::view negative length is not allowed"); } +#endif return VecView(this->ptr_ + offset, length); } @@ -217,12 +234,17 @@ class Vec : public VecView { size_t length = std::numeric_limits::max()) const { if (length == std::numeric_limits::max()) { length = this->size_ - offset; +#if MANIFOLD_EXCEPTIONS if (length < 0) throw std::out_of_range("Vec::cview out of range"); - } else if (offset + length > this->size_ || offset < 0) { +#endif + } +#if MANIFOLD_EXCEPTIONS + else if (offset + length > this->size_ || offset < 0) { throw std::out_of_range("Vec::cview out of range"); } else if (length < 0) { throw std::out_of_range("Vec::cview negative length is not allowed"); } +#endif return VecView(this->ptr_ + offset, length); } diff --git a/src/utilities/include/vec_view.h b/src/utilities/include/vec_view.h index dd70cd330..747802990 100644 --- a/src/utilities/include/vec_view.h +++ b/src/utilities/include/vec_view.h @@ -14,7 +14,9 @@ #pragma once +#if MANIFOLD_EXCEPTIONS #include +#endif namespace manifold { @@ -46,16 +48,16 @@ class VecView { operator VecView() const { return {ptr_, size_}; } inline const T &operator[](size_t i) const { - if (i >= size_) { - throw std::out_of_range("Vec out of range"); - } +#if MANIFOLD_EXCEPTIONS + if (i >= size_) throw std::out_of_range("Vec out of range"); +#endif return ptr_[i]; } inline T &operator[](size_t i) { - if (i >= size_) { - throw std::out_of_range("Vec out of range"); - } +#if MANIFOLD_EXCEPTIONS + if (i >= size_) throw std::out_of_range("Vec out of range"); +#endif return ptr_[i]; } @@ -69,26 +71,34 @@ class VecView { Iter end() { return ptr_ + size_; } const T &front() const { +#if MANIFOLD_EXCEPTIONS if (size_ == 0) throw std::out_of_range("attempt to take the front of an empty vector"); +#endif return ptr_[0]; } const T &back() const { +#if MANIFOLD_EXCEPTIONS if (size_ == 0) throw std::out_of_range("attempt to take the back of an empty vector"); +#endif return ptr_[size_ - 1]; } T &front() { +#if MANIFOLD_EXCEPTIONS if (size_ == 0) throw std::out_of_range("attempt to take the front of an empty vector"); +#endif return ptr_[0]; } T &back() { +#if MANIFOLD_EXCEPTIONS if (size_ == 0) throw std::out_of_range("attempt to take the back of an empty vector"); +#endif return ptr_[size_ - 1]; } From df00c1baf3540d62cd671d20d31d5b7a3cea16f5 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Sun, 9 Jun 2024 02:05:47 +0800 Subject: [PATCH 04/24] CI for building without exception --- .github/workflows/manifold.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/manifold.yml b/.github/workflows/manifold.yml index 4026c0186..010a0534b 100644 --- a/.github/workflows/manifold.yml +++ b/.github/workflows/manifold.yml @@ -107,6 +107,9 @@ jobs: timeout-minutes: 30 runs-on: ubuntu-22.04 if: github.event.pull_request.draft == false + strategy: + matrix: + exception: [ON, OFF] steps: - name: Install dependencies run: | @@ -128,7 +131,7 @@ jobs: source ./emsdk/emsdk_env.sh mkdir build cd build - emcmake cmake -DCMAKE_BUILD_TYPE=Release .. && emmake make + emcmake cmake -DCMAKE_BUILD_TYPE=Release -DMANIFOLD_EXCEPTIONS=${{matrix.exception}} .. && emmake make - name: Test WASM run: | cd build/test @@ -142,6 +145,7 @@ jobs: cp ../manifold.* ./dist/ - name: Upload WASM files uses: actions/upload-artifact@v4 + if: matrix.exception == 'ON' with: name: wasm path: bindings/wasm/examples/dist/ From 1f748adb485599f8fee18f8e44ff1c58c8192017 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Sun, 9 Jun 2024 02:07:47 +0800 Subject: [PATCH 05/24] format --- src/manifold/include/manifold.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/manifold/include/manifold.h b/src/manifold/include/manifold.h index 0c887d850..935b5d5bd 100644 --- a/src/manifold/include/manifold.h +++ b/src/manifold/include/manifold.h @@ -47,7 +47,7 @@ class CsgLeafNode; struct MeshGL { /// Number of property vertices uint32_t NumVert() const { -#if MANIFOLD_EXCEPTIONS +#if MANIFOLD_EXCEPTIONS if (vertProperties.size() / numProp >= std::numeric_limits::max()) throw std::out_of_range("mesh too large"); @@ -56,7 +56,7 @@ struct MeshGL { }; /// Number of triangles uint32_t NumTri() const { -#if MANIFOLD_EXCEPTIONS +#if MANIFOLD_EXCEPTIONS if (vertProperties.size() / numProp >= std::numeric_limits::max()) throw std::out_of_range("mesh too large"); From d1edf3b1eb4274ad5cc55900f1afebe0c09fcfa9 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Sun, 9 Jun 2024 02:08:30 +0800 Subject: [PATCH 06/24] another fix --- bindings/python/manifold3d.cpp | 4 ++-- src/manifold/src/face_op.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bindings/python/manifold3d.cpp b/bindings/python/manifold3d.cpp index f620ec987..9b4151c87 100644 --- a/bindings/python/manifold3d.cpp +++ b/bindings/python/manifold3d.cpp @@ -155,7 +155,7 @@ struct nb::detail::type_caster>> { size_t num_vec = vec.size(); T *buffer = new T[num_vec * N]; nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[](T *) p; }); - for (int i = 0; i < num_vec; i++) { + for (size_t i = 0; i < num_vec; i++) { for (int j = 0; j < N; j++) { buffer[i * N + j] = vec[i][j]; } @@ -517,7 +517,7 @@ NB_MODULE(manifold3d, m) { .def_ro("run_original_id", &MeshGL::runOriginalID) .def_ro("face_id", &MeshGL::faceID) .def_static( - "level_set", + "level_set", [](const std::function &f, std::vector bounds, float edgeLength, float level = 0.0) { // Same format as Manifold.bounding_box diff --git a/src/manifold/src/face_op.cpp b/src/manifold/src/face_op.cpp index 0eceb4788..d3874219f 100644 --- a/src/manifold/src/face_op.cpp +++ b/src/manifold/src/face_op.cpp @@ -188,7 +188,7 @@ void Manifold::Impl::Face2Tri(const Vec& faceEdge, triRef.push_back(r); }, std::placeholders::_1); - for (int face = 0; face < faceEdge.size() - 1; ++face) { + for (size_t face = 0; face < faceEdge.size() - 1; ++face) { processFace2(face); } #endif From f33724364baf045adef811b85ea22d16d803632f Mon Sep 17 00:00:00 2001 From: pca006132 Date: Sun, 9 Jun 2024 02:11:02 +0800 Subject: [PATCH 07/24] msvc stuff --- src/utilities/include/utils.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/utilities/include/utils.h b/src/utilities/include/utils.h index 1c13cd0d3..f4e206d5d 100644 --- a/src/utilities/include/utils.h +++ b/src/utilities/include/utils.h @@ -18,6 +18,11 @@ #include #include +#if defined(_MSC_VER) +#include +typedef SSIZE_T ssize_t; +#endif + #ifdef MANIFOLD_DEBUG #include #include From fd014b6de16e3e50fee2ae5ac25e2a208dc3646c Mon Sep 17 00:00:00 2001 From: pca006132 Date: Sun, 9 Jun 2024 02:15:12 +0800 Subject: [PATCH 08/24] fix python bindings --- bindings/python/manifold3d.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bindings/python/manifold3d.cpp b/bindings/python/manifold3d.cpp index 9b4151c87..55784025b 100644 --- a/bindings/python/manifold3d.cpp +++ b/bindings/python/manifold3d.cpp @@ -68,7 +68,7 @@ struct nb::detail::type_caster> { int size = PyObject_Size(src.ptr()); // negative on failure if (size != N) return false; make_caster t_cast; - for (size_t i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { if (!t_cast.from_python(src[i], flags, cleanup)) return false; value[i] = t_cast.value; } @@ -298,7 +298,7 @@ NB_MODULE(manifold3d, m) { nb::ndarray> array; std::vector vec; if (nb::try_cast(result, array)) { - if (array.ndim() != 1 || array.shape(0) != newNumProp) + if (array.ndim() != 1 || array.shape(0) != static_cast(newNumProp)) throw std::runtime_error("Invalid vector shape, expected (" + std::to_string(newNumProp) + ")"); for (int i = 0; i < newNumProp; i++) newProps[i] = array(i); @@ -384,7 +384,7 @@ NB_MODULE(manifold3d, m) { "sharpened_edges.size() != edge_smoothness.size()"); } std::vector vec(sharpened_edges.size()); - for (int i = 0; i < vec.size(); i++) { + for (size_t i = 0; i < vec.size(); i++) { vec[i] = {sharpened_edges[i], edge_smoothness[i]}; } return Manifold::Smooth(mesh, vec); From 94bfe232b8786ac26f10e10cdab768d3f2b4a324 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Sun, 9 Jun 2024 02:15:21 +0800 Subject: [PATCH 09/24] update nix --- flake.lock | 6 +++--- flake.nix | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/flake.lock b/flake.lock index e7334b7ad..de866f1f1 100644 --- a/flake.lock +++ b/flake.lock @@ -53,11 +53,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1704722960, - "narHash": "sha256-mKGJ3sPsT6//s+Knglai5YflJUF2DGj7Ai6Ynopz0kI=", + "lastModified": 1717602782, + "narHash": "sha256-pL9jeus5QpX5R+9rsp3hhZ+uplVHscNJh8n8VpqscM0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "317484b1ead87b9c1b8ac5261a8d2dd748a0492d", + "rev": "e8057b67ebf307f01bdcc8fba94d94f75039d1f6", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 9dc3e708c..43aa05ce0 100644 --- a/flake.nix +++ b/flake.nix @@ -72,7 +72,7 @@ { parallel-backend = "none"; } { parallel-backend = "tbb"; - build-tools = with pkgs; [ tbb_2021_8 pkg-config ]; + build-tools = with pkgs; [ tbb pkg-config ]; } ]; in @@ -126,7 +126,7 @@ numpy ]; buildInputs = with pkgs; [ - tbb_2021_8 + tbb glm clipper2 ]; @@ -156,7 +156,7 @@ devShell = pkgs.mkShell { buildInputs = with pkgs; [ cmake - tbb_2021_8 + tbb gtest ]; }; From b33f8d8301ce4025215b216e7c5bc2feacd201f1 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Sun, 9 Jun 2024 02:16:27 +0800 Subject: [PATCH 10/24] formatting --- bindings/python/manifold3d.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bindings/python/manifold3d.cpp b/bindings/python/manifold3d.cpp index 55784025b..50bdadc26 100644 --- a/bindings/python/manifold3d.cpp +++ b/bindings/python/manifold3d.cpp @@ -107,7 +107,7 @@ struct nb::detail::type_caster> { static handle from_cpp(glm_type mat, rv_policy policy, cleanup_list *cleanup) noexcept { T *buffer = new T[R * C]; - nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[](T *) p; }); + nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[] (T *)p; }); for (int i = 0; i < R; i++) { for (int j = 0; j < C; j++) { // py is (Rows, Cols), glm is (Cols, Rows) @@ -154,7 +154,7 @@ struct nb::detail::type_caster>> { cleanup_list *cleanup) noexcept { size_t num_vec = vec.size(); T *buffer = new T[num_vec * N]; - nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[](T *) p; }); + nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[] (T *)p; }); for (size_t i = 0; i < num_vec; i++) { for (int j = 0; j < N; j++) { buffer[i * N + j] = vec[i][j]; @@ -298,7 +298,8 @@ NB_MODULE(manifold3d, m) { nb::ndarray> array; std::vector vec; if (nb::try_cast(result, array)) { - if (array.ndim() != 1 || array.shape(0) != static_cast(newNumProp)) + if (array.ndim() != 1 || + array.shape(0) != static_cast(newNumProp)) throw std::runtime_error("Invalid vector shape, expected (" + std::to_string(newNumProp) + ")"); for (int i = 0; i < newNumProp; i++) newProps[i] = array(i); From dca5365f31904e8956320c1793a5911a092bae24 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Sun, 9 Jun 2024 02:21:34 +0800 Subject: [PATCH 11/24] old llvm somehow likes this better --- bindings/python/manifold3d.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/python/manifold3d.cpp b/bindings/python/manifold3d.cpp index 50bdadc26..d2295d264 100644 --- a/bindings/python/manifold3d.cpp +++ b/bindings/python/manifold3d.cpp @@ -107,7 +107,7 @@ struct nb::detail::type_caster> { static handle from_cpp(glm_type mat, rv_policy policy, cleanup_list *cleanup) noexcept { T *buffer = new T[R * C]; - nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[] (T *)p; }); + nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[](T *) p; }); for (int i = 0; i < R; i++) { for (int j = 0; j < C; j++) { // py is (Rows, Cols), glm is (Cols, Rows) @@ -154,7 +154,7 @@ struct nb::detail::type_caster>> { cleanup_list *cleanup) noexcept { size_t num_vec = vec.size(); T *buffer = new T[num_vec * N]; - nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[] (T *)p; }); + nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[](T *) p; }); for (size_t i = 0; i < num_vec; i++) { for (int j = 0; j < N; j++) { buffer[i * N + j] = vec[i][j]; From a16b20bc851ba2cf5ac8274d848539cb28bd940d Mon Sep 17 00:00:00 2001 From: pca006132 Date: Thu, 20 Jun 2024 12:55:30 +0800 Subject: [PATCH 12/24] fix bug --- src/manifold/src/csg_tree.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/manifold/src/csg_tree.cpp b/src/manifold/src/csg_tree.cpp index bf1950d73..1d6c6b4a5 100644 --- a/src/manifold/src/csg_tree.cpp +++ b/src/manifold/src/csg_tree.cpp @@ -537,18 +537,20 @@ void CsgOpNode::BatchUnion() const { // with O(n^2) complexity to take too long. // If the number of children exceeded this limit, we will operate on chunks // with size kMaxUnionSize. - constexpr int kMaxUnionSize = 1000; + constexpr size_t kMaxUnionSize = 1000; auto impl = impl_.GetGuard(); auto &children_ = impl->children_; while (children_.size() > 1) { - const int start = (children_.size() > kMaxUnionSize) - ? (children_.size() - kMaxUnionSize) - : 0; + const size_t start = (children_.size() > kMaxUnionSize) + ? (children_.size() - kMaxUnionSize) + : 0; Vec boxes; boxes.reserve(children_.size() - start); - for (const auto &child : children_) - boxes.push_back( - std::dynamic_pointer_cast(child)->GetImpl()->bBox_); + for (size_t i = start; i < children_.size(); i++) { + boxes.push_back(std::dynamic_pointer_cast(children_[i]) + ->GetImpl() + ->bBox_); + } // partition the children into a set of disjoint sets // each set contains a set of children that are pairwise disjoint std::vector> disjointSets; From 97d91a4267fe88c893335258e8b830d0380a9601 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Thu, 20 Jun 2024 13:18:05 +0800 Subject: [PATCH 13/24] rename ASSERT into DEBUG_ASSERT --- meshIO/src/meshIO.cpp | 14 +++++++------- src/collider/src/collider.cpp | 4 ++-- src/manifold/src/boolean3.cpp | 12 ++++++------ src/manifold/src/boolean_result.cpp | 12 ++++++------ src/manifold/src/constructors.cpp | 4 ++-- src/manifold/src/csg_tree.cpp | 2 +- src/manifold/src/edge_op.cpp | 2 +- src/manifold/src/face_op.cpp | 10 +++++----- src/manifold/src/shared.h | 2 +- src/manifold/src/sort.cpp | 22 +++++++++++----------- src/manifold/src/subdivision.cpp | 2 +- src/polygon/src/polygon.cpp | 12 ++++++------ src/utilities/include/optional_assert.h | 6 +++--- src/utilities/include/sparse.h | 4 ++-- 14 files changed, 54 insertions(+), 54 deletions(-) diff --git a/meshIO/src/meshIO.cpp b/meshIO/src/meshIO.cpp index 3a36ebc8e..58de5b4ba 100644 --- a/meshIO/src/meshIO.cpp +++ b/meshIO/src/meshIO.cpp @@ -91,7 +91,7 @@ void ExportScene(aiScene* scene, const std::string& filename) { delete scene; - ASSERT(result == AI_SUCCESS, userErr, exporter.GetErrorString()); + DEBUG_ASSERT(result == AI_SUCCESS, userErr, exporter.GetErrorString()); } } // namespace @@ -141,7 +141,7 @@ Mesh ImportMesh(const std::string& filename, bool forceCleanup) { const aiScene* scene = importer.ReadFile(filename, flags); - ASSERT(scene, userErr, importer.GetErrorString()); + DEBUG_ASSERT(scene, userErr, importer.GetErrorString()); Mesh mesh_out; for (size_t i = 0; i < scene->mNumMeshes; ++i) { @@ -153,7 +153,7 @@ Mesh ImportMesh(const std::string& filename, bool forceCleanup) { } for (size_t j = 0; j < mesh_i->mNumFaces; ++j) { const aiFace face = mesh_i->mFaces[j]; - ASSERT(face.mNumIndices == 3, userErr, + DEBUG_ASSERT(face.mNumIndices == 3, userErr, "Non-triangular face in " + filename); mesh_out.triVerts.emplace_back(face.mIndices[0], face.mIndices[1], face.mIndices[2]); @@ -199,7 +199,7 @@ void ExportMesh(const std::string& filename, const MeshGL& mesh, int c = options.mat.normalChannels[i]; validChannels &= c >= 3 && c < (int)mesh.numProp; } - ASSERT(validChannels, userErr, + DEBUG_ASSERT(validChannels, userErr, "When faceted is false, valid normalChannels must be supplied."); mesh_out->mNormals = new aiVector3D[mesh_out->mNumVertices]; } @@ -211,7 +211,7 @@ void ExportMesh(const std::string& filename, const MeshGL& mesh, validChannels &= c < (int)mesh.numProp; hasColor |= c >= 0; } - ASSERT(validChannels, userErr, "Invalid colorChannels."); + DEBUG_ASSERT(validChannels, userErr, "Invalid colorChannels."); if (hasColor) mesh_out->mColors[0] = new aiColor4D[mesh_out->mNumVertices]; for (size_t i = 0; i < mesh_out->mNumVertices; ++i) { @@ -284,13 +284,13 @@ void ExportMesh(const std::string& filename, const Mesh& mesh, mesh_out->mNumVertices = mesh.vertPos.size(); mesh_out->mVertices = new aiVector3D[mesh_out->mNumVertices]; if (!options.faceted) { - ASSERT( + DEBUG_ASSERT( mesh.vertNormal.size() == mesh.vertPos.size(), userErr, "vertNormal must be the same length as vertPos when faceted is false."); mesh_out->mNormals = new aiVector3D[mesh_out->mNumVertices]; } if (!options.mat.vertColor.empty()) { - ASSERT(mesh.vertPos.size() == options.mat.vertColor.size(), userErr, + DEBUG_ASSERT(mesh.vertPos.size() == options.mat.vertColor.size(), userErr, "If present, vertColor must be the same length as vertPos."); mesh_out->mColors[0] = new aiColor4D[mesh_out->mNumVertices]; } diff --git a/src/collider/src/collider.cpp b/src/collider/src/collider.cpp index becc04401..1d56036ec 100644 --- a/src/collider/src/collider.cpp +++ b/src/collider/src/collider.cpp @@ -285,7 +285,7 @@ namespace manifold { Collider::Collider(const VecView& leafBB, const VecView& leafMorton) { ZoneScoped; - ASSERT(leafBB.size() == leafMorton.size(), userErr, + DEBUG_ASSERT(leafBB.size() == leafMorton.size(), userErr, "vectors must be the same length"); int num_nodes = 2 * leafBB.size() - 1; // assign and allocate members @@ -347,7 +347,7 @@ SparseIndices Collider::Collisions(const VecView& queriesIn) const { */ void Collider::UpdateBoxes(const VecView& leafBB) { ZoneScoped; - ASSERT(leafBB.size() == NumLeaves(), userErr, + DEBUG_ASSERT(leafBB.size() == NumLeaves(), userErr, "must have the same number of updated boxes as original"); // copy in leaf node Boxes strided_range::Iter> leaves(nodeBBox_.begin(), nodeBBox_.end(), 2); diff --git a/src/manifold/src/boolean3.cpp b/src/manifold/src/boolean3.cpp index d3e17b63e..6eeaaad5b 100644 --- a/src/manifold/src/boolean3.cpp +++ b/src/manifold/src/boolean3.cpp @@ -30,7 +30,7 @@ namespace { glm::vec2 Interpolate(glm::vec3 pL, glm::vec3 pR, float x) { const float dxL = x - pL.x; const float dxR = x - pR.x; - ASSERT(dxL * dxR <= 0, logicErr, "Boolean manifold error: not in domain"); + DEBUG_ASSERT(dxL * dxR <= 0, logicErr, "Boolean manifold error: not in domain"); const bool useL = fabs(dxL) < fabs(dxR); const glm::vec3 dLR = pR - pL; const float lambda = (useL ? dxL : dxR) / dLR.x; @@ -46,7 +46,7 @@ glm::vec4 Intersect(const glm::vec3 &pL, const glm::vec3 &pR, const glm::vec3 &qL, const glm::vec3 &qR) { const float dyL = qL.y - pL.y; const float dyR = qR.y - pR.y; - ASSERT(dyL * dyR <= 0, logicErr, "Boolean manifold error: no intersection"); + DEBUG_ASSERT(dyL * dyR <= 0, logicErr, "Boolean manifold error: no intersection"); const bool useL = fabs(dyL) < fabs(dyR); const float dx = pR.x - pL.x; float lambda = (useL ? dyL : dyR) / (dyL - dyR); @@ -236,7 +236,7 @@ struct Kernel11 { if (s11 == 0) { // No intersection xyzz11 = glm::vec4(NAN); } else { - ASSERT(k == 2, logicErr, "Boolean manifold error: s11"); + DEBUG_ASSERT(k == 2, logicErr, "Boolean manifold error: s11"); xyzz11 = Intersect(pRL[0], pRL[1], qRL[0], qRL[1]); const int p1s = halfedgeP[p1].startVert; @@ -328,13 +328,13 @@ struct Kernel02 { if (s02 == 0) { // No intersection z02 = NAN; } else { - ASSERT(k == 2, logicErr, "Boolean manifold error: s02"); + DEBUG_ASSERT(k == 2, logicErr, "Boolean manifold error: s02"); glm::vec3 vertPos = vertPosP[p0]; z02 = Interpolate(yzzRL[0], yzzRL[1], vertPos.y)[1]; if (forward) { if (!Shadows(vertPos.z, z02, expandP * vertNormalP[p0].z)) s02 = 0; } else { - // ASSERT(closestVert != -1, topologyErr, "No closest vert"); + // DEBUG_ASSERT(closestVert != -1, topologyErr, "No closest vert"); if (!Shadows(z02, vertPos.z, expandP * vertNormalP[closestVert].z)) s02 = 0; } @@ -436,7 +436,7 @@ struct Kernel12 { if (x12 == 0) { // No intersection v12 = glm::vec3(NAN); } else { - ASSERT(k == 2, logicErr, "Boolean manifold error: v12"); + DEBUG_ASSERT(k == 2, logicErr, "Boolean manifold error: v12"); const glm::vec4 xzyy = Intersect(xzyLR0[0], xzyLR0[1], xzyLR1[0], xzyLR1[1]); v12.x = xzyy[0]; diff --git a/src/manifold/src/boolean_result.cpp b/src/manifold/src/boolean_result.cpp index 929ed32a3..e62951db0 100644 --- a/src/manifold/src/boolean_result.cpp +++ b/src/manifold/src/boolean_result.cpp @@ -243,12 +243,12 @@ std::vector PairUp(std::vector &edgePos) { // geometrically valid. If the order does not go start-end-start-end... then // the input and output are not geometrically valid and this algorithm becomes // a heuristic. - ASSERT(edgePos.size() % 2 == 0, topologyErr, + DEBUG_ASSERT(edgePos.size() % 2 == 0, topologyErr, "Non-manifold edge! Not an even number of points."); ssize_t nEdges = edgePos.size() / 2; auto middle = std::partition(edgePos.begin(), edgePos.end(), [](EdgePos x) { return x.isStart; }); - ASSERT(middle - edgePos.begin() == nEdges, topologyErr, "Non-manifold edge!"); + DEBUG_ASSERT(middle - edgePos.begin() == nEdges, topologyErr, "Non-manifold edge!"); auto cmp = [](EdgePos a, EdgePos b) { return a.edgePos < b.edgePos; }; std::stable_sort(edgePos.begin(), middle, cmp); std::stable_sort(middle, edgePos.end(), cmp); @@ -642,7 +642,7 @@ Manifold::Impl Boolean3::Result(OpType op) const { assemble.Start(); #endif - ASSERT((expandP_ > 0) == (op == OpType::Add), logicErr, + DEBUG_ASSERT((expandP_ > 0) == (op == OpType::Add), logicErr, "Result op type not compatible with constructor op type."); const int c1 = op == OpType::Intersect ? 0 : 1; const int c2 = op == OpType::Add ? 1 : 0; @@ -786,7 +786,7 @@ Manifold::Impl Boolean3::Result(OpType op) const { // Level 6 if (ManifoldParams().intermediateChecks) - ASSERT(outR.IsManifold(), logicErr, "polygon mesh is not manifold!"); + DEBUG_ASSERT(outR.IsManifold(), logicErr, "polygon mesh is not manifold!"); outR.Face2Tri(faceEdge, halfedgeRef); @@ -797,7 +797,7 @@ Manifold::Impl Boolean3::Result(OpType op) const { #endif if (ManifoldParams().intermediateChecks) - ASSERT(outR.IsManifold(), logicErr, "triangulated mesh is not manifold!"); + DEBUG_ASSERT(outR.IsManifold(), logicErr, "triangulated mesh is not manifold!"); CreateProperties(outR, inP_, inQ_); @@ -806,7 +806,7 @@ Manifold::Impl Boolean3::Result(OpType op) const { outR.SimplifyTopology(); if (ManifoldParams().intermediateChecks) - ASSERT(outR.Is2Manifold(), logicErr, "simplified mesh is not 2-manifold!"); + DEBUG_ASSERT(outR.Is2Manifold(), logicErr, "simplified mesh is not 2-manifold!"); #ifdef MANIFOLD_DEBUG simplify.Stop(); diff --git a/src/manifold/src/constructors.cpp b/src/manifold/src/constructors.cpp index 21ee2038d..6772652b2 100644 --- a/src/manifold/src/constructors.cpp +++ b/src/manifold/src/constructors.cpp @@ -80,7 +80,7 @@ namespace manifold { */ Manifold Manifold::Smooth(const MeshGL& meshGL, const std::vector& sharpenedEdges) { - ASSERT(meshGL.halfedgeTangent.empty(), std::runtime_error, + DEBUG_ASSERT(meshGL.halfedgeTangent.empty(), std::runtime_error, "when supplying tangents, the normal constructor should be used " "rather than Smooth()."); @@ -122,7 +122,7 @@ Manifold Manifold::Smooth(const MeshGL& meshGL, */ Manifold Manifold::Smooth(const Mesh& mesh, const std::vector& sharpenedEdges) { - ASSERT(mesh.halfedgeTangent.empty(), std::runtime_error, + DEBUG_ASSERT(mesh.halfedgeTangent.empty(), std::runtime_error, "when supplying tangents, the normal constructor should be used " "rather than Smooth()."); diff --git a/src/manifold/src/csg_tree.cpp b/src/manifold/src/csg_tree.cpp index 786522356..ca0e3d78c 100644 --- a/src/manifold/src/csg_tree.cpp +++ b/src/manifold/src/csg_tree.cpp @@ -457,7 +457,7 @@ std::shared_ptr CsgOpNode::BatchBoolean( std::vector> &results) { ZoneScoped; auto getImplPtr = GetImplPtr(); - ASSERT(operation != OpType::Subtract, logicErr, + DEBUG_ASSERT(operation != OpType::Subtract, logicErr, "BatchBoolean doesn't support Difference."); // common cases if (results.size() == 0) return std::make_shared(); diff --git a/src/manifold/src/edge_op.cpp b/src/manifold/src/edge_op.cpp index 0efb68588..a45a0b8a2 100644 --- a/src/manifold/src/edge_op.cpp +++ b/src/manifold/src/edge_op.cpp @@ -368,7 +368,7 @@ void Manifold::Impl::UpdateVert(int vert, int startEdge, int endEdge) { current = NextHalfedge(current); halfedge_[current].startVert = vert; current = halfedge_[current].pairedHalfedge; - ASSERT(current != startEdge, logicErr, "infinite loop in decimator!"); + DEBUG_ASSERT(current != startEdge, logicErr, "infinite loop in decimator!"); } } diff --git a/src/manifold/src/face_op.cpp b/src/manifold/src/face_op.cpp index d3874219f..cd1cbddbc 100644 --- a/src/manifold/src/face_op.cpp +++ b/src/manifold/src/face_op.cpp @@ -49,7 +49,7 @@ void Manifold::Impl::Face2Tri(const Vec& faceEdge, const int firstEdge = faceEdge[face]; const int lastEdge = faceEdge[face + 1]; const int numEdge = lastEdge - firstEdge; - ASSERT(numEdge >= 3, topologyErr, "face has less than three edges."); + DEBUG_ASSERT(numEdge >= 3, topologyErr, "face has less than three edges."); const glm::vec3 normal = faceNormal_[face]; if (numEdge == 3) { // Single triangle @@ -66,7 +66,7 @@ void Manifold::Impl::Face2Tri(const Vec& faceEdge, std::swap(tri[1], tri[2]); std::swap(ends[1], ends[2]); } - ASSERT(ends[0] == tri[1] && ends[1] == tri[2] && ends[2] == tri[0], + DEBUG_ASSERT(ends[0] == tri[1] && ends[1] == tri[2] && ends[2] == tri[0], topologyErr, "These 3 edges do not form a triangle!"); addTri(face, tri, normal, halfedgeRef[firstEdge]); @@ -94,7 +94,7 @@ void Manifold::Impl::Face2Tri(const Vec& faceEdge, tri1[1] = halfedge_[firstEdge + i].startVert; } } - ASSERT(glm::all(glm::greaterThanEqual(tri0, glm::ivec3(0))) && + DEBUG_ASSERT(glm::all(glm::greaterThanEqual(tri0, glm::ivec3(0))) && glm::all(glm::greaterThanEqual(tri1, glm::ivec3(0))), topologyErr, "non-manifold quad!"); bool firstValid = triCCW(tri0) && triCCW(tri1); @@ -143,7 +143,7 @@ void Manifold::Impl::Face2Tri(const Vec& faceEdge, for_each(autoPolicy(faceEdge.size()), countAt(0_z), countAt(faceEdge.size() - 1), [&](size_t face) { triCount[face] = faceEdge[face + 1] - faceEdge[face] - 2; - ASSERT(triCount[face] >= 1, topologyErr, + DEBUG_ASSERT(triCount[face] >= 1, topologyErr, "face has less than three edges."); if (triCount[face] > 2) group.run([&, face] { @@ -223,7 +223,7 @@ PolygonsIdx Manifold::Impl::Face2Polygons(VecView::IterC start, int vert = (start + thisEdge)->startVert; polys.back().push_back({projection * vertPos_[vert], vert}); const auto result = vert_edge.find((start + thisEdge)->endVert); - ASSERT(result != vert_edge.end(), topologyErr, "non-manifold edge"); + DEBUG_ASSERT(result != vert_edge.end(), topologyErr, "non-manifold edge"); thisEdge = result->second; vert_edge.erase(result); } diff --git a/src/manifold/src/shared.h b/src/manifold/src/shared.h index f18c1fe48..6a330bcc8 100644 --- a/src/manifold/src/shared.h +++ b/src/manifold/src/shared.h @@ -196,7 +196,7 @@ Vec inline CreateTmpEdges(const Vec& halfedge) { remove_if( autoPolicy(edges.size()), edges.begin(), edges.end(), TmpInvalid()) - edges.begin(); - ASSERT(numEdge == halfedge.size() / 2, topologyErr, "Not oriented!"); + DEBUG_ASSERT(numEdge == halfedge.size() / 2, topologyErr, "Not oriented!"); edges.resize(numEdge); return edges; } diff --git a/src/manifold/src/sort.cpp b/src/manifold/src/sort.cpp index 24d641438..aa82ef6e7 100644 --- a/src/manifold/src/sort.cpp +++ b/src/manifold/src/sort.cpp @@ -245,7 +245,7 @@ void Manifold::Impl::Finish() { if (halfedge_.size() == 0) return; CompactProps(); - ASSERT(halfedge_.size() % 6 == 0, topologyErr, + DEBUG_ASSERT(halfedge_.size() % 6 == 0, topologyErr, "Not an even number of faces after sorting faces!"); #ifdef MANIFOLD_DEBUG @@ -254,25 +254,25 @@ void Manifold::Impl::Finish() { halfedge_.end(), extrema, Extrema()); #endif - ASSERT(extrema.startVert >= 0, topologyErr, "Vertex index is negative!"); - ASSERT(extrema.endVert < static_cast(NumVert()), topologyErr, + DEBUG_ASSERT(extrema.startVert >= 0, topologyErr, "Vertex index is negative!"); + DEBUG_ASSERT(extrema.endVert < static_cast(NumVert()), topologyErr, "Vertex index exceeds number of verts!"); - ASSERT(extrema.face >= 0, topologyErr, "Face index is negative!"); - ASSERT(extrema.face < static_cast(NumTri()), topologyErr, + DEBUG_ASSERT(extrema.face >= 0, topologyErr, "Face index is negative!"); + DEBUG_ASSERT(extrema.face < static_cast(NumTri()), topologyErr, "Face index exceeds number of faces!"); - ASSERT(extrema.pairedHalfedge >= 0, topologyErr, + DEBUG_ASSERT(extrema.pairedHalfedge >= 0, topologyErr, "Halfedge index is negative!"); - ASSERT(extrema.pairedHalfedge < 2 * static_cast(NumEdge()), topologyErr, + DEBUG_ASSERT(extrema.pairedHalfedge < 2 * static_cast(NumEdge()), topologyErr, "Halfedge index exceeds number of halfedges!"); - ASSERT(meshRelation_.triRef.size() == NumTri() || + DEBUG_ASSERT(meshRelation_.triRef.size() == NumTri() || meshRelation_.triRef.size() == 0, logicErr, "Mesh Relation doesn't fit!"); - ASSERT(faceNormal_.size() == NumTri() || faceNormal_.size() == 0, logicErr, + DEBUG_ASSERT(faceNormal_.size() == NumTri() || faceNormal_.size() == 0, logicErr, "faceNormal size = " + std::to_string(faceNormal_.size()) + ", NumTri = " + std::to_string(NumTri())); // TODO: figure out why this has a flaky failure and then enable reading // vertNormals from a Mesh. - // ASSERT(vertNormal_.size() == NumVert() || vertNormal_.size() == 0, + // DEBUG_ASSERT(vertNormal_.size() == NumVert() || vertNormal_.size() == 0, // logicErr, // "vertNormal size = " + std::to_string(vertNormal_.size()) + // ", NumVert = " + std::to_string(NumVert())); @@ -280,7 +280,7 @@ void Manifold::Impl::Finish() { CalculateNormals(); collider_ = Collider(faceBox, faceMorton); - ASSERT(Is2Manifold(), logicErr, "mesh is not 2-manifold!"); + DEBUG_ASSERT(Is2Manifold(), logicErr, "mesh is not 2-manifold!"); } /** diff --git a/src/manifold/src/subdivision.cpp b/src/manifold/src/subdivision.cpp index b9f40923d..6d3b73716 100644 --- a/src/manifold/src/subdivision.cpp +++ b/src/manifold/src/subdivision.cpp @@ -281,7 +281,7 @@ class Partition { return edgeOffsets[edge] + (edgeFwd[edge] ? 1 : -1) * idx; }; - ASSERT(glm::all(glm::greaterThanEqual(edgeAdded, glm::ivec4(0))), logicErr, + DEBUG_ASSERT(glm::all(glm::greaterThanEqual(edgeAdded, glm::ivec4(0))), logicErr, "negative divisions!"); int corner = -1; diff --git a/src/polygon/src/polygon.cpp b/src/polygon/src/polygon.cpp index e665017dd..23fe50dba 100644 --- a/src/polygon/src/polygon.cpp +++ b/src/polygon/src/polygon.cpp @@ -63,19 +63,19 @@ std::vector Triangles2Edges( } void CheckTopology(const std::vector &halfedges) { - ASSERT(halfedges.size() % 2 == 0, topologyErr, "Odd number of halfedges."); + DEBUG_ASSERT(halfedges.size() % 2 == 0, topologyErr, "Odd number of halfedges."); ssize_t n_edges = halfedges.size() / 2; std::vector forward(halfedges.size()), backward(halfedges.size()); auto end = std::copy_if(halfedges.begin(), halfedges.end(), forward.begin(), [](PolyEdge e) { return e.endVert > e.startVert; }); - ASSERT(std::distance(forward.begin(), end) == n_edges, topologyErr, + DEBUG_ASSERT(std::distance(forward.begin(), end) == n_edges, topologyErr, "Half of halfedges should be forward."); forward.resize(n_edges); end = std::copy_if(halfedges.begin(), halfedges.end(), backward.begin(), [](PolyEdge e) { return e.endVert < e.startVert; }); - ASSERT(std::distance(backward.begin(), end) == n_edges, topologyErr, + DEBUG_ASSERT(std::distance(backward.begin(), end) == n_edges, topologyErr, "Half of halfedges should be backward."); backward.resize(n_edges); @@ -88,7 +88,7 @@ void CheckTopology(const std::vector &halfedges) { std::stable_sort(forward.begin(), forward.end(), cmp); std::stable_sort(backward.begin(), backward.end(), cmp); for (ssize_t i = 0; i < n_edges; ++i) { - ASSERT(forward[i].startVert == backward[i].startVert && + DEBUG_ASSERT(forward[i].startVert == backward[i].startVert && forward[i].endVert == backward[i].endVert, topologyErr, "Not manifold."); } @@ -112,7 +112,7 @@ void CheckGeometry(const std::vector &triangles, vertPos[poly[i].idx] = poly[i].pos; } } - ASSERT(std::all_of(triangles.begin(), triangles.end(), + DEBUG_ASSERT(std::all_of(triangles.begin(), triangles.end(), [&vertPos, precision](const glm::ivec3 &tri) { return CCW(vertPos[tri[0]], vertPos[tri[1]], vertPos[tri[2]], precision) >= 0; @@ -899,7 +899,7 @@ class EarClip { v = v->right; } - ASSERT(v->right == v->left, logicErr, "Triangulator error!"); + DEBUG_ASSERT(v->right == v->left, logicErr, "Triangulator error!"); PRINT("Finished poly"); } diff --git a/src/utilities/include/optional_assert.h b/src/utilities/include/optional_assert.h index 75f32684a..afbdb6748 100644 --- a/src/utilities/include/optional_assert.h +++ b/src/utilities/include/optional_assert.h @@ -31,8 +31,8 @@ void Assert(bool condition, const char* file, int line, const std::string& cond, throw Ex(output.str()); } } -#define ASSERT(condition, EX, msg) \ +#define DEBUG_ASSERT(condition, EX, msg) \ Assert(condition, __FILE__, __LINE__, #condition, msg); #else -#define ASSERT(condition, EX, msg) -#endif \ No newline at end of file +#define DEBUG_ASSERT(condition, EX, msg) +#endif diff --git a/src/utilities/include/sparse.h b/src/utilities/include/sparse.h index a151b31e9..86bf73751 100644 --- a/src/utilities/include/sparse.h +++ b/src/utilities/include/sparse.h @@ -133,7 +133,7 @@ class SparseIndices { } size_t RemoveZeros(Vec& S) { - ASSERT(S.size() == size(), userErr, + DEBUG_ASSERT(S.size() == size(), userErr, "Different number of values than indicies!"); VecView view = AsVec64(); auto zBegin = zip(S.begin(), view.begin()); @@ -164,7 +164,7 @@ class SparseIndices { template size_t KeepFinite(Vec& v, Vec& x) { - ASSERT(x.size() == size(), userErr, + DEBUG_ASSERT(x.size() == size(), userErr, "Different number of values than indicies!"); VecView view = AsVec64(); auto zBegin = zip(v.begin(), x.begin(), view.begin()); From 9620c59bc8705839d696eebdb7a6eebb57aedf51 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Thu, 20 Jun 2024 13:18:16 +0800 Subject: [PATCH 14/24] remove unused file --- extras/perf | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 extras/perf diff --git a/extras/perf b/extras/perf deleted file mode 100644 index d2d9cf917..000000000 --- a/extras/perf +++ /dev/null @@ -1,22 +0,0 @@ -2022-02-22 -CPU: -nTri = 512, time = 0.0176101 sec -nTri = 2048, time = 0.0196583 sec -nTri = 8192, time = 0.0355035 sec -nTri = 32768, time = 0.0999017 sec -nTri = 131072, time = 0.334987 sec -nTri = 524288, time = 1.25136 sec -nTri = 2097152, time = 5.81453 sec -nTri = 8388608, time = 26.987 sec - -GPU: -nTri = 512, time = 0.00846689 sec -nTri = 2048, time = 0.0115478 sec -nTri = 8192, time = 0.0222773 sec -nTri = 32768, time = 0.0560136 sec -nTri = 131072, time = 0.176548 sec -nTri = 524288, time = 0.670403 sec -nTri = 2097152, time = 2.60109 sec -nTri = 8388608, time = 10.5697 sec - - From 32e4e80b85a3815370e12c9db3062c43cd13baf9 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Thu, 20 Jun 2024 13:38:58 +0800 Subject: [PATCH 15/24] use ASSERT and remove obsolete limits --- src/manifold/include/manifold.h | 16 +++----- src/manifold/src/boolean3.cpp | 5 --- src/manifold/src/boolean_result.cpp | 23 ++++------- src/manifold/src/face_op.cpp | 4 -- src/manifold/src/impl.cpp | 19 --------- src/utilities/include/optional_assert.h | 7 ++++ src/utilities/include/vec.h | 52 +++++++------------------ src/utilities/include/vec_view.h | 34 ++++++---------- 8 files changed, 46 insertions(+), 114 deletions(-) diff --git a/src/manifold/include/manifold.h b/src/manifold/include/manifold.h index 935b5d5bd..f33be2cfd 100644 --- a/src/manifold/include/manifold.h +++ b/src/manifold/include/manifold.h @@ -47,20 +47,16 @@ class CsgLeafNode; struct MeshGL { /// Number of property vertices uint32_t NumVert() const { -#if MANIFOLD_EXCEPTIONS - if (vertProperties.size() / numProp >= - std::numeric_limits::max()) - throw std::out_of_range("mesh too large"); -#endif + ASSERT(vertProperties.size() / numProp < + static_cast(std::numeric_limits::max()), + std::out_of_range("mesh too large for MeshGL")); return vertProperties.size() / numProp; }; /// Number of triangles uint32_t NumTri() const { -#if MANIFOLD_EXCEPTIONS - if (vertProperties.size() / numProp >= - std::numeric_limits::max()) - throw std::out_of_range("mesh too large"); -#endif + ASSERT(triVerts.size() / 3 < + static_cast(std::numeric_limits::max()), + std::out_of_range("mesh too large for MeshGL")); return triVerts.size() / 3; }; diff --git a/src/manifold/src/boolean3.cpp b/src/manifold/src/boolean3.cpp index 6eeaaad5b..ac7bb08d4 100644 --- a/src/manifold/src/boolean3.cpp +++ b/src/manifold/src/boolean3.cpp @@ -578,11 +578,6 @@ Boolean3::Boolean3(const Manifold::Impl &inP, const Manifold::Impl &inQ, Intersect12(inQ, inP, s20, p2q0, s11, p1q1, z20, xyzz11, p2q1_, false); PRINT("x21 size = " << x21_.size()); -#if MANIFOLD_EXCEPTIONS - if (x12_.size() + x21_.size() >= std::numeric_limits::max()) - throw std::out_of_range("mesh too large"); -#endif - Vec p0 = p0q2.Copy(false); p0q2.Resize(0); Vec q0 = p2q0.Copy(true); diff --git a/src/manifold/src/boolean_result.cpp b/src/manifold/src/boolean_result.cpp index e62951db0..b3d08704c 100644 --- a/src/manifold/src/boolean_result.cpp +++ b/src/manifold/src/boolean_result.cpp @@ -104,10 +104,6 @@ std::tuple, Vec> SizeOutput( ZoneScoped; Vec sidesPerFacePQ(inP.NumTri() + inQ.NumTri(), 0); // note: numFaceR <= facePQ2R.size() = sidesPerFacePQ.size() + 1 -#if MANIFOLD_EXCEPTIONS - if (sidesPerFacePQ.size() + 1 >= std::numeric_limits::max()) - throw std::out_of_range("boolean result too large"); -#endif auto sidesPerFaceP = sidesPerFacePQ.view(0, inP.NumTri()); auto sidesPerFaceQ = sidesPerFacePQ.view(inP.NumTri(), inQ.NumTri()); @@ -244,11 +240,12 @@ std::vector PairUp(std::vector &edgePos) { // the input and output are not geometrically valid and this algorithm becomes // a heuristic. DEBUG_ASSERT(edgePos.size() % 2 == 0, topologyErr, - "Non-manifold edge! Not an even number of points."); + "Non-manifold edge! Not an even number of points."); ssize_t nEdges = edgePos.size() / 2; auto middle = std::partition(edgePos.begin(), edgePos.end(), [](EdgePos x) { return x.isStart; }); - DEBUG_ASSERT(middle - edgePos.begin() == nEdges, topologyErr, "Non-manifold edge!"); + DEBUG_ASSERT(middle - edgePos.begin() == nEdges, topologyErr, + "Non-manifold edge!"); auto cmp = [](EdgePos a, EdgePos b) { return a.edgePos < b.edgePos; }; std::stable_sort(edgePos.begin(), middle, cmp); std::stable_sort(middle, edgePos.end(), cmp); @@ -546,12 +543,6 @@ void CreateProperties(Manifold::Impl &outR, const Manifold::Impl &inP, propMissIdx[0].resize(inQ.NumPropVert(), -1); propMissIdx[1].resize(inP.NumPropVert(), -1); -#if MANIFOLD_EXCEPTIONS - if (static_cast(outR.NumVert()) * static_cast(numProp) >= - std::numeric_limits::max()) - throw std::out_of_range("too many vertices"); -#endif - outR.meshRelation_.properties.reserve(outR.NumVert() * numProp); int idx = 0; @@ -643,7 +634,7 @@ Manifold::Impl Boolean3::Result(OpType op) const { #endif DEBUG_ASSERT((expandP_ > 0) == (op == OpType::Add), logicErr, - "Result op type not compatible with constructor op type."); + "Result op type not compatible with constructor op type."); const int c1 = op == OpType::Intersect ? 0 : 1; const int c2 = op == OpType::Add ? 1 : 0; const int c3 = op == OpType::Intersect ? 1 : -1; @@ -797,7 +788,8 @@ Manifold::Impl Boolean3::Result(OpType op) const { #endif if (ManifoldParams().intermediateChecks) - DEBUG_ASSERT(outR.IsManifold(), logicErr, "triangulated mesh is not manifold!"); + DEBUG_ASSERT(outR.IsManifold(), logicErr, + "triangulated mesh is not manifold!"); CreateProperties(outR, inP_, inQ_); @@ -806,7 +798,8 @@ Manifold::Impl Boolean3::Result(OpType op) const { outR.SimplifyTopology(); if (ManifoldParams().intermediateChecks) - DEBUG_ASSERT(outR.Is2Manifold(), logicErr, "simplified mesh is not 2-manifold!"); + DEBUG_ASSERT(outR.Is2Manifold(), logicErr, + "simplified mesh is not 2-manifold!"); #ifdef MANIFOLD_DEBUG simplify.Stop(); diff --git a/src/manifold/src/face_op.cpp b/src/manifold/src/face_op.cpp index cd1cbddbc..a33b93606 100644 --- a/src/manifold/src/face_op.cpp +++ b/src/manifold/src/face_op.cpp @@ -156,10 +156,6 @@ void Manifold::Impl::Face2Tri(const Vec& faceEdge, // prefix sum computation (assign unique index to each face) and preallocation exclusive_scan(autoPolicy(triCount.size()), triCount.begin(), triCount.end(), triCount.begin(), 0_z); -#if MANIFOLD_EXCEPTIONS - if (triCount.back() >= std::numeric_limits::max()) - throw std::out_of_range("too many triangles"); -#endif triVerts.resize(triCount.back()); triNormal.resize(triCount.back()); triRef.resize(triCount.back()); diff --git a/src/manifold/src/impl.cpp b/src/manifold/src/impl.cpp index 31fbfcb88..4f9fbbd83 100644 --- a/src/manifold/src/impl.cpp +++ b/src/manifold/src/impl.cpp @@ -348,17 +348,6 @@ Manifold::Impl::Impl(const MeshGL& meshGL, const auto numVert = meshGL.NumVert(); const auto numTri = meshGL.NumTri(); - if (meshGL.numProp > 3 && - static_cast(numVert) * static_cast(meshGL.numProp - 3) >= - std::numeric_limits::max()) { -#if MANIFOLD_EXCEPTIONS - throw std::out_of_range("mesh too large"); -#else - MarkFailure(Error::InvalidConstruction); - return; -#endif - } - if (meshGL.numProp < 3) { MarkFailure(Error::MissingPositionProperties); return; @@ -492,14 +481,6 @@ Manifold::Impl::Impl(const Mesh& mesh, const MeshRelationD& relation, const std::vector& propertyTolerance, bool hasFaceIDs) : vertPos_(mesh.vertPos), halfedgeTangent_(mesh.halfedgeTangent) { - if (mesh.triVerts.size() >= std::numeric_limits::max()) { -#if MANIFOLD_EXCEPTIONS - throw std::out_of_range("mesh too large"); -#else - MarkFailure(Error::InvalidConstruction); - return; -#endif - } meshRelation_ = {relation.originalID, relation.numProp, relation.properties, relation.meshIDtransform}; diff --git a/src/utilities/include/optional_assert.h b/src/utilities/include/optional_assert.h index afbdb6748..7e3590af6 100644 --- a/src/utilities/include/optional_assert.h +++ b/src/utilities/include/optional_assert.h @@ -36,3 +36,10 @@ void Assert(bool condition, const char* file, int line, const std::string& cond, #else #define DEBUG_ASSERT(condition, EX, msg) #endif + +#if MANIFOLD_EXCEPTIONS +#define ASSERT(condition, EX) \ + if (!(condition)) throw (EX); +#else +#define ASSERT(condition, EX) +#endif diff --git a/src/utilities/include/vec.h b/src/utilities/include/vec.h index 8e5afef78..21bc7fac5 100644 --- a/src/utilities/include/vec.h +++ b/src/utilities/include/vec.h @@ -64,9 +64,7 @@ class Vec : public VecView { auto policy = autoPolicy(this->size_); if (this->size_ != 0) { this->ptr_ = reinterpret_cast(malloc(this->size_ * sizeof(T))); -#if MANIFOLD_EXCEPTIONS - if (this->ptr_ == nullptr) throw std::bad_alloc(); -#endif + ASSERT(this->ptr_ != nullptr, std::bad_alloc()); TracyAllocS(this->ptr_, this->size_ * sizeof(T), 3); uninitialized_copy(policy, vec.begin(), vec.end(), this->ptr_); } @@ -78,9 +76,7 @@ class Vec : public VecView { auto policy = autoPolicy(this->size_); if (this->size_ != 0) { this->ptr_ = reinterpret_cast(malloc(this->size_ * sizeof(T))); -#if MANIFOLD_EXCEPTIONS - if (this->ptr_ == nullptr) throw std::bad_alloc(); -#endif + ASSERT(this->ptr_ != nullptr, std::bad_alloc()); TracyAllocS(this->ptr_, this->size_ * sizeof(T), 3); uninitialized_copy(policy, vec.begin(), vec.end(), this->ptr_); } @@ -119,9 +115,7 @@ class Vec : public VecView { auto policy = autoPolicy(this->size_); if (this->size_ != 0) { this->ptr_ = reinterpret_cast(malloc(this->size_ * sizeof(T))); -#if MANIFOLD_EXCEPTIONS - if (this->ptr_ == nullptr) throw std::bad_alloc(); -#endif + ASSERT(this->ptr_ != nullptr, std::bad_alloc()); TracyAllocS(this->ptr_, this->size_ * sizeof(T), 3); uninitialized_copy(policy, other.begin(), other.end(), this->ptr_); } @@ -165,9 +159,7 @@ class Vec : public VecView { void reserve(size_t n) { if (n > capacity_) { T *newBuffer = reinterpret_cast(malloc(n * sizeof(T))); -#if MANIFOLD_EXCEPTIONS - if (newBuffer == nullptr) throw std::bad_alloc(); -#endif + ASSERT(newBuffer != nullptr, std::bad_alloc()); TracyAllocS(newBuffer, n * sizeof(T), 3); if (this->size_ > 0) uninitialized_copy(autoPolicy(this->size_), this->ptr_, @@ -196,9 +188,7 @@ class Vec : public VecView { T *newBuffer = nullptr; if (this->size_ > 0) { newBuffer = reinterpret_cast(malloc(this->size_ * sizeof(T))); -#if MANIFOLD_EXCEPTIONS - if (newBuffer == nullptr) throw std::bad_alloc(); -#endif + ASSERT(newBuffer != nullptr, std::bad_alloc()); TracyAllocS(newBuffer, this->size_ * sizeof(T), 3); uninitialized_copy(autoPolicy(this->size_), this->ptr_, this->ptr_ + this->size_, newBuffer); @@ -213,38 +203,22 @@ class Vec : public VecView { VecView view(size_t offset = 0, size_t length = std::numeric_limits::max()) { - if (length == std::numeric_limits::max()) { + if (length == std::numeric_limits::max()) length = this->size_ - offset; -#if MANIFOLD_EXCEPTIONS - if (length < 0) throw std::out_of_range("Vec::view out of range"); -#endif - } -#if MANIFOLD_EXCEPTIONS - else if (offset + length > this->size_ || offset < 0) { - throw std::out_of_range("Vec::view out of range"); - } else if (length < 0) { - throw std::out_of_range("Vec::view negative length is not allowed"); - } -#endif + ASSERT(length >= 0, std::out_of_range("Vec::view out of range")); + ASSERT(offset + length <= this->size_ && offset >= 0, + std::out_of_range("Vec::view out of range")); return VecView(this->ptr_ + offset, length); } VecView cview( size_t offset = 0, size_t length = std::numeric_limits::max()) const { - if (length == std::numeric_limits::max()) { + if (length == std::numeric_limits::max()) length = this->size_ - offset; -#if MANIFOLD_EXCEPTIONS - if (length < 0) throw std::out_of_range("Vec::cview out of range"); -#endif - } -#if MANIFOLD_EXCEPTIONS - else if (offset + length > this->size_ || offset < 0) { - throw std::out_of_range("Vec::cview out of range"); - } else if (length < 0) { - throw std::out_of_range("Vec::cview negative length is not allowed"); - } -#endif + ASSERT(length >= 0, std::out_of_range("Vec::cview out of range")); + ASSERT(offset + length <= this->size_ && offset >= 0, + std::out_of_range("Vec::cview out of range")); return VecView(this->ptr_ + offset, length); } diff --git a/src/utilities/include/vec_view.h b/src/utilities/include/vec_view.h index 747802990..4c133402e 100644 --- a/src/utilities/include/vec_view.h +++ b/src/utilities/include/vec_view.h @@ -18,6 +18,8 @@ #include #endif +#include "optional_assert.h" + namespace manifold { /** @@ -48,16 +50,12 @@ class VecView { operator VecView() const { return {ptr_, size_}; } inline const T &operator[](size_t i) const { -#if MANIFOLD_EXCEPTIONS - if (i >= size_) throw std::out_of_range("Vec out of range"); -#endif + ASSERT(i < size_, std::out_of_range("Vec out of range")); return ptr_[i]; } inline T &operator[](size_t i) { -#if MANIFOLD_EXCEPTIONS - if (i >= size_) throw std::out_of_range("Vec out of range"); -#endif + ASSERT(i < size_, std::out_of_range("Vec out of range")); return ptr_[i]; } @@ -71,34 +69,26 @@ class VecView { Iter end() { return ptr_ + size_; } const T &front() const { -#if MANIFOLD_EXCEPTIONS - if (size_ == 0) - throw std::out_of_range("attempt to take the front of an empty vector"); -#endif + ASSERT(size_ != 0, + std::out_of_range("Attempt to take the front of an empty vector")); return ptr_[0]; } const T &back() const { -#if MANIFOLD_EXCEPTIONS - if (size_ == 0) - throw std::out_of_range("attempt to take the back of an empty vector"); -#endif + ASSERT(size_ != 0, + std::out_of_range("Attempt to take the back of an empty vector")); return ptr_[size_ - 1]; } T &front() { -#if MANIFOLD_EXCEPTIONS - if (size_ == 0) - throw std::out_of_range("attempt to take the front of an empty vector"); -#endif + ASSERT(size_ != 0, + std::out_of_range("Attempt to take the front of an empty vector")); return ptr_[0]; } T &back() { -#if MANIFOLD_EXCEPTIONS - if (size_ == 0) - throw std::out_of_range("attempt to take the back of an empty vector"); -#endif + ASSERT(size_ != 0, + std::out_of_range("Attempt to take the back of an empty vector")); return ptr_[size_ - 1]; } From 86e2b5d030f4014bb7814cfc00b582e6aa13826b Mon Sep 17 00:00:00 2001 From: pca006132 Date: Thu, 20 Jun 2024 13:40:53 +0800 Subject: [PATCH 16/24] polygon: change to size_t --- src/polygon/src/polygon.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/polygon/src/polygon.cpp b/src/polygon/src/polygon.cpp index 23fe50dba..ec93f269d 100644 --- a/src/polygon/src/polygon.cpp +++ b/src/polygon/src/polygon.cpp @@ -169,7 +169,7 @@ bool IsConvex(const PolygonsIdx &polys, float precision) { // it's okay because that zero-length edge will also get tested // non-normalized and will trip det == 0. glm::vec2 lastEdge = glm::normalize(firstEdge); - for (int v = 0; v < poly.size(); ++v) { + for (size_t v = 0; v < poly.size(); ++v) { const glm::vec2 edge = v + 1 < poly.size() ? poly[v + 1].pos - poly[v].pos : firstEdge; const float det = determinant2x2(lastEdge, edge); @@ -187,18 +187,18 @@ bool IsConvex(const PolygonsIdx &polys, float precision) { * avoid creating high-degree vertices. */ std::vector TriangulateConvex(const PolygonsIdx &polys) { - const int numTri = transform_reduce( + const size_t numTri = transform_reduce( autoPolicy(polys.size()), polys.begin(), polys.end(), [](const SimplePolygonIdx &poly) { return poly.size() - 2; }, 0, - thrust::plus()); + thrust::plus()); std::vector triangles; triangles.reserve(numTri); for (const SimplePolygonIdx &poly : polys) { - int i = 0; - int k = poly.size() - 1; + size_t i = 0; + size_t k = poly.size() - 1; bool right = true; while (i + 1 < k) { - const int j = right ? i + 1 : k - 1; + const size_t j = right ? i + 1 : k - 1; triangles.push_back({poly[i].idx, poly[j].idx, poly[k].idx}); if (right) { i = j; @@ -230,7 +230,7 @@ class EarClip { EarClip(const PolygonsIdx &polys, float precision) : precision_(precision) { ZoneScoped; - int numVert = 0; + size_t numVert = 0; for (const SimplePolygonIdx &poly : polys) { numVert += poly.size(); } From 486a6b090dda1181577d0a87d71531d43768403c Mon Sep 17 00:00:00 2001 From: pca006132 Date: Thu, 20 Jun 2024 14:47:24 +0800 Subject: [PATCH 17/24] format --- meshIO/src/meshIO.cpp | 9 +++++---- src/collider/src/collider.cpp | 4 ++-- src/manifold/src/boolean3.cpp | 6 ++++-- src/manifold/src/constructors.cpp | 8 ++++---- src/manifold/src/csg_tree.cpp | 2 +- src/manifold/src/face_op.cpp | 8 ++++---- src/manifold/src/sort.cpp | 26 +++++++++++++------------ src/manifold/src/subdivision.cpp | 4 ++-- src/polygon/src/polygon.cpp | 21 ++++++++++---------- src/utilities/include/optional_assert.h | 2 +- src/utilities/include/sparse.h | 4 ++-- 11 files changed, 50 insertions(+), 44 deletions(-) diff --git a/meshIO/src/meshIO.cpp b/meshIO/src/meshIO.cpp index 58de5b4ba..3021d034e 100644 --- a/meshIO/src/meshIO.cpp +++ b/meshIO/src/meshIO.cpp @@ -154,7 +154,7 @@ Mesh ImportMesh(const std::string& filename, bool forceCleanup) { for (size_t j = 0; j < mesh_i->mNumFaces; ++j) { const aiFace face = mesh_i->mFaces[j]; DEBUG_ASSERT(face.mNumIndices == 3, userErr, - "Non-triangular face in " + filename); + "Non-triangular face in " + filename); mesh_out.triVerts.emplace_back(face.mIndices[0], face.mIndices[1], face.mIndices[2]); } @@ -199,8 +199,9 @@ void ExportMesh(const std::string& filename, const MeshGL& mesh, int c = options.mat.normalChannels[i]; validChannels &= c >= 3 && c < (int)mesh.numProp; } - DEBUG_ASSERT(validChannels, userErr, - "When faceted is false, valid normalChannels must be supplied."); + DEBUG_ASSERT( + validChannels, userErr, + "When faceted is false, valid normalChannels must be supplied."); mesh_out->mNormals = new aiVector3D[mesh_out->mNumVertices]; } @@ -291,7 +292,7 @@ void ExportMesh(const std::string& filename, const Mesh& mesh, } if (!options.mat.vertColor.empty()) { DEBUG_ASSERT(mesh.vertPos.size() == options.mat.vertColor.size(), userErr, - "If present, vertColor must be the same length as vertPos."); + "If present, vertColor must be the same length as vertPos."); mesh_out->mColors[0] = new aiColor4D[mesh_out->mNumVertices]; } diff --git a/src/collider/src/collider.cpp b/src/collider/src/collider.cpp index 1d56036ec..321818b1f 100644 --- a/src/collider/src/collider.cpp +++ b/src/collider/src/collider.cpp @@ -286,7 +286,7 @@ Collider::Collider(const VecView& leafBB, const VecView& leafMorton) { ZoneScoped; DEBUG_ASSERT(leafBB.size() == leafMorton.size(), userErr, - "vectors must be the same length"); + "vectors must be the same length"); int num_nodes = 2 * leafBB.size() - 1; // assign and allocate members nodeBBox_.resize(num_nodes); @@ -348,7 +348,7 @@ SparseIndices Collider::Collisions(const VecView& queriesIn) const { void Collider::UpdateBoxes(const VecView& leafBB) { ZoneScoped; DEBUG_ASSERT(leafBB.size() == NumLeaves(), userErr, - "must have the same number of updated boxes as original"); + "must have the same number of updated boxes as original"); // copy in leaf node Boxes strided_range::Iter> leaves(nodeBBox_.begin(), nodeBBox_.end(), 2); auto policy = autoPolicy(NumInternal()); diff --git a/src/manifold/src/boolean3.cpp b/src/manifold/src/boolean3.cpp index ac7bb08d4..c03e120c7 100644 --- a/src/manifold/src/boolean3.cpp +++ b/src/manifold/src/boolean3.cpp @@ -30,7 +30,8 @@ namespace { glm::vec2 Interpolate(glm::vec3 pL, glm::vec3 pR, float x) { const float dxL = x - pL.x; const float dxR = x - pR.x; - DEBUG_ASSERT(dxL * dxR <= 0, logicErr, "Boolean manifold error: not in domain"); + DEBUG_ASSERT(dxL * dxR <= 0, logicErr, + "Boolean manifold error: not in domain"); const bool useL = fabs(dxL) < fabs(dxR); const glm::vec3 dLR = pR - pL; const float lambda = (useL ? dxL : dxR) / dLR.x; @@ -46,7 +47,8 @@ glm::vec4 Intersect(const glm::vec3 &pL, const glm::vec3 &pR, const glm::vec3 &qL, const glm::vec3 &qR) { const float dyL = qL.y - pL.y; const float dyR = qR.y - pR.y; - DEBUG_ASSERT(dyL * dyR <= 0, logicErr, "Boolean manifold error: no intersection"); + DEBUG_ASSERT(dyL * dyR <= 0, logicErr, + "Boolean manifold error: no intersection"); const bool useL = fabs(dyL) < fabs(dyR); const float dx = pR.x - pL.x; float lambda = (useL ? dyL : dyR) / (dyL - dyR); diff --git a/src/manifold/src/constructors.cpp b/src/manifold/src/constructors.cpp index 6772652b2..48fd3385e 100644 --- a/src/manifold/src/constructors.cpp +++ b/src/manifold/src/constructors.cpp @@ -81,8 +81,8 @@ namespace manifold { Manifold Manifold::Smooth(const MeshGL& meshGL, const std::vector& sharpenedEdges) { DEBUG_ASSERT(meshGL.halfedgeTangent.empty(), std::runtime_error, - "when supplying tangents, the normal constructor should be used " - "rather than Smooth()."); + "when supplying tangents, the normal constructor should be used " + "rather than Smooth()."); // Don't allow any triangle merging. std::vector propertyTolerance(meshGL.numProp - 3, -1); @@ -123,8 +123,8 @@ Manifold Manifold::Smooth(const MeshGL& meshGL, Manifold Manifold::Smooth(const Mesh& mesh, const std::vector& sharpenedEdges) { DEBUG_ASSERT(mesh.halfedgeTangent.empty(), std::runtime_error, - "when supplying tangents, the normal constructor should be used " - "rather than Smooth()."); + "when supplying tangents, the normal constructor should be used " + "rather than Smooth()."); Impl::MeshRelationD relation = {(int)ReserveIDs(1)}; std::shared_ptr impl = std::make_shared(mesh, relation); diff --git a/src/manifold/src/csg_tree.cpp b/src/manifold/src/csg_tree.cpp index ca0e3d78c..781896644 100644 --- a/src/manifold/src/csg_tree.cpp +++ b/src/manifold/src/csg_tree.cpp @@ -458,7 +458,7 @@ std::shared_ptr CsgOpNode::BatchBoolean( ZoneScoped; auto getImplPtr = GetImplPtr(); DEBUG_ASSERT(operation != OpType::Subtract, logicErr, - "BatchBoolean doesn't support Difference."); + "BatchBoolean doesn't support Difference."); // common cases if (results.size() == 0) return std::make_shared(); if (results.size() == 1) diff --git a/src/manifold/src/face_op.cpp b/src/manifold/src/face_op.cpp index a33b93606..cb131aff8 100644 --- a/src/manifold/src/face_op.cpp +++ b/src/manifold/src/face_op.cpp @@ -67,7 +67,7 @@ void Manifold::Impl::Face2Tri(const Vec& faceEdge, std::swap(ends[1], ends[2]); } DEBUG_ASSERT(ends[0] == tri[1] && ends[1] == tri[2] && ends[2] == tri[0], - topologyErr, "These 3 edges do not form a triangle!"); + topologyErr, "These 3 edges do not form a triangle!"); addTri(face, tri, normal, halfedgeRef[firstEdge]); } else if (numEdge == 4) { // Pair of triangles @@ -95,8 +95,8 @@ void Manifold::Impl::Face2Tri(const Vec& faceEdge, } } DEBUG_ASSERT(glm::all(glm::greaterThanEqual(tri0, glm::ivec3(0))) && - glm::all(glm::greaterThanEqual(tri1, glm::ivec3(0))), - topologyErr, "non-manifold quad!"); + glm::all(glm::greaterThanEqual(tri1, glm::ivec3(0))), + topologyErr, "non-manifold quad!"); bool firstValid = triCCW(tri0) && triCCW(tri1); tri0[2] = tri1[1]; tri1[2] = tri0[1]; @@ -144,7 +144,7 @@ void Manifold::Impl::Face2Tri(const Vec& faceEdge, countAt(faceEdge.size() - 1), [&](size_t face) { triCount[face] = faceEdge[face + 1] - faceEdge[face] - 2; DEBUG_ASSERT(triCount[face] >= 1, topologyErr, - "face has less than three edges."); + "face has less than three edges."); if (triCount[face] > 2) group.run([&, face] { std::vector newTris = generalTriangulation(face); diff --git a/src/manifold/src/sort.cpp b/src/manifold/src/sort.cpp index aa82ef6e7..8bb91887f 100644 --- a/src/manifold/src/sort.cpp +++ b/src/manifold/src/sort.cpp @@ -246,7 +246,7 @@ void Manifold::Impl::Finish() { CompactProps(); DEBUG_ASSERT(halfedge_.size() % 6 == 0, topologyErr, - "Not an even number of faces after sorting faces!"); + "Not an even number of faces after sorting faces!"); #ifdef MANIFOLD_DEBUG Halfedge extrema = {0, 0, 0, 0}; @@ -254,22 +254,24 @@ void Manifold::Impl::Finish() { halfedge_.end(), extrema, Extrema()); #endif - DEBUG_ASSERT(extrema.startVert >= 0, topologyErr, "Vertex index is negative!"); + DEBUG_ASSERT(extrema.startVert >= 0, topologyErr, + "Vertex index is negative!"); DEBUG_ASSERT(extrema.endVert < static_cast(NumVert()), topologyErr, - "Vertex index exceeds number of verts!"); + "Vertex index exceeds number of verts!"); DEBUG_ASSERT(extrema.face >= 0, topologyErr, "Face index is negative!"); DEBUG_ASSERT(extrema.face < static_cast(NumTri()), topologyErr, - "Face index exceeds number of faces!"); + "Face index exceeds number of faces!"); DEBUG_ASSERT(extrema.pairedHalfedge >= 0, topologyErr, - "Halfedge index is negative!"); - DEBUG_ASSERT(extrema.pairedHalfedge < 2 * static_cast(NumEdge()), topologyErr, - "Halfedge index exceeds number of halfedges!"); + "Halfedge index is negative!"); + DEBUG_ASSERT(extrema.pairedHalfedge < 2 * static_cast(NumEdge()), + topologyErr, "Halfedge index exceeds number of halfedges!"); DEBUG_ASSERT(meshRelation_.triRef.size() == NumTri() || - meshRelation_.triRef.size() == 0, - logicErr, "Mesh Relation doesn't fit!"); - DEBUG_ASSERT(faceNormal_.size() == NumTri() || faceNormal_.size() == 0, logicErr, - "faceNormal size = " + std::to_string(faceNormal_.size()) + - ", NumTri = " + std::to_string(NumTri())); + meshRelation_.triRef.size() == 0, + logicErr, "Mesh Relation doesn't fit!"); + DEBUG_ASSERT(faceNormal_.size() == NumTri() || faceNormal_.size() == 0, + logicErr, + "faceNormal size = " + std::to_string(faceNormal_.size()) + + ", NumTri = " + std::to_string(NumTri())); // TODO: figure out why this has a flaky failure and then enable reading // vertNormals from a Mesh. // DEBUG_ASSERT(vertNormal_.size() == NumVert() || vertNormal_.size() == 0, diff --git a/src/manifold/src/subdivision.cpp b/src/manifold/src/subdivision.cpp index 6d3b73716..07253e34d 100644 --- a/src/manifold/src/subdivision.cpp +++ b/src/manifold/src/subdivision.cpp @@ -281,8 +281,8 @@ class Partition { return edgeOffsets[edge] + (edgeFwd[edge] ? 1 : -1) * idx; }; - DEBUG_ASSERT(glm::all(glm::greaterThanEqual(edgeAdded, glm::ivec4(0))), logicErr, - "negative divisions!"); + DEBUG_ASSERT(glm::all(glm::greaterThanEqual(edgeAdded, glm::ivec4(0))), + logicErr, "negative divisions!"); int corner = -1; int last = 3; diff --git a/src/polygon/src/polygon.cpp b/src/polygon/src/polygon.cpp index ec93f269d..f4e2f593d 100644 --- a/src/polygon/src/polygon.cpp +++ b/src/polygon/src/polygon.cpp @@ -63,20 +63,21 @@ std::vector Triangles2Edges( } void CheckTopology(const std::vector &halfedges) { - DEBUG_ASSERT(halfedges.size() % 2 == 0, topologyErr, "Odd number of halfedges."); + DEBUG_ASSERT(halfedges.size() % 2 == 0, topologyErr, + "Odd number of halfedges."); ssize_t n_edges = halfedges.size() / 2; std::vector forward(halfedges.size()), backward(halfedges.size()); auto end = std::copy_if(halfedges.begin(), halfedges.end(), forward.begin(), [](PolyEdge e) { return e.endVert > e.startVert; }); DEBUG_ASSERT(std::distance(forward.begin(), end) == n_edges, topologyErr, - "Half of halfedges should be forward."); + "Half of halfedges should be forward."); forward.resize(n_edges); end = std::copy_if(halfedges.begin(), halfedges.end(), backward.begin(), [](PolyEdge e) { return e.endVert < e.startVert; }); DEBUG_ASSERT(std::distance(backward.begin(), end) == n_edges, topologyErr, - "Half of halfedges should be backward."); + "Half of halfedges should be backward."); backward.resize(n_edges); std::for_each(backward.begin(), backward.end(), @@ -89,8 +90,8 @@ void CheckTopology(const std::vector &halfedges) { std::stable_sort(backward.begin(), backward.end(), cmp); for (ssize_t i = 0; i < n_edges; ++i) { DEBUG_ASSERT(forward[i].startVert == backward[i].startVert && - forward[i].endVert == backward[i].endVert, - topologyErr, "Not manifold."); + forward[i].endVert == backward[i].endVert, + topologyErr, "Not manifold."); } } @@ -113,11 +114,11 @@ void CheckGeometry(const std::vector &triangles, } } DEBUG_ASSERT(std::all_of(triangles.begin(), triangles.end(), - [&vertPos, precision](const glm::ivec3 &tri) { - return CCW(vertPos[tri[0]], vertPos[tri[1]], - vertPos[tri[2]], precision) >= 0; - }), - geometryErr, "triangulation is not entirely CCW!"); + [&vertPos, precision](const glm::ivec3 &tri) { + return CCW(vertPos[tri[0]], vertPos[tri[1]], + vertPos[tri[2]], precision) >= 0; + }), + geometryErr, "triangulation is not entirely CCW!"); } void Dump(const PolygonsIdx &polys) { diff --git a/src/utilities/include/optional_assert.h b/src/utilities/include/optional_assert.h index 7e3590af6..2a2299372 100644 --- a/src/utilities/include/optional_assert.h +++ b/src/utilities/include/optional_assert.h @@ -39,7 +39,7 @@ void Assert(bool condition, const char* file, int line, const std::string& cond, #if MANIFOLD_EXCEPTIONS #define ASSERT(condition, EX) \ - if (!(condition)) throw (EX); + if (!(condition)) throw(EX); #else #define ASSERT(condition, EX) #endif diff --git a/src/utilities/include/sparse.h b/src/utilities/include/sparse.h index 86bf73751..ee048adc2 100644 --- a/src/utilities/include/sparse.h +++ b/src/utilities/include/sparse.h @@ -134,7 +134,7 @@ class SparseIndices { size_t RemoveZeros(Vec& S) { DEBUG_ASSERT(S.size() == size(), userErr, - "Different number of values than indicies!"); + "Different number of values than indicies!"); VecView view = AsVec64(); auto zBegin = zip(S.begin(), view.begin()); auto zEnd = zip(S.end(), view.end()); @@ -165,7 +165,7 @@ class SparseIndices { template size_t KeepFinite(Vec& v, Vec& x) { DEBUG_ASSERT(x.size() == size(), userErr, - "Different number of values than indicies!"); + "Different number of values than indicies!"); VecView view = AsVec64(); auto zBegin = zip(v.begin(), x.begin(), view.begin()); auto zEnd = zip(v.end(), x.end(), view.end()); From 1988a675224842cbb3ab312636ff7235247d70c7 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Thu, 20 Jun 2024 14:50:14 +0800 Subject: [PATCH 18/24] fix sign compare --- src/manifold/src/smoothing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/manifold/src/smoothing.cpp b/src/manifold/src/smoothing.cpp index 387b881fb..50992cdd2 100644 --- a/src/manifold/src/smoothing.cpp +++ b/src/manifold/src/smoothing.cpp @@ -770,7 +770,7 @@ void Manifold::Impl::DistributeTangents(const Vec& fixedHalfedges) { } current = halfedge; - int i = 0; + size_t i = 0; do { current = NextHalfedge(halfedge_[current].pairedHalfedge); if (IsMarkedInsideQuad(current)) continue; From 68681a4cfb4e29a652cbc85518a927f402e2b292 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Thu, 20 Jun 2024 15:06:06 +0800 Subject: [PATCH 19/24] install optional_assert.h --- src/utilities/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/utilities/CMakeLists.txt b/src/utilities/CMakeLists.txt index 413474678..561ee9360 100644 --- a/src/utilities/CMakeLists.txt +++ b/src/utilities/CMakeLists.txt @@ -89,4 +89,6 @@ endif() target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17) install(TARGETS ${PROJECT_NAME} EXPORT manifoldTargets) -install(FILES include/public.h include/vec_view.h include/tri_dist.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME}) +install(FILES + include/public.h include/vec_view.h include/tri_dist.h include/optional_assert.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME}) From a8591b6eb499d04a2f7f8a659ddd888e90dac0cb Mon Sep 17 00:00:00 2001 From: pca006132 Date: Fri, 28 Jun 2024 10:39:18 +0800 Subject: [PATCH 20/24] address comments --- bindings/c/include/manifoldc.h | 4 +-- bindings/c/manifoldc.cpp | 7 ++-- bindings/python/manifold3d.cpp | 46 ++++++++++++------------- samples/src/scallop.cpp | 4 +-- src/manifold/include/manifold.h | 4 +-- src/manifold/src/boolean3.cpp | 14 ++++---- src/manifold/src/edge_op.cpp | 4 +-- src/manifold/src/smoothing.cpp | 8 ++--- src/polygon/src/polygon.cpp | 14 ++++---- src/utilities/include/optional_assert.h | 3 ++ src/utilities/include/public.h | 6 ++-- src/utilities/include/utils.h | 5 --- src/utilities/include/vec.h | 3 -- src/utilities/include/vec_view.h | 4 --- 14 files changed, 60 insertions(+), 66 deletions(-) diff --git a/bindings/c/include/manifoldc.h b/bindings/c/include/manifoldc.h index df6b154d8..1fb9781fc 100644 --- a/bindings/c/include/manifoldc.h +++ b/bindings/c/include/manifoldc.h @@ -155,8 +155,8 @@ ManifoldManifold *manifold_sphere(void *mem, float radius, int circular_segments); ManifoldManifold *manifold_of_meshgl(void *mem, ManifoldMeshGL *mesh); ManifoldManifold *manifold_smooth(void *mem, ManifoldMeshGL *mesh, - int *half_edges, float *smoothness, - int n_idxs); + size_t *half_edges, float *smoothness, + size_t n_idxs); ManifoldManifold *manifold_extrude(void *mem, ManifoldCrossSection *cs, float height, int slices, float twist_degrees, float scale_x, diff --git a/bindings/c/manifoldc.cpp b/bindings/c/manifoldc.cpp index f88296cf1..651bee173 100644 --- a/bindings/c/manifoldc.cpp +++ b/bindings/c/manifoldc.cpp @@ -367,10 +367,10 @@ ManifoldMeshGL *manifold_meshgl_w_tangents(void *mem, float *vert_props, } ManifoldManifold *manifold_smooth(void *mem, ManifoldMeshGL *mesh, - int *half_edges, float *smoothness, - int n_edges) { + size_t *half_edges, float *smoothness, + size_t n_edges) { auto smooth = std::vector(); - for (int i = 0; i < n_edges; ++i) { + for (size_t i = 0; i < n_edges; ++i) { smooth.push_back({half_edges[i], smoothness[i]}); } auto m = Manifold::Smooth(*from_c(mesh), smooth); @@ -392,7 +392,6 @@ ManifoldManifold *manifold_extrude(void *mem, ManifoldCrossSection *cs, } ManifoldManifold *manifold_revolve(void *mem, ManifoldCrossSection *cs, - int circular_segments) { auto m = Manifold::Revolve(*from_c(cs), circular_segments); return to_c(new (mem) Manifold(m)); diff --git a/bindings/python/manifold3d.cpp b/bindings/python/manifold3d.cpp index d2295d264..2dfa4007f 100644 --- a/bindings/python/manifold3d.cpp +++ b/bindings/python/manifold3d.cpp @@ -59,16 +59,16 @@ struct glm_name { }; // handle glm::vecN -template +template struct nb::detail::type_caster> { using glm_type = glm::vec; NB_TYPE_CASTER(glm_type, const_name(glm_name::name)); bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept { - int size = PyObject_Size(src.ptr()); // negative on failure + size_t size = PyObject_Size(src.ptr()); // negative on failure if (size != N) return false; make_caster t_cast; - for (int i = 0; i < size; i++) { + for (size_t i = 0; i < size; i++) { if (!t_cast.from_python(src[i], flags, cleanup)) return false; value[i] = t_cast.value; } @@ -77,24 +77,24 @@ struct nb::detail::type_caster> { static handle from_cpp(glm_type vec, rv_policy policy, cleanup_list *cleanup) noexcept { nb::list out; - for (int i = 0; i < N; i++) out.append(vec[i]); + for (size_t i = 0; i < N; i++) out.append(vec[i]); return out.release(); } }; // handle glm::matMxN -template +template struct nb::detail::type_caster> { using glm_type = glm::mat; using numpy_type = nb::ndarray>; NB_TYPE_CASTER(glm_type, const_name(glm_name::name)); bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept { - int rows = PyObject_Size(src.ptr()); // negative on failure + size_t rows = PyObject_Size(src.ptr()); // negative on failure if (rows != R) return false; for (size_t i = 0; i < R; i++) { const nb::object &slice = src[i]; - int cols = PyObject_Size(slice.ptr()); // negative on failure + size_t cols = PyObject_Size(slice.ptr()); // negative on failure if (cols != C) return false; for (size_t j = 0; j < C; j++) { make_caster t_cast; @@ -108,8 +108,8 @@ struct nb::detail::type_caster> { cleanup_list *cleanup) noexcept { T *buffer = new T[R * C]; nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[](T *) p; }); - for (int i = 0; i < R; i++) { - for (int j = 0; j < C; j++) { + for (size_t i = 0; i < R; i++) { + for (size_t j = 0; j < C; j++) { // py is (Rows, Cols), glm is (Cols, Rows) buffer[i * C + j] = mat[j][i]; } @@ -121,7 +121,7 @@ struct nb::detail::type_caster> { }; // handle std::vector -template +template struct nb::detail::type_caster>> { using glm_type = glm::vec; using numpy_type = nb::ndarray>; @@ -131,18 +131,18 @@ struct nb::detail::type_caster>> { bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept { make_caster arr_cast; if (arr_cast.from_python(src, flags, cleanup)) { - int num_vec = arr_cast.value.shape(0); + size_t num_vec = arr_cast.value.shape(0); value.resize(num_vec); - for (int i = 0; i < num_vec; i++) { - for (int j = 0; j < N; j++) { + for (size_t i = 0; i < num_vec; i++) { + for (size_t j = 0; j < N; j++) { value[i][j] = arr_cast.value(i, j); } } } else { - int num_vec = PyObject_Size(src.ptr()); // negative on failure - if (num_vec < 0) return false; + size_t num_vec = PyObject_Size(src.ptr()); // negative on failure + if (num_vec == static_cast(-1)) return false; value.resize(num_vec); - for (int i = 0; i < num_vec; i++) { + for (size_t i = 0; i < num_vec; i++) { make_caster vec_cast; if (!vec_cast.from_python(src[i], flags, cleanup)) return false; value[i] = vec_cast.value; @@ -154,9 +154,9 @@ struct nb::detail::type_caster>> { cleanup_list *cleanup) noexcept { size_t num_vec = vec.size(); T *buffer = new T[num_vec * N]; - nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[](T *) p; }); + nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[] (T *)p; }); for (size_t i = 0; i < num_vec; i++) { - for (int j = 0; j < N; j++) { + for (size_t j = 0; j < N; j++) { buffer[i * N + j] = vec[i][j]; } } @@ -167,7 +167,7 @@ struct nb::detail::type_caster>> { }; // handle VecView -template +template struct nb::detail::type_caster>> { using glm_type = glm::vec; using numpy_type = nb::ndarray>; @@ -178,10 +178,10 @@ struct nb::detail::type_caster>> { make_caster arr_cast; if (!arr_cast.from_python(src, flags, cleanup)) return false; // TODO try 2d iterators if numpy cast fails - int num_vec = arr_cast.value.shape(0); + size_t num_vec = arr_cast.value.shape(0); if (num_vec != value.size()) return false; - for (int i = 0; i < num_vec; i++) { - for (int j = 0; j < N; j++) { + for (size_t i = 0; i < num_vec; i++) { + for (size_t j = 0; j < N; j++) { value[i][j] = arr_cast.value(i, j); } } @@ -378,7 +378,7 @@ NB_MODULE(manifold3d, m) { "(xmin, ymin, zmin, xmax, ymax, zmax).") .def_static( "smooth", - [](const MeshGL &mesh, std::vector sharpened_edges, + [](const MeshGL &mesh, std::vector sharpened_edges, std::vector edge_smoothness) { if (sharpened_edges.size() != edge_smoothness.size()) { throw std::runtime_error( diff --git a/samples/src/scallop.cpp b/samples/src/scallop.cpp index d72d5f495..2b24637f3 100644 --- a/samples/src/scallop.cpp +++ b/samples/src/scallop.cpp @@ -43,7 +43,7 @@ Manifold Scallop() { if (j == 2 * wiggles) j = 0; float smoothness = 1 - sharpness * glm::cos((theta + delta / 2) / 2); - int halfedge = 3 * scallop.triVerts.size() + 1; + size_t halfedge = 3 * scallop.triVerts.size() + 1; sharpenedEdges.push_back({halfedge, smoothness}); scallop.triVerts.push_back({0, 2 + i, 2 + j}); @@ -54,4 +54,4 @@ Manifold Scallop() { return Manifold::Smooth(scallop, sharpenedEdges); } -} // namespace manifold \ No newline at end of file +} // namespace manifold diff --git a/src/manifold/include/manifold.h b/src/manifold/include/manifold.h index f33be2cfd..143c8edae 100644 --- a/src/manifold/include/manifold.h +++ b/src/manifold/include/manifold.h @@ -48,14 +48,14 @@ struct MeshGL { /// Number of property vertices uint32_t NumVert() const { ASSERT(vertProperties.size() / numProp < - static_cast(std::numeric_limits::max()), + static_cast(std::numeric_limits::max()), std::out_of_range("mesh too large for MeshGL")); return vertProperties.size() / numProp; }; /// Number of triangles uint32_t NumTri() const { ASSERT(triVerts.size() / 3 < - static_cast(std::numeric_limits::max()), + static_cast(std::numeric_limits::max()), std::out_of_range("mesh too large for MeshGL")); return triVerts.size() / 3; }; diff --git a/src/manifold/src/boolean3.cpp b/src/manifold/src/boolean3.cpp index c03e120c7..27e442950 100644 --- a/src/manifold/src/boolean3.cpp +++ b/src/manifold/src/boolean3.cpp @@ -139,9 +139,9 @@ inline thrust::pair Shadow01( // https://github.com/scandum/binary_search/blob/master/README.md // much faster than standard binary search on large arrays -ssize_t monobound_quaternary_search(VecView array, int64_t key) { +size_t monobound_quaternary_search(VecView array, int64_t key) { if (array.size() == 0) { - return -1; + return std::numeric_limits::max(); } size_t bot = 0; size_t top = array.size(); @@ -396,8 +396,8 @@ struct Kernel12 { for (int vert : {edge.startVert, edge.endVert}) { const int64_t key = forward ? SparseIndices::EncodePQ(vert, q2) : SparseIndices::EncodePQ(q2, vert); - const ssize_t idx = monobound_quaternary_search(p0q2, key); - if (idx != -1) { + const size_t idx = monobound_quaternary_search(p0q2, key); + if (idx != std::numeric_limits::max()) { const int s = s02[idx]; x12 += s * ((vert == edge.startVert) == forward ? 1 : -1); if (k < 2 && (k == 0 || (s != 0) != shadows)) { @@ -417,8 +417,10 @@ struct Kernel12 { const int q1F = edge.IsForward() ? q1 : edge.pairedHalfedge; const int64_t key = forward ? SparseIndices::EncodePQ(p1, q1F) : SparseIndices::EncodePQ(q1F, p1); - const ssize_t idx = monobound_quaternary_search(p1q1, key); - if (idx != -1) { // s is implicitly zero for anything not found + const size_t idx = monobound_quaternary_search(p1q1, key); + if (idx != + std::numeric_limits::max()) { // s is implicitly zero for + // anything not found const int s = s11[idx]; x12 -= s * (edge.IsForward() ? 1 : -1); if (k < 2 && (k == 0 || (s != 0) != shadows)) { diff --git a/src/manifold/src/edge_op.cpp b/src/manifold/src/edge_op.cpp index a45a0b8a2..d224c05a3 100644 --- a/src/manifold/src/edge_op.cpp +++ b/src/manifold/src/edge_op.cpp @@ -112,7 +112,7 @@ struct SwappableEdge { struct SortEntry { int start; int end; - unsigned int index; + size_t index; inline bool operator<(const SortEntry& other) const { return start == other.start ? end < other.end : start < other.start; } @@ -156,7 +156,7 @@ void Manifold::Impl::SimplifyTopology() { ZoneScopedN("DedupeEdge"); Vec entries; entries.reserve(nbEdges / 2); - for (unsigned int i = 0; i < nbEdges; ++i) { + for (size_t i = 0; i < nbEdges; ++i) { if (halfedge_[i].IsForward()) { entries.push_back({halfedge_[i].startVert, halfedge_[i].endVert, i}); } diff --git a/src/manifold/src/smoothing.cpp b/src/manifold/src/smoothing.cpp index 50992cdd2..4a3ff3263 100644 --- a/src/manifold/src/smoothing.cpp +++ b/src/manifold/src/smoothing.cpp @@ -434,9 +434,9 @@ std::vector Manifold::Impl::SharpenEdges( float minSharpAngle, float minSmoothness) const { std::vector sharpenedEdges; const float minRadians = glm::radians(minSharpAngle); - for (int e = 0; e < static_cast(halfedge_.size()); ++e) { + for (size_t e = 0; e < halfedge_.size(); ++e) { if (!halfedge_[e].IsForward()) continue; - const int pair = halfedge_[e].pairedHalfedge; + const size_t pair = halfedge_[e].pairedHalfedge; const float dihedral = glm::acos(glm::dot(faceNormal_[e / 3], faceNormal_[pair / 3])); if (dihedral > minRadians) { @@ -912,7 +912,7 @@ void Manifold::Impl::CreateTangents(std::vector sharpenedEdges) { halfedgeTangent_.swap(tangent); // Add sharpened edges around faces, just on the face side. - for (int tri = 0; tri < static_cast(NumTri()); ++tri) { + for (size_t tri = 0; tri < NumTri(); ++tri) { if (!triIsFlatFace[tri]) continue; for (const int j : {0, 1, 2}) { const int tri2 = halfedge_[3 * tri + j].pairedHalfedge / 3; @@ -932,7 +932,7 @@ void Manifold::Impl::CreateTangents(std::vector sharpenedEdges) { const int pair = halfedge_[edge.halfedge].pairedHalfedge; const int idx = forward ? edge.halfedge : pair; if (edges.find(idx) == edges.end()) { - edges[idx] = {edge, {pair, 1}}; + edges[idx] = {edge, {static_cast(pair), 1}}; if (!forward) std::swap(edges[idx].first, edges[idx].second); } else { Smoothness& e = forward ? edges[idx].first : edges[idx].second; diff --git a/src/polygon/src/polygon.cpp b/src/polygon/src/polygon.cpp index f4e2f593d..ab04456a2 100644 --- a/src/polygon/src/polygon.cpp +++ b/src/polygon/src/polygon.cpp @@ -65,19 +65,21 @@ std::vector Triangles2Edges( void CheckTopology(const std::vector &halfedges) { DEBUG_ASSERT(halfedges.size() % 2 == 0, topologyErr, "Odd number of halfedges."); - ssize_t n_edges = halfedges.size() / 2; + size_t n_edges = halfedges.size() / 2; std::vector forward(halfedges.size()), backward(halfedges.size()); auto end = std::copy_if(halfedges.begin(), halfedges.end(), forward.begin(), [](PolyEdge e) { return e.endVert > e.startVert; }); - DEBUG_ASSERT(std::distance(forward.begin(), end) == n_edges, topologyErr, - "Half of halfedges should be forward."); + DEBUG_ASSERT( + static_cast(std::distance(forward.begin(), end)) == n_edges, + topologyErr, "Half of halfedges should be forward."); forward.resize(n_edges); end = std::copy_if(halfedges.begin(), halfedges.end(), backward.begin(), [](PolyEdge e) { return e.endVert < e.startVert; }); - DEBUG_ASSERT(std::distance(backward.begin(), end) == n_edges, topologyErr, - "Half of halfedges should be backward."); + DEBUG_ASSERT( + static_cast(std::distance(backward.begin(), end)) == n_edges, + topologyErr, "Half of halfedges should be backward."); backward.resize(n_edges); std::for_each(backward.begin(), backward.end(), @@ -88,7 +90,7 @@ void CheckTopology(const std::vector &halfedges) { }; std::stable_sort(forward.begin(), forward.end(), cmp); std::stable_sort(backward.begin(), backward.end(), cmp); - for (ssize_t i = 0; i < n_edges; ++i) { + for (size_t i = 0; i < n_edges; ++i) { DEBUG_ASSERT(forward[i].startVert == backward[i].startVert && forward[i].endVert == backward[i].endVert, topologyErr, "Not manifold."); diff --git a/src/utilities/include/optional_assert.h b/src/utilities/include/optional_assert.h index 2a2299372..3c5f9d6f8 100644 --- a/src/utilities/include/optional_assert.h +++ b/src/utilities/include/optional_assert.h @@ -15,6 +15,9 @@ #pragma once #include "public.h" +#if MANIFOLD_EXCEPTIONS +#include +#endif #ifdef MANIFOLD_DEBUG #include diff --git a/src/utilities/include/public.h b/src/utilities/include/public.h index a579f3eff..d11a7f806 100644 --- a/src/utilities/include/public.h +++ b/src/utilities/include/public.h @@ -154,7 +154,7 @@ struct Mesh { */ struct Smoothness { /// The halfedge index = 3 * tri + i, referring to Mesh.triVerts[tri][i]. - int halfedge; + size_t halfedge; /// A value between 0 and 1, where 0 is sharp and 1 is the default and the /// curvature is interpolated between these values. The two paired halfedges /// can have different values while maintaining C-1 continuity (except for 0). @@ -678,7 +678,7 @@ inline std::ostream& operator<<(std::ostream& stream, const Rect& box) { template void Dump(const std::vector& vec) { std::cout << "Vec = " << std::endl; - for (int i = 0; i < vec.size(); ++i) { + for (size_t i = 0; i < vec.size(); ++i) { std::cout << i << ", " << vec[i] << ", " << std::endl; } std::cout << std::endl; @@ -692,7 +692,7 @@ void Diff(const std::vector& a, const std::vector& b) { << std::endl; return; } - for (int i = 0; i < a.size(); ++i) { + for (size_t i = 0; i < a.size(); ++i) { if (a[i] != b[i]) std::cout << i << ": " << a[i] << ", " << b[i] << std::endl; } diff --git a/src/utilities/include/utils.h b/src/utilities/include/utils.h index f4e206d5d..1c13cd0d3 100644 --- a/src/utilities/include/utils.h +++ b/src/utilities/include/utils.h @@ -18,11 +18,6 @@ #include #include -#if defined(_MSC_VER) -#include -typedef SSIZE_T ssize_t; -#endif - #ifdef MANIFOLD_DEBUG #include #include diff --git a/src/utilities/include/vec.h b/src/utilities/include/vec.h index 21bc7fac5..59db747fb 100644 --- a/src/utilities/include/vec.h +++ b/src/utilities/include/vec.h @@ -13,9 +13,6 @@ // limitations under the License. #pragma once -#if MANIFOLD_EXCEPTIONS -#include -#endif #if TRACY_ENABLE && TRACY_MEMORY_USAGE #include "tracy/Tracy.hpp" #else diff --git a/src/utilities/include/vec_view.h b/src/utilities/include/vec_view.h index 4c133402e..74708ffff 100644 --- a/src/utilities/include/vec_view.h +++ b/src/utilities/include/vec_view.h @@ -14,10 +14,6 @@ #pragma once -#if MANIFOLD_EXCEPTIONS -#include -#endif - #include "optional_assert.h" namespace manifold { From a446e0daa11cc2748d88a429ec43f85a54f3e9c2 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Fri, 28 Jun 2024 10:47:27 +0800 Subject: [PATCH 21/24] fix --- bindings/python/manifold3d.cpp | 2 +- src/utilities/include/optional_assert.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/python/manifold3d.cpp b/bindings/python/manifold3d.cpp index 508e0f2a6..16ee2d106 100644 --- a/bindings/python/manifold3d.cpp +++ b/bindings/python/manifold3d.cpp @@ -154,7 +154,7 @@ struct nb::detail::type_caster>> { cleanup_list *cleanup) noexcept { size_t num_vec = vec.size(); T *buffer = new T[num_vec * N]; - nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[] (T *)p; }); + nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[](T *) p; }); for (size_t i = 0; i < num_vec; i++) { for (size_t j = 0; j < N; j++) { buffer[i * N + j] = vec[i][j]; diff --git a/src/utilities/include/optional_assert.h b/src/utilities/include/optional_assert.h index 3c5f9d6f8..94d947ef7 100644 --- a/src/utilities/include/optional_assert.h +++ b/src/utilities/include/optional_assert.h @@ -16,7 +16,7 @@ #include "public.h" #if MANIFOLD_EXCEPTIONS -#include +#include #endif #ifdef MANIFOLD_DEBUG From 80b83fd2b704910c91faa711c48bde632f0769d6 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Fri, 28 Jun 2024 12:06:45 +0800 Subject: [PATCH 22/24] fix --- src/manifold/src/constructors.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/manifold/src/constructors.cpp b/src/manifold/src/constructors.cpp index 8e12e3ae2..92548060a 100644 --- a/src/manifold/src/constructors.cpp +++ b/src/manifold/src/constructors.cpp @@ -257,14 +257,14 @@ Manifold Manifold::Extrude(const Polygons& crossSection, float height, auto& triVerts = triVertsDH; int nCrossSection = 0; bool isCone = scaleTop.x == 0.0 && scaleTop.y == 0.0; - int idx = 0; + size_t idx = 0; PolygonsIdx polygonsIndexed; for (auto& poly : crossSection) { nCrossSection += poly.size(); SimplePolygonIdx simpleIndexed; for (const glm::vec2& polyVert : poly) { vertPos.push_back({polyVert.x, polyVert.y, 0.0f}); - simpleIndexed.push_back({polyVert, idx++}); + simpleIndexed.push_back({polyVert, static_cast(idx++)}); } polygonsIndexed.push_back(simpleIndexed); } @@ -277,10 +277,10 @@ Manifold Manifold::Extrude(const Polygons& crossSection, float height, size_t j = 0; size_t idx = 0; for (const auto& poly : crossSection) { - for (int vert = 0; vert < poly.size(); ++vert) { - int offset = idx + nCrossSection * i; - int thisVert = vert + offset; - int lastVert = (vert == 0 ? poly.size() : vert) - 1 + offset; + for (size_t vert = 0; vert < poly.size(); ++vert) { + size_t offset = idx + nCrossSection * i; + size_t thisVert = vert + offset; + size_t lastVert = (vert == 0 ? poly.size() : vert) - 1 + offset; if (i == nDivisions && isCone) { triVerts.push_back({nCrossSection * i + j, lastVert - nCrossSection, thisVert - nCrossSection}); @@ -333,7 +333,7 @@ Manifold Manifold::Revolve(const Polygons& crossSection, int circularSegments, Polygons polygons; float radius = 0; for (const SimplePolygon& poly : crossSection) { - int i = 0; + size_t i = 0; while (i < poly.size() && poly[i].x < 0) { ++i; } @@ -341,13 +341,13 @@ Manifold Manifold::Revolve(const Polygons& crossSection, int circularSegments, continue; } polygons.push_back({}); - const int start = i; + const size_t start = i; do { if (poly[i].x >= 0) { polygons.back().push_back(poly[i]); radius = glm::max(radius, poly[i].x); } - const int next = i + 1 == poly.size() ? 0 : i + 1; + const size_t next = i + 1 == poly.size() ? 0 : i + 1; if ((poly[next].x < 0) != (poly[i].x < 0)) { const float y = poly[next].y + poly[next].x * (poly[i].y - poly[next].y) / @@ -396,7 +396,7 @@ Manifold Manifold::Revolve(const Polygons& crossSection, int circularSegments, } for (size_t polyVert = 0; polyVert < poly.size(); ++polyVert) { - const int startPosIndex = vertPos.size(); + const size_t startPosIndex = vertPos.size(); if (!isFullRevolution) startPoses.push_back(startPosIndex); From eeefbeab105947e78d34bfc2c6e33c244150c28c Mon Sep 17 00:00:00 2001 From: pca006132 Date: Fri, 28 Jun 2024 12:36:52 +0800 Subject: [PATCH 23/24] fix --- bindings/python/manifold3d.cpp | 203 ++++++++++++++------------- bindings/python/third_party/nanobind | 2 +- src/manifold/src/boolean_result.cpp | 8 +- 3 files changed, 114 insertions(+), 99 deletions(-) diff --git a/bindings/python/manifold3d.cpp b/bindings/python/manifold3d.cpp index 16ee2d106..f8cb5de04 100644 --- a/bindings/python/manifold3d.cpp +++ b/bindings/python/manifold3d.cpp @@ -59,16 +59,16 @@ struct glm_name { }; // handle glm::vecN -template +template struct nb::detail::type_caster> { using glm_type = glm::vec; NB_TYPE_CASTER(glm_type, const_name(glm_name::name)); bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept { - size_t size = PyObject_Size(src.ptr()); // negative on failure + int size = PyObject_Size(src.ptr()); // negative on failure if (size != N) return false; make_caster t_cast; - for (size_t i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { if (!t_cast.from_python(src[i], flags, cleanup)) return false; value[i] = t_cast.value; } @@ -77,26 +77,26 @@ struct nb::detail::type_caster> { static handle from_cpp(glm_type vec, rv_policy policy, cleanup_list *cleanup) noexcept { nb::list out; - for (size_t i = 0; i < N; i++) out.append(vec[i]); + for (int i = 0; i < N; i++) out.append(vec[i]); return out.release(); } }; // handle glm::matMxN -template +template struct nb::detail::type_caster> { using glm_type = glm::mat; using numpy_type = nb::ndarray>; NB_TYPE_CASTER(glm_type, const_name(glm_name::name)); bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept { - size_t rows = PyObject_Size(src.ptr()); // negative on failure + int rows = PyObject_Size(src.ptr()); // negative on failure if (rows != R) return false; - for (size_t i = 0; i < R; i++) { + for (int i = 0; i < R; i++) { const nb::object &slice = src[i]; - size_t cols = PyObject_Size(slice.ptr()); // negative on failure + int cols = PyObject_Size(slice.ptr()); // negative on failure if (cols != C) return false; - for (size_t j = 0; j < C; j++) { + for (int j = 0; j < C; j++) { make_caster t_cast; if (!t_cast.from_python(slice[j], flags, cleanup)) return false; value[j][i] = t_cast.value; @@ -107,9 +107,9 @@ struct nb::detail::type_caster> { static handle from_cpp(glm_type mat, rv_policy policy, cleanup_list *cleanup) noexcept { T *buffer = new T[R * C]; - nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[](T *) p; }); - for (size_t i = 0; i < R; i++) { - for (size_t j = 0; j < C; j++) { + nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[] (T *)p; }); + for (int i = 0; i < R; i++) { + for (int j = 0; j < C; j++) { // py is (Rows, Cols), glm is (Cols, Rows) buffer[i * C + j] = mat[j][i]; } @@ -121,10 +121,10 @@ struct nb::detail::type_caster> { }; // handle std::vector -template +template struct nb::detail::type_caster>> { using glm_type = glm::vec; - using numpy_type = nb::ndarray>; + using numpy_type = nb::ndarray>; NB_TYPE_CASTER(std::vector, const_name(glm_name::multi_name)); @@ -134,7 +134,7 @@ struct nb::detail::type_caster>> { size_t num_vec = arr_cast.value.shape(0); value.resize(num_vec); for (size_t i = 0; i < num_vec; i++) { - for (size_t j = 0; j < N; j++) { + for (int j = 0; j < N; j++) { value[i][j] = arr_cast.value(i, j); } } @@ -154,23 +154,23 @@ struct nb::detail::type_caster>> { cleanup_list *cleanup) noexcept { size_t num_vec = vec.size(); T *buffer = new T[num_vec * N]; - nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[](T *) p; }); + nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[] (T *)p; }); for (size_t i = 0; i < num_vec; i++) { - for (size_t j = 0; j < N; j++) { + for (int j = 0; j < N; j++) { buffer[i * N + j] = vec[i][j]; } } numpy_type arr{buffer, {num_vec, N}, std::move(mem_mgr)}; - return ndarray_wrap(arr.handle(), int(ndarray_framework::numpy), policy, + return ndarray_wrap(arr.handle(), ndarray_framework::numpy, policy, cleanup); } }; // handle VecView -template +template struct nb::detail::type_caster>> { using glm_type = glm::vec; - using numpy_type = nb::ndarray>; + using numpy_type = nb::ndarray>; NB_TYPE_CASTER(manifold::VecView, const_name(glm_name::multi_name)); @@ -181,7 +181,7 @@ struct nb::detail::type_caster>> { size_t num_vec = arr_cast.value.shape(0); if (num_vec != value.size()) return false; for (size_t i = 0; i < num_vec; i++) { - for (size_t j = 0; j < N; j++) { + for (int j = 0; j < N; j++) { value[i][j] = arr_cast.value(i, j); } } @@ -189,11 +189,12 @@ struct nb::detail::type_caster>> { } static handle from_cpp(Value vec, rv_policy policy, cleanup_list *cleanup) noexcept { + // do we have ownership issue here? size_t num_vec = vec.size(); static_assert(sizeof(vec[0]) == (N * sizeof(T)), "VecView -> numpy requires packed structs"); - numpy_type arr{&vec[0], {num_vec, N}}; - return ndarray_wrap(arr.handle(), int(ndarray_framework::numpy), policy, + numpy_type arr{&vec[0], {num_vec, N}, nb::handle()}; + return ndarray_wrap(arr.handle(), ndarray_framework::numpy, policy, cleanup); } }; @@ -294,8 +295,9 @@ NB_MODULE(manifold3d, m) { const float *oldProps) { auto result = f(v, nb::ndarray( - oldProps, {static_cast(oldNumProp)})); - nb::ndarray> array; + oldProps, {static_cast(oldNumProp)}, + nb::handle())); + nb::ndarray> array; std::vector vec; if (nb::try_cast(result, array)) { if (array.ndim() != 1 || @@ -449,59 +451,59 @@ NB_MODULE(manifold3d, m) { // affect the original array passed into the function "__init__", [](MeshGL *self, - nb::ndarray, nb::c_contig> - &vertProp, - nb::ndarray, nb::c_contig> - &triVerts, - const std::optional, + nb::ndarray, nb::c_contig> &vertProp, + nb::ndarray, nb::c_contig> &triVerts, + const std::optional, nb::c_contig>> &mergeFromVert, - const std::optional, + const std::optional, nb::c_contig>> &mergeToVert, - const std::optional, - nb::c_contig>> &runIndex, - const std::optional, + const std::optional< + nb::ndarray, nb::c_contig>> &runIndex, + const std::optional, nb::c_contig>> &runOriginalID, - std::optional, + std::optional, nb::c_contig>> &runTransform, - const std::optional, - nb::c_contig>> &faceID, - const std::optional, + const std::optional< + nb::ndarray, nb::c_contig>> &faceID, + const std::optional, nb::c_contig>> &halfedgeTangent, float precision) { - new (self) MeshGL(); - MeshGL &out = *self; - out.numProp = vertProp.shape(1); - out.vertProperties = toVector(vertProp.data(), vertProp.size()); + new (self) MeshGL(); + MeshGL &out = *self; + out.numProp = vertProp.shape(1); + out.vertProperties = + toVector(vertProp.data(), vertProp.size()); - out.triVerts = toVector(triVerts.data(), triVerts.size()); + out.triVerts = toVector(triVerts.data(), triVerts.size()); - if (mergeFromVert.has_value()) - out.mergeFromVert = - toVector(mergeFromVert->data(), mergeFromVert->size()); + if (mergeFromVert.has_value()) + out.mergeFromVert = toVector(mergeFromVert->data(), + mergeFromVert->size()); - if (mergeToVert.has_value()) - out.mergeToVert = - toVector(mergeToVert->data(), mergeToVert->size()); + if (mergeToVert.has_value()) + out.mergeToVert = + toVector(mergeToVert->data(), mergeToVert->size()); - if (runIndex.has_value()) - out.runIndex = toVector(runIndex->data(), runIndex->size()); + if (runIndex.has_value()) + out.runIndex = + toVector(runIndex->data(), runIndex->size()); - if (runOriginalID.has_value()) - out.runOriginalID = - toVector(runOriginalID->data(), runOriginalID->size()); + if (runOriginalID.has_value()) + out.runOriginalID = toVector(runOriginalID->data(), + runOriginalID->size()); - if (runTransform.has_value()) { - out.runTransform = - toVector(runTransform->data(), runTransform->size()); - } + if (runTransform.has_value()) { + out.runTransform = + toVector(runTransform->data(), runTransform->size()); + } - if (faceID.has_value()) - out.faceID = toVector(faceID->data(), faceID->size()); + if (faceID.has_value()) + out.faceID = toVector(faceID->data(), faceID->size()); - if (halfedgeTangent.has_value()) { - out.halfedgeTangent = - toVector(halfedgeTangent->data(), halfedgeTangent->size()); - } + if (halfedgeTangent.has_value()) { + out.halfedgeTangent = toVector(halfedgeTangent->data(), + halfedgeTangent->size()); + } }, nb::arg("vert_properties"), nb::arg("tri_verts"), nb::arg("merge_from_vert") = nb::none(), @@ -511,27 +513,39 @@ NB_MODULE(manifold3d, m) { nb::arg("run_transform") = nb::none(), nb::arg("face_id") = nb::none(), nb::arg("halfedge_tangent") = nb::none(), nb::arg("precision") = 0) - .def_prop_ro("vert_properties", - [](const MeshGL &self) { - return nb::ndarray( - self.vertProperties.data(), - {self.vertProperties.size() / self.numProp, self.numProp}); - }, nb::rv_policy::reference_internal) - .def_prop_ro("tri_verts", - [](const MeshGL &self) { - return nb::ndarray( - self.triVerts.data(), {self.triVerts.size() / 3, 3}); - }, nb::rv_policy::reference_internal) - .def_prop_ro("run_transform", - [](const MeshGL &self) { - return nb::ndarray( - self.runTransform.data(), {self.runTransform.size() / 12, 4, 3}); - }, nb::rv_policy::reference_internal) - .def_prop_ro("halfedge_tangent", - [](const MeshGL &self) { - return nb::ndarray( - self.halfedgeTangent.data(), {self.halfedgeTangent.size() / 12, 3, 4}); - }, nb::rv_policy::reference_internal) + .def_prop_ro( + "vert_properties", + [](const MeshGL &self) { + return nb::ndarray( + self.vertProperties.data(), + {self.vertProperties.size() / self.numProp, self.numProp}, + nb::handle()); + }, + nb::rv_policy::reference_internal) + .def_prop_ro( + "tri_verts", + [](const MeshGL &self) { + return nb::ndarray( + self.triVerts.data(), {self.triVerts.size() / 3, 3}, + nb::handle()); + }, + nb::rv_policy::reference_internal) + .def_prop_ro( + "run_transform", + [](const MeshGL &self) { + return nb::ndarray( + self.runTransform.data(), {self.runTransform.size() / 12, 4, 3}, + nb::handle()); + }, + nb::rv_policy::reference_internal) + .def_prop_ro( + "halfedge_tangent", + [](const MeshGL &self) { + return nb::ndarray( + self.halfedgeTangent.data(), + {self.halfedgeTangent.size() / 12, 3, 4}, nb::handle()); + }, + nb::rv_policy::reference_internal) .def_ro("merge_from_vert", &MeshGL::mergeFromVert) .def_ro("merge_to_vert", &MeshGL::mergeToVert) .def_ro("run_index", &MeshGL::runIndex) @@ -541,15 +555,16 @@ NB_MODULE(manifold3d, m) { "level_set", [](const std::function &f, std::vector bounds, float edgeLength, float level = 0.0) { - // Same format as Manifold.bounding_box - Box bound = {glm::vec3(bounds[0], bounds[1], bounds[2]), - glm::vec3(bounds[3], bounds[4], bounds[5])}; - - std::function cppToPython = [&f](glm::vec3 v) { - return f(v.x, v.y, v.z); - }; - Mesh result = LevelSet(cppToPython, bound, edgeLength, level, false); - return MeshGL(result); + // Same format as Manifold.bounding_box + Box bound = {glm::vec3(bounds[0], bounds[1], bounds[2]), + glm::vec3(bounds[3], bounds[4], bounds[5])}; + + std::function cppToPython = [&f](glm::vec3 v) { + return f(v.x, v.y, v.z); + }; + Mesh result = + LevelSet(cppToPython, bound, edgeLength, level, false); + return MeshGL(result); }, nb::arg("f"), nb::arg("bounds"), nb::arg("edgeLength"), nb::arg("level") = 0.0, diff --git a/bindings/python/third_party/nanobind b/bindings/python/third_party/nanobind index 1a309ba44..8d7f1ee06 160000 --- a/bindings/python/third_party/nanobind +++ b/bindings/python/third_party/nanobind @@ -1 +1 @@ -Subproject commit 1a309ba444a47e081dc6213d72345a2fbbd20795 +Subproject commit 8d7f1ee0621c17fa370b704b2100ffa0243d5bfb diff --git a/src/manifold/src/boolean_result.cpp b/src/manifold/src/boolean_result.cpp index b3d08704c..9afc6150d 100644 --- a/src/manifold/src/boolean_result.cpp +++ b/src/manifold/src/boolean_result.cpp @@ -241,16 +241,16 @@ std::vector PairUp(std::vector &edgePos) { // a heuristic. DEBUG_ASSERT(edgePos.size() % 2 == 0, topologyErr, "Non-manifold edge! Not an even number of points."); - ssize_t nEdges = edgePos.size() / 2; + size_t nEdges = edgePos.size() / 2; auto middle = std::partition(edgePos.begin(), edgePos.end(), [](EdgePos x) { return x.isStart; }); - DEBUG_ASSERT(middle - edgePos.begin() == nEdges, topologyErr, - "Non-manifold edge!"); + DEBUG_ASSERT(static_cast(middle - edgePos.begin()) == nEdges, + topologyErr, "Non-manifold edge!"); auto cmp = [](EdgePos a, EdgePos b) { return a.edgePos < b.edgePos; }; std::stable_sort(edgePos.begin(), middle, cmp); std::stable_sort(middle, edgePos.end(), cmp); std::vector edges; - for (ssize_t i = 0; i < nEdges; ++i) + for (size_t i = 0; i < nEdges; ++i) edges.push_back({edgePos[i].vert, edgePos[i + nEdges].vert, -1, -1}); return edges; } From 84ba93c1ab46b486d4413dc86c58f9cd37964857 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Fri, 28 Jun 2024 12:38:51 +0800 Subject: [PATCH 24/24] fix format --- bindings/python/manifold3d.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/python/manifold3d.cpp b/bindings/python/manifold3d.cpp index f8cb5de04..e9d5798cf 100644 --- a/bindings/python/manifold3d.cpp +++ b/bindings/python/manifold3d.cpp @@ -107,7 +107,7 @@ struct nb::detail::type_caster> { static handle from_cpp(glm_type mat, rv_policy policy, cleanup_list *cleanup) noexcept { T *buffer = new T[R * C]; - nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[] (T *)p; }); + nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[](T *) p; }); for (int i = 0; i < R; i++) { for (int j = 0; j < C; j++) { // py is (Rows, Cols), glm is (Cols, Rows) @@ -154,7 +154,7 @@ struct nb::detail::type_caster>> { cleanup_list *cleanup) noexcept { size_t num_vec = vec.size(); T *buffer = new T[num_vec * N]; - nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[] (T *)p; }); + nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[](T *) p; }); for (size_t i = 0; i < num_vec; i++) { for (int j = 0; j < N; j++) { buffer[i * N + j] = vec[i][j];