RayShoot, MeshRay

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 System.Collections.Generic.List[Rhino.Geometry.GeometryBase]() first, Add() your element, then call that same method.

1 Like

Thanks @piac,

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)


rays.gh (11.2 KB)

3 Likes

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.

Thanks!

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 :frowning: such a disappointment.
I have to find the one that works with meshes…

I don’t know who wrote the wrapper. Maybe @dale or @stevebaer can help.

It’s on the to-do list.

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

– Dale

Thanks @dale,
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 :older_man:

2 Likes

Thanks @AndersDeleuran,

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[0]]

reflex_vec = ref(MyVector,facenormal)


Raybouncing_3_mesh.gh (11.0 KB)

1 Like

Yes exactly, shove that in a loop and you should be good :slight_smile:

Hi @dale,

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.

thank you,

–jarek

1 Like

Hello Anders
Thank you for sharing the idea.

I have a little question about the code you share .
Cause the None-data return to the List of Face-IDs,
When I try to use it to sort the mesh-surfaces it will always shows :‘None Type’ object is not subscriptable . May you give me some advice?

Sorry for bother.

@fred1357944, you need to be more specific. Where does the exception happen?
‘None Type’ object is not subscriptable usually means that you’re trying to do a list type operation, for instance item = my_list[0], on a variable that currently is None (not a list).

Generally speaking, if you have a case where a variable can be a list or None, you have to account for that by using for instance an if statement.

if my_var is not None:
    # do the list operation
    my_var.sort()
    print my_var[0]
else:
   # my_var is None; do something else
   pass
1 Like