For anyone who's interested: I took Ivan's function and added support for
animated Axis / Camera nodes (it was only concatenating a single frame).
Cheers -E

def consolidateAnimatedNodeTransforms(axisNode):
    # This is based on Ivan B's consolidateNodeTransforms().
    # Added support for animated Axis/Camera nodes. Also, if it's
    # a Camera being concatenated, then projection settings get copied.
    # -Ean C 24/Feb/2011

    m = nuke.math.Matrix4()

    n = nuke.createNode(axisNode.Class())
    n['scaling'].setExpression('curve')
    n['rotate'].setExpression('curve')
    n['translate'].setExpression('curve')

    if axisNode.Class() == 'Camera2':
        # If this is a Camera node, copy over important Projection settings.
        camNode = axisNode

        # Get the current values
        focal_v = camNode['focal'].toScript()
        haperture_v = camNode['haperture'].toScript()
        vaperture_v = camNode['vaperture'].toScript()
        near_v = camNode['near'].toScript()
        far_v = camNode['far'].toScript()
        win_translate_v = camNode['win_translate'].toScript()
        win_scale_v = camNode['win_scale'].toScript()
        winroll_v = camNode['winroll'].toScript()
        focal_point_v = camNode['focal_point'].toScript()

        # Copy them over to new Camera
        n['focal'].fromScript(focal_v)
        n['haperture'].fromScript(haperture_v)
        n['vaperture'].fromScript(vaperture_v)
        n['near'].fromScript(near_v)
        n['far'].fromScript(far_v)
        n['win_translate'].fromScript(win_translate_v)
        n['win_scale'].fromScript(win_scale_v)
        n['winroll'].fromScript(winroll_v)
        n['focal_point'].fromScript(focal_point_v)

    first_frame_v = nuke.root()['first_frame'].value()
    last_frame_v = nuke.root()['last_frame'].value()

    scale_anim = n['scaling'].animations()
    rotate_anim = n['rotate'].animations()
    translate_anim = n['translate'].animations()

    for i in range(int(first_frame_v), int(last_frame_v+1)):

        k = axisNode['world_matrix']
        k_time_aware = axisNode['world_matrix'].getValueAt(i)

        for y in range(k.height()):
            for x in range(k.width()):
                m[x+(y*k.width())] = k_time_aware[y + k.width()*x]

            transM =nuke.math.Matrix4(m)
            transM.translationOnly()
            rotM = nuke.math.Matrix4(m)
            rotM.rotationOnly()
            scaleM = nuke.math.Matrix4(m)
            scaleM.scaleOnly()

            scale = (scaleM.xAxis().x, scaleM.yAxis().y, scaleM.zAxis().z)

            rot = rotM.rotationsZXY()
            rotDegrees = ( math.degrees(rot[0]), math.degrees(rot[1]),
math.degrees(rot[2]) )

            trans = (transM[12], transM[13], transM[14])

            for s in range(3):
                scale_anim[s].setKey(i, scale[s])
                rotate_anim[s].setKey(i, rotDegrees[s])
                translate_anim[s].setKey(i, trans[s])



On Mon, Nov 29, 2010 at 11:33 AM, Scott Willman <[email protected]>wrote:

> Wow, Ivan, thank you! This should definately get me started :)
>
> Ivan Busquets wrote:
>
>> What he said :)
>>
>> If you just want to use that within a gizmo/group, linking to the
>> world_matrix of your input Axis/Camera should be enough to replicate all
>> concatenated transforms.
>>
>> However, if you need to get back absolute values in terms of
>> position/rotation/scale, you'll need to derive them yourself (with a little
>> help from nuke.math)
>>
>> Here's an example if you just wanted to get the final concatenated
>> position:
>>
>> ######################
>> import math
>>
>> def getAxisWPos(axisNode):
>>
>>    k = axisNode['world_matrix']
>>    m = nuke.math.Matrix4()
>>
>>    for y in range(k.height()):
>>        for x in range(k.width()):
>>            m[x+(y*k.width())] = k.value(x,y)
>>
>>    p = m.transform(nuke.math.Vector3(0,0,0))
>>    return (p.x, p.y, p.z)
>>
>> worldPos =  getAxisWPos(nuke.selectedNode())
>> ######################
>>
>> Or, if you wanted to create a new Axis/Camera node and fill it with the
>> concatenated translation, rotation and scale values, you could do something
>> like this: (please note that this should account for everything except for
>> skew transformations)
>>
>> ######################
>> def consolidateNodeTransforms(axisNode):
>>
>>    k = axisNode['world_matrix']
>>    m = nuke.math.Matrix4()
>>
>>    nuke.selectAll()
>>    nuke.invertSelection()
>>       k = axisNode['world_matrix']
>>    m = nuke.math.Matrix4()
>>    for y in range(k.height()):
>>        for x in range(k.width()):
>>            m[x+(y*k.width())] = k.value(x,y)
>>
>>    transM =nuke.math.Matrix4(m)
>>    transM.translationOnly()
>>    rotM = nuke.math.Matrix4(m)
>>    rotM.rotationOnly()
>>    scaleM = nuke.math.Matrix4(m)
>>    scaleM.scaleOnly()
>>       scale = (scaleM.xAxis().x, scaleM.yAxis().y, scaleM.zAxis().z)
>>    rot = rotM.rotationsZXY()
>>    trans = (transM[12], transM[13], transM[14])
>>
>>    n = nuke.createNode(axisNode.Class())
>>    n['scaling'].setValue(scale)
>>    n['rotate'].setValue((math.degrees(rot[0]), math.degrees(rot[1]),
>> math.degrees(rot[2])))
>>    n['translate'].setValue(trans)
>>
>> consolidateNodeTransforms(nuke.selectedNode())
>> ######################
>>
>>
>> Disclaimer: I just wrote those and have only done a couple of tests, so
>> there's a good chance they may break (no exceptions handled, etc), but
>> hopefully it'll get you on the right track.
>>
>> Hope that helps.
>>
>> Cheers,
>> Ivan
>>
>> On Sun, Nov 28, 2010 at 3:20 PM, Frank Rueter <[email protected]<mailto:
>> [email protected]>> wrote:
>>
>>    that's what the world matrix knob is for (in 6.1)
>>
>>
>>    On Nov 29, 2010, at 12:12 PM, [email protected]
>>    <mailto:[email protected]> wrote:
>>
>>    > I've got a camera that has an Axis node plugged in. The camera
>>    also has
>>    > transforms on it. Is there a way to get the resolved world-space
>>    > pos/rot/scale of the camera?
>>    >
>>    > Thanks guys
>>    >
>>    >
>>    >
>>    >
>>    > Cinesite (Europe) Ltd. Registered Office: HemelOne, Boundary
>>    Way, Hemel Hempstead, Herts, HP2 7YU Registered in Cardiff No.
>>    2820389 VAT No. 630 5446 60
>>    > _______________________________________________
>>    > Nuke-python mailing list
>>    > [email protected]
>>    <mailto:[email protected]>
>>
>>    > http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python
>>
>>    _______________________________________________
>>    Nuke-python mailing list
>>    [email protected]
>>    <mailto:[email protected]>
>>
>>    http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python
>>
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> Nuke-python mailing list
>> [email protected]
>> http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python
>>
>>
>
> Cinesite (Europe) Ltd. Registered Office: HemelOne, Boundary Way, Hemel
> Hempstead, Herts, HP2 7YU Registered in Cardiff No. 2820389 VAT No. 630 5446
> 60
> _______________________________________________
> Nuke-python mailing list
> [email protected]
> http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python
>
_______________________________________________
Nuke-python mailing list
[email protected]
http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python

Reply via email to