Вчера Паша в скайп-чате школы предложил интересную задачку
[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)
вроде работает
надеюсь было интересно и полезно