/// <summary> /// Calls action for each (node, fullyInside) in this tree that is intersecting the given hull. /// </summary> public static IEnumerable <CellQueryResult> ForEachNodeIntersecting( this IPointCloudNode self, Hull3d hull, bool doNotTraverseSubnodesWhenFullyInside, int minCellExponent = int.MinValue ) { if (self == null) { yield break; } if (self.Cell.Exponent < minCellExponent) { yield break; } for (var i = 0; i < hull.PlaneCount; i++) { if (!self.IntersectsNegativeHalfSpace(hull.PlaneArray[i])) { yield break; } } bool fullyInside = true; for (var i = 0; i < hull.PlaneCount; i++) { if (!self.InsideNegativeHalfSpace(hull.PlaneArray[i])) { fullyInside = false; break; } } yield return(new CellQueryResult(self, fullyInside)); if (fullyInside && doNotTraverseSubnodesWhenFullyInside) { yield break; } if (self.Subnodes == null) { yield break; } for (var i = 0; i < 8; i++) { var n = self.Subnodes[i]; if (n == null) { continue; } var xs = ForEachNodeIntersecting(n.Value, hull, doNotTraverseSubnodesWhenFullyInside, minCellExponent); foreach (var x in xs) { yield return(x); } } }
/// <summary> /// Calls action for each (node, fullyInside) in this pointset, that is intersecting the given hull. /// </summary> public static void ForEachIntersectingNode( this IPointCloudNode self, bool outOfCore, Hull3d hull, bool doNotTraverseSubnodesWhenFullyInside, Action <IPointCloudNode, bool> action, CancellationToken ct = default ) { ct.ThrowIfCancellationRequested(); for (var i = 0; i < hull.PlaneCount; i++) { if (!self.IntersectsNegativeHalfSpace(hull.PlaneArray[i])) { return; } } bool fullyInside = true; for (var i = 0; i < hull.PlaneCount; i++) { if (!self.InsideNegativeHalfSpace(hull.PlaneArray[i])) { fullyInside = false; break; } } action(self, fullyInside); if (fullyInside && doNotTraverseSubnodesWhenFullyInside) { return; } if (self.Subnodes == null) { return; } if (outOfCore) { for (var i = 0; i < 8; i++) { var n = self.Subnodes[i]; if (n != null) { n.Value.ForEachIntersectingNode(outOfCore, hull, doNotTraverseSubnodesWhenFullyInside, action, ct); } } } else { for (var i = 0; i < 8; i++) { var n = self.Subnodes[i]; if (n != null) { if (n.TryGetValue(out IPointCloudNode node)) { node.ForEachIntersectingNode(outOfCore, hull, doNotTraverseSubnodesWhenFullyInside, action, ct); } } } } }