set cut_paste_input [stack 0] version 13.1 v2 BackdropNode { inputs 0 name BackdropNode24 tile_color 0xc0c0c001 label "Pulse Generator" note_font_size 100 selected true xpos -483 ypos -180 bdwidth 761 bdheight 259 } push $cut_paste_input NoOp { name MF_PulseGenerator_v1_ knobChanged "n = nuke.thisNode()\nk = nuke.thisKnob()\nif k.name() == \"apply\":\n n\[\"pValue\"].setEnabled(n\[\"apply\"].getValue()!=0)\n \nif k.name() == \"type\":\n # Disable length when no need it\n if n\[\"type\"].getValue() in range(1,4):\n n\[\"length\"].setEnabled(False)\n n\[\"length\"].setValue(1)\n else:\n n\[\"length\"].setEnabled(True)\n # Disable expression when no need it\n if n\[\"type\"].getValue() in range(0,3):\n n\[\"expression\"].setValue(\"\")\n n\[\"expression\"].setEnabled(False)\n else:\n n\[\"expression\"].setEnabled(True)\n # Disable expression when no need it\n if n\[\"type\"].getValue() in range(1,3):\n n\[\"pValueOffset\"].setValue(1)\n n\[\"pValueOffset\"].setEnabled(False)\n else:\n n\[\"pValueOffset\"].setEnabled(True)\n \nif k.name() == \"frameRng\":\n n\[\"startFrame\"].setEnabled(n\[\"frameRng\"].getValue()!=0)\n n\[\"endFrame\"].setEnabled(n\[\"frameRng\"].getValue()!=0)" selected true xpos -154 ypos -29 addUserKnob {20 user} addUserKnob {7 aValue l "Active Value" t "This is the trigger value when is \"on\""} aValue 1 addUserKnob {7 length l Length t "This is the length of the trigger activity." -STARTLINE R 0 10} length 1 addUserKnob {7 pValue l "Passive value" t "This is the value of the trigger when is \"off\""} addUserKnob {7 pValueOffset l Offset t "This is the number of frames between active and passive values." -STARTLINE R 1 10} pValueOffset 1 addUserKnob {6 apply l Apply t "Check to apply the passive value" -STARTLINE} apply true addUserKnob {4 type l Type t "- default: Creates a one event trigger.\n\n- even: Creates a trigger on even numbers on the frame range.\n\n- odd: Creates a trigger on odd numbers on the frame range.\n\n- multiple of X: Creates a trigger on frames multiples of the number introduced.\n\n- every X frames: Creates a trigger that starts on the current frame and repeats every X frames. X is the number introduced.\n" M {default even odd "multiple of X" "every X frames" "" "" "" "" "" ""}} addUserKnob {1 expression l " X=" t "Write a number here" -STARTLINE +DISABLED} addUserKnob {4 interpolation l Interpolation t "Interpolate keyframes with one of these nuke interpolations" M {Smooth Constant Linear Catmull-Rom Cubic "" "" "" "" "" ""}} addUserKnob {6 frameRng l "Frame Range" t "Check for using your own frame range." +STARTLINE} addUserKnob {3 startFrame l "" -STARTLINE +DISABLED} startFrame 1001 addUserKnob {3 endFrame l "" -STARTLINE +DISABLED} endFrame 1052 addUserKnob {22 generatePulse l "Generate Pulse" T "import re\n\n#Set the interpolation value on a curve\ndef setInterpolation(animcurve, interpolation):\n if interpolation == 0:\n for k in animcurve:\n k.interpolation = nuke.SMOOTH\n elif interpolation == 1:\n for k in animcurve:\n k.interpolation = nuke.CONSTANT\n elif interpolation == 2:\n for k in animcurve:\n k.interpolation = nuke.LINEAR\n elif interpolation == 3:\n for k in animcurve:\n k.interpolation = nuke.CATMULL_ROM\n elif interpolation == 4:\n for k in animcurve:\n k.interpolation = nuke.CUBIC\n\n#Set a default one shot trigger.\ndef default(frame, aValue, pValue, pValueOffset, length, interpolation):\n for num in range(0, length):\n v.setValueAt(aValue, frame + num)\n if thisN\['apply'].getValue():\n v.setValueAt(pValue, frame - pValueOffset)\n v.setValueAt(pValue, frame + length + pValueOffset - 1)\n \n#Set a Trigger on multiple frames of a given number\ndef multiple(frameRange, aValue, pValue, pValueOffset, interpolation, number):\n for f in range(frameRange\[0],frameRange\[1] + 1):\n if(f%number == 0):\n v.setValueAt(aValue, f)\n if thisN\['apply'].getValue():\n v.setValueAt(pValue, f - pValueOffset)\n if ((f+1)<(frameRange\[1] + 1)):\n v.setValueAt(pValue, f + pValueOffset)\n# else:\n# v.setValueAt(aValue, f)\n# if thisN\['apply'].getValue():\n# v.setValueAt(pValue, f)\n \n#Set a Trigger on odd frames of the frame Range \ndef odd(frameRange, aValue, pValue, interpolation):\n for f in range(frameRange\[0],frameRange\[1] + 1):\n if(f%2 != 0):\n v.setValueAt(aValue, f)\n elif thisN\['apply'].getValue():\n v.setValueAt(pValue, f)\n \n#Set a Trigger on every given number frames. Starting on any frame. Even out of the frame range. \ndef everyX(frame, frameRange, aValue, pValue, pValueOffset, interpolation, number, length):\n for f in range(frame, frameRange\[1] + 1, number):\n for num in range(0,length):\n v.setValueAt(aValue, f + num)\n if thisN\['apply'].getValue():\n v.setValueAt(pValue, f - pValueOffset)\n if((f + length) < (frameRange\[1] + 1)):\n v.setValueAt(pValue, f + length + pValueOffset -1)\n\n \n#Get project and nuke variables\nthisN = nuke.thisNode()\np = re.compile('^-?\[0-9]+\$')\nn = nuke.Root()\nframeRng = \[]\nprint (n.firstFrame(), thisN\['startFrame'].getValue(), thisN\['endFrame'].getValue())\nif (thisN\['frameRng'].getValue() == 1):\n frameRng.append(int(thisN\['startFrame'].getValue()))\n frameRng.append(int(thisN\['endFrame'].getValue()))\nelse:\n frameRng.append(n.firstFrame())\n frameRng.append(n.lastFrame())\nfr = nuke.frame()\n\n#Get Trigger information\naVal = thisN\['aValue'].getValue()\npVal = thisN\['pValue'].getValue()\npVOffset = thisN\['pValueOffset'].getValue()\nl = int(thisN\['length'].getValue())\ninter = thisN\['interpolation'].getValue()\nt = thisN\['type'].getValue()\n\n#Set expression\nexpr = 0\nif (thisN\['expression'].getValue() != \"\") and p.match(thisN\['expression'].getValue()):\n expr = int(thisN\['expression'].getValue())\n\nif t == 0:\n #Create and set Trigger\n nMult = nuke.nodes.Multiply()\n nMult.setXYpos(thisN.xpos()+100,thisN.ypos()+50)\n v = nMult\['value']\n v.setAnimated()\n \n default(fr, aVal, pVal, pVOffset, l, inter)\n animC = v.animation(0).keys()\n setInterpolation(animC, inter)\n nMult.setName('Trigger_On', uncollide=True)\n if (thisN\['labelOn'].getValue() == 1):\n nMult\['label'].setValue(\"Frame \" + str(fr) + \"\\\\n Active for \" + str(l) + \" frames\")\n\nelif t == 1:\n #Create and set Trigger\n nMult = nuke.nodes.Multiply()\n nMult.setXYpos(thisN.xpos()+100,thisN.ypos()+50)\n v = nMult\['value']\n v.setAnimated()\n \n multiple(frameRng, aVal, pVal, 1, inter,2)\n nMult.setName('Trigger_On', uncollide=True)\n if (thisN\['labelOn'].getValue() == 1):\n nMult\['label'].setValue(\" even frames\")\n \nelif t == 2:\n #Create and set Trigger\n nMult = nuke.nodes.Multiply()\n nMult.setXYpos(thisN.xpos()+100,thisN.ypos()+50)\n v = nMult\['value']\n v.setAnimated()\n \n odd(frameRng, aVal, pVal, inter)\n nMult.setName('Trigger_On', uncollide=True)\n if (thisN\['labelOn'].getValue() == 1):\n nMult\['label'].setValue(\" odd frames\")\n\nelif t == 3:\n if (thisN\['expression'].getValue() != \"\") and p.match(thisN\['expression'].getValue()):\n if (int(thisN\['expression'].getValue()) != 1): \n if ((pVOffset*2) <= expr):\n #Create and set Trigger\n nMult = nuke.nodes.Multiply()\n nMult.setXYpos(thisN.xpos()+100,thisN.ypos()+50)\n v = nMult\['value']\n v.setAnimated()\n \n multiple(frameRng, aVal, pVal, pVOffset, inter, expr)\n nMult.setName('Trigger_On', uncollide=True)\n if (thisN\['labelOn'].getValue() == 1):\n nMult\['label'].setValue(\"frames multiple of \" + str(expr))\n else:\n nuke.message('For this multiple, you need to decrease the passive offset value.')\n else:\n nuke.message('Multiple has to be higher than 1')\n else:\n nuke.message('Introduce a number X or choose another type of Trigger')\n \nelif t == 4:\n if (thisN\['expression'].getValue() != \"\") and p.match(thisN\['expression'].getValue()):\n if (int(thisN\['expression'].getValue()) != 1): \n if ((pVOffset*2) <= expr):\n if (l < expr):\n #Create and set Trigger\n nMult = nuke.nodes.Multiply()\n nMult.setXYpos(thisN.xpos()+100,thisN.ypos()+50)\n v = nMult\['value']\n v.setAnimated()\n if (thisN\['frameRng'].getValue() == 1):\n fr = int(thisN\['startFrame'].getValue())\n everyX(fr,frameRng, aVal, pVal, pVOffset, inter, expr, l)\n nMult.setName('Trigger_On', uncollide=True)\n if (thisN\['labelOn'].getValue() == 1):\n nMult\['label'].setValue(\"every \" + str(expr) + \" frames\" + \"\\\\n\" + \"from frame \" + str(fr) + \"\\\\n\" + \"Active for \" + str(l) + \" frames\")\n else:\n nuke.message('Length of activity has to be lower than X')\n else:\n nuke.message('For this multiple, you need to decrease the passive offset value.')\n else:\n nuke.message('Multiple has to be higher than 1')\n else:\n nuke.message('Introduce a number X or choose another type of Trigger') " +STARTLINE} addUserKnob {6 labelOn l "Display info" t "Displays information on node's label" -STARTLINE} labelOn true addUserKnob {26 _1 l "" +STARTLINE} addUserKnob {26 version_author l "" +STARTLINE T "
MF_PulseGenerator v1.0 - manuelferia.com, April 2023
"} addUserKnob {20 help_1 l help} addUserKnob {26 howto l "How to use"} addUserKnob {26 explanation l "" +STARTLINE T "1.- Set the active value of the pulse.\n\n2.- Set the number of frames that the pulse is active. (length)\n\n3.- Set the passive value of the pulse. Check Apply to use this setting.\n\n4.- Select passive value offset. By default 1. This is the number of frames between active and passive value.\n\n5.- Select the type of pulse you will apply.\n\n - default: Creates a one event pulse.\n\n - even: Creates a pulse on even numbers on the frame range.\n\n - odd: Creates a pulse on odd numbers on the frame range.\n\n - multiple of X: Creates a pulse on frames multiples of the number introduced.\n\n - every X frames: Creates a pulse that starts on the current frame \n and repeats every X frames. X is the number introduced.\n\n6.- Select the type of interpolation you want on the keyframes.\n\n7.- Select a Frame Range. By default, it will get the project settings frame range.\n\n8.- Press the \"Generate Pulse\" button."} }