Вчера Паша в скайп-чате школы предложил интересную задачку
[16.06.2010 15:18:39] Павел Раевский: способ перевода RGB изображения в монохром это сложить значения R, G, B каналов помноженные на весовые коэффициенты
[16.06.2010 15:18:55] Павел Раевский: обычно это 0.3 R 0.59 G 0.11 B
[16.06.2010 15:19:14] Павел Раевский: нужно сделать так чтобы была возможность рулить этими коэффициентами
[16.06.2010 15:19:46] Павел Раевский: если я дергаю рульку R две другие должны соответственно смещаться так чтобы в сумма коэффициентов была равна 1
[16.06.2010 15:20:02] Павел Раевский: просто экспрешшны уводят в бесконечный цикл и вешают нюк
Разумеется все попытки завязать кнобы каждый на каждого приведут к бесконечному циклу
Если Нюк сумеет его отследить, вывалит ошибку
Но ещё скорее всего он попросту рухнет или повиснет
Для решения подобного рода задачи нам потребуется повесить на наши кнобы обработчик события
В этом обработчике алгоритм работает относительно изменяемой кнобы и не приводит к зацикливанию
С приходом шестого Нюка у нас появилась возможность по работе с обработчиками событий
раздел "nuke.callbacks" документации по скриптованию на питоне
В данном случае нас интересует функция nuke.addKnobChanged(call, args=(), kwargs={}, nodeClass='*')
всё до банального просто определяем функцию через def
параметры нам в данном случае не нужны
и передаём её в addKnobChanged
там же указываем для какого типа нод будет определён данный обработчик
для поставленной задачи я использовал Expression
def funk(): n = nuke.thisNode() k = nuke.thisKnob() #algorythm nuke.addKnobChanged(funk, nodeClass="Expression")
Думаю понятно, что в теле функции, нужный нам алгоритм
Пониять какая кноба вызвала функцию можем опросив nuke.thisKnob().name()
По алгоритму для данной задачи писать не буду
Его можно посмотреть внутри ноды
Одна залепа
Когда Нюку запускать скрипт с добавлением обработчика?
Я пошёл до банального прямо
Повесил скрипт на кнопочку Inintialize внутри ноды
до тех пор пока на неё хоть раз не ткнёшь, Нюк не будет знать не про наш обработчик события
в общем, если будет более жизненно необходимая задача, может придумается что-нить более элегантное
устал писать
вот скрипт
set cut_paste_input [stack 0] version 6.0 v3 push $cut_paste_input Group { name GrayscapeConverter1 tile_color 0x595959ff selected true xpos -432 ypos -167 addUserKnob {20 User_1 l Controllers} addUserKnob {41 fR l Red T GrayConverter1.fR} addUserKnob {41 fG l Green T GrayConverter1.fG} addUserKnob {41 fB l Blue T GrayConverter1.fB} addUserKnob {41 setDef l "set to Default" T GrayConverter1.setDef} addUserKnob {41 init l "Initialize Node" -STARTLINE T GrayConverter1.init} } Input { inputs 0 name Input1 xpos -426 ypos -174 } Expression { channel0 rgb expr0 fR*r+fG*g+fB*b name GrayConverter1 tile_color 0x7f7f7fff xpos -426 ypos -134 addUserKnob {20 User l Controllers} addUserKnob {7 fR l Red} fR 0.3000000014 addUserKnob {7 fG l Green} fG 0.5900000005 addUserKnob {7 fB l Blue} fB 0.11 addUserKnob {7 ffR +INVISIBLE} ffR 0.3 addUserKnob {7 ffG +INVISIBLE} ffG 0.59 addUserKnob {7 ffB +INVISIBLE} ffB 0.11 addUserKnob {22 setDef l "set to Default" T "nuke.thisNode().knob(\"fR\").setValue(0.3)\nnuke.thisNode().knob(\"fG\").setValue(0.59)\nnuke.thisNode().knob(\"fB\").setValue(0.11)\n\nnuke.thisNode().knob(\"ffR\").setValue(0.3)\nnuke.thisNode().knob(\"ffG\").setValue(0.59)\nnuke.thisNode().knob(\"ffB\").setValue(0.11)\n\n" +STARTLINE} addUserKnob {22 init l "Initialize Node" -STARTLINE T "def funk():\n n = nuke.thisNode()\n k = nuke.thisKnob()\n b = 0\n if k.name()==\"fR\":\n b = 1\n k1 = k\n k2 = n.knob(\"fG\")\n k3 = n.knob(\"fB\")\n kd = n.knob(\"ffR\")\n kd2 = n.knob(\"ffG\")\n kd3 = n.knob(\"ffB\")\n elif k.name()==\"fG\":\n k1 = k\n k2 = n.knob(\"fR\")\n k3 = n.knob(\"fB\")\n kd = n.knob(\"ffG\")\n kd2 = n.knob(\"ffR\")\n kd3 = n.knob(\"ffB\")\n b = 1\n elif k.name() == \"fB\":\n k1 = k\n k2 = n.knob(\"fR\")\n k3 = n.knob(\"fG\")\n kd = n.knob(\"ffB\")\n kd2 = n.knob(\"ffR\")\n kd3 = n.knob(\"ffG\")\n b = 1\n if b==1:\n k1v = k1.value()\n k2v = k2.value()\n k3v = k3.value()\n kdv = kd.value()\n df=k1v-kdv\n df2 = df/2\n k2.setValue(k2v-df2)\n k3.setValue(k3v-df2)\n kd.setValue(k1v)\n if k2.value()<0:\n k3.setValue(k3.value()+k2.value())\n k2.setValue(0)\n elif k3.value()<0:\n k2.setValue(k2.value()+k3.value())\n k3.setValue(0)\n kd2.setValue(k2.value())\n kd3.setValue(k3.value())\nnuke.thisNode().knob(\"setDef\").execute()\nnuke.addKnobChanged(funk, nodeClass=\"Expression\")\n"} } Output { name Output1 xpos -426 ypos -34 } end_group
Копируем, вставляем, смотрим (Nuke 6 only)
вроде работает
надеюсь было интересно и полезно