-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Fix #7449: sample_points_poisson_disk is extremely slow #7450
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1110,6 +1110,74 @@ TEST(TriangleMesh, SamplePointsUniformly) { | |||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| TEST(TriangleMesh, SamplePointsPoissonDisk) { | ||||||||||||||||||||
| // Empty mesh should throw | ||||||||||||||||||||
| auto mesh_empty = geometry::TriangleMesh(); | ||||||||||||||||||||
| EXPECT_THROW(mesh_empty.SamplePointsPoissonDisk(100), std::runtime_error); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Simple triangle mesh in z=0 plane: (0,0,0), (1,0,0), (0,1,0) | ||||||||||||||||||||
| std::vector<Eigen::Vector3d> vertices = {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}}; | ||||||||||||||||||||
| std::vector<Eigen::Vector3i> triangles = {{0, 1, 2}}; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| auto mesh_simple = geometry::TriangleMesh(); | ||||||||||||||||||||
| mesh_simple.vertices_ = vertices; | ||||||||||||||||||||
| mesh_simple.triangles_ = triangles; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| size_t n_points = 100; | ||||||||||||||||||||
| auto pcd = mesh_simple.SamplePointsPoissonDisk(n_points); | ||||||||||||||||||||
| EXPECT_EQ(pcd->points_.size(), n_points); | ||||||||||||||||||||
| EXPECT_TRUE(pcd->colors_.size() == 0); | ||||||||||||||||||||
| EXPECT_TRUE(pcd->normals_.size() == 0); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // All points must lie on the triangle surface (z=0, x>=0, y>=0, x+y<=1) | ||||||||||||||||||||
| for (size_t i = 0; i < pcd->points_.size(); ++i) { | ||||||||||||||||||||
| const auto &p = pcd->points_[i]; | ||||||||||||||||||||
| EXPECT_NEAR(p(2), 0.0, 1e-10); | ||||||||||||||||||||
| EXPECT_GE(p(0), -1e-10); | ||||||||||||||||||||
| EXPECT_GE(p(1), -1e-10); | ||||||||||||||||||||
| EXPECT_LE(p(0) + p(1), 1.0 + 1e-10); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Poisson disk property: minimum pairwise distance should be > 0 | ||||||||||||||||||||
| // (points are spread apart, not clustered) | ||||||||||||||||||||
| double min_dist = std::numeric_limits<double>::max(); | ||||||||||||||||||||
| for (size_t i = 0; i < pcd->points_.size(); ++i) { | ||||||||||||||||||||
| for (size_t j = i + 1; j < pcd->points_.size(); ++j) { | ||||||||||||||||||||
| double d = (pcd->points_[i] - pcd->points_[j]).norm(); | ||||||||||||||||||||
| min_dist = std::min(min_dist, d); | ||||||||||||||||||||
|
Comment on lines
+1143
to
+1147
|
||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
| // For 100 points on a triangle with area 0.5, the theoretical Poisson disk | ||||||||||||||||||||
| // radius is r = 2*sqrt(area/n / (2*sqrt(3))) ≈ 0.057. After sample | ||||||||||||||||||||
| // elimination the actual minimum distance should be a meaningful fraction | ||||||||||||||||||||
| // of that. We just check it's not degenerate (> 0.01). | ||||||||||||||||||||
| EXPECT_GT(min_dist, 0.01); | ||||||||||||||||||||
|
Comment on lines
+1150
to
+1154
|
||||||||||||||||||||
| // For 100 points on a triangle with area 0.5, the theoretical Poisson disk | |
| // radius is r = 2*sqrt(area/n / (2*sqrt(3))) ≈ 0.057. After sample | |
| // elimination the actual minimum distance should be a meaningful fraction | |
| // of that. We just check it's not degenerate (> 0.01). | |
| EXPECT_GT(min_dist, 0.01); | |
| // The exact minimum distance depends on RNG and implementation details. | |
| // To avoid flaky tests, only check that points are not degenerate | |
| // (no coincident samples). | |
| EXPECT_GT(min_dist, 1e-8); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
KDTreeFlann::SearchRadius’s signature was changed by adding a new parameter. Even with a default value, this is an ABI-breaking change (different mangled symbol) for any downstream C++ code built against the previous Open3D library. To avoid breaking existing binaries, consider keeping the original 4-arg overload and adding a new 5-arg overload that forwards internally (and explicitly instantiate both overloads as needed).