RayMeshGridIntersect : ReferenceTarget

RayMeshGridIntersect - superclass: ReferenceTarget; super-superclass:MAXWrapper - 1:0 - classID: #(930131240, 656216840) 

Provides advanced ray-to-mesh intersection methods using a uniform voxel grid as acceleration method.

Properties

<RayMeshGridIntersect>.nodeList ArrayParameter default: #() -- node array; Node_List   

Get/set the array of nodes.

Note: Despite the implementation as an array parameter, the RayMeshGridIntersect does NOT actually operate on all objects in the list, but only on the FIRST object in the list. If the intersection against multiple objects is required, a separate RayMeshGridIntersect instance should be created for each one and the intersections have to be processed one after the other within a MAXScript loop.

RayMeshGridIntersect interfaces:

Interface: rayMeshGridIntersectOps 

Methods:

<void>initialize <integer>gridSize 

Initializes the voxel grid with the specified grid size.

The grid size value defines the number of voxels along all 3 axes.

The actual size of the voxels depends on the bounding box of the nodes to be processed.

<void>addNode <node>addNode 

Adds a node to the node list.

Please see the Note above - only the first object on the list will be used!

<void>buildGrid() 

Fills in the voxel grid with data.

<void>free() 

Removes all data from the voxel grid.

<integer>intersectBox <point3>min <point3>max 

Performs a box intersection using the specified min. and max. points in world space.

<integer>intersectSphere <point3>center <float>radius 

Performs a sphere intersection using the specified center and radius.

<integer>intersectRay <point3>p <point3>dir <boolean>doubleSided 

Performs a ray intersection using the specified position and direction.

If the doubleSided argument is False, only intersection with faces whose normals point towards the ray will be collected.

When it is True, the faces will be considered double-sided and intersected even when their normals are pointing in the direction of the ray.

The result is 0 if not intersection was detected, or a positive number representing the number of faces that have been intersected.

<integer>intersectSegment <point3>p1<point3>p2 <boolean>doubleSided 

Performs a segment intersection using the specified two world positions.

This is similar to intersectRay, but instead of a point and direction, the intersection ray is defined using two absolute positions in space, where p1 is the origin and the direction is from p1 to p2.

If the doubleSided argument is False, only intersection with faces whose normals point towards the ray will be collected.

When it is True, the faces will be considered double-sided and intersected even when their normals are pointing in the direction of the ray.

The result is 0 if no intersection was detected, or a positive number representing the number of faces that have been hit.

<integer>getHitFace <integer>index 

Returns the index of the TriMesh face for the indexed hit.

The index can be a positive number between 1 and the number of hits reported by the last intersection method.

<point3>getHitBary <integer>index 

Returns the Barycentric Coordinates of the TriMesh face for the indexed hit.

The index can be a positive number between 1 and the number of hits reported by the last intersection method.

<point3>getHitNormal <integer>index 

Returns the face normal of the TriMesh face for the indexed hit in world space.

The index can be a positive number between 1 and the number of hits reported by the last intersection method.

<float>getHitDist <integer>index 

Returns the distance to the indexed hit.

The index can be a positive number between 1 and the number of hits reported by the last intersection method.

<integer>intersectSegmentDebug <point3>p1 <point3>p2 <boolean>doubleSided <integer>gridID 

This method is for debugging purposes only.

<integer>getClosestHit() 

Returns the index of the closest hit.

<integer>getFarthestHit() 

Returns the index of the farthest hit.

<integer>closestFace <point3>p 

Performs intersections from the specified world point with all faces and returns the number of hits as integer.

You can use the getClosestHit() and getFarthestHit() to determine the closest and farthest faces to the specified world point, getHitDist() to determine the distance to every face, and getPerpDist() to determine the perpendicular distance to the point.

<float>getPerpDist <integer>index 

Returns the perpendicular distance to the indexed hit.

The index can be a positive number between 1 and the number of hits reported by the last intersection method.

<void>ClearStats() 

Clears all statistics.

<void>PrintStats() 

Prints current statistics, including number of faces and number of searches performed.

The following example creates a sphere and a geosphere, registers the sphere with the voxel grid and then shoots rays from each vertex of the geosphere and selects the faces of the sphere that these rays have hit.

EXAMPLE

   (
   resetMaxFile #noprompt --reset the scene
   theSphere = Sphere radius:40 segs:50 pos:[100,200,300] --create a sphere
   theGeoSphere = Geosphere radius:100 segs:3 pos:[100,200,300] --create a geosphere
   theFacesArray = #() --init. an array to collect face selection

   rm = RayMeshGridIntersect () --create an instance of the Reference Target
   rm.Initialize 10 --init. the voxel grid size to 10x10x10
   rm.addNode theSphere --add the sphere to the grid
   rm.buildGrid () --build the grid data (collecting faces into the grid voxels)
   theGSMesh = snapshotasmesh theGeoSphere --grab the TriMesh of the Geosphere
   for v = 1 to theGSMesh.numverts do --go through all verts of the Geosphere
   (
   thePos = getVert theGSMesh v --get the position of the vertex
   theNormal = -(getNormal theGSMesh v) --get the normal of the vertex, reverse direction
   theHitsCount = rm.intersectRay thePos theNormal false --intersect the ray with the sphere
   if theHitsCount > 0 then --if have hit anything...
   (
    theIndex = rm.getClosestHit () --get the index of the closest hit by the ray
    theFace = rm.getHitFace theIndex --get the face index corresponding to that indexed hit
    append theFacesArray theFace --add to the face array to select the face...
   )
   else
    format "The Ray % Missed\n" v
   )

   ms = mesh_select() --create a mesh select modifier
   addModifier theSphere ms --add on top of the sphere
   select theSphere --select the sphere
   max modify mode --go to modify panel
   setFaceSelection theSphere 1 theFacesArray --set the selection in the MeshSelect
   subObjectLevel = 3 --go to face selection level
   )