I think there's a few things that are playing against you in that code.

- First, in your convertToIndex function, you're returning the wrong
index number (at least based on how you're calling the different
positions in the matrix later). Either change the order of your x and
y arguments when you call the function, or, probably easier, just
change your converToIndex function to return (x*d+y) instead of
(y*d+x).

- The same problem happens in your setRotationFromMatrix function.
You're filling the matrix object in the same order that's returned by
the matrix knob, which is unfortunately wrong. Either change your
matrix-filling loop so it reads something like this:

   m4 = _nukemath.Matrix4()
   k = node['matrix']
   for y in range(k.height()):
      for x in range(k.width()):
          m4[x+(y*k.width())] = k.value(x,y)

Or leave it as you have it now, but then transpose the resulting
matrix so you have it in the right order (column major) for the
following operations.

- For your setScaleFromMatrix function; directly accessing those
indices to get the scaling components will only work if your matrix is
a scale only matrix. You could do:

# Assuming m4 is your matrix already built from the matrix knob:
m4.scaleOnly()
scale = m4.transform(nuke.math.Vector3(1,1,1)) # Use the matrix to
scale a vector at (1,1,1)
# And then scale.x, scale.y and scale.z would be your scaling factors

- Something else you might want to consider to make your code a bit
shorter and easier for you to update would be to build a matrix object
only once, and then pass it to your setTranslation, setRotation and
setScale functions, so you don't have to deal with building your
matrix object every time.

- One last thing. I may be wrong, but I assume you want to collapse
the final position/rotation/etc of a camera that has parented
transformations? If that's the case, you'll probably want to get those
from the camera's "world_matrix" knob, and not the "matrix" knob,
which only holds the local transforms.

Hope that helps!

Cheers,
Ivan


On Wed, Jul 20, 2011 at 12:20 PM, Gerard Keating <[email protected]> wrote:
> Hi,
> I am trying to convert camera node from using the matrix to using its
> scale translate and rotate knobs but I can't seem to get it to line
> up. Is there an easy way to do this?
> Here's my code:
> import logging
> import math
>
> import nuke
> import nukescripts
>
> def makeSRTNodeOfSelectedNodes():
>    selectedNodes = nuke.selectedNodes()
>    if len(selectedNodes)!=1:
>        nuke.message("Please select one camera node")
>        return False
>    nukescripts.edit.node_copypaste()
>    cameraNode = nuke.selectedNode()
>    convertCameraFromMatrixToSRT(cameraNode)
>
> def convertCameraFromMatrixToSRT(cameraNode, startFrame=None, endFrame=None):
>    if startFrame==None:
>        startFrame = int(nuke.root()["first_frame"].value())
>    if endFrame==None:
>        endFrame = int(nuke.root()["last_frame"].value())
>    for frame in xrange(startFrame, endFrame+1):
>        setScaleFromMatrix(cameraNode, frame)
>        setRotationFromMatrix(cameraNode, frame)
>        setTranslationFromMatrix(cameraNode, frame)
>    cameraNode['useMatrix'].setValue(False)
>
> def setTranslationFromMatrix(node, frame):
>    node['translate'].setKeyAt(frame)
>    tx = node['matrix'].valueAt(frame, converToIndex(0, 3))
>    node['translate'].setValueAt(tx, frame, 0)
>    #
>    ty = node['matrix'].valueAt(frame, converToIndex(1, 3))
>    node['translate'].setValueAt(ty, frame, 1)
>    #
>    tz = node['matrix'].valueAt(frame, converToIndex(2, 3))
>    node['translate'].setValueAt(tz, frame, 2)
>
> def setScaleFromMatrix(node, frame):
>    node['scaling'].setKeyAt(frame)
>    sx = node['matrix'].valueAt(frame, converToIndex(0, 0))
>    node['scaling'].setValueAt(sx, frame, 0)
>    #
>    sy = node['matrix'].valueAt(frame, converToIndex(1, 1))
>    node['scaling'].setValueAt(sy, frame, 1)
>    #
>    sz = node['matrix'].valueAt(frame, converToIndex(2, 2))
>    node['scaling'].setValueAt(sz, frame, 2)
>
> def setRotationFromMatrix(node, frame):
>    import _nukemath
>    m4 = _nukemath.Matrix4()
>    for i in xrange(16):
>        v = node['matrix'].valueAt(frame,i)
>        logging.debug("Matrix value at %d=%f", i, v)
>        m4[i] = v
>    m4.rotationOnly()
>    ZXYRotation = m4.rotationsZXY()
>    logging.debug("ZXY rotation=%s", ZXYRotation)
>    node['rot_order'].setValue("ZXY")
>    node['rotate'].setKeyAt(frame)
>    for i in xrange(3):
>        r = ZXYRotation[i]
>        d = math.degrees(r)
>        node['rotate'].setValueAt(d, frame, i)
>
> def converToIndex(x, y, d=4):
>    return y*d+x
> _______________________________________________
> Nuke-python mailing list
> [email protected], http://forums.thefoundry.co.uk/
> http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python
>
_______________________________________________
Nuke-python mailing list
[email protected], http://forums.thefoundry.co.uk/
http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python

Reply via email to