Fix segfault (infinite recursion) of PointCloud::DetectPlanarPatches … #6794
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
…if multiple points have same coordinates
Type
Motivation and Context
The
PointCloud::DetectPlanarPatches
function will raise a Segmentation Fault due to infinite recursion when the point cloud has at least N points with the same coordinates, where N is the value of the function's argumentmin_num_points
.Checklist:
python util/check_style.py --apply
to apply Open3D code styleto my code.
updated accordingly.
results (e.g. screenshots or numbers) here.
Description
The
PointCloud::DetectPlanarPatches
function callsSplitAndDetectPlanesRecursive
, a recursive function that recursively splits the point cloud into 8 smaller point clouds (children nodes). This function continues to call itself until noBoundaryVolumeHierarchy
node can be partitioned.However, since the stop criteria to not partition a node into new children nodes is
(indices_.size() <= min_points_ || child_size < min_size_ || indices_.size() < 2)
in PointCloudPlanarPatchDetection.cpp#L90 (whereindices_.size()
is the n. of points in the node,min_points_
is hardcoded 1, andmin_size_
is hardcoded 0) andif (node->indices_.size() < min_num_points) return false;
in PointCloudPlanarPatchDetection.cpp#L737 (wheremin_num_points
is the argument of DetectPlanarPatches), with the current parameters if the point cloud contains >=min_num_points
points with same coordinates, no stop criteria will ever be satisfied.Hence, this PR simply changes the value of
min_size_
from 0 to 1e-10. This value is small enough (1 tenth of a nanometer) to not interfere with microscopic point clouds, but big enough to avoid a too-deep recursion.With this change, the segfault occurrence due to infinite recursion is fixed, while before it was jointly dependent on
min_num_points
and the number of points with the same coordinatesTest
Testing code (modify
N_EQUAL_POINTS and PLANAR_DETECTION_MIN_POINTS
to test the segfault edge case)Output before the change
Output with new change
Warning logs were obtained by adding
at line 737 of PointCloudPlanarPatchDetection.cpp (after
node->Partition();
)Note:
min_num_points
is not specified, it will be set to 0 by the pybinding, and then in theDetectPlanaPatches
function:if (min_num_points == 0) { min_num_points = std::max(static_cast<size_t>(10), static_cast<size_t>(points_.size() * 0.001)); }
DetectPlanarPatches
' argumentmin_num_points
to set themin_size_
value for the stop criterion of the node partitioning (instead of the hardcoded 1), but in reality, this will only change the segfault condition from >=min_num_points
with same coordinates to >min_num_points
with same coordinates