MaxScript [Newbie Question] Selecting faces by intersection

Hello everyone,

I accidentally Posted this in AdministrativeQuestions > Suggestions, and Feedback, so if anyone knows and can share how to delete threads, I can remove it from there. Anyways …

I’ve been lurking for a little while but decided to ask a curious question. I couldn’t find the answer when I did a quick search.

What I’d like to do is select the faces of ObjA by the shape of ObjB in 3DS Max 2013.

How I thought about achieving this was to use RayMeshGirdIntersect to fire a ray from every vertex of ObjA to ObjB, record the index of faces that were intersected to theArray and then passing that array to setFaceSelection ObjA 1 theArray.

The trouble I have is that if I have two planes, one on top of the other, that look like and ObjA is denser then ObjB i get holes in my selection. So I decided to tessellate ObjB which increases the number of rays and faces hit but still has holes and the function runs pretty slow. Tessellating more would presumably fix the holes but not the time issue.

So I guess I have couple questions:

  1. Is there a better way to select the faces of ObjA from the shape of ObjB without actually changing the objects much.
  2. If rays are the way to go, is there a way to make operation run faster. Here’s a snippet of the maxscript code. Adding tessellation doubles the time on my machine.

start = timestamp()
ObjA = Plane pos:[0,0,0] length:200  width:200 lengthsegs:150 widthsegs:150
ObjB = Plane pos:[0,0,-50] length:100  width:100 lengthsegs:2 widthsegs:2
theArray = #()

convertTo ObjB editable_mesh

--tessellate if needed
--tm = Tessellate()
--tm.iterations = 3
--addModifier ObjB tm

rayGrid = RayMeshGridIntersect()
rayGrid.Initialize 1
rayGrid.addNode ObjA
rayGrid.BuildGrid()

vertCount = ObjB.numverts
for v = 1 to vertCount where (
    pos = getVert ObjB v
    dir = getNormal ObjB v
    hitFaces = rayGrid.intersectRay pos dir true
    (hitFaces > 0)) do (
        join theArray (for h = 1 to hitFaces collect (rayGrid.getHitFace h))
)

--deleteModifier ObjB 1
ms = mesh_select()
addModifier ObjA ms
select ObjA
setFaceSelection ObjA 1 theArray
subObjectLevel = 4 

end = timestamp()
format "Selecting the faces took % seconds
" ((end-start)/1000.0)

  1. The other idea I had was to possibly translate ObjB to ObjA until the intersect and then finding out what faces on ObjB were touching what faces on ObjA. But I couldn’t find a lot of info on actual face to face intersections.

Any insight would be greatly appreciated,

Alex

I’ll try and help. While my strain of work is similar at the moment, I’ve not really tested your used method of RayMeshGridIntersect, so please do take my suggestions with a grain of salt.

  1. Is there a better way? Likely.

Based on the sample in the docs, not every face gets hit, and thus the selection with holes.
I think you may need to try some sampling with getClosestHit() and getFarthestHit() and add the faces between into the array.
That is assuming I am understanding what you mean when you say there are holes in the selection.

If you are only using planes, you might try to use bounding boxes to get your face selection.
In my testing of your script in Max2011, tesselation shrunk the selection count and took significantly longer to process, so that, at the moment looks like a bad idea.

I might be missing something obvious but why not (ab)use Volume Select modifier for that purpose?

ahosking -
yeah I ended up filtering the faces by the Bounding Box of ObjB and then using an point on triangle check I saw on
Point in triangle test for the rest. Turned out pretty well. :smiley:

Swordslayer -
Nope you aren’t missing anything. Volume Select modifier does what I need. I was just trying an exercise to see if I could figure out how to do it on my own. I knew about Volume select but if could figure it out how to code it, I may be able to apply it to other scenarios.

Thanks!

Wonderful,
That is some handy information.
I am glad you got the problem solved!