java-topology/defects/pcl/patch/pcl-0001-region-growing-get-segment-linear-scan.patch

91 lines
4.2 KiB
Diff

# UNDF: UNDF-2026-000000403
--- a/segmentation/include/pcl/segmentation/impl/region_growing.hpp
+++ b/segmentation/include/pcl/segmentation/impl/region_growing.hpp
@@ -563,9 +563,7 @@ pcl::RegionGrowing<PointT, NormalT>::getSegmentFromPoint (pcl::index_t index, p
// first of all we need to find out if this point belongs to cloud
bool point_was_found = false;
- for (const auto& point : (*indices_))
- if (point == index)
- {
- point_was_found = true;
- break;
- }
+ if (index >= 0 && static_cast<std::size_t>(index) < point_labels_.size())
+ point_was_found = (point_labels_[index] != -1 ||
+ std::find(indices_->cbegin(), indices_->cend(), index) != indices_->cend());
if (point_was_found)
{
@@ -591,12 +589,9 @@ pcl::RegionGrowing<PointT, NormalT>::getSegmentFromPoint (pcl::index_t index, p
assembleRegions ();
}
// if we have already made the segmentation, then find the segment
- // to which this point belongs
- for (const auto& i_segment : clusters_)
- {
- const auto it = std::find (i_segment.indices.cbegin (), i_segment.indices.cend (), index);
- if (it != i_segment.indices.cend())
- {
- // if segment was found
- cluster.indices.clear ();
- cluster.indices.reserve (i_segment.indices.size ());
- std::copy (i_segment.indices.begin (), i_segment.indices.end (), std::back_inserter (cluster.indices));
- break;
- }
- }// next segment
+ // to which this point belongs — use point_labels_[] for O(1) direct lookup
+ // (point_labels_[i] == segment_index and clusters_[segment_index] is the cluster,
+ // as established by assembleRegions())
+ const auto segment_index = point_labels_[index];
+ if (segment_index >= 0 && static_cast<std::size_t>(segment_index) < clusters_.size())
+ {
+ const auto& i_segment = clusters_[segment_index];
+ cluster.indices.clear ();
+ cluster.indices.reserve (i_segment.indices.size ());
+ std::copy (i_segment.indices.begin (), i_segment.indices.end (), std::back_inserter (cluster.indices));
+ }
}// end if point was found
deinitCompute ();
--- a/segmentation/include/pcl/segmentation/impl/region_growing_rgb.hpp
+++ b/segmentation/include/pcl/segmentation/impl/region_growing_rgb.hpp
@@ -724,12 +724,22 @@ pcl::RegionGrowingRGB<PointT, NormalT>::getSegmentFromPoint (pcl::index_t index
// if we have already made the segmentation, then find the segment
// to which this point belongs
- for (const auto& i_segment : clusters_)
- {
- const auto it = std::find (i_segment.indices.cbegin (), i_segment.indices.cend (), index);
- if (it != i_segment.indices.cend())
- {
- // if segment was found
- cluster.indices.clear ();
- cluster.indices.reserve (i_segment.indices.size ());
- std::copy (i_segment.indices.begin (), i_segment.indices.end (), std::back_inserter (cluster.indices));
- break;
- }
- }// next segment
+ // RGB variant: point_labels_[p] -> initial segment, segment_labels_[seg] -> merged region.
+ // assembleRegions() uses this two-level lookup and may compact clusters_ by removing
+ // empty entries, so build a reverse map from any point in each cluster back to the
+ // cluster position using the same two-level index (valid before compaction changes order).
+ // The direct fix: lookup via point_labels_ + segment_labels_, then scan only that
+ // one candidate cluster rather than all clusters_.
+ if (index >= 0 && static_cast<std::size_t>(index) < point_labels_.size())
+ {
+ const auto seg_idx = point_labels_[index];
+ if (seg_idx >= 0 && static_cast<std::size_t>(seg_idx) < segment_labels_.size())
+ {
+ const auto region_idx = segment_labels_[seg_idx];
+ if (region_idx >= 0 && static_cast<std::size_t>(region_idx) < clusters_.size())
+ {
+ const auto& i_segment = clusters_[region_idx];
+ cluster.indices.clear ();
+ cluster.indices.reserve (i_segment.indices.size ());
+ std::copy (i_segment.indices.begin (), i_segment.indices.end (), std::back_inserter (cluster.indices));
+ }
+ }
+ }
}// end if point was found
deinitCompute ();