Skip to content

Instantly share code, notes, and snippets.

@jeremybep
Created March 6, 2023 20:12
Show Gist options
  • Save jeremybep/4a446e8376b5cbc67d1bee90e4300e09 to your computer and use it in GitHub Desktop.
Save jeremybep/4a446e8376b5cbc67d1bee90e4300e09 to your computer and use it in GitHub Desktop.
Foundry nuke - bake camera with arnlold metadata
import nuke
import os
import math
'''
TODO :
Manque FOV Fichier Maya, voir pour extract en metadata.
AJOUT DE LA STEREO
exemple pour une FLenght:
import math
node = nuke.toNode("reader")
metaData = node.metadata()
hAperture = 35.0
vAperture = (hAperture)*(metaData['exr/CameraFilmApertureVertical'])
focal = hAperture / (2 * math.tan(math.radians(32.52)/2.0))
print round(focal, 3)
READER_NAME = "reader_baked"
CAMERA_NAME = "exr_baked_cam"
SCANRENDER = "ScanRender_baked"
'''
bakedNode = nuke.toNode('BAKE_CAMERA')
READER_NAME = bakedNode.knob('readername').value()
CAMERA_NAME = bakedNode.knob('cameraname').value()
SCANRENDER = bakedNode.knob('scanrendername').value()
def getMetadataMatrix(meta_list):
m = nuke.math.Matrix4()
try:
for i in range (0,16) :
m[i] = meta_list[i]
except:
m.makeIdentity()
return m
def ExrToCamera():
# Get Read Node Name to MetaData
node = nuke.toNode(READER_NAME)
metaData = node.metadata()
# Request fields
reqFields = ['exr/%s' % i for i in ('worldToCamera', 'worldToNDC')]
if not set( reqFields ).issubset( metaData ):
nuke.message('no basic matrices for camera found')
print 'no basic matrices for camera found'
return
else:
print 'found needed data'
# Add/Check some Var, convert inch to mm
imageWidth = metaData['input/width']
imageHeight = metaData['input/height']
aspectRatio = float(imageWidth)/float(imageHeight)
hAperture = 35.0
vAperture = hAperture/aspectRatio
#val = node.metadata( 'exr/cameraAperture', frame)
#fov = node.metadata( 'exr/cameraFov', frame)
#focal = hAperture / (2 * math.tan(math.radians(fov)/2.0))
focalLengthMeta = metaData['exr/CameraFocalLength']
focalLengthCam = hAperture*focalLengthMeta
# Try fix Sample AA Arnold to ScanLine Render
try:
scan_render = nuke.toNode(SCANRENDER)
aa_sample = metaData['exr/arnold/AA_samples']
scan_render['samples'].clearAnimated()
scan_render['samples'].setAnimated()
scan_render['samples'].setValue( aa_sample )
except:
print "No ScanLine Render"
# Get frame settings and prompt user
first = node.firstFrame()
last = node.lastFrame()
ret = nuke.getFramesAndViews( 'Create Camera', '%s-%s' %( first, last ) )
frameRange = nuke.FrameRange( ret[0] )
camViews = (ret[1])
for act in camViews:
# Get Camera node
cam = nuke.toNode(CAMERA_NAME)
# Reset settings
cam['focal'].clearAnimated()
cam['haperture'].clearAnimated()
cam['vaperture'].clearAnimated()
cam['matrix'].clearAnimated()
cam['matrix'].clearAnimated()
# Apply basic no keyframe value
cam['useMatrix'].setValue( True )
cam['haperture'].setValue ( hAperture )
cam['vaperture'].setValue ( vAperture )
cam['focal'].setValue ( round(focalLengthCam, 1) )
for k in ( 'focal', 'matrix'):
cam[k].setAnimated()
task = nuke.ProgressTask( 'Baking camera %s' % node.name() )
for curTask, frame in enumerate( frameRange ):
if task.isCancelled():
break
task.setMessage( 'processing %s' % frame )
wTC = node.metadata('exr/worldToCamera',frame, act)
wTN = node.metadata('exr/worldToNDC',frame, act)
worldNDC = wTN
# Make table
lx = (-1 - worldNDC[12] - worldNDC[8]) / worldNDC[0]
rx = (1 - worldNDC[12] - worldNDC[8]) / worldNDC[0]
by = (-1 - worldNDC[13] - worldNDC[9]) / worldNDC[5]
ty = (1 - worldNDC[13] - worldNDC[9]) / worldNDC[5]
swW = max( lx , rx ) - min( lx , rx ) # Screen Window Width
swH = max( by , ty ) - min( by , ty ) # Screen Window Height
cam['focal'].setValueAt( float( round(focalLengthCam, 1) ), frame )
# Matrix math for rotation and translation
matrixList = wTC
camMatrix = getMetadataMatrix(wTC)
flipZ=nuke.math.Matrix4()
flipZ.makeIdentity()
flipZ.scale(1,1,-1)
transposedMatrix = nuke.math.Matrix4(camMatrix)
transposedMatrix.transpose()
transposedMatrix=transposedMatrix*flipZ
invMatrix=transposedMatrix.inverse()
for i in range(0,16):
matrixList[i]=invMatrix[i]
for i, v in enumerate( matrixList ):
cam[ 'matrix' ].setValueAt( v, frame, i)
task.setProgress( int( float(curTask) / frameRange.frames() *100) )
ExrToCamera()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment