Python States and Handles

   2103   6   0
User Avatar
Member
575 posts
Joined: Nov. 2005
Offline
Hello,

some questions about the python states and how to deal with handles properly.

1. The python state handle example creates a static and a dynamic handle. when You drag the static xform handle the connected parameters get a direct connection to the handle, as soon as You move the handle You, the connected parameters are highlighted in the parameter window and update during interaction.




I would like to have this behavior with a dynamic handle as well, but I could only come up with a slightly looser connection, by adding updates to the "onHandleToState" and "onStateToHandle" methods. Is there a better way to do this. Best would be to have it to behave the same way like a static handle.


2. I want to align the handle to a specific point on a input curve. The curve has a rot attribute with the rotation vector in it. I added a method to set the pivot on the handle. Now I want to call this method as soon as I enter the state, but could not find a way. the "onEnter" method seemed to be the right point for this, but i could not get access to the parameters of the handle and the node, the state is working on.

I called the methods on the "onHandleToState" and "onStateToHandle" methods but this does not work right and feels just wrong . The handle is transformed correctly as soon as I move it slightly.

Is there a way to call this initial method as soon as the states is entered?

"""
State:          handle a
State type:     handle_a
Description:    handle a
Author:         mmatzeder
Date Created:   December 31, 2020 - 09:53:26
"""

# Usage: Make sure to add 6 float parameters to the node:
# newparameter, newparameter2, newparameter3, newparameter4, newparameter5, newparameter6.
# Select node and hit enter in the viewer.

import hou
import viewerstate.utils as su

def positionHandle(node, parms):

    parms["px"] = node.node("Out").geometry().points()[0].position().x()
    parms["py"] = node.node("Out").geometry().points()[0].position().y()
    parms["pz"] = node.node("Out").geometry().points()[0].position().z()   
    parms["pivot_rx"] = node.node("Out").geometry().points()[0].attribValue("rot")[0]
    parms["pivot_ry"] = node.node("Out").geometry().points()[0].attribValue("rot")[1]
    parms["pivot_rz"] = node.node("Out").geometry().points()[0].attribValue("rot")[2]

class State(object):
    def __init__(self, state_name, scene_viewer):
        self.state_name = state_name
        self.scene_viewer = scene_viewer

        self.xform_handle = hou.Handle(self.scene_viewer, "Xform")

    def onEnter(self, kwargs):
        self.xform_handle.show(True)
        print self.xform_handle

    def onHandleToState(self, kwargs):
        """ Used with bound dynamic handles to implement the state 
        action when a handle is modified.
        """
        node = kwargs["node"]
        handle = kwargs["handle"]
        parms = kwargs["parms"]
        mod_parms = kwargs["mod_parms"]
        prev_parms = kwargs["prev_parms"]
        ui_event = kwargs["ui_event"]
        self.log(parms)
        if handle == self.xform_handle.name():
            positionHandle(node, parms)
            node.parm("tx").set(parms["tx"])
            node.parm("ty").set(parms["ty"])
            node.parm("tz").set(parms["tz"])
            node.parm("rx").set(parms["rx"])
            node.parm("ry").set(parms["ry"])
            node.parm("rz").set(parms["rz"])
            
    def onStateToHandle(self, kwargs):
        """ Used with bound dynamic handles to implement the handle 
        action when a state node parm is modified.
        """

        handle = kwargs["handle"]
        parms = kwargs["parms"]
        node = kwargs["node"]

        if handle == self.xform_handle.name():
            positionHandle(node, parms)
            parms["tx"] = node.parm("tx").evalAsFloat()
            parms["ty"] = node.parm("ty").evalAsFloat()
            parms["tz"] = node.parm("tz").evalAsFloat()
            parms["rx"] = node.parm("rx").evalAsFloat()
            parms["ry"] = node.parm("ry").evalAsFloat()
            parms["rz"] = node.parm("rz").evalAsFloat()
        self.log(parms)


def createViewerStateTemplate():
    """ Mandatory entry point to create and return the viewer state 
        template to register. """

    state_typename = kwargs["type"].definition().sections()["DefaultState"].contents()
    state_label = "handle a"
    state_cat = hou.sopNodeTypeCategory()

    template = hou.ViewerStateTemplate(state_typename, state_label, state_cat)
    template.bindFactory(State)
    template.bindIcon(kwargs["type"].icon())


    template.bindHandle( "xform", "Xform")



    return template



I attached a little hip with embedded assets, thanks for Your time
Edited by sanostol - Dec. 31, 2020 07:06:31

Attachments:
handle_a.hipnc (175.3 KB)
Screenshot_handle_moving.png (22.2 KB)

User Avatar
Member
575 posts
Joined: Nov. 2005
Offline
Hello, is there a way to position a dynamic handle as soon as the state is entered? It seems to be not possible. I hope I'm wrong, but the "onEnter" method does not have access to the parms of the handle and the handle itself
kwargs only contains 'node', 'state_flags', state_parms' and 'state_name', state_parms is empty
so there is no way to position the handle correctly as soon as one enters the state

thanks for Your time
User Avatar
Member
122 posts
Joined: June 2019
Offline
In your example from the first post you can call self.xform_handle.update(True) in OnEnter. That triggers OnStateToHandle where you can position your handle based on your own logic.
User Avatar
Member
575 posts
Joined: Nov. 2005
Offline
thank You, but does not work here, I still have to touch the handle to run the OnStateToHandle
User Avatar
Member
122 posts
Joined: June 2019
Offline
Yeah, sorry - looks like you don't have to use immediate mode. Just
self.xform_handle.update()

At least for me it's working (see attached)

Are you on Win or OSX/Linux? I see couple of issues on updating the viewport on OSX but handles updating usually working fine.

Attachments:
handle_a.hipnc (146.3 KB)

User Avatar
Member
575 posts
Joined: Nov. 2005
Offline
Great, works fine, thank You!
Where the hell did You find that
I'm on Linux/W10.
User Avatar
Member
122 posts
Joined: June 2019
Offline
Just had the same requirements for my state
You can check this one: https://www.sidefx.com/docs/houdini/hom/hou/Handle.html [www.sidefx.com] there are some other useful methods

xform_handlefrom your example is basically object of this class.

Sometimes I see some issues regarding updating viewport (on my OSX machine especially) but I think it comes from qt side of Houdini not from the states api.
  • Quick Links