Skip to content

Instantly share code, notes, and snippets.

@RH2
Created May 11, 2022 01:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RH2/5197d7000685a1f0686f747a00d20139 to your computer and use it in GitHub Desktop.
Save RH2/5197d7000685a1f0686f747a00d20139 to your computer and use it in GitHub Desktop.
blenderraycastsample.py
import bpy
from mathutils import Vector, Quaternion
import numpy as np
import bmesh
import glob
import os
os.system('clear')
def lerp( t, a, b):
return a + t * (b - a)
def project(camera, coords):
# objects to consider
obj = bpy.data.objects['geometry']
# background = bpy.data.objects['plane']
targets = [obj]
# camera object which defines ray source
cam = camera
print(cam.name)
# save current view mode
mode = bpy.context.area.type
# set view mode to 3D to have all needed variables available
bpy.context.area.type = "VIEW_3D"
# get vectors which define view frustum of camera
frame = cam.data.view_frame(scene=bpy.context.scene)
topRight = frame[0]
bottomRight = frame[1]
bottomLeft = frame[2]
topLeft = frame[3]
# number of pixels in X/Y direction
resolutionX = int(bpy.context.scene.render.resolution_x * (bpy.context.scene.render.resolution_percentage / 100))
resolutionY = int(bpy.context.scene.render.resolution_y * (bpy.context.scene.render.resolution_percentage / 100))
# setup vectors to match pixels
# xRange = np.linspace(topLeft[0], topRight[0], 4)
# yRange = np.linspace(topLeft[1], bottomLeft[1], 4)
# print("xRange",xRange,"yRange",yRange)
print("coords",coords)
#for each x and y, interpolate between left,right, bottom,top
xRange = []
yRange = []
for x,y in coords:
#print("x is:",x,"y is:", y)
xRange.append(lerp(x,topLeft[0],topRight[0]))
yRange.append(lerp(y,topLeft[1],bottomLeft[1]))
print(xRange,yRange)
xRange = np.array(xRange)
yRange = np.array(yRange)
#ycoords = np.interp(np.array(ys),topLeft[1],bottomLeft[1])
# for x,y in zip(xcoords,ycoords):
# x = np.interp(x,topLeft[0],topRight[0])
# y = np.interp(y,topLeft[1],bottomLeft[1])
# array to store hit information
values = np.empty((xRange.size, yRange.size), dtype=object)
# indices for array mapping
indexX = 0
indexY = 0
# filling array with None
for x in xRange:
for y in yRange:
values[indexX,indexY] = None
indexY += 1
indexX += 1
indexY = 0
hits = []
# iterate over all targets
for target in targets:
# calculate origin
matrixWorld = target.matrix_world
matrixWorldInverted = matrixWorld.inverted()
origin = matrixWorldInverted @ cam.matrix_world.translation
for x,y in coords:
x = (lerp(x,topLeft[0],topRight[0]))
y = (lerp(y,topLeft[1],bottomLeft[1]))
pixelVector = Vector((x, y, topLeft[2]))
pixelVector.rotate(cam.matrix_world.to_quaternion())
destination = matrixWorldInverted @ (pixelVector + cam.matrix_world.translation)
direction = (destination - origin).normalized()
hit, location, norm, face = target.ray_cast(origin, direction)
if hit:
#values[indexX,indexY] = (matrixWorld @ location)
hits.append(matrixWorld @ location)
# create new mesh
# source: https://devtalk.blender.org/t/alternative-in-2-80-to-create-meshes-from-python-using-the-tessfaces-api/7445/3
mesh = bpy.data.meshes.new(name='created mesh')
bm = bmesh.new()
for hit in hits:
# no hit at this position
if hit is None:
continue
# add new vertex
bm.verts.new((hit[0], hit[1], hit[2]))
# # iterate over all possible hits
# for index, location in np.ndenumerate(values):
# # no hit at this position
# if location is None:
# continue
# # add new vertex
# bm.verts.new((location[0], location[1], location[2]))
# make the bmesh the object's mesh
bm.to_mesh(mesh)
bm.free() # always do this when finished
# We're done setting up the mesh values, update mesh object and
# let Blender do some checks on it
mesh.update()
mesh.validate()
# Create Object whose Object Data is our new mesh
obj = bpy.data.objects.new('created object', mesh)
# Add *Object* to the scene, not the mesh
scene = bpy.context.scene
scene.collection.objects.link(obj)
# Select the new object and make it active
bpy.ops.object.select_all(action='DESELECT')
obj.select_set(True)
bpy.context.view_layer.objects.active = obj
# reset view mode
bpy.context.area.type = mode
print("Done.")
path = r"A:\Controllerscan\coke\mov1\det_clean"
wildcard = r"*.txt"
completePath = os.path.join(path, wildcard)
print(completePath)
for det in glob.iglob(completePath):
f = open(det, "r")
head,tail = os.path.split(det)
cameraname = tail.replace(".txt",".png")
cam = bpy.data.objects[cameraname]
print(cam)
coords = []
content = f.read()
for line in content.split("\n"):
if line != "":
vars = line.split(",")
u = float(vars[2])
v = float(vars[3])
coords.append([u,v])
#print(vars)
#point = geo.createPoint()
#point.setAttribValue("id", int(vars[0]))
#point.setAttribValue("corner", int(vars[1]))
#point.setPosition( (float(vars[2]), (1.0-float(vars[3])) , 0.0) )
if len(coords) > 0:
project(cam, coords)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment