#python #callback #nuke
#python #обратный вызов #nuke
Вопрос:
Я написал узел автоматической записи, в котором есть обратные вызовы и knobChange, но они перестают работать, когда я снова открываю скрипт nuke. Итак, сначала, когда создается узел автоматической записи, он работает так, как задумано, но как только я сохраняю и повторно открываю скрипт, узел записи отключается от обратных вызовов и knobChange. Я ценю некоторую помощь в этом, поскольку я думаю, что есть что-то, что я просмотрел или пропустил.
Вот код — меня можно упростить, но пока все равно.
import re
# Create write node
w = nuke.createNode('Write', inpanel=True)
count = 1
while nuke.exists('MN_AutoWrite_PUBLISH' str(count)):
count = 1
w.knob('name').setValue('MN_AutoWrite_PUBLISH' str(count))
# Create knobs
t = nuke.Tab_Knob("Project Path")
w.addKnob(t)
w.addKnob(nuke.String_Knob('proj_root', 'Project Root', ''))
w.addKnob(nuke.String_Knob('nes', '2D Folder', ''))
w.addKnob(nuke.String_Knob('seq', 'Sequence', ''))
w.addKnob(nuke.String_Knob('projShot', 'Shot', ''))
w.addKnob(nuke.String_Knob('projApp', 'App', ''))
w.addKnob(nuke.String_Knob('file_name', 'File Name', ''))
w.addKnob(nuke.String_Knob('projInit', 'Initials', ''))
w.addKnob(nuke.Text_Knob(''))
w.addKnob(nuke.Text_Knob('File Format'))
w.addKnob(nuke.String_Knob('pub', 'Fullpath', ''))
w.addKnob(nuke.Text_Knob(''))
w.addKnob(nuke.Boolean_Knob('png_bool', 'PNG', True))
w.addKnob(nuke.Boolean_Knob('tiff_bool', 'Tiff', False))
w.addKnob(nuke.Boolean_Knob('exr_bool', 'EXR', False))
w.addKnob(nuke.Text_Knob(''))
w.addKnob(nuke.Boolean_Knob('jpg_bool', 'Jpeg', False))
# Set output settings
w.knob('file_type').setValue('exr')
w.knob('create_directories').setValue('true')
def outputPath():
''' # Set output path '''
output_path = (w.knob('pub').getValue())
w.knob('file').fromScript(output_path)
# Set output path function
def updatePaths():
# global projFile
# global projSeq
# global InitReplacePublish
# global projInit
# Get file paths
saveDir = nuke.root()['name'].value()
dir = saveDir.split("/")
dirUnderScore = saveDir.split("_")
dirDot = saveDir.split(".")
projRoot = dir[0] "/" dir[1]
projNes = "/2D/_Renders/"
projSeq = dir[4] "/"
projShot = dir[5] "/"
projApp = "Nuke/"
projInit = dirUnderScore[-1].split(".")
projInitDot = projInit[0] "."
split = dir[-1].split(".")
projFile = re.sub(r"(vd{3,})", "", split[0] r".####" setFileType())
projFileReplace = projFile.replace("__", "_",1)
InitReplacePublish = projFileReplace.replace(projInitDot, "Publish.",1)
#assembles full publhs output path
pub = projRoot projNes projSeq projShot projApp "Publish/" InitReplacePublish
print "--------------------------"
print "projInit:" projInit [0]
print "projInitDot: " projInitDot
print "split:" split[0]
print "projFile: " projFile
print "projFileReplace: " projFileReplace
print "InitReplacePublish: " InitReplacePublish
print "--------------------------"
# Update path knobs
w.knob('proj_root').setValue(projRoot)
w.knob('nes').setValue(projNes)
w.knob('seq').setValue(projSeq)
w.knob('projShot').setValue(projShot)
w.knob('projApp').setValue(projApp)
w.knob('file_name').setValue(InitReplacePublish)
w.knob('projInit').setValue(projInit[0])
w.knob('pub').setValue(pub)
outputPath()
def setFileType():
if w.knob('tiff_bool').getValue():
return ".tif"
elif w.knob('exr_bool').getValue():
return ".exr"
elif w.knob('png_bool').getValue():
return ".png"
elif w.knob('jpg_bool').getValue():
return ".jpg"
else:
print("ERROR: File type not selected")
def setFileTypeTiff():
w.knob('exr_bool').setValue(False)
w.knob('png_bool').setValue(False)
w.knob('jpg_bool').setValue(False)
w.knob('file_type').setValue('tiff')
w.knob('compression').setValue('LZW')
w.knob('datatype').setValue('16 bit')
updatePaths()
def setFileTypeEXR():
w.knob('tiff_bool').setValue(False)
w.knob('png_bool').setValue(False)
w.knob('jpg_bool').setValue(False)
w.knob('file_type').setValue('exr')
updatePaths()
def setFileTypePNG():
w.knob('tiff_bool').setValue(False)
w.knob('exr_bool').setValue(False)
w.knob('jpg_bool').setValue(False)
w.knob('file_type').setValue('png')
w.knob('datatype').setValue('16 bit')
updatePaths()
def setFileTypeJpg():
w.knob('tiff_bool').setValue(False)
w.knob('exr_bool').setValue(False)
w.knob('png_bool').setValue(False)
w.knob('file_type').setValue('jpeg')
updatePaths()
setFileTypePNG()
# Callbacks
def removeCallbacks():
nuke.removeOnScriptSave(updatePaths)
nuke.removeOnScriptClose(updatePaths)
nuke.removeBeforeRender(updatePaths)
nuke.removeOnDestroy(removeCallbacks)
print("REMOVED CALLBACKS")
# Add callbacks
nuke.addOnScriptSave(updatePaths)
nuke.addOnScriptClose(updatePaths)
nuke.addBeforeRender(updatePaths)
nuke.addOnDestroy(removeCallbacks)
w['knobChanged'].setValue('''
k = nuke.thisKnob().name()
if k == "tiff_bool":
setFileTypeTiff()
elif k == "exr_bool":
setFileTypeEXR()
elif k == "jpg_bool":
setFileTypeJpg()
elif k == "png_bool":
setFileTypePNG()
else:
outputPath()
''')
Ответ №1:
nuke.addOnScriptSave(updatePaths)
nuke.addOnScriptClose(updatePaths)
nuke.addBeforeRender(updatePaths)
nuke.addOnDestroy(removeCallbacks)
Эти обратные вызовы активны только в экземпляре скрипта, который у вас есть при инициализации кода. После этого они исчезли навсегда!
Если вы хотите, вы можете определить этот код в своем init.py , Хотя код не будет сохраняться для других пользователей / установок таким образом.
Возможно, вам лучше использовать обратные вызовы beforeRender / afterRender узла записи для этого кода. Они удобно отображаются на узле записи в виде текстовых полей (хотя вам придется сжать свой код там). Как только он появится в этих полях, он также будет сохранен в файле сценария.
Комментарии:
1. Спасибо вам за это. У нас есть Nuke init.py на сервере, на который указывает переменная Windows NUKE env. Поскольку это находится на сервере и доступно для всех, считаете ли вы, что лучше сохранить его в файле инициализации или по-прежнему использовать узел записи до / после рендеринга?
2. И если я должен добавить обратные вызовы в init-файл, каков наилучший способ сделать это, поскольку он не найдет defs, если я скопирую вставку.