How do I transform Breps to IEnumerable[GeometryBase] ?
RayShoot expects an enumerable (for example, a list) of Breps rather than a single Brep.
yes, but if i set type hint to list then i get:
expected IEnumerable[GeometryBase], got list
Please can you post a sample that can be tested?
This might be a RhinoCommon/IronPython edge case I think, where you might need to build a
Add() your element, then call that same method.
I uploaded the file. I remember getting stuck into this before. I don’t know how to transform a list of breps into IEnumerable[GeometryBase]
IEnumerable.gh (12.8 KB)
Ok I got it:
geometry type hint = GeometryBase but as Item access.
and then the code looks like this:
import rhinoscriptsyntax as rs import Rhino import System ray = Rhino.Geometry.Ray3d(rayStart, rayVec) geo = System.Collections.Generic.List[Rhino.Geometry.GeometryBase]() geo.Add(geometry) a = Rhino.Geometry.Intersect.Intersection.RayShoot(ray,geo,maxReflections)
Still doesn’t solve my problem though because now I get each brep separately so the ray bounces for each of them separate, instead of bouncing between them…
You can do it this way:
__author__ = "b.chipara" __version__ = "2019.10.30" import rhinoscriptsyntax as rs import Rhino import scriptcontext as sc from System.Collections.Generic import List ray = Rhino.Geometry.Ray3d(rayStart, rayVec) newlist = List[Rhino.Geometry.GeometryBase]() for g in geometries: newlist.Add(g) a = Rhino.Geometry.Intersect.Intersection.RayShoot(ray,newlist,maxReflections)
Ok, got it.
used a for loop to place each brep in the list, rather than creating a list for each brep with that brep inside - as I was doing above.
Yes, the thing is that it expects exactly a type, not a “normal” Python list.
For clarity, I’m thinking, will it be better if the GHPython component would have IEnumerable[GeometryBase] as a type hint, so it will automatically transform a “normal” Python list of geometry into a type?
I don’t know which other functions expect it…
This was done this way because Python users usually want to deal with Python lists. This is more a side-case of IronPython integration. Now that you know it, it will be easily to handle it.
Ray3D doesn’t work with trimmed surfaces such a disappointment.
I have to find the one that works with meshes…
It’s on the to-do list.
I see some interesting applications for this but it has been on the list for quite some time.
Is there another method for this? Something that works with meshes maybe?
You can get the first hit using
Rhino.Geometry.Intersect.Intersection.MeshRay, but you’ll have to implement further bounces from here yourself. If you have issues implementing the second overload, here’s an example:
Edit: My first topic on Discourse was also related to this issue
Something like this, but in a loop?
If I want to bounce it several times…
import Rhino as rc from System import Array import clr import rhinoscriptsyntax as rs def meshRayIntersect(mesh,point,vector): """ Intersect a mesh with a ray, including intersected mesh face IDs """ ray = rc.Geometry.Ray3d(point,vector) faceIDs = clr.StrongBox[Array[int]]() rayP = rc.Geometry.Intersect.Intersection.MeshRay(mesh,ray,faceIDs) if rayP >= 0.0: rayPt = ray.PointAt(rayP) faceIDs = list(faceIDs.Value) return rayPt,faceIDs else: return None, None def ref(v,n): """ Calculate reflection vector """ d = rs.VectorDotProduct(v,n) ref = rs.VectorReverse(v-(2*d*n)) return ref XPt, XIDs = meshRayIntersect(MyMesh,MyPoint,MyVector) normal_list = rs.MeshFaceNormals(MyMesh) facenormal = normal_list[XIDs] reflex_vec = ref(MyVector,facenormal)
Yes exactly, shove that in a loop and you should be good
Would it be possible to expose the MeshRay functionality as RhinoScript method for V7 ?
It has a potential to speed up a lot of tools we have that currently rely either on mesh/line intersection or PointPick but have to filter out all the results just to get the first ray bounce, which is what I am after 99% of cases.