Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
PlanarProjection Planar Projection Generates 2D coordinates for points in 3D space. Works on 4 points at once, is instantaneous to calculate, and generates a 4x4 transform matrix for use in rotos.
set cut_paste_input [stack 0]
push $cut_paste_input
Group {
name PlanarProjection
help "<b>Planar Projection</b>\nGenerates 2D coordinates for points in 3D space. Type in 3D point coordinates, or use vertex selection in 3D viewer and click set to pick average of selected points, or set points to set all four points at once. \n\nYou can connect node output to scene together with your pointcloud or geometry and see where your points are located in 3d space. Double click any of them to move it in 3d space like any traditional nuke transform control. \n\nA matrix transform is also generated to be used with RotoPaint, SplineWarp and GridWarp nodes. If you are using matrix in GridWarp, points have to be in clockwise order, pick them one by one! \n\nCommand set points doesn't respect selection order! \n\nCheck out the demo video on my website! Kudos to Ivan Busquets for help with matrix math. \n\n-- developed by Vit Sedlacek 2012 www.vitsedlacek.com \n\n-- Modified by Jed Smith to make calculation time nearly instantaneous, fix some bugs and create a BG input so that the sampled format could be easily specified instead of using nuke.root() format. Also enabled animated 3d input points, and added some functionality in the set knobs to snarf data from axis nodes.\nhttp://gist.github.com/jedypod"
addUserKnob {20 PlanarProjection}
addUserKnob {26 ""}
addUserKnob {26 usage_label_header l " " T "<font size=4>\n<b>Input 3D Positions</b>"}
addUserKnob {20 usage_label_grp l " help" n 1}
usage_label_grp 0
addUserKnob {26 usage_label l " " T "<font size=3>\nSelect any number of points in the 3D view, in vertex selection mode.<br/>\n<b>Set from Selection</b>: 4 points will be set based on the selection bounds.<br/>\n<b>Set from Axes</b>: Gets position from 4 axis nodes with or without animation.<br/>\n<b>Set Animated</b>: Set the target point. For animated geometry.<br/>\n<b>Set Point</b>: Set point from vertex selection. If no vertex selection,<br/>\n set from selected Axis. If no axis, set from selected pixel value (for PWorld).<br/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"}
addUserKnob {20 endGroup n -1}
addUserKnob {22 set_from_selection l "Set from Selection" t "Set value of all points If Axis nodes are selected, it grabs translate values from them. If not, the first 4 selected vertexes in the 3D viewport is used instead. " T "## Set points to selected\nfrom __future__ import with_statement\nfrom nukescripts import snap3d as sn\n\n\nnode = nuke.thisNode()\nnode.begin()\nmatch_sel = nuke.toNode('_MATCH_SELECTION_')\n\nsn.translateRotateScaleToPoints(match_sel)\n\naxes = \[nuke.toNode('LL'), nuke.toNode('LR'), nuke.toNode('UR'), nuke.toNode('UL')]\nfor i, axis in enumerate(axes):\n matrix = axis\['world_matrix']\n translate = \[matrix.getValue(3), matrix.getValue(7), matrix.getValue(11)]\n node\['ip\{0\}'.format(i+1)].setValue(translate)" +STARTLINE}
addUserKnob {22 set_from_axes l "Set from Axes" t "Select up to 4 different axes, which can be animated. This button will set the points to each axis in selection order." -STARTLINE T "node = nuke.thisNode()\nnuke.root().begin()\n\naxis_nodes = \[axis for axis in nuke.selectedNodes() if axis.Class() == \"Axis2\"]\nif axis_nodes:\n if len(axis_nodes) > 4:\n nuke.message(\"More than 4 axis nodes selected: Will only use the first 4 selected ones.\")\n axis_nodes = list(reversed(axis_nodes)) # Reverse selected so it goes in selection order\n for i in xrange(4):\n point = node\[\"ip\{0\}\".format(i+1)]\n axis = axis_nodes\[i]\n if axis\['translate'].isAnimated():\n point.clearAnimated()\n point.copyAnimations(axis\['translate'].animations())\n else:\n point.clearAnimated()\n point.setValue(axis\['translate'].getValue())"}
addUserKnob {22 clear_input l Clear t "Remove all animated and non-default knob values." -STARTLINE T "n = nuke.thisNode()\n\nfor i in xrange(4):\n kip = n\['ip'+str(i+1)]\n kip.clearAnimated()\n kip.setValue(kip.defaultValue())"}
addUserKnob {22 set_single_animated l "Set Animated" t "Sets single point to selected vertex position. Set the target knob to put the data on." T "import nuke\nfrom nukescripts import snap3d as sn\n\ndef _get_framerange():\n first_frame = int(nuke.numvalue('root.first_frame'))\n last_frame = int(nuke.numvalue('root.last_frame'))\n step = 1\n default_frange = str(nuke.FrameRange(first_frame, last_frame, step))\n frange = nuke.getInput('Enter Frame Range:', default_frange)\n if not frange:\n return None\n else:\n try:\n return nuke.FrameRange(frange)\n except:\n nuke.message('Invalid frame range')\n return None\n\ndef get_vertex_position(frame):\n # return last selected vertex position on specified frame\n vertices = sn.getSelection()\n if not vertices:\n nuke.message(\"A vertex must be selected.\")\n return\n center = sn.calcAveragePosition(vertices)\n vertices.translate(-center)\n return center\n\ndef calc_vertex_positions():\n framerange = _get_framerange()\n if not framerange:\n return\n curvetool = nuke.nodes.CurveTool()\n positions_animcurve = \[\[], \[], \[]]\n for frame in framerange:\n nuke.execute(curvetool, frame, frame)\n curpos = get_vertex_position(frame)\n if curpos:\n for i in xrange(3):\n positions_animcurve\[i].append(nuke.AnimationKey(frame, curpos\[i]))\n if curvetool:\n nuke.delete(curvetool)\n return positions_animcurve\n\nnode = nuke.thisNode()\nnuke.root().begin()\niptarget = node\['iptarget'].getValue()\nipknob = node\['ip\{0\}'.format(int(iptarget)+1)]\nipknob.clearAnimated()\nipknob.setAnimated()\n\npositions = calc_vertex_positions()\nfor index, curve in enumerate(ipknob.animations()):\n curve.addKey(positions\[index])" +STARTLINE}
addUserKnob {22 set_point l "Set Point" -STARTLINE T "import nuke\nfrom nukescripts import snap3d as sn\n\ndef get_vertex_position():\n points = sn.getSelection()\n if not points:\n return None\n pos = sn.calcAveragePosition(points)\n return pos\n\nif __name__==\"__main__\":\n node = nuke.thisNode()\n nuke.root().begin()\n axis_nodes = \[axis for axis in nuke.selectedNodes() if axis.Class() == \"Axis2\"]\n iptarget = node\['iptarget'].getValue()\n ipknob = node\['ip\{0\}'.format(int(iptarget)+1)]\n pos = get_vertex_position()\n if pos:\n ipknob.setValue(pos)\n elif axis_nodes:\n axis = axis_nodes\[-1]\n if axis\['translate'].isAnimated():\n ipknob.clearAnimated()\n ipknob.copyAnimations(axis\['translate'].animations())\n else:\n ipknob.clearAnimated()\n ipknob.setValue(axis\['translate'].getValue())\n else:\n viewer = nuke.activeViewer().node()\n if viewer.input(0):\n viewed_node = viewer.input(0)\n if not nuke.selectedNodes():\n viewed_node.setSelected(1)\n else:\n viewed_node = nuke.activeViewer().node()\n bboxinfo = nuke.activeViewer().node()\['colour_sample_bbox'].value()\n aspect = float(viewed_node.width() * viewed_node.pixelAspect()) / float(viewed_node.height())\n cornerA = \[(bboxinfo\[0]*0.5+0.5) * viewed_node.width(), (((bboxinfo\[1] * 0.5) + (0.5/aspect)) * aspect) * viewed_node.height()]\n cornerB = \[(bboxinfo\[2]*0.5+0.5) * viewed_node.width(), (((bboxinfo\[3] * 0.5) + (0.5/aspect)) * aspect) * viewed_node.height()]\n area = \[cornerB\[0] - cornerA\[0], cornerB\[1] - cornerA\[1]]\n center = \[cornerA\[0] + (area\[0]/2), cornerA\[1] + (area\[1] / 2)]\n color_sample = \[viewed_node.sample('rgba.red', center\[0], center\[1], area\[0], area\[1]), viewed_node.sample('rgba.green', center\[0], center\[1], area\[0], area\[1]), viewed_node.sample('rgba.blue', center\[0], center\[1], area\[0], area\[1])]\n ipknob.setValue(color_sample)"}
addUserKnob {4 iptarget l "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;target" -STARTLINE M {"point 1" "point 2" "point 3" "point 4" "" ""}}
iptarget "point 2"
addUserKnob {41 ip1 l "point 1" T point_1.translate}
addUserKnob {22 set_ip1 l "Set 1" t "Set point 1 to current selection." -STARTLINE T "node = nuke.thisNode()\nnode\['iptarget'].setValue(0)\nnode\['set_point'].execute()"}
addUserKnob {41 ip2 l "point 2" T point_2.translate}
addUserKnob {22 set_ip2 l "Set 2" t "Set point 2 to current selection." -STARTLINE T "node = nuke.thisNode()\nnode\['iptarget'].setValue(1)\nnode\['set_point'].execute()"}
addUserKnob {41 ip3 l "point 3" T point_3.translate}
addUserKnob {22 set_ip3 l "Set 3" t "Set point 3 to current selection." -STARTLINE T "node = nuke.thisNode()\nnode\['iptarget'].setValue(2)\nnode\['set_point'].execute()"}
addUserKnob {41 ip4 l "point 4" T point_4.translate}
addUserKnob {22 set_ip4 l "Set 4" t "Set point 4 to current selection." -STARTLINE T "node = nuke.thisNode()\nnode\['iptarget'].setValue(3)\nnode\['set_point'].execute()"}
addUserKnob {26 ""}
addUserKnob {26 reconcile_explanation l " " T "<font size=4><b>Reconcile Points into Screen Space</b>"}
addUserKnob {20 reconcile_points_grp l " help" n 1}
reconcile_points_grp 0
addUserKnob {26 reconcile_points_help l " " T "<font size=3>Press Calculate and the 3D points will be reconciled into 2d tracking data. <br/>\nA perspective transform matrix is also calculated. <br/>This enables tracking in \ntranslation, rotation, scale and perspective.\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"}
addUserKnob {20 endGroup_1 l endGroup n -1}
addUserKnob {22 Calculate t "Calculate the reconciled 2D points for each 3D point.\n\nAlso calculate a matrix transform for the planar surface, if there are 4 total points. This can then be used for Rotos and CornerPins." T "import nuke\nfrom nukescripts import snap3d as sn\nimport math\n\n\ndef cameraProjectionMatrix(cameraNode, frame, imageformat):\n ## modified code from nukescripts/Snap3D\n\n # Matrix to transform points into camera-relative coords.\n wm = nuke.math.Matrix4()\n for i in xrange(16):\n wm\[i] = cameraNode\['matrix'].getValueAt(frame,i)\n wm.transpose()\n camTransform = wm.inverse()\n\n # Matrix to take the camera projection knobs into account\n roll = float(cameraNode\['winroll'].getValueAt(frame,0))\n scale_x = float(cameraNode\['win_scale'].getValueAt(frame,0))\n scale_y = float(cameraNode\['win_scale'].getValueAt(frame,1))\n translate_x = float(cameraNode\['win_translate'].getValueAt(frame,0))\n translate_y = float(cameraNode\['win_translate'].getValueAt(frame,1))\n m = nuke.math.Matrix4()\n m.makeIdentity()\n m.rotateZ(math.radians(roll))\n m.scale(1.0 / scale_x, 1.0 / scale_y, 1.0)\n m.translate(-translate_x, -translate_y, 0.0)\n\n # Projection matrix based on the focal length, aperture and clipping planes of the camera\n focal_length = float(cameraNode\['focal'].getValueAt(frame))\n h_aperture = float(cameraNode\['haperture'].getValueAt(frame))\n near = float(cameraNode\['near'].getValueAt(frame))\n far = float(cameraNode\['far'].getValueAt(frame))\n projection_mode = int(cameraNode\['projection_mode'].getValueAt(frame))\n p = nuke.math.Matrix4()\n p.projection(focal_length / h_aperture, near, far, projection_mode == 0)\n\n # Matrix to translate the projected points into normalised pixel coords\n imageAspect = float(imageformat.height()) / float(imageformat.width())\n\n t = nuke.math.Matrix4()\n t.makeIdentity()\n t.translate( 1.0, 1.0 - (1.0 - imageAspect / float(imageformat.pixelAspect())), 0.0 )\n\n # Matrix to scale normalised pixel coords into actual pixel coords.\n x_scale = float(imageformat.width()) / 2.0\n y_scale = x_scale * imageformat.pixelAspect()\n s = nuke.math.Matrix4()\n s.makeIdentity()\n s.scale(x_scale, y_scale, 1.0)\n\n # The projection matrix transforms points into camera coords, modifies based\n # on the camera knob values, projects points into clip coords, translates the\n # clip coords so that they lie in the range 0,0 - 2,2 instead of -1,-1 - 1,1,\n # then scales the clip coords to proper pixel coords.\n return s * t * p * m * camTransform\n\n\n\ndef pointsToMatrix(frame, node, reference_frame=None):\n cpToMtx = nuke.math.Matrix4()\n cpFromMtx = nuke.math.Matrix4()\n\n # Get a list of Vector2 objects for each of the 'to' knobs and each of the 'from' knobs.\n ToVectors = \[nuke.math.Vector2(node\[f].getValueAt(frame, 0), node\[f].getValueAt(frame, 1)) for f in sorted(node.knobs().keys()) if f.startswith('op')]\n\n # Feed all 4 coordinates into the mapUnitSquareToQuad() function\n cpToMtx.mapUnitSquareToQuad(ToVectors\[0].x, ToVectors\[0].y, ToVectors\[1].x, ToVectors\[1].y, ToVectors\[2].x, ToVectors\[2].y, ToVectors\[3].x, ToVectors\[3].y)\n\n # If we have a reference frame, use the to vectors on that frame as our from matrix, otherwise use the image width and height\n if reference_frame:\n FromVectors = \[nuke.math.Vector2(node\[f].getValueAt(reference_frame, 0), node\[f].getValueAt(reference_frame, 1)) for f in sorted(node.knobs().keys()) if f.startswith('op')]\n cpFromMtx.mapUnitSquareToQuad(FromVectors\[0].x, FromVectors\[0].y, FromVectors\[1].x, FromVectors\[1].y, FromVectors\[2].x, FromVectors\[2].y, FromVectors\[3].x, FromVectors\[3].y)\n else:\n cpFromMtx.mapUnitSquareToQuad(0, 0, node.width(), 0, node.width(), node.height(), 0, node.height())\n\n transform_matrix = cpToMtx * cpFromMtx.inverse()\n\n # This is not needed to apply the transformation. The matrix is already correct.\n # However, the matrix knob in rotopaint is indexed differently (row major), so I just transpose the matrix here to make it easier to copy its values to the knob\n transform_matrix.transpose()\n\n # Fill in the transform_matrix knob of the target node\n return transform_matrix\n\n\n\ndef projectPoints(frame, camera=None, point=None, imageformat=None):\n # Modify projectpoint function in nukescripts.snap3d to add frame argument\n if not imageformat:\n imageformat = nuke.root()\['format'].value()\n camMatrix = cameraProjectionMatrix(camera, frame, imageformat)\n if camMatrix == None:\n raise RuntimeError, \"snap3d.cameraProjectionMatrix() returned None for camera.\"\n\n if not ( isinstance(point, list) or isinstance(point, tuple) ):\n raise ValueError, \"Argument point must be a list or tuple.\"\n\n for point in point:\n # Would be nice to not do this for every item but since lists/tuples can\n # containg anything...\n if isinstance(point, nuke.math.Vector3):\n pt = point\n elif isinstance(point, list) or isinstance(point, tuple):\n pt = nuke.math.Vector3(point\[0], point\[1], point\[2])\n else:\n raise ValueError, \"All items in point must be nuke.math.Vector3 or list/tuple of 3 floats.\"\n\n tPos = camMatrix * nuke.math.Vector4(pt.x, pt.y, pt.z, 1.0)\n #print tPos\n try:\n yield nuke.math.Vector2(tPos.x / tPos.w, tPos.y / tPos.w)\n except ZeroDivisionError:\n print \"Zero Division Error on frame \{0\} with point data \{1\}\".format(frame, point)\n yield nuke.math.Vector2()\n\n\ndef calculate(node):\n # Get the input Camera and verify it is right. (Assume camera is topnode of input to handle dots)\n cam_input = node.input(1)\n # Sanity check\n if not (cam_input and isinstance(cam_input, nuke.Node)):\n nuke.message(\"A Camera node must be connected.\")\n return\n if 'Camera' in cam_input.Class():\n cam = cam_input\n else:\n cam = nuke.toNode(nuke.tcl(\"full_name \[topnode %s]\" % cam_input.name()))\n bg = node.input(0)\n if not bg:\n nuke.message(\"BG not connected, so the root format will be used to reconcile the 3D points into screen space.\")\n\n # Get framerange to operate on from camera animation curves\n first = None\n last = None\n try:\n if cam\['translate'].isAnimated():\n for curve in cam\['translate'].animations():\n if first == None:\n first = int(curve.keys()\[0].x)\n else:\n first = min(first, int(curve.keys()\[0].x))\n for curve in cam\['translate'].animations():\n if last == None:\n last = int(curve.keys()\[-1].x)\n else:\n last = max(last, int(curve.keys()\[-1].x))\n elif cam\['rotate'].isAnimated():\n for curve in cam\['rotate'].animations():\n if first == None:\n first = int(curve.keys()\[0].x)\n else:\n first = min(first, int(curve.keys()\[0].x))\n for curve in cam\['rotate'].animations():\n if last == None:\n last = int(curve.keys()\[-1].x)\n else:\n last = max(last, int(curve.keys()\[-1].x))\n else:\n nuke.message(\"Input Camera is not animated.\")\n return\n except:\n nuke.message(\"Something went wrong getting the camera animation. Using Root framerange...\")\n first = nuke.root().firstFrame()\n last = nuke.root().lastFrame()\n\n\n framerange = nuke.FrameRange('\{0\}-\{1\}'.format(first, last))\n\n # Loop through the 3D points, reconcile the coordinates through the camera into screen space\n for opnum in xrange(4):\n # Only run if the ip knob is not default\n ipknob = node\[\"ip\{0\}\".format(opnum+1)]\n if not ipknob.notDefault():\n print \"Skipping \{0\} because it is still default!\".format('ip'+str(opnum+1))\n continue\n\n opknob = node\[\"op\{0\}\".format(opnum+1)]\n opknob.clearAnimated()\n opknob.setAnimated()\n\n # Building the data into a list of AnimationKey objects,\n # and then applying that list to the knob using addKey is significantly faster than other methods.\n # This makes the Calculate button instantaneous instead of taking forever.\n point_animcurve = \[\[], \[]]\n for frame in framerange:\n\n #print \"values are \", ipknob.getValueAt(frame)\n # Sample input point knob on every frame if it's animated or expression-linked\n if ipknob.isAnimated() or ipknob.hasExpression():\n point = projectPoints(frame, cam, \[ipknob.getValueAt(frame)], node.format()).next()\n else:\n point = projectPoints(frame, cam, \[ipknob.value()], node.format()).next()\n for index in xrange(2):\n point_animcurve\[index].append(nuke.AnimationKey(frame, point\[index]))\n\n for index, curve in enumerate(opknob.animations()):\n curve.addKey(point_animcurve\[index])\n\n # Calculate the transformation Matrix, if we have 4 output points\n for i in xrange(4):\n ipknob = node\[\"op\{0\}\".format(i+1)]\n #print 'op'+str(i+1)+' IS NOT DEFAULT'\n if not ipknob.notDefault():\n return\n mknob = node\['matrix']\n mknob.clearAnimated()\n mknob.setAnimated()\n\n use_reference_frame = True\n reference_frame = node\['identity_frame'].getValue()\n\n matrix_animcurve = \[\[] for i in xrange(16)]\n for frame in framerange:\n if use_reference_frame:\n matrix_data = pointsToMatrix(frame, node, reference_frame)\n else:\n matrix_data = pointsToMatrix(frame, node)\n for index in xrange(16):\n matrix_animcurve\[index].append(nuke.AnimationKey(frame, matrix_data\[index]))\n matrix_animcurve = \[\[] for i in xrange(16)]\n for frame in framerange:\n if use_reference_frame:\n matrix_data = pointsToMatrix(frame, node, reference_frame)\n else:\n matrix_data = pointsToMatrix(frame, node)\n for index in xrange(16):\n matrix_animcurve\[index].append(nuke.AnimationKey(frame, matrix_data\[index]))\n\n for index, item in enumerate(mknob.animations()):\n item.addKey(matrix_animcurve\[index])\n for index, item in enumerate(mknob.animations()):\n item.addKey(matrix_animcurve\[index])\n\nif __name__==\"__main__\":\n calculate(nuke.thisNode())" +STARTLINE}
addUserKnob {22 clear_out l Clear t "Clear output knobs." -STARTLINE T "n = nuke.thisNode()\n\nfor i in xrange(4):\n kop = n\['op'+str(i+1)]\n kop.clearAnimated()\n kop.setValue(kop.defaultValue())\n n\['matrix'].clearAnimated()\n n\['matrix'].setValue(\[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1])"}
addUserKnob {12 op1 l "point 1"}
addUserKnob {12 op2 l "point 2"}
addUserKnob {12 op3 l "point 3"}
addUserKnob {12 op4 l "point 4"}
addUserKnob {41 matrix t "Calculated matrix." T Matrix_original.matrix}
addUserKnob {26 identity_frame_label l " " T "\nIdentity Frame"}
addUserKnob {3 identity_frame l " " t "If a frame is specified here, the matrix calculated will be relative to this frame. On the reference frame the matrix will be a null transformation."}
identity_frame {1001}
addUserKnob {22 set_current l Current -STARTLINE T nuke.thisNode().knob('identity_frame').setValue(nuke.frame())}
addUserKnob {26 ""}
addUserKnob {26 link_tracking_label l " " T "<font size=4><b>Link Tracking Data to Nodes</b>"}
addUserKnob {20 link_tracking_help_grp l " help" n 1}
link_tracking_help_grp 0
addUserKnob {26 link_tracking_help l " " T "<font size=3>\n<b>Expression link</b> will keep a live expression to the data on this node, in case it is updated.\n<br/><b>Independent identity frame</b> will add extra knobs to the created node to allow you to \n<br/>specify an independent identity frame on the node. It's heavier!\n<br/>&nbsp;&nbsp;&nbsp;&nbsp;"}
addUserKnob {20 endGroup_2 l endGroup n -1}
addUserKnob {22 create_tracker3 l Tracker3 t "Create a Tracker3 class Tracker node, in case this is what you prefer to link roto shapes to." T "# Create tracker3 node\nfrom __future__ import with_statement\ngrid_x = int(nuke.toNode('preferences').knob('GridWidth').value())\ngrid_y = int(nuke.toNode('preferences').knob('GridHeight').value())\npproj = nuke.thisNode()\nwith nuke.root():\n track_node = nuke.nodes.Tracker3()\n track_node.setXYpos(pproj.xpos()-grid_x*0, pproj.ypos()+grid_y*2)\n _ = \[n.setSelected(False) for n in nuke.allNodes()]\n track_node.setSelected(True)\n enable_knobs = \['enable1', 'enable2', 'enable3', 'enable4']\n trs_knobs = \['use_for1', 'use_for2', 'use_for3', 'use_for4']\n track_knobs = \['track1', 'track2', 'track3', 'track4']\n\n for i, k in enumerate(enable_knobs):\n if pproj\['op\{0\}'.format(i+1)].isAnimated():\n track_node\[k].setValue(True)\n for i, k in enumerate(trs_knobs):\n if pproj\['op\{0\}'.format(i+1)].isAnimated():\n track_node\[k].setValue(7)\n for i, track in enumerate(track_knobs):\n if pproj\['op\{0\}'.format(i+1)].isAnimated():\n tknob = track_node\[track]\n tknob.clearAnimated()\n tknob.setAnimated()\n for x, c in enumerate(tknob.animations()):\n opknob = pproj\['op\{0\}'.format(track.split('track')\[-1])]\n if opknob.isAnimated():\n c.addKey(opknob.animation(x).keys())\n else:\n tknob.clearAnimated()\n # This hackiness is necessary so knob values work correctly\n track_node.setTab(2)\n track_node.showControlPanel()\n track_node\[trs_knobs\[0]].setValue(1)\n track_node\[trs_knobs\[0]].setValue(7)\n track_node.hideControlPanel()" +STARTLINE}
addUserKnob {22 create_tracker4 l Tracker4 t "Create Tracker4 class tracker node." -STARTLINE T "from __future__ import with_statement\n\n# http://community.foundry.com/discuss/topic/99665\n# https://www.mail-archive.com/nuke-python@support.thefoundry.co.uk/msg04697.html\n\ngrid_x = int(nuke.toNode('preferences').knob('GridWidth').value())\ngrid_y = int(nuke.toNode('preferences').knob('GridHeight').value())\nnode = nuke.thisNode()\nexpression_link = node\['expression_link'].getValue()\n# pros not worth the cons ... disabling expression linking Tracker4 nodes for now\nexpression_link = False\n\nif expression_link:\n nuke.message(\"Warning: If expression linking a Tracker4 node, it must be placed in the \\nimage stream in order to evaluate correctly.\")\n\nwith nuke.root():\n _ = \[n.setSelected(False) for n in nuke.allNodes()]\n track_node = nuke.createNode('Tracker4')\n track_node.setXYpos(node.xpos()-grid_x*0, node.ypos()+grid_y*2)\n _ = \[n.setSelected(False) for n in nuke.allNodes()]\n track_node.setSelected(True)\n\n # First line 3rd number is length of tracks: explicitly setting it to 4 here.\n tracks_fromscript = \"\{ 1 31 4 \} \\n\{ \{ 5 1 20 enable e 1 \} \\n\{ 3 1 75 name name 1 \} \\n\{ 2 1 58 track_x track_x 1 \} \\n\{ 2 1 58 track_y track_y 1 \} \\n\{ 2 1 63 offset_x offset_x 1 \} \\n\{ 2 1 63 offset_y offset_y 1 \} \\n\{ 4 1 27 T T 1 \} \\n\{ 4 1 27 R R 1 \} \\n\{ 4 1 27 S S 1 \} \\n\{ 2 0 45 error error 1 \} \\n\{ 1 1 0 error_min error_min 1 \} \\n\{ 1 1 0 error_max error_max 1 \} \\n\{ 1 1 0 pattern_x pattern_x 1 \} \\n\{ 1 1 0 pattern_y pattern_y 1 \} \\n\{ 1 1 0 pattern_r pattern_r 1 \} \\n\{ 1 1 0 pattern_t pattern_t 1 \} \\n\{ 1 1 0 search_x search_x 1 \} \\n\{ 1 1 0 search_y search_y 1 \} \\n\{ 1 1 0 search_r search_r 1 \} \\n\{ 1 1 0 search_t search_t 1 \} \\n\{ 2 1 0 key_track key_track 1 \} \\n\{ 2 1 0 key_search_x key_search_x 1 \} \\n\{ 2 1 0 key_search_y key_search_y 1 \} \\n\{ 2 1 0 key_search_r key_search_r 1 \} \\n\{ 2 1 0 key_search_t key_search_t 1 \} \\n\{ 2 1 0 key_track_x key_track_x 1 \} \\n\{ 2 1 0 key_track_y key_track_y 1 \} \\n\{ 2 1 0 key_track_r key_track_r 1 \} \\n\{ 2 1 0 key_track_t key_track_t 1 \} \\n\{ 2 1 0 key_centre_offset_x key_centre_offset_x 1 \} \\n\{ 2 1 0 key_centre_offset_y key_centre_offset_y 1 \} \\n\} \"\n default_track_end_script = \" \{0\} \{0\} 1 1 1 \{0\} 1 0 -32 -32 32 32 -22 -22 22 22 \{0\} \{0\} \{0\} \{0\} \{0\} \{0\} \{0\} \{0\} \{0\} \{0\} \{0\} \}\\n\"\n\n # Loop through each 2d track knob and add it's animation to the Tracker4 node.\n track_knobs = \['op1', 'op2', 'op3', 'op4']\n all_trackdata = \[]\n for i, knobname in enumerate(track_knobs):\n opknob = node\[knobname]\n if opknob.isAnimated():\n trackdata = \[]\n # Gather animation data from opknobs\n for i, curve in enumerate(opknob.animations()):\n if expression_link:\n if i == 0:\n dimension = 'x'\n elif i == 1:\n dimension = 'y'\n trackdata_string = \" \{\{\{0\}\}\}\".format(\"parent.\{0\}.\{1\}.\{2\}\".format(node.fullName(), knobname, dimension))\n trackdata.append(trackdata_string)\n # livelink_transform must be true in order for expression links to work correctly on a tracker node\n track_node\['livelink_transform'].setValue(True)\n else:\n trackdata_string = \" \{ curve\"\n for key in curve.keys():\n trackdata_string += \" x\{0\} \{1\}\".format(int(key.x), key.y)\n trackdata_string += \"\}\"\n trackdata.append(trackdata_string)\n all_trackdata.append(trackdata)\n\n else:\n i -= 1\n continue\n # Append data to fromscript\n tracks_fromscript += \"\\n\{\\n\"\n for i, curve in enumerate(all_trackdata):\n tracks_fromscript += \" \{ \{1\} \"\n tracks_fromscript += \"\\\"track_\{0\}\\\"\".format(i)\n for dim in curve:\n tracks_fromscript += \"\{0\}\".format(dim)\n tracks_fromscript += default_track_end_script\n tracks_fromscript += \"\\n\}\"\n tracks_knob = track_node\['tracks']\n tracks_knob.fromScript(tracks_fromscript)\n # Force update of Translate / Rotate / Scale\n track_node.showControlPanel()\n track_node.setTab(0)\n tracks_knob.setValue(0, 6)\n tracks_knob.setValue(1, 6)\n track_node.hideControlPanel()\n track_node\['keyframe_display'].setValue(3)"}
addUserKnob {6 expression_link l "expression link" t "If enabled, expression links will be created instead of copying the animation curves" +STARTLINE}
expression_link true
addUserKnob {6 independent_identity_frame l "independent identity frame" t "Add an independent identity frame to the output node. (More expressions! Use with caution.)" -STARTLINE}
addUserKnob {22 create_rotopaint l "Roto / Add Layer" t "Create a roto node with a layer that has the matrix transform in it to use for tracking. \n\nWorks with any number of Existing Roto / RotoPaint / SplineWarp nodes as well if they are selected." T "## Create Rotopaint\nimport nuke\nimport nuke.rotopaint as rp\nimport _curvelib as cl\n\ngrid_x = int(nuke.toNode('preferences').knob('GridWidth').value())\ngrid_y = int(nuke.toNode('preferences').knob('GridHeight').value())\nnode = nuke.thisNode()\nmatrix = node\['matrix']\nnuke.root().begin()\nidentity_frame = int(node\['identity_frame'].getValue())\nexpression_link = node\['expression_link'].getValue()\nindependent_identity_frame = node\['independent_identity_frame'].getValue()\n\nfirst = None\nfor every in matrix.animations():\n if first == None:\n first = int(every.keys()\[0].x)\n else:\n first = min(first, int(every.keys()\[0].x))\n\nlast = None\nfor every in matrix.animations():\n if last == None:\n last = int(every.keys()\[0].x)\n else:\n last = max(last, int(every.keys()\[-1].x))\n\n\nif first != None and last != None:\n if matrix.isAnimated():\n # Get all selected roto nodes\n selected_roto_nodes = \[n for n in nuke.selectedNodes() if n.Class() in \[\"Roto\", \"RotoPaint\", \"SplineWarp3\"]]\n if not selected_roto_nodes:\n _ = \[n.setSelected(False) for n in nuke.allNodes()]\n roto_node = nuke.createNode(\"Roto\", inpanel=False)\n roto_node.setXYpos(node.xpos()-grid_x*0, node.ypos()+grid_y*2)\n roto_node.setSelected(True)\n selected_roto_nodes = \[roto_node]\n\n for roto_node in selected_roto_nodes:\n\n curve_knob = roto_node\['curves']\n roto_layer = rp.Layer(curve_knob)\n roto_layer.name = node.name()\n\n curve = \[cl.AnimCurve() for i in range(16)]\n\n # Add independent identity frame calculation onto the target node.\n if expression_link and independent_identity_frame:\n # Add identity frame knob\n roto_node.addKnob(nuke.Tab_Knob('Identity Frame'))\n roto_node.addKnob(nuke.Int_Knob('identity_frame', 'identity frame'))\n roto_node\['identity_frame'].setValue(int(node\['identity_frame'].getValue()))\n roto_node.addKnob(nuke.PyScript_Knob('identity_to_curframe', 'Current'))\n roto_node.knob('identity_to_curframe').setTooltip(\"Set identity frame to current frame.\")\n roto_node.knob('identity_to_curframe').setCommand(\"nuke.thisNode().knob('identity_frame').setValue(nuke.frame())\")\n roto_node.setTab(1)\n\n roto_node.addKnob(nuke.Double_Knob('determinant', 'determinant'))\n determinant = \"parent.\{0\}.matrix.3(identity_frame) * parent.\{0\}.matrix.6(identity_frame) * parent.\{0\}.matrix.9(identity_frame) * parent.\{0\}.matrix.12(identity_frame)- parent.\{0\}.matrix.2(identity_frame) * parent.\{0\}.matrix.7(identity_frame) * parent.\{0\}.matrix.9(identity_frame) * parent.\{0\}.matrix.12(identity_frame)- parent.\{0\}.matrix.3(identity_frame) * parent.\{0\}.matrix.5(identity_frame) * parent.\{0\}.matrix.10(identity_frame) * parent.\{0\}.matrix.12(identity_frame)+ parent.\{0\}.matrix.1(identity_frame) * parent.\{0\}.matrix.7(identity_frame) * parent.\{0\}.matrix.10(identity_frame) * parent.\{0\}.matrix.12(identity_frame)+ parent.\{0\}.matrix.2(identity_frame) * parent.\{0\}.matrix.5(identity_frame) * parent.\{0\}.matrix.11(identity_frame) * parent.\{0\}.matrix.12(identity_frame)- parent.\{0\}.matrix.1(identity_frame) * parent.\{0\}.matrix.6(identity_frame) * parent.\{0\}.matrix.11(identity_frame) * parent.\{0\}.matrix.12(identity_frame)- parent.\{0\}.matrix.3(identity_frame) * parent.\{0\}.matrix.6(identity_frame) * parent.\{0\}.matrix.8(identity_frame) * parent.\{0\}.matrix.13(identity_frame)+ parent.\{0\}.matrix.2(identity_frame) * parent.\{0\}.matrix.7(identity_frame) * parent.\{0\}.matrix.8(identity_frame) * parent.\{0\}.matrix.13(identity_frame)+ parent.\{0\}.matrix.3(identity_frame) * parent.\{0\}.matrix.4(identity_frame) * parent.\{0\}.matrix.10(identity_frame) * parent.\{0\}.matrix.13(identity_frame)- parent.\{0\}.matrix.0(identity_frame) * parent.\{0\}.matrix.7(identity_frame) * parent.\{0\}.matrix.10(identity_frame) * parent.\{0\}.matrix.13(identity_frame)- parent.\{0\}.matrix.2(identity_frame) * parent.\{0\}.matrix.4(identity_frame) * parent.\{0\}.matrix.11(identity_frame) * parent.\{0\}.matrix.13(identity_frame)+ parent.\{0\}.matrix.0(identity_frame) * parent.\{0\}.matrix.6(identity_frame) * parent.\{0\}.matrix.11(identity_frame) * parent.\{0\}.matrix.13(identity_frame)+ parent.\{0\}.matrix.3(identity_frame) * parent.\{0\}.matrix.5(identity_frame) * parent.\{0\}.matrix.8(identity_frame) * parent.\{0\}.matrix.14(identity_frame)- parent.\{0\}.matrix.1(identity_frame) * parent.\{0\}.matrix.7(identity_frame) * parent.\{0\}.matrix.8(identity_frame) * parent.\{0\}.matrix.14(identity_frame)- parent.\{0\}.matrix.3(identity_frame) * parent.\{0\}.matrix.4(identity_frame) * parent.\{0\}.matrix.9(identity_frame) * parent.\{0\}.matrix.14(identity_frame)+ parent.\{0\}.matrix.0(identity_frame) * parent.\{0\}.matrix.7(identity_frame) * parent.\{0\}.matrix.9(identity_frame) * parent.\{0\}.matrix.14(identity_frame)+ parent.\{0\}.matrix.1(identity_frame) * parent.\{0\}.matrix.4(identity_frame) * parent.\{0\}.matrix.11(identity_frame) * parent.\{0\}.matrix.14(identity_frame)- parent.\{0\}.matrix.0(identity_frame) * parent.\{0\}.matrix.5(identity_frame) * parent.\{0\}.matrix.11(identity_frame) * parent.\{0\}.matrix.14(identity_frame)- parent.\{0\}.matrix.2(identity_frame) * parent.\{0\}.matrix.5(identity_frame) * parent.\{0\}.matrix.8(identity_frame) * parent.\{0\}.matrix.15(identity_frame)+ parent.\{0\}.matrix.1(identity_frame) * parent.\{0\}.matrix.6(identity_frame) * parent.\{0\}.matrix.8(identity_frame) * parent.\{0\}.matrix.15(identity_frame)+ parent.\{0\}.matrix.2(identity_frame) * parent.\{0\}.matrix.4(identity_frame) * parent.\{0\}.matrix.9(identity_frame) * parent.\{0\}.matrix.15(identity_frame)- parent.\{0\}.matrix.0(identity_frame) * parent.\{0\}.matrix.6(identity_frame) * parent.\{0\}.matrix.9(identity_frame) * parent.\{0\}.matrix.15(identity_frame)- parent.\{0\}.matrix.1(identity_frame) * parent.\{0\}.matrix.4(identity_frame) * parent.\{0\}.matrix.10(identity_frame) * parent.\{0\}.matrix.15(identity_frame)+ parent.\{0\}.matrix.0(identity_frame) * parent.\{0\}.matrix.5(identity_frame) * parent.\{0\}.matrix.10(identity_frame) * parent.\{0\}.matrix.15(identity_frame)\".format(node.fullName())\n roto_node\['determinant'].setExpression(determinant)\n for i in xrange(4):\n roto_node.addKnob(nuke.BBox_Knob(\"invmatrix\{0\}\".format(i)))\n # view-source:https://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n roto_node\['invmatrix0'].setExpression(\"(parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.13(identity_frame) + parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.14(identity_frame) - parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.14(identity_frame) - parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.15(identity_frame) + parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 0)\n roto_node\['invmatrix0'].setExpression(\"(parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.14(identity_frame) + parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.14(identity_frame) + parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.15(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 1)\n roto_node\['invmatrix0'].setExpression(\"(parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.13(identity_frame) + parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.14(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.14(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.15(identity_frame) + parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 2)\n roto_node\['invmatrix0'].setExpression(\"(parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.9(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.9(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.10(identity_frame) + parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.10(identity_frame) + parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.11(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.11(identity_frame))/determinant\".format(node.fullName()), 3)\n roto_node\['invmatrix1'].setExpression(\"(parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.14(identity_frame) + parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.14(identity_frame) + parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.15(identity_frame) - parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 0)\n roto_node\['invmatrix1'].setExpression(\"(parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.12(identity_frame) + parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.14(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.14(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.15(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 1)\n roto_node\['invmatrix1'].setExpression(\"(parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.14(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.14(identity_frame) + parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.15(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 2)\n roto_node\['invmatrix1'].setExpression(\"(parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.8(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.8(identity_frame) + parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.10(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.10(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.11(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.11(identity_frame))/determinant\".format(node.fullName()), 3)\n roto_node\['invmatrix2'].setExpression(\"(parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.12(identity_frame) + parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.15(identity_frame) + parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 0)\n roto_node\['invmatrix2'].setExpression(\"(parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.13(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.13(identity_frame) + parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.15(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 1)\n roto_node\['invmatrix2'].setExpression(\"(parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.12(identity_frame) + parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.15(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 2)\n roto_node\['invmatrix2'].setExpression(\"(parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.8(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.8(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.9(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.9(identity_frame) + parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.11(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.11(identity_frame))/determinant\".format(node.fullName()), 3)\n roto_node\['invmatrix3'].setExpression(\"(parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.13(identity_frame) + parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.13(identity_frame) + parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.14(identity_frame) - parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.14(identity_frame))/determinant\".format(node.fullName()), 0)\n roto_node\['invmatrix3'].setExpression(\"(parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.12(identity_frame) + parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.14(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.14(identity_frame))/determinant\".format(node.fullName()), 1)\n roto_node\['invmatrix3'].setExpression(\"(parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.13(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.13(identity_frame) + parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.14(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.14(identity_frame))/determinant\".format(node.fullName()), 2)\n roto_node\['invmatrix3'].setExpression(\"(parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.8(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.8(identity_frame) + parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.9(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.9(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.10(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.10(identity_frame))/determinant\".format(node.fullName()), 3)\n\n # view-source:https://www.euclideanspace.com/maths/algebra/matrix/arithmetic/fourD/index.htm\n curve\[0].expressionString = \"parent.\{0\}.matrix.0*invmatrix0.0 + parent.\{0\}.matrix.1*invmatrix1.0 + parent.\{0\}.matrix.2*invmatrix2.0 + parent.\{0\}.matrix.3*invmatrix3.0\".format(node.fullName())\n curve\[1].expressionString = \"parent.\{0\}.matrix.0*invmatrix0.1 + parent.\{0\}.matrix.1*invmatrix1.1 + parent.\{0\}.matrix.2*invmatrix2.1 + parent.\{0\}.matrix.3*invmatrix3.1\".format(node.fullName())\n curve\[2].expressionString = \"parent.\{0\}.matrix.0*invmatrix0.2 + parent.\{0\}.matrix.1*invmatrix1.2 + parent.\{0\}.matrix.2*invmatrix2.2 + parent.\{0\}.matrix.3*invmatrix3.2\".format(node.fullName())\n curve\[3].expressionString = \"parent.\{0\}.matrix.0*invmatrix0.3 + parent.\{0\}.matrix.1*invmatrix1.3 + parent.\{0\}.matrix.2*invmatrix2.3 + parent.\{0\}.matrix.3*invmatrix3.3\".format(node.fullName())\n\n curve\[4].expressionString = \"parent.\{0\}.matrix.4*invmatrix0.0 + parent.\{0\}.matrix.5*invmatrix1.0 + parent.\{0\}.matrix.6*invmatrix2.0 + parent.\{0\}.matrix.7*invmatrix3.0\".format(node.fullName())\n curve\[5].expressionString = \"parent.\{0\}.matrix.4*invmatrix0.1 + parent.\{0\}.matrix.5*invmatrix1.1 + parent.\{0\}.matrix.6*invmatrix2.1 + parent.\{0\}.matrix.7*invmatrix3.1\".format(node.fullName())\n curve\[6].expressionString = \"parent.\{0\}.matrix.4*invmatrix0.2 + parent.\{0\}.matrix.5*invmatrix1.2 + parent.\{0\}.matrix.6*invmatrix2.2 + parent.\{0\}.matrix.7*invmatrix3.2\".format(node.fullName())\n curve\[7].expressionString = \"parent.\{0\}.matrix.4*invmatrix0.3 + parent.\{0\}.matrix.5*invmatrix1.3 + parent.\{0\}.matrix.6*invmatrix2.3 + parent.\{0\}.matrix.7*invmatrix3.3\".format(node.fullName())\n\n curve\[8].expressionString = \"parent.\{0\}.matrix.8*invmatrix0.0 + parent.\{0\}.matrix.9*invmatrix1.0 + parent.\{0\}.matrix.10*invmatrix2.0 + parent.\{0\}.matrix.11*invmatrix3.0\".format(node.fullName())\n curve\[9].expressionString = \"parent.\{0\}.matrix.8*invmatrix0.1 + parent.\{0\}.matrix.9*invmatrix1.1 + parent.\{0\}.matrix.10*invmatrix2.1 + parent.\{0\}.matrix.11*invmatrix3.1\".format(node.fullName())\n curve\[10].expressionString = \"parent.\{0\}.matrix.8*invmatrix0.2 + parent.\{0\}.matrix.9*invmatrix1.2 + parent.\{0\}.matrix.10*invmatrix2.2 + parent.\{0\}.matrix.11*invmatrix3.2\".format(node.fullName())\n curve\[11].expressionString = \"parent.\{0\}.matrix.8*invmatrix0.3 + parent.\{0\}.matrix.9*invmatrix1.3 + parent.\{0\}.matrix.10*invmatrix2.3 + parent.\{0\}.matrix.11*invmatrix3.3\".format(node.fullName())\n\n curve\[12].expressionString = \"parent.\{0\}.matrix.12*invmatrix0.0 + parent.\{0\}.matrix.13*invmatrix1.0 + parent.\{0\}.matrix.14*invmatrix2.0 + parent.\{0\}.matrix.15*invmatrix3.0\".format(node.fullName())\n curve\[13].expressionString = \"parent.\{0\}.matrix.12*invmatrix0.1 + parent.\{0\}.matrix.13*invmatrix1.1 + parent.\{0\}.matrix.14*invmatrix2.1 + parent.\{0\}.matrix.15*invmatrix3.1\".format(node.fullName())\n curve\[14].expressionString = \"parent.\{0\}.matrix.12*invmatrix0.2 + parent.\{0\}.matrix.13*invmatrix1.2 + parent.\{0\}.matrix.14*invmatrix2.2 + parent.\{0\}.matrix.15*invmatrix3.2\".format(node.fullName())\n curve\[15].expressionString = \"parent.\{0\}.matrix.12*invmatrix0.3 + parent.\{0\}.matrix.13*invmatrix1.3 + parent.\{0\}.matrix.14*invmatrix2.3 + parent.\{0\}.matrix.15*invmatrix3.3\".format(node.fullName())\n\n for i in range(16):\n curve\[i].useExpression = True\n roto_node\['label'].setValue('\{0\}: x\[value identity_frame]'.format(node.name()))\n\n elif expression_link and not independent_identity_frame:\n # Just expression link\n for f in range(first,last+1):\n for i in range(16):\n if node\['expression_link'].getValue():\n curve\[i].expressionString = \"parent.\{0\}.matrix.\{1\}\".format(node.fullName(), i)\n curve\[i].useExpression = True\n else:\n curve\[i].addKey(int(f), matrix.valueAt(f)\[i])\n roto_node\['label'].setValue('\{0\}: x\{1\}'.format(node.name(), identity_frame))\n else:\n # Copy the animation curves as is\n for f in range(first, last+1):\n for i in range(16):\n curve\[i].addKey(int(f), node\['matrix'].getValueAt(f, i))\n roto_node\['label'].setValue('\{0\}: x\{1\}'.format(node.name(), identity_frame))\n\n for y in range(1,5):\n for x in range(1,5):\n cell = ((y-1)*4)+x-1\n roto_layer.getTransform().setExtraMatrixAnimCurve(y-1,x-1, curve\[cell])\n curve_knob.rootLayer.append(roto_layer)\n roto_node.setTab(1)" +STARTLINE}
addUserKnob {22 create_cornerpin l CornerPin t "Create a cornerpin node, using the specified identity frame, if enabled. \n\nIf you need a CornerPin stabilizing, click the invert checkbox." -STARTLINE T "## Create Cornerpin\ngrid_x = int(nuke.toNode('preferences').knob('GridWidth').value())\ngrid_y = int(nuke.toNode('preferences').knob('GridHeight').value())\n\nnode = nuke.thisNode()\nnuke.root().begin()\n\n_ = \[n.setSelected(False) for n in nuke.allNodes()]\ncornerpin = nuke.createNode(\"CornerPin2D\", inpanel=False)\ncornerpin.setXYpos(node.xpos()-grid_x*0, node.ypos()+grid_y*2)\ncornerpin.setSelected(True)\ncornerpin.addKnob(nuke.Tab_Knob('Identity Frame'))\ncornerpin.addKnob(nuke.Int_Knob('identity_frame', 'identity frame'))\nreference_frame = int(node\['identity_frame'].getValue())\ncornerpin\['identity_frame'].setValue(int(node\['identity_frame'].getValue()))\ncornerpin\['label'].setValue(\"PlanarProjection : ref x\{0\}\".format('\[value identity_frame]'))\n\nfor i in xrange(1, 5):\n if node\['expression_link'].getValue():\n cornerpin\['to\{0\}'.format(i)].setExpression(\"parent.\{0\}.op\{1\}\".format(node.fullName(), i))\n else:\n cornerpin\['to\{0\}'.format(i)].copyAnimations(node\['op\{0\}'.format(i)].animations())\n cornerpin\['from\{0\}'.format(i)].setExpression('to\{0\}(identity_frame)'.format(i))\ncornerpin.setTab(1)"}
addUserKnob {22 create_cornerpin_matrix l "CornerPin Matrix" t "Create a Cornerpin with the animation in the extra matrix knob instead of the to/from knobs." -STARTLINE T "## Create Cornerpin with tracking data in matrix\ngrid_x = int(nuke.toNode('preferences').knob('GridWidth').value())\ngrid_y = int(nuke.toNode('preferences').knob('GridHeight').value())\n\nnode = nuke.thisNode()\nnuke.root().begin()\n\n_ = \[n.setSelected(False) for n in nuke.allNodes()]\ncornerpin = nuke.createNode(\"CornerPin2D\", inpanel=False)\ncornerpin.setXYpos(node.xpos()-grid_x*0, node.ypos()+grid_y*2)\ncornerpin.setSelected(True)\n\n\nreference_frame = int(node\['identity_frame'].getValue())\nexpression_link = node\['expression_link'].getValue()\nindependent_identity_frame = node\['independent_identity_frame'].getValue()\ncpmatrix = cornerpin\['transform_matrix']\n\nif expression_link and independent_identity_frame:\n # Add identity frame knob\n cornerpin.addKnob(nuke.Tab_Knob('Identity Frame'))\n cornerpin.addKnob(nuke.Int_Knob('identity_frame', 'identity frame'))\n cornerpin\['identity_frame'].setValue(int(node\['identity_frame'].getValue()))\n cornerpin.addKnob(nuke.PyScript_Knob('identity_to_curframe', 'Current'))\n cornerpin.knob('identity_to_curframe').setTooltip(\"Set identity frame to current frame.\")\n cornerpin.knob('identity_to_curframe').setCommand(\"nuke.thisNode().knob('identity_frame').setValue(nuke.frame())\")\n cornerpin.setTab(1)\n\n cornerpin.addKnob(nuke.Double_Knob('determinant', 'determinant'))\n determinant = \"parent.\{0\}.matrix.3(identity_frame) * parent.\{0\}.matrix.6(identity_frame) * parent.\{0\}.matrix.9(identity_frame) * parent.\{0\}.matrix.12(identity_frame)- parent.\{0\}.matrix.2(identity_frame) * parent.\{0\}.matrix.7(identity_frame) * parent.\{0\}.matrix.9(identity_frame) * parent.\{0\}.matrix.12(identity_frame)- parent.\{0\}.matrix.3(identity_frame) * parent.\{0\}.matrix.5(identity_frame) * parent.\{0\}.matrix.10(identity_frame) * parent.\{0\}.matrix.12(identity_frame)+ parent.\{0\}.matrix.1(identity_frame) * parent.\{0\}.matrix.7(identity_frame) * parent.\{0\}.matrix.10(identity_frame) * parent.\{0\}.matrix.12(identity_frame)+ parent.\{0\}.matrix.2(identity_frame) * parent.\{0\}.matrix.5(identity_frame) * parent.\{0\}.matrix.11(identity_frame) * parent.\{0\}.matrix.12(identity_frame)- parent.\{0\}.matrix.1(identity_frame) * parent.\{0\}.matrix.6(identity_frame) * parent.\{0\}.matrix.11(identity_frame) * parent.\{0\}.matrix.12(identity_frame)- parent.\{0\}.matrix.3(identity_frame) * parent.\{0\}.matrix.6(identity_frame) * parent.\{0\}.matrix.8(identity_frame) * parent.\{0\}.matrix.13(identity_frame)+ parent.\{0\}.matrix.2(identity_frame) * parent.\{0\}.matrix.7(identity_frame) * parent.\{0\}.matrix.8(identity_frame) * parent.\{0\}.matrix.13(identity_frame)+ parent.\{0\}.matrix.3(identity_frame) * parent.\{0\}.matrix.4(identity_frame) * parent.\{0\}.matrix.10(identity_frame) * parent.\{0\}.matrix.13(identity_frame)- parent.\{0\}.matrix.0(identity_frame) * parent.\{0\}.matrix.7(identity_frame) * parent.\{0\}.matrix.10(identity_frame) * parent.\{0\}.matrix.13(identity_frame)- parent.\{0\}.matrix.2(identity_frame) * parent.\{0\}.matrix.4(identity_frame) * parent.\{0\}.matrix.11(identity_frame) * parent.\{0\}.matrix.13(identity_frame)+ parent.\{0\}.matrix.0(identity_frame) * parent.\{0\}.matrix.6(identity_frame) * parent.\{0\}.matrix.11(identity_frame) * parent.\{0\}.matrix.13(identity_frame)+ parent.\{0\}.matrix.3(identity_frame) * parent.\{0\}.matrix.5(identity_frame) * parent.\{0\}.matrix.8(identity_frame) * parent.\{0\}.matrix.14(identity_frame)- parent.\{0\}.matrix.1(identity_frame) * parent.\{0\}.matrix.7(identity_frame) * parent.\{0\}.matrix.8(identity_frame) * parent.\{0\}.matrix.14(identity_frame)- parent.\{0\}.matrix.3(identity_frame) * parent.\{0\}.matrix.4(identity_frame) * parent.\{0\}.matrix.9(identity_frame) * parent.\{0\}.matrix.14(identity_frame)+ parent.\{0\}.matrix.0(identity_frame) * parent.\{0\}.matrix.7(identity_frame) * parent.\{0\}.matrix.9(identity_frame) * parent.\{0\}.matrix.14(identity_frame)+ parent.\{0\}.matrix.1(identity_frame) * parent.\{0\}.matrix.4(identity_frame) * parent.\{0\}.matrix.11(identity_frame) * parent.\{0\}.matrix.14(identity_frame)- parent.\{0\}.matrix.0(identity_frame) * parent.\{0\}.matrix.5(identity_frame) * parent.\{0\}.matrix.11(identity_frame) * parent.\{0\}.matrix.14(identity_frame)- parent.\{0\}.matrix.2(identity_frame) * parent.\{0\}.matrix.5(identity_frame) * parent.\{0\}.matrix.8(identity_frame) * parent.\{0\}.matrix.15(identity_frame)+ parent.\{0\}.matrix.1(identity_frame) * parent.\{0\}.matrix.6(identity_frame) * parent.\{0\}.matrix.8(identity_frame) * parent.\{0\}.matrix.15(identity_frame)+ parent.\{0\}.matrix.2(identity_frame) * parent.\{0\}.matrix.4(identity_frame) * parent.\{0\}.matrix.9(identity_frame) * parent.\{0\}.matrix.15(identity_frame)- parent.\{0\}.matrix.0(identity_frame) * parent.\{0\}.matrix.6(identity_frame) * parent.\{0\}.matrix.9(identity_frame) * parent.\{0\}.matrix.15(identity_frame)- parent.\{0\}.matrix.1(identity_frame) * parent.\{0\}.matrix.4(identity_frame) * parent.\{0\}.matrix.10(identity_frame) * parent.\{0\}.matrix.15(identity_frame)+ parent.\{0\}.matrix.0(identity_frame) * parent.\{0\}.matrix.5(identity_frame) * parent.\{0\}.matrix.10(identity_frame) * parent.\{0\}.matrix.15(identity_frame)\".format(node.fullName())\n cornerpin\['determinant'].setExpression(determinant)\n for i in xrange(4):\n cornerpin.addKnob(nuke.BBox_Knob(\"invmatrix\{0\}\".format(i)))\n # view-source:https://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm\n cornerpin\['invmatrix0'].setExpression(\"(parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.13(identity_frame) + parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.14(identity_frame) - parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.14(identity_frame) - parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.15(identity_frame) + parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 0)\n cornerpin\['invmatrix0'].setExpression(\"(parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.14(identity_frame) + parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.14(identity_frame) + parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.15(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 1)\n cornerpin\['invmatrix0'].setExpression(\"(parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.13(identity_frame) + parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.14(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.14(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.15(identity_frame) + parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 2)\n cornerpin\['invmatrix0'].setExpression(\"(parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.9(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.9(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.10(identity_frame) + parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.10(identity_frame) + parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.11(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.11(identity_frame))/determinant\".format(node.fullName()), 3)\n cornerpin\['invmatrix1'].setExpression(\"(parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.14(identity_frame) + parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.14(identity_frame) + parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.15(identity_frame) - parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 0)\n cornerpin\['invmatrix1'].setExpression(\"(parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.12(identity_frame) + parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.14(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.14(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.15(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 1)\n cornerpin\['invmatrix1'].setExpression(\"(parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.14(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.14(identity_frame) + parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.15(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 2)\n cornerpin\['invmatrix1'].setExpression(\"(parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.8(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.8(identity_frame) + parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.10(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.10(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.11(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.11(identity_frame))/determinant\".format(node.fullName()), 3)\n cornerpin\['invmatrix2'].setExpression(\"(parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.12(identity_frame) + parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.15(identity_frame) + parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 0)\n cornerpin\['invmatrix2'].setExpression(\"(parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.13(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.11(identity_frame)*parent.\{0\}.matrix.13(identity_frame) + parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.15(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 1)\n cornerpin\['invmatrix2'].setExpression(\"(parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.12(identity_frame) + parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.15(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.15(identity_frame))/determinant\".format(node.fullName()), 2)\n cornerpin\['invmatrix2'].setExpression(\"(parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.8(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.8(identity_frame) - parent.\{0\}.matrix.3(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.9(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.7(identity_frame)*parent.\{0\}.matrix.9(identity_frame) + parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.11(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.11(identity_frame))/determinant\".format(node.fullName()), 3)\n cornerpin\['invmatrix3'].setExpression(\"(parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.13(identity_frame) + parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.13(identity_frame) + parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.14(identity_frame) - parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.14(identity_frame))/determinant\".format(node.fullName()), 0)\n cornerpin\['invmatrix3'].setExpression(\"(parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.12(identity_frame) + parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.10(identity_frame)*parent.\{0\}.matrix.13(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.8(identity_frame)*parent.\{0\}.matrix.14(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.9(identity_frame)*parent.\{0\}.matrix.14(identity_frame))/determinant\".format(node.fullName()), 1)\n cornerpin\['invmatrix3'].setExpression(\"(parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.12(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.13(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.13(identity_frame) + parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.14(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.14(identity_frame))/determinant\".format(node.fullName()), 2)\n cornerpin\['invmatrix3'].setExpression(\"(parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.8(identity_frame) - parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.8(identity_frame) + parent.\{0\}.matrix.2(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.9(identity_frame) - parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.6(identity_frame)*parent.\{0\}.matrix.9(identity_frame) - parent.\{0\}.matrix.1(identity_frame)*parent.\{0\}.matrix.4(identity_frame)*parent.\{0\}.matrix.10(identity_frame) + parent.\{0\}.matrix.0(identity_frame)*parent.\{0\}.matrix.5(identity_frame)*parent.\{0\}.matrix.10(identity_frame))/determinant\".format(node.fullName()), 3)\n\n # view-source:https://www.euclideanspace.com/maths/algebra/matrix/arithmetic/fourD/index.htm\n cpmatrix.setExpression(\"parent.\{0\}.matrix.0*invmatrix0.0 + parent.\{0\}.matrix.1*invmatrix1.0 + parent.\{0\}.matrix.2*invmatrix2.0 + parent.\{0\}.matrix.3*invmatrix3.0\".format(node.fullName()), 0)\n cpmatrix.setExpression(\"parent.\{0\}.matrix.0*invmatrix0.1 + parent.\{0\}.matrix.1*invmatrix1.1 + parent.\{0\}.matrix.2*invmatrix2.1 + parent.\{0\}.matrix.3*invmatrix3.1\".format(node.fullName()), 1)\n cpmatrix.setExpression(\"parent.\{0\}.matrix.0*invmatrix0.2 + parent.\{0\}.matrix.1*invmatrix1.2 + parent.\{0\}.matrix.2*invmatrix2.2 + parent.\{0\}.matrix.3*invmatrix3.2\".format(node.fullName()), 2)\n cpmatrix.setExpression(\"parent.\{0\}.matrix.0*invmatrix0.3 + parent.\{0\}.matrix.1*invmatrix1.3 + parent.\{0\}.matrix.2*invmatrix2.3 + parent.\{0\}.matrix.3*invmatrix3.3\".format(node.fullName()), 3)\n cpmatrix.setExpression(\"parent.\{0\}.matrix.4*invmatrix0.0 + parent.\{0\}.matrix.5*invmatrix1.0 + parent.\{0\}.matrix.6*invmatrix2.0 + parent.\{0\}.matrix.7*invmatrix3.0\".format(node.fullName()), 4)\n cpmatrix.setExpression(\"parent.\{0\}.matrix.4*invmatrix0.1 + parent.\{0\}.matrix.5*invmatrix1.1 + parent.\{0\}.matrix.6*invmatrix2.1 + parent.\{0\}.matrix.7*invmatrix3.1\".format(node.fullName()), 5)\n cpmatrix.setExpression(\"parent.\{0\}.matrix.4*invmatrix0.2 + parent.\{0\}.matrix.5*invmatrix1.2 + parent.\{0\}.matrix.6*invmatrix2.2 + parent.\{0\}.matrix.7*invmatrix3.2\".format(node.fullName()), 6)\n cpmatrix.setExpression(\"parent.\{0\}.matrix.4*invmatrix0.3 + parent.\{0\}.matrix.5*invmatrix1.3 + parent.\{0\}.matrix.6*invmatrix2.3 + parent.\{0\}.matrix.7*invmatrix3.3\".format(node.fullName()), 7)\n cpmatrix.setExpression(\"parent.\{0\}.matrix.8*invmatrix0.0 + parent.\{0\}.matrix.9*invmatrix1.0 + parent.\{0\}.matrix.10*invmatrix2.0 + parent.\{0\}.matrix.11*invmatrix3.0\".format(node.fullName()), 8)\n cpmatrix.setExpression(\"parent.\{0\}.matrix.8*invmatrix0.1 + parent.\{0\}.matrix.9*invmatrix1.1 + parent.\{0\}.matrix.10*invmatrix2.1 + parent.\{0\}.matrix.11*invmatrix3.1\".format(node.fullName()), 9)\n cpmatrix.setExpression(\"parent.\{0\}.matrix.8*invmatrix0.2 + parent.\{0\}.matrix.9*invmatrix1.2 + parent.\{0\}.matrix.10*invmatrix2.2 + parent.\{0\}.matrix.11*invmatrix3.2\".format(node.fullName()), 10)\n cpmatrix.setExpression(\"parent.\{0\}.matrix.8*invmatrix0.3 + parent.\{0\}.matrix.9*invmatrix1.3 + parent.\{0\}.matrix.10*invmatrix2.3 + parent.\{0\}.matrix.11*invmatrix3.3\".format(node.fullName()), 11)\n cpmatrix.setExpression(\"parent.\{0\}.matrix.12*invmatrix0.0 + parent.\{0\}.matrix.13*invmatrix1.0 + parent.\{0\}.matrix.14*invmatrix2.0 + parent.\{0\}.matrix.15*invmatrix3.0\".format(node.fullName()), 12)\n cpmatrix.setExpression(\"parent.\{0\}.matrix.12*invmatrix0.1 + parent.\{0\}.matrix.13*invmatrix1.1 + parent.\{0\}.matrix.14*invmatrix2.1 + parent.\{0\}.matrix.15*invmatrix3.1\".format(node.fullName()), 13)\n cpmatrix.setExpression(\"parent.\{0\}.matrix.12*invmatrix0.2 + parent.\{0\}.matrix.13*invmatrix1.2 + parent.\{0\}.matrix.14*invmatrix2.2 + parent.\{0\}.matrix.15*invmatrix3.2\".format(node.fullName()), 14)\n cpmatrix.setExpression(\"parent.\{0\}.matrix.12*invmatrix0.3 + parent.\{0\}.matrix.13*invmatrix1.3 + parent.\{0\}.matrix.14*invmatrix2.3 + parent.\{0\}.matrix.15*invmatrix3.3\".format(node.fullName()), 15)\n\n cornerpin\['label'].setValue(\"PlanarProjection : ref x\{0\}\".format('\[value identity_frame]'))\nelif expression_link and not independent_identity_frame:\n cornerpin\['label'].setValue('\{0\}: x\{1\}'.format(node.name(), reference_frame))\n for i in range(16):\n cpmatrix.setExpression(\"parent.\{0\}.matrix.\{1\}\".format(node.fullName(), i), i)\nelse:\n cornerpin\['label'].setValue('\{0\}: x\{1\}'.format(node.name(), reference_frame))\n cpmatrix.copyAnimations(matrix.animations())"}
addUserKnob {22 create_gridwarp l GridWarp -STARTLINE T "node = nuke.thisNode()\nmatrix = node\['matrix']\nnuke.root().begin()\ngrid_x = int(nuke.toNode('preferences').knob('GridWidth').value())\ngrid_y = int(nuke.toNode('preferences').knob('GridHeight').value())\nexpression_link = node\['expression_link'].getValue()\n\nif matrix.isAnimated():\n _ = \[n.setSelected(False) for n in nuke.allNodes()]\n gridwarp = nuke.createNode(\"GridWarp3\")\n gridwarp.setXYpos(node.xpos()-grid_x*0, node.ypos()+grid_y*2)\n gridwarp.setSelected(True)\n\n # Add Label\n reference_frame = int(node\['identity_frame'].getValue())\n if expression_link:\n gridwarp\['label'].setValue('\{0\}: x\[value identity_frame]'.format(node.name()))\n else:\n gridwarp\['label'].setValue('\{0\}: x\{1\}'.format(node.name(), reference_frame))\n\n gridwarp_matrices = \[gridwarp\['source_grid_transform_matrix'], gridwarp\['destination_grid_transform_matrix']]\n\n if expression_link:\n for i in range(16):\n for gridwarp_matrix in gridwarp_matrices:\n gridwarp_matrix.setExpression(\"parent.\{0\}.matrix.\{1\}\".format(node.fullName(), i), i)\n else:\n gridwarp_matrices\[0].copyAnimations(matrix.animations())"}
addUserKnob {26 ""}
addUserKnob {26 desc l " " T "developed by Vit Sedlacek www.vitsedlacek.com\noptimized and improved by Jed Smith - http://gist.github.com/jedypod"}
}
Axis2 {
inputs 0
useMatrix true
name Matrix_original
xpos -276
ypos -260
disable true
}
Input {
inputs 0
name InputBG
label "\[value number]"
xpos 620
ypos -304
addUserKnob {20 User}
addUserKnob {18 ip1 R -100 100}
ip1 {0 0 0}
addUserKnob {6 ip1_panelDropped l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {6 ip1_panelDropped_1 l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {6 ip1_panelDropped_1_1 l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {6 ip1_panelDropped_1_1_1 l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {18 ip2 l "" +STARTLINE R -100 100}
ip2 {0 0 0}
addUserKnob {6 ip2_panelDropped l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {6 ip2_panelDropped_1 l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {6 ip2_panelDropped_1_1 l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {6 ip2_panelDropped_1_1_1 l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {18 ip3 l "" +STARTLINE R -100 100}
ip3 {0 0 0}
addUserKnob {6 ip3_panelDropped l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {6 ip3_panelDropped_1 l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {6 ip3_panelDropped_1_1 l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {6 ip3_panelDropped_1_1_1 l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {18 ip4 l "" +STARTLINE R -100 100}
ip4 {0 0 0}
addUserKnob {6 ip4_panelDropped l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {6 ip4_panelDropped_1 l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {6 ip4_panelDropped_1_1 l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {6 ip4_panelDropped_1_1_1 l "panel dropped state" -STARTLINE +HIDDEN}
}
Output {
name Output1
xpos 600
ypos 531
}
Axis2 {
inputs 0
translate {0.5 0.5 0}
useMatrix true
matrix {
{{parent._MATCH_SELECTION_.matrix} {parent._MATCH_SELECTION_.matrix} {parent._MATCH_SELECTION_.matrix} {parent._MATCH_SELECTION_.matrix}}
{{parent._MATCH_SELECTION_.matrix} {parent._MATCH_SELECTION_.matrix} {parent._MATCH_SELECTION_.matrix} {parent._MATCH_SELECTION_.matrix}}
{{parent._MATCH_SELECTION_.matrix} {parent._MATCH_SELECTION_.matrix} {parent._MATCH_SELECTION_.matrix} {parent._MATCH_SELECTION_.matrix}}
{{parent._MATCH_SELECTION_.matrix} {parent._MATCH_SELECTION_.matrix} {parent._MATCH_SELECTION_.matrix} {parent._MATCH_SELECTION_.matrix}}
}
name CENTER
xpos -190
ypos 78
addUserKnob {20 User}
addUserKnob {7 plane_size l "" +STARTLINE R 0.1 100}
plane_size 1
}
set N3193a750 [stack 0]
Axis2 {
translate {{parent.CENTER.plane_size/2} {parent.CENTER.plane_size/2} 0}
name UR
xpos -131
ypos 222
}
push $N3193a750
Axis2 {
translate {{-parent.CENTER.plane_size/2} {parent.CENTER.plane_size/2} 0}
name UL
xpos -23
ypos 222
}
push $N3193a750
Axis2 {
translate {{parent.CENTER.plane_size/2} {-parent.CENTER.plane_size/2} 0}
name LR
xpos -241
ypos 222
}
push $N3193a750
Axis2 {
translate {{-parent.CENTER.plane_size/2} {-parent.CENTER.plane_size/2} 0}
name LL
xpos -367
ypos 222
}
TransformGeo {
inputs 0
translate {-53.84128952 26.45331383 -89.45389557}
rotate {-36.82652664 86.55776215 93.70707703}
scaling {3.87788868 4.277028561 1.28276515}
name _MATCH_SELECTION_
xpos -40
ypos 99
}
Input {
inputs 0
name InputCam
label "\[value number]"
xpos 440
ypos -303
number 1
}
push 0
Axis2 {
inputs 0
name point_4
xpos 300
ypos -270
}
Axis2 {
inputs 0
name point_3
xpos 190
ypos -270
}
Axis2 {
inputs 0
name point_2
xpos 80
ypos -270
}
Axis2 {
inputs 0
name point_1
xpos -30
ypos -271
}
Scene {
inputs 6
name Scene1
xpos 450
ypos -95
}
end_group
@jedypod

This comment has been minimized.

Copy link
Owner Author

jedypod commented Sep 30, 2015

Added an update so it will work with animated 3d point sources - just expression link or copy the animation curve of your axis to the input point source, and also enabled the set knobs to grab position data from Axis nodes (including animated).

@jedypod

This comment has been minimized.

Copy link
Owner Author

jedypod commented Mar 3, 2016

Added an update to create a tracker with the calculated animation data. Tired of doing this by hand :P

@jedypod

This comment has been minimized.

Copy link
Owner Author

jedypod commented Jun 19, 2016

  • Added an option to specify a reference frame, so that the matrix transform will be a null operation on that frame. Useful if you need to switch rotos between tracking nodes, or accidentally draw your shape on the wrong tracking layer.
  • Fixed issue with Tracker3 not updating it's tracking keyframes.
  • Optimized and condensed the create nodes buttons.
@rafaelperez

This comment has been minimized.

Copy link

rafaelperez commented May 21, 2020

Just came to say this is one of my most loved scripts for Nuke. It saves me so much time, I'm truly grateful for it. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.