@@ -710,6 +710,41 @@ def bvh_segment_intersection(bvh: BVHNode, segment:NDArray[float]|Segment):
710710 return intersections
711711
712712
713+ # 72208
714+ def bvh_triangle_segment_intersection_one (bvh : BVHNode , segment :NDArray [float ]| Segment ):
715+ if not isinstance (segment ,np .ndarray ):
716+ segment = np .array (segment )
717+
718+
719+ stack = [(bvh , segment )]
720+
721+ while stack :
722+ current_bvh , current_segment = stack .pop ()
723+ bb = aabb (segment )
724+
725+ if not aabb_intersect (current_bvh .bounding_box ._arr ,bb ):
726+ continue
727+
728+ current_segment = segment_aabb_clip (current_bvh .bounding_box ._arr , segment )
729+
730+ if current_segment is None :
731+ continue
732+
733+ if current_bvh .object is not None :
734+
735+ point ,flag = intersect_triangle_segment (current_bvh .object .a ,current_bvh .object .b ,current_bvh .object .c ,current_segment [0 ],current_segment [1 ])
736+ if flag != 0 :
737+ return True ,point ,current_bvh .object
738+
739+ else :
740+
741+ stack .append ((current_bvh .left , current_segment ))
742+ stack .append ((current_bvh .right , current_segment ))
743+
744+
745+ return False ,None ,None
746+
747+
713748# perf history
714749# 495417
715750# 458500
@@ -722,6 +757,7 @@ def bvh_segment_intersection(bvh: BVHNode, segment:NDArray[float]|Segment):
722757# 139292
723758# 138250
724759# 120625
760+
725761from mmcore .numeric .vectors import dot_array_x_vec
726762def bvh_ray_intersection (bvh :BVHNode , ray :Ray ):
727763 """
@@ -750,13 +786,35 @@ def bvh_ray_intersection(bvh:BVHNode, ray:Ray):
750786
751787 return result
752788
789+
753790def build_bvh_from_mesh (points :NDArray [float ],indices :NDArray [int ]):
754791 return build_bvh ([Triangle (tri ) for tri in points [indices ]])
755792from mmcore .numeric .algorithms .moller import intersect_triangle_segment
756793
757- def bvh_triangle_ray_intersection (triangles_bvh :BVHNode ,ray :Ray ):
794+ def mesh_bvh_ray_intersection (triangles_bvh :BVHNode ,ray :Ray ):
795+ """
796+ Determines the intersection points where a ray intersects with the triangles
797+ within a bounding volume hierarchy (BVH). The function processes a ray,
798+ determines intersections with a BVH structure, and evaluates each triangle
799+ intersection, returning a list of intersected points, triangles, and their
800+ respective distances sorted by proximity from the ray origin.
801+
802+ :param triangles_bvh: A bounding volume hierarchy (BVH) node that contains the
803+ spatial hierarchy and triangle geometry for intersection
804+ testing.
805+ :type triangles_bvh: BVHNode
806+ :param ray: The ray to be tested for intersection with the BVH and contained
807+ triangles.
808+ :type ray: Ray
809+ :return: A list of tuples representing the intersection data. Each tuple
810+ contains the intersection point, the intersected triangle, and the
811+ scalar distance from the ray origin.
812+ :rtype: list[tuple[Point, Triangle, float]]
813+ """
758814 maybe = []
759815 segment = segment_aabb_clip (triangles_bvh .bounding_box ._arr , ray ._arr )
816+ if segment is None :
817+ return maybe
760818 direction = segment [1 ]- segment [0 ]
761819 for tri ,segm in bvh_segment_intersection (triangles_bvh ,segment ):
762820
@@ -776,3 +834,16 @@ def bvh_triangle_ray_intersection(triangles_bvh:BVHNode,ray:Ray):
776834
777835
778836
837+ def mesh_bvh_segment_intersection_one (mesh_bvh :BVHNode , segment :NDArray [float ])-> tuple [NDArray [float ],Triangle ] | None :
838+ """
839+
840+ :param mesh_bvh: BVH with Triangle instances in leafs
841+ :param segment: numpy array with shape (2,3) e.g. [start_point,end_point]
842+
843+ :return: the first intersection found in the form (point,triangle) or None if no intersection is found.
844+ :rtype: tuple[ndarray[(3,),float], Triangle] | None
845+ """
846+ success , point , tri = bvh_triangle_segment_intersection_one (mesh_bvh ,segment )
847+ if success :
848+ return point ,tri
849+
0 commit comments