[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.....
–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: