Rhino 7 Intersection.RayShoot() limitation / Improvement suggestions

I’ve found a limitation / improvement suggestion for the new Intersection.RayShoot() method in Rhino 7:

Rhino.Geometry.Intersect.RayShootEvent[] RayShoot(System.Collections.Generic.IEnumerable<Rhino.Geometry.GeometryBase> geometry, Rhino.Geometry.Ray3d ray, int maxReflections)

If I want to only perform the RayShoot on a subset of faces from a Brep, I extract the faces and store the ones I want to evaluate in a list. The RayShootEvent I expect in say the example below, should stores the GeometryIndex and BrepFaceIndex of the faces as they exist in the Brep BrepFaceList, but it seems that calling Brep.Faces and iterating through the list to store only the faces I need creates new instances of the BrepFace’s which therefore do not share the same FaceIndex’s or SurfaceIndex’s as those found in the BrepFaceList. Subsequently the results from the RayShootEvent do not correlate with the original brep which is severely limiting.

Yep, it’s on the list.

https://mcneel.myjetbrains.com/youtrack/issue/RH-13351

– Dale

1 Like

Hello,Thomas.

can you share an example of how to use Rhino.Geometry.Intersect.RayShootEvent in python?

When I’m trying it shows the error like this.

Runtime error (SyntaxErrorException): unexpected token ‘]’

File “”, line 16
a = rg.Intersect.RayShootEventRayShoot(ray,newlist,maxReflections)
^
SyntaxError: unexpected token ‘]’

Hi @fred1357944

Assuming rg is an alias of the Rhino.Geometry namespace, then you need to make your call from the Intersection class:

a = rg.Intersect.Intersection.RayShoot(ray,newlist,maxReflections)

Also, your exception message is warning you of a syntax error using square brackets. If your code snippet is correct then simply updating your syntax to my suggestion would remove the brackets and resolve the exception. You only use square brackets immediately proceeding a reference to an object (a variable etc) if its a collection and therefore indexable.

Empty brackets in this context is otherwise meaningless/incorrect, just don’t get confused by list declarations in Python (e.g. myList = [] ) where empty square brackets proceeding the assignment operator initializes a collection. Its all about semantics ultimately :+1:.

Thank you Thomas,
may you give me some more advice,I still don’t know how to get the Brep_Face which been hit by the ray.

You need to access to the BrepFaceList from your Brep which you passed into the rayshoot then get its myBrep.Faces and index the list using the RayShootEvent.BrepFaceIndex.

I havent tested this code, I’ve just wrote it on the fly from memory, but it will look something like this. Where it gets more complicated is if your geometry list contains more than one brep, in which case you’ll need to also use the GeometryIndex to locate the brep corresponding to the RayShootEvent so you can target the correct face, but for simplicity I’ve only used 1 brep in the example below:

geometry = List[Brep](myBrep)

ray = Ray3d(origin, direction);

rayShootEvents = Intersection.RayShoot(geometry, ray, 1)

facesList = myBrep.Faces

facesHit = []
for rayShootEvent in rayShootEvents:
	faceHit = facesList[rayShootEvent.BrepFaceIndex]

	facesHit.append(faceHit)
1 Like

@dale thanks for the response. I read through the dialog on the link, and noticed the discussion in respect to performance if trimmed faces are implemented in the ray shoot. As we also need this functionality in our projects, we’ve implemented a workaround which appears to be relatively reliable without too much of a performance hit; evaluate the hit point using IsPointOnFace() after shooting the ray. If the pointFaceRelation isn’t Interior we re-cast the ray from the hit point until a face is hit where the hit point is Interior. Edge-cases are obviously a problem, but it doesn’t affect our needs, so for now this is a decent workaround.

Thank you Thomas it helps a lot.