I’m trying to write a script that scans an object from a particular perspective and creates a copy of it with no occluded geometry. Mostly I’m planning to use the ray_cast function for this, but documentation on it seems to be a bit lacking, and I was only able to find one other support thread on the subject which was a bit out of date.
-
The ray_cast function takes three parameters: origin, direction and distance. Distance is optional, so I did away with that. I assumed direction was a vector, but the other support thread suggested it was a destination point, which is a bit confusing. The documentation doesn’t give any detail on this, anyone know which it’s supposed to be?
-
It seems to return four values: result (boolean, did it hit or not), location (point at which it hit), normal (not useful to me), face index (also not useful). How exactly do I access the value I want? Currently I’m using:
cast = ray_cast(someparameters)
then looking at cast[0], cast[1] etc. to see the individual return values, but I’m not sure if that’s how it’s supposed to be used.
-
I’m also running into the following error when I run my script on the default cube: “runtime error: Cube has no mesh data to be used for ray casting.” It’s in edit mode if that makes a difference.
-
ray_cast works in object space, but my points are in global space. What’s the easiest way to convert between the two? I tried a couple of suggestions from another support thread but they didn’t quite work. Possibly outdated.
Thanks in advance for any and all replies. Here’s the relevant section of my current code:
def createMatrix (direction, rows, columns, center, pitch, height, width):
#Opening Variables
target = bpy.context.scene.objects.active
matrix = []
ceiling = findZBoundary("Top")
floor = findZBoundary("Bottom")
if (direction == "Top"):
startPoint = [center[0] - (width / 2), center[1] - (height / 2), ceiling]
scanStart = [startPoint[0], startPoint[0], ceiling]
scanEnd = [startPoint[0], startPoint[0], floor]
else:
startPoint = [center[0] - (width / 2), center[1] - (height / 2), floor]
scanStart = [startPoint[0], startPoint[0], floor]
scanEnd = [startPoint[0], startPoint[0], ceiling]
#Convert to object space
#I commented these out because they weren't working
#startPoint = target.matrix_local * startPoint
#scanStart = target.matrix_local * scanStart
#scanEnd = target.matrix_local * scanEnd
#Populate Matrix
for i in range(rows):
#Create new row
row = []
#Populate row
for j in range(columns):
#Update scanStart and ScanEnd
scanStart [0] = startPoint[0] + (j * pitch)
scanStart [1] = startPoint[1] + (i * pitch)
scanEnd [0] = startPoint[0] + (j * pitch)
scanEnd [1] = startPoint[1] + (i * pitch)
#Cast Ray
scan = target.ray_cast(scanStart, scanEnd)
#Find new point
if (scan[0] == True):
#Ray hit object, set newPoint to it's value
newPoint = scan[1]
else:
#Ray missed object, create newPoint on parting plane
newPoint = scanPoint
newPoint [2] = center [2]
#Convert to global space
#newpoint = target.matrix_world * newpoint
#Add result to row
row.append(newPoint)
#Append row to matrix
matrix.append(row)
#Deleteme
#print("Here's the matrix")
#print(matrix)
#Return result
return matrix