Notifications
Clear all

[Closed] Mirroring a Ray

I try to get the oposite faces with RayMeshGridIntersect()

 Its nearly to be done.
 
 1). But i ned some idea how can reverse an ray.
 2). And little help ,becose some times i not get all the faces in to an array. 
 (some of them is missing I dont know why?)
 
 -----------------------------------------------
 
 (
     struct normalPoints
     (
         start,end,
         fn getRay obj face =
         (
             local nPoints = #()
             local p2 = polyOp.getFaceCenter obj face -- second point lower
             local normal = normalize (polyOp.getFaceNormal obj face)
             local p1 = p2 + normal * 2 -- firsrt point upper
             return (append nPoints (normalPoints start: p1 end: p2))
         ),
         fn mirrorRay obj ray =            
         (        
              --?????
         )
     )
         
     local obj = selection[1]
      if obj != undefined do
      (  
         local rm = RayMeshGridIntersect() --create an instance of the Reference Target 
         rm.Initialize 10 --init. the voxel grid size to 10x10x10
         rm.addNode obj --add the Editable_Poly to the grid
         rm.buildGrid() --build 
 
         local fSel = polyOp.getFaceSelection obj
         local norP = normalPoints() --instance from structure
         
         for f in fSel do --go through selected faces of the Editable_Poly
         (
             local ray = norP.getRay obj f --get two points to define a ray
             print (rm.intersectSegment ray[1].start ray[1].end false) --fill rm.
             print (rm.getHitFace 1) --get face
         )
     )
 )
 
 ------------------------------------------
 sory for my english ,its terible i know.....
4 Replies

–To test script create a simple sphere segments:32.
–Withh most of faces is working but some of them return “face not found” (189)

(
local obj = selection[1]
local rm = RayMeshGridIntersect() –create an instance of the Reference Target
rm.Initialize 10 –init. the voxel grid size to 10x10x10
rm.addNode obj –add the Editable_Poly to the grid
rm.buildGrid() –build

 local face = 182 -- a random face

 local p2 = polyOp.getFaceCenter obj face -- second point lower
 local normal = normalize (polyOp.getFaceNormal obj face) -- get normalized normal from face
 local p1 = p2 + normal * 2 -- firsrt point upper
 
 if (rm.intersectSegment p1 p2 false) != 0 --fill rm.
 then format "found face:%

” (rm.getHitFace 1) –get face
else print “face not found”
)

– some advice where Im vrong?

Seems like RayMeshGridIntersect works internally with a tri-mesh so the indices to hit faces are refering to the tri-mesh and not the editable poly object. So you have to convert your object to editable mesh to be able to see the actual hit faces.

And if what you want is to collect the faces behind one face, you have to reverse the face normal to calculate the collision segment:

segmentStart = meshOp.getFaceCenter
local normal = normalize (getFaceNormal obj face)
segmentEnd = segmentStart - normal * segmentLength

Keep in mind that the face used as segment starting point, will be hit too, so if you don’t want this to happen, you have to offset the segment start a bit:

segmentStart -= normal * offsetDistance

More things. If you are trying to collect faces behind another face, you have to enable the double sided option in the intersectSegment function. Otherwise only faces facing to the ray will we hit. And as you know already, all the faces behind another one in a sphere are facing to the oposite direction, so no face will be hit. Also, is important the segment length because if it’s too small, no face will be hit.

So the code should be something like this (tested with a sphere of radius 50, 32 segments, converted to editable mesh):

(

local obj = selection[1]

local rm = RayMeshGridIntersect() --create an instance of the Reference Target
rm.Initialize 10 --init. the voxel grid size to 10x10x10
rm.addNode obj --add the Editable_Poly to the grid
rm.buildGrid() --build

local segmentLength = 150
local offsetDistance = 0	-- Assign a possitive value to avoid the base face being hit
local doubleSided = true
local baseFace = 182 -- a random face

local segmentStart = meshOp.getFaceCenter obj baseFace
local normal = normalize (getFaceNormal obj baseFace)
segmentStart -= normal * offsetDistance
local segmentEnd = segmentStart - normal * segmentLength

-- Help us to visualize the segment
try ( delete (getNodeByName "colSegment") ) catch ()
Tape name:"colSegment" pos:segmentStart target:(targetObject pos:segmentEnd)

local numHits = rm.intersectSegment segmentStart segmentEnd doubleSided

local faces = for i = 1 to numHits collect (rm.getHitFace i)

-- Select hit faces
setFaceSelection obj faces

max modify mode
subObjectLevel = 4
completeRedraw()
)

Hope that helps.

Good advice

–mabe you know to how i can reverse the ray to get oposite faces?

it that right?

p1 = segmentStart
p2 = segmentEnd

p1.x += – obj.pos.x – calculate offset from obj pivot

segmentOpositeStart = [obj.pos.x – p1.x, p1.y , p1.z] – oposite face position in x
segmentOpositeEnd = ???

Thank you HalfVector It’s very helpful!

(
fn drawLineBetweenTwoPoints pointA pointB =
(
local ss = SplineShape pos: pointA
addNewSpline ss
addKnot ss 1 #corner #line PointA
addKnot ss 1 #corner #line PointB
updateShape ss
)
fn getRay obj face rm offsetDistance rayLength =
(
local normal = normalize (polyOp.getFaceNormal obj face) – get normalized normal from face
–incerase size of ray (intersect face)
local rayEnd = (polyOp.getFaceCenter obj face) – normal * offsetDistance –second point lower
local rayStart = rayEnd + normal * rayLength –firsrt point upper

       --create spline helpers for check normals from rays
       local newSpline = drawLineBetweenTwoPoints rayStart rayEnd
       
       if (rm.intersectSegment rayStart rayEnd true) != 0 --fill rm.
       then format "found face:%

” (rm.getHitFace 1) –get face
else format “face:% Is not found in rayStart:% rayEnd:%
” f rayStart rayEnd
)
fn getOpositeFace obj face rm offsetDistance rayLength =
(
local normal = normalize (polyOp.getFaceNormal obj face) – get normalized normal from face
–incerase size of ray (intersect face)
local rayEnd = (polyOp.getFaceCenter obj face) – normal * offsetDistance –second point lower
local rayStart = rayEnd + normal * rayLength –firsrt point upper
–inverse ray
rayEnd.x += – obj.pos.x – calculate offset from polyObj pivot
rayStart.x += – obj.pos.x – calculate offset from polyObj pivot

       local rayOpositeStart = [obj.pos.x - rayEnd.x, rayEnd.y , rayEnd.z] --oposite vert position
       local rayOpositeEnd = [obj.pos.x - rayStart.x, rayStart.y , rayStart.z] --oposite vert position
       --create spline helpers for check normals from rays
       local newSpline = drawLineBetweenTwoPoints rayOpositeStart rayOpositeEnd
       --return face number
       if (rm.intersectSegment rayOpositeStart rayOpositeEnd true) != 0 --fill rm.
       then format "found Opositeface:%

” (rm.getHitFace 1) –get face
else format “face:% Is not found in rayOpositeStart:% rayOpositeEnd:%
” f rayOpositeStart rayOpositeEnd
)

   local obj = selection[1]
   local rayLength = 2
   local offsetDistance = 0.1    -- Assign a possitive value to avoid the base face being hit 

   local rm = RayMeshGridIntersect() --create an instance of the Reference Target
   rm.Initialize 10 --init. the voxel grid size to 10x10x10
   rm.addNode obj --add the Editable_Poly to the grid
   rm.buildGrid() --build

   local fSel = polyOp.getFaceSelection obj
   for f in fSel do --go through selected faces of the Editable_Poly
   (
       getOpositeFace obj f rm offsetDistance rayLength 
   )
   --polyop.setfaceselection obj coze

)

Thanks for you help :bounce: