Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MinGap function #765

Merged
merged 49 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
f712fd5
Add tests for intersection
mleleszi Mar 3, 2024
903c573
Add POC MinGap implementation and tests
mleleszi Mar 3, 2024
0d1c887
Add tests where closest point falls on the triangle's face or on one …
mleleszi Mar 6, 2024
d1496a2
Create TriangleDistance declaration
mleleszi Mar 6, 2024
849c82c
Delete intersect tests
mleleszi Mar 6, 2024
197e6d7
Add stub MinGap definition
mleleszi Mar 6, 2024
e21c5f2
Add triangle distance impl
mleleszi Mar 9, 2024
7bcee3b
Add comments
mleleszi Mar 9, 2024
55cdabd
Fix tests
mleleszi Mar 9, 2024
d5c5f84
Fix build
mleleszi Mar 9, 2024
4c59675
Use collider
mleleszi Mar 10, 2024
3da4b64
Collider exploration
mleleszi Mar 11, 2024
bb3b227
Collider impl, cleanup
mleleszi Mar 11, 2024
1f07dd5
Use par transform
mleleszi Mar 11, 2024
03745fa
Revert settings.json, add comments
mleleszi Mar 11, 2024
91d48ec
Add comments
mleleszi Mar 11, 2024
1c9cdd4
Move tri_dist to utils
mleleszi Mar 14, 2024
42b8af7
Delete unnecessary include
mleleszi Mar 14, 2024
2c0ebdb
Create lambda for bounding box expansion
mleleszi Mar 14, 2024
2804cd4
Move duplicate logic to lambda
mleleszi Mar 14, 2024
3c8501c
Cleanup
mleleszi Mar 20, 2024
24d1ee0
Use floats instead of doubles, use glm::clamp instead of own implemen…
mleleszi Mar 20, 2024
df9367b
User ternaries
mleleszi Mar 20, 2024
ee073a1
Remove DistanceTriangleTriangleSquared out params
mleleszi Mar 20, 2024
29d8ee6
Move MinGap impl to Impl
mleleszi Mar 24, 2024
e6d70c8
Use std::array instead of C-style
mleleszi Mar 24, 2024
5455f05
Modify MinGap test cases for clarity, add overlapping tri_dist test
mleleszi Mar 24, 2024
1719c8c
Add c, wasm, python bindings
mleleszi Mar 24, 2024
dde24f7
Merge branch 'master' into mingap-poc
mleleszi Mar 24, 2024
f5e8cc3
Fix formatting
mleleszi Mar 24, 2024
1b93a6c
Clean up comments
mleleszi Mar 24, 2024
84878cb
Test whether faceboxes need to be sorted
mleleszi Mar 25, 2024
71e2c57
Add min_gap example to all_apis.py
mleleszi Mar 27, 2024
50b551c
Fix formatting
mleleszi Mar 27, 2024
38ce232
Clean up python binding
mleleszi Mar 27, 2024
19d356e
Fix edge to edge test case
mleleszi Mar 27, 2024
5979ea3
Test BVH culling
mleleszi Mar 28, 2024
0f47505
Remove sorting of other manifold's boxes
mleleszi Mar 28, 2024
5e3732c
Use collider_ member, remove sorting
mleleszi Mar 28, 2024
25643de
Move tests to manifold_test.cpp
mleleszi Mar 28, 2024
93a1726
Remove whitespace
mleleszi Mar 28, 2024
7979fe9
Rename some tests for clarity
mleleszi Mar 28, 2024
8ac46f5
Remove redundant test, modify test for edge to edge test for clarity
mleleszi Mar 29, 2024
a237f74
Fix comments
mleleszi Mar 29, 2024
8713ca2
Parallelize narrow phase
mleleszi Mar 30, 2024
5659396
Reduce sphere res in test case to not cause out of memory error
mleleszi Mar 30, 2024
ca020cf
Add complex test case
mleleszi Mar 30, 2024
8ed4373
Remove unnecessary cast
mleleszi Mar 30, 2024
3786209
Refactor functor is lambda
mleleszi Apr 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,4 @@
},
"python.formatting.provider": "none",
"clang-format.executable": "clang-format",
}
}
2 changes: 2 additions & 0 deletions bindings/c/include/manifoldc.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ ManifoldManifold *manifold_set_properties(
void (*fun)(float *new_prop, ManifoldVec3 position, const float *old_prop));
ManifoldManifold *manifold_calculate_curvature(void *mem, ManifoldManifold *m,
int gaussian_idx, int mean_idx);
float manifold_min_gap(ManifoldManifold *m, ManifoldManifold *other,
float searchLength);
ManifoldManifold *manifold_calculate_normals(void *mem, ManifoldManifold *m,
int normal_idx,
int min_sharp_angle);
Expand Down
5 changes: 5 additions & 0 deletions bindings/c/manifoldc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,11 @@ ManifoldManifold *manifold_calculate_curvature(void *mem, ManifoldManifold *m,
return to_c(new (mem) Manifold(man));
}

float manifold_min_gap(ManifoldManifold *m, ManifoldManifold *other,
float searchLength) {
return from_c(m)->MinGap(*from_c(other), searchLength);
}

ManifoldManifold *manifold_calculate_normals(void *mem, ManifoldManifold *m,
int normal_idx,
int min_sharp_angle) {
Expand Down
3 changes: 3 additions & 0 deletions bindings/python/examples/all_apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ def all_manifold():
m = m.trim_by_plane((0, 0, 1), 0)
m = m.warp(lambda p: (p[0] + 1, p[1] / 2, p[2] * 2))
m = m.warp_batch(lambda ps: ps * [1, 0.5, 2] + [1, 0, 0])
m = Manifold.cube()
m2 = Manifold.cube().translate([2, 0, 0])
d = m.min_gap(m2, 2)


def run():
Expand Down
4 changes: 4 additions & 0 deletions bindings/python/manifold3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,10 @@ NB_MODULE(manifold3d, m) {
.def("calculate_curvature", &Manifold::CalculateCurvature,
nb::arg("gaussian_idx"), nb::arg("mean_idx"),
manifold__calculate_curvature__gaussian_idx__mean_idx)
.def("min_gap", &Manifold::MinGap, nb::arg("other"),
nb::arg("search_length"),
"Returns the minimum gap between two manifolds."
"Returns a float between 0 and searchLength.")
.def("calculate_normals", &Manifold::CalculateNormals,
nb::arg("normal_idx"), nb::arg("min_sharp_angle") = 60,
manifold__calculate_normals__normal_idx__min_sharp_angle)
Expand Down
1 change: 1 addition & 0 deletions bindings/wasm/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ EMSCRIPTEN_BINDINGS(whatever) {
.function("precision", &Manifold::Precision)
.function("genus", &Manifold::Genus)
.function("getProperties", &Manifold::GetProperties)
.function("minGap", &Manifold::MinGap)
.function("calculateCurvature", &Manifold::CalculateCurvature)
.function("calculateNormals", &Manifold::CalculateNormals)
.function("originalID", &Manifold::OriginalID)
Expand Down
7 changes: 7 additions & 0 deletions bindings/wasm/manifold-encapsulated-types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,13 @@ export class Manifold {
*/
getProperties(): Properties;


/*
* Returns the minimum gap between two manifolds. Returns a float between
* 0 and searchLength.
*/
minGap(other: Manifold, searchLength: number): number;

// Export

/**
Expand Down
1 change: 1 addition & 0 deletions src/manifold/include/manifold.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ class Manifold {
float Precision() const;
int Genus() const;
Properties GetProperties() const;
float MinGap(const Manifold& other, float searchLength) const;
///@}

/** @name Mesh ID
Expand Down
52 changes: 52 additions & 0 deletions src/manifold/src/impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "mesh_fixes.h"
#include "par.h"
#include "svd.h"
#include "tri_dist.h"

namespace {
using namespace manifold;
Expand Down Expand Up @@ -902,4 +903,55 @@ SparseIndices Manifold::Impl::VertexCollisionsZ(
else
return collider_.Collisions<false, false>(vertsIn);
}
/*
* Returns the minimum gap between two manifolds. Returns a float between
* 0 and searchLength.
*/
float Manifold::Impl::MinGap(const Manifold::Impl& other,
float searchLength) const {
ZoneScoped;
Vec<Box> faceBox;
Vec<uint32_t> faceMorton;

this->GetFaceBoxMorton(faceBox, faceMorton);
this->SortFaceBoxMorton(faceBox, faceMorton);

transform(autoPolicy(faceBox.size()), faceBox.begin(), faceBox.end(),
faceBox.begin(), [searchLength](const Box& box) {
return Box(box.min - glm::vec3(searchLength),
box.max + glm::vec3(searchLength));
});

Vec<Box> faceBoxOther;
Vec<uint32_t> faceMortonOther;

other.GetFaceBoxMorton(faceBoxOther, faceMortonOther);
other.SortFaceBoxMorton(faceBoxOther, faceMortonOther);

Collider collider{faceBox, faceMorton};
mleleszi marked this conversation as resolved.
Show resolved Hide resolved

SparseIndices collisions = collider.Collisions(faceBoxOther.cview());

float minDistanceSquared = searchLength * searchLength;

for (int i = 0; i < collisions.size(); ++i) {
mleleszi marked this conversation as resolved.
Show resolved Hide resolved
const int tri = collisions.Get(i, 1);
const int triOther = collisions.Get(i, 0);

std::array<glm::vec3, 3> p;
std::array<glm::vec3, 3> q;

for (const int j : {0, 1, 2}) {
p[j] = vertPos_[halfedge_[3 * tri + j].startVert];
q[j] = other.vertPos_[other.halfedge_[3 * triOther + j].startVert];
}

float distanceSquared = DistanceTriangleTriangleSquared(p, q);

minDistanceSquared = std::min(minDistanceSquared, distanceSquared);
}

return sqrt(minDistanceSquared);
};

} // namespace manifold
3 changes: 3 additions & 0 deletions src/manifold/src/impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ struct Manifold::Impl {
SparseIndices EdgeCollisions(const Impl& B, bool inverted = false) const;
SparseIndices VertexCollisionsZ(VecView<const glm::vec3> vertsIn,
bool inverted = false) const;
float MinGap(const Impl& other, float searchLength) const;

bool IsEmpty() const { return NumVert() == 0; }
int NumVert() const { return vertPos_.size(); }
Expand Down Expand Up @@ -111,6 +112,8 @@ struct Manifold::Impl {
void CompactProps();
void GetFaceBoxMorton(Vec<Box>& faceBox, Vec<uint32_t>& faceMorton) const;
void SortFaces(Vec<Box>& faceBox, Vec<uint32_t>& faceMorton);
void SortFaceBoxMorton(Vec<Box>& faceBox, Vec<uint32_t>& faceMorton) const;

void GatherFaces(const Vec<int>& faceNew2Old);
void GatherFaces(const Impl& old, const Vec<int>& faceNew2Old);

Expand Down
18 changes: 18 additions & 0 deletions src/manifold/src/manifold.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "csg_tree.h"
#include "impl.h"
#include "par.h"
#include "tri_dist.h"

namespace {
using namespace manifold;
Expand Down Expand Up @@ -926,4 +927,21 @@ Manifold Manifold::Hull() const { return Hull(GetMesh().vertPos); }
Manifold Manifold::Hull(const std::vector<Manifold>& manifolds) {
return Compose(manifolds).Hull();
}

/**
* Returns the minimum gap between two manifolds. Returns a float between
* 0 and searchLength.
*
* @param other The other manifold to compute the minimum gap to.
* @param searchLength The maximum distance to search for a minimum gap.
*/
float Manifold::MinGap(const Manifold& other, float searchLength) const {
auto intersect = *this ^ other;
auto prop = intersect.GetProperties();

if (prop.volume != 0) return 0.0f;

return GetCsgLeafNode().GetImpl()->MinGap(*other.GetCsgLeafNode().GetImpl(),
searchLength);
}
} // namespace manifold
21 changes: 21 additions & 0 deletions src/manifold/src/sort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,27 @@ void Manifold::Impl::SortFaces(Vec<Box>& faceBox, Vec<uint32_t>& faceMorton) {
GatherFaces(faceNew2Old);
}

/**
* Sorts the bounding box and Morton code arrays based on the Morton codes.
* Leaves the original manifold untouched.
*/
void Manifold::Impl::SortFaceBoxMorton(Vec<Box>& faceBox,
Vec<uint32_t>& faceMorton) const {
ZoneScoped;
Vec<int> faceNew2Old(NumTri());
auto policy = autoPolicy(faceNew2Old.size());
sequence(policy, faceNew2Old.begin(), faceNew2Old.end());

stable_sort(policy, zip(faceMorton.begin(), faceNew2Old.begin()),
zip(faceMorton.end(), faceNew2Old.end()),
[](const thrust::tuple<uint32_t, int>& a,
const thrust::tuple<uint32_t, int>& b) {
return thrust::get<0>(a) < thrust::get<0>(b);
});

Permute(faceBox, faceNew2Old);
}

/**
* Creates the halfedge_ vector for this manifold by copying a set of faces from
* another manifold, given by oldHalfedge. Input faceNew2Old defines the old
Expand Down
2 changes: 1 addition & 1 deletion src/utilities/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,4 @@ 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 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME})
install(FILES include/public.h include/vec_view.h include/tri_dist.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME})
Loading
Loading