The Foundry NUKE 10.5v5 – обратные вызовы не работают при повторном открытии скрипта

#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, если я скопирую вставку.