Viewer State Browser help

   3024   14   0
User Avatar
Member
97 posts
Joined: May 2015
Offline
So i been reading all of Writing custom viewer states in Python for the past 2 days and followed the Loading a state from the Houdini path steps. Got everything working but im not seeing anything pop up on the console like it said it would. Also would this be the ideal way to check what the mouse is hovered over?

Attachments:
Screenshot (584).png (976.0 KB)

User Avatar
Staff
396 posts
Joined: Feb. 2018
Online
Can you post your demo state ? I'll have a look.
User Avatar
Staff
396 posts
Joined: Feb. 2018
Online
Here's an OBJ state I created with the viewer state code generator.
Image Not Found

Attachments:
2020-01-09_08-39-35.mp4 (9.5 MB)

User Avatar
Member
97 posts
Joined: May 2015
Offline
mabelzile
Here's an OBJ state I created with the viewer state code generator.
Image Not Found

Thank you for the video, got it working but how come the documentation does it different. Are they out of date? also i check what stateutils module has and theres nothing in it also, so why is it in the the code snippet for example?
Edited by Shadowjonny - Jan. 9, 2020 16:41:16
User Avatar
Staff
396 posts
Joined: Feb. 2018
Online
Shadowjonny
mabelzile
Here's an OBJ state I created with the viewer state code generator.
Image Not Found

Thank you for the video, got it working but how come the documentation does it different. Are they out of date? also i check what stateutils module has and theres nothing in it also, so why is it in the the code snippet for example?

Which example are you referring to ? stateutils is just a module importing everything from viewerstate.utils and was kept to avoid breaking clients code.
User Avatar
Member
97 posts
Joined: May 2015
Offline
mabelzile
Shadowjonny
mabelzile
Here's an OBJ state I created with the viewer state code generator.
Image Not Found

Thank you for the video, got it working but how come the documentation does it different. Are they out of date? also i check what stateutils module has and theres nothing in it also, so why is it in the the code snippet for example?

Which example are you referring to ? stateutils is just a module importing everything from viewerstate.utils and was kept to avoid breaking clients code.

https://www.sidefx.com/docs/houdini/hom/python_states.html [www.sidefx.com] was following the “Loading a state from the Houdini path”. Also you are right it does lead to viewerstate.utils, but some how the documentation just somehow confuse me. Like i just want to know what each function does inside those modules and start building, i have to either test it out or open the modules with pycharm to see what it returns. Also quick question where can i find what “ui_event” does cause i see it with all the states, isnt that the same as hou.UIEvent but i get an error when i put that in the code snippet for the State.

ui_event = kwargs["ui_event"]
User Avatar
Member
41 posts
Joined: Feb. 2018
Offline
Shadowjonny
Also quick question where can i find what “ui_event” does cause i see it with all the states, isnt that the same as hou.UIEvent but i get an error when i put that in the code snippet for the State.

Hi Jonny, not sure if I get your question, but I think
kwargs["ui_event"]
indeed returns an instance of hou.UIEvent? You can then call its methods like hou.UIEvent.device(), hou.UIEvent.reason(), etc.
Edited by AlanZ - Jan. 11, 2020 13:09:38
User Avatar
Member
97 posts
Joined: May 2015
Offline
AlanZ
Shadowjonny
Also quick question where can i find what “ui_event” does cause i see it with all the states, isnt that the same as hou.UIEvent but i get an error when i put that in the code snippet for the State.

Hi Jonny, not sure if I get your question, but I think
kwargs["ui_event"]
indeed returns an instance of hou.UIEvent? You can then call its methods like hou.UIEvent.device(), hou.UIEvent.reason(), etc.

Indeed i agree it is that but i want to know where i can get a list of things i can put inside kwargs. Cause i got an error when i put:

node = kwargs['node'] #inside OnMouseEvent for State got an error 

yet i see it in the code snippet for example in the python state viewer documentation.
Edited by Shadowjonny - Jan. 11, 2020 14:14:36
User Avatar
Member
41 posts
Joined: Feb. 2018
Offline
Shadowjonny
but i want to know where i can get a list of things i can put inside kwargs

I see. kwargs is different for different methods in your State. Since it's a dictionary, you can just print out its keys to inspect.

def onMouseEvent(self, kwargs):
    print kwargs.keys() # or "print (kwargs.keys())" in Python 3

#['node', 'state_flags', 'state_parms', 'ui_event']

kwargs['node']
shouldn't generate an error though. Can u post a screenshot or something?
User Avatar
Staff
396 posts
Joined: Feb. 2018
Online
Shadowjonny
AlanZ
Shadowjonny
Also quick question where can i find what “ui_event” does cause i see it with all the states, isnt that the same as hou.UIEvent but i get an error when i put that in the code snippet for the State.

Hi Jonny, not sure if I get your question, but I think
kwargs["ui_event"]
indeed returns an instance of hou.UIEvent? You can then call its methods like hou.UIEvent.device(), hou.UIEvent.reason(), etc.

Indeed i agree it is that but i want to know where i can get a list of things i can put inside kwargs. Cause i got an error when i put:

node = kwargs['node'] #inside OnMouseEvent for State got an error 

yet i see it in the code snippet for example in the python state viewer documentation.
kwargs is the dictionary holding the arguments passed to event handlers, it's documented documented here [www.sidefx.com]
User Avatar
Member
97 posts
Joined: May 2015
Offline
AlanZ
Shadowjonny
but i want to know where i can get a list of things i can put inside kwargs

I see. kwargs is different for different methods in your State. Since it's a dictionary, you can just print out its keys to inspect.

def onMouseEvent(self, kwargs):
    print kwargs.keys() # or "print (kwargs.keys())" in Python 3

#['node', 'state_flags', 'state_parms', 'ui_event']

kwargs['node']
shouldn't generate an error though. Can u post a screenshot or something?

just tested again and its working guess i typed it wrong when i first was typing it last night. My bad
User Avatar
Member
97 posts
Joined: May 2015
Offline
Thank you guys for clearing somethings out really appreciate it.
User Avatar
Member
97 posts
Joined: May 2015
Offline
Im sorry for so many question but python in houdini is confusing comapred to maya or blender for me somehow.
User Avatar
Member
97 posts
Joined: May 2015
Offline
mabelzile
Shadowjonny
AlanZ
Shadowjonny
Also quick question where can i find what “ui_event” does cause i see it with all the states, isnt that the same as hou.UIEvent but i get an error when i put that in the code snippet for the State.

Hi Jonny, not sure if I get your question, but I think
kwargs["ui_event"]
indeed returns an instance of hou.UIEvent? You can then call its methods like hou.UIEvent.device(), hou.UIEvent.reason(), etc.

Indeed i agree it is that but i want to know where i can get a list of things i can put inside kwargs. Cause i got an error when i put:

node = kwargs['node'] #inside OnMouseEvent for State got an error 

yet i see it in the code snippet for example in the python state viewer documentation.
kwargs is the dictionary holding the arguments passed to event handlers, it's documented documented here [www.sidefx.com]

Been stuck with trying to select a point in the viewport, what would you say im missing or doing wrong? been going through the selection_demo and it doesnt really help me understand how it got to be able to select from prim to points. Im trying to select self points not the points from the connected node in 0.
import hou
import hdefereval
import viewerstate.utils as su

def _refreshDrawables(state):
    """ Creates a drawable for each point added.
    """
    pointCount = state.pointCount()
    if state.clear_drawables:
        state.drawables = []

        for index in range(pointCount):            
            state.addDrawable(index)
        state.clear_drawables = False
        
    elif state.add_drawable:
        state.addDrawable(pointCount-1)
        state.add_drawable = False
    state.scene_viewer.curViewport().draw()          
    state.post = True



class State(object):
    def __init__(self, state_name, scene_viewer):
        self.state_name = state_name
        self.scene_viewer = scene_viewer
        
        self.pressed = False
        self.index = 0    
        self.node = None        
        self.drawables = []
        self.post = True
        self.clear_drawables = False
        self.add_drawable = False

    def onEnter(self,kwargs):
        """ Called on node bound states when it starts
        """
        self.node = kwargs["node"]        
        self.node.addEventCallback([hou.nodeEventType.ParmTupleChanged], self.nodeParmCB)
        
        # post a refresh to draw a point for the existing multiparms
        self.postRefreshDrawables(clear=True)   
        
    def onExit(self,kwargs):
        """ Called when the state terminates
        """
        self.node.removeAllEventCallbacks()

    def onInterrupt(self, kwargs):
        """ Called when the state is interrupted e.g when the mouse 
        moves outside the viewport
        """
        self.finish()

    def onMouseEvent(self, kwargs):
        """ Process mouse events
        """
        ui_event = kwargs["ui_event"]
        device = ui_event.device()
        origin, direction = ui_event.ray()
        inputs = self.node.inputs()
        
        # Only try intersecting geometry if this node has input
        geo_intersector = None
        if inputs and inputs[0]:
            geometry = inputs[0].geometry()
            geo_intersector = su.GeometryIntersector(geometry, scene_viewer=self.scene_viewer)
            isGeo = None
               
        
        if geo_intersector:            
            isGeo = geo_intersector.intersect(origin, direction)
            position = geo_intersector.position
            
            
        # Create/move point if LMB is down
        if device.isLeftButton():
            if isGeo == True:
              self.start()
              self.setPoint(self.index, position)            
            
        else:
            self.finish()

        # Must return True to consume the event
        return True
    
    def onDraw(self, kwargs):
        """ Called for rendering a state e.g. required for 
        hou.AdvancedDrawable objects
        """
        handle = kwargs["draw_handle"]
        for drawable in self.drawables:
            drawable.draw(handle)

    def onDrawInterrupt(self, kwargs):
        """ Called for rendering an interrupted state e.g. required for 
        hou.AdvancedDrawable objects
        """
        self.onDraw(kwargs)
        
    def PointSel(self,kwargs):
        sel = kwargs['selection']
        
        ss = sel.selections()
        
        print(ss)

    def onSelection(self, kwargs):
        """ Called when a selector has selected something
        """        
        state_parms = kwargs["state_parms"]

        self.log(kwargs)

        # Must return True to accept the selection
        return self.PointSel(kwargs)

    def onStartSelection(self, kwargs):
        """ Called when a bound selector has been started
        """       
        self.log(kwargs)
        
    def nodeParmCB(self, **kwargs):
        """ Clear the point drawables if something has changed 
            on the multiparm. """
        self.postRefreshDrawables(clear=True)
        
    def postRefreshDrawables(self, **kwargs):
        """ Post a job on the UI queue to refresh the drawables.
            Only one job at a time can be posted.
        """
        if self.post:
            try:
                self.clear_drawables = kwargs['clear']
                self.add_drawable = False
            except:
                try:
                    self.add_drawable = kwargs['add']
                    self.clear_drawables = False
                except:
                    pass

            hdefereval.executeDeferred(_refreshDrawables, self)        
            self.post = False
                                   
    def addDrawable(self, index):
        """ Creates a sphere drawable for each multiparm point.
        """
        pt_name = "pt%d" % index
        parm_tuple = self.node.parmTuple(pt_name)
    
        geo = hou.Geometry()
        sph_verb = hou.sopNodeTypeCategory().nodeVerb("sphere")
        # We want a polygon mesh sphere
        sph_verb.setParms({
            "type": 2
        })
        sph_verb.execute(geo, [])
        
        drawable = hou.GeometryDrawable(self.scene_viewer, hou.drawableGeometryType.Line,
            "pt_hilite", geo )
        drawable.show(True)

        rad = 0.05
        pos = hou.Vector3(parm_tuple[0].evalAsFloat(),
            parm_tuple[1].evalAsFloat(),
            parm_tuple[2].evalAsFloat())
            
        parms = {
            'translate': (pos[0],pos[1],pos[2]), 
            'scale': (rad, rad, rad),
            "color1": (1.0,0.0,0.0,0.7)
        }
        
        drawable.setParams(parms)
        self.drawables.append(drawable)           
             
    def pointCount(self):
        """ This is how you get the number of instances 
            in a multiparm. 
        """
        try:
            multiparm = self.node.parm("points")
            return multiparm.evalAsInt()
        except:
            return 0

    def insertPoint(self):
        index = self.pointCount()
        multiparm = self.node.parm("points")
        multiparm.insertMultiParmInstance(index)
        return index

    def setPoint(self, index, position):
        self.node.parm("usept%d" % index).set(1)
        self.node.parmTuple("pt%d" % index).set(position)    

    def start(self):
        if not self.pressed:
            self.scene_viewer.beginStateUndo("Add point")
            self.postRefreshDrawables(add=True)                
            self.index = self.insertPoint()
        self.pressed = True

    def finish(self):
        if self.pressed:
            self.scene_viewer.endStateUndo()
        self.pressed = False    


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 = "Pipe Setup System"
    state_cat = hou.sopNodeTypeCategory()

    template = hou.ViewerStateTemplate(state_typename, state_label, state_cat)
    template.bindFactory(State)
    template.bindIcon(kwargs["type"].icon())
    
    KeyStart = su.hotkey(state_typename, 'Point Selection','1') 
    
    template.bindGeometrySelector(prompt="Point Selection", 
     allow_drag=True, 
     quick_select=True, 
     auto_start=True, 
     use_existing_selection=False, 
     consume_selection=True, 
     secure_selection=hou.secureSelectionOption.Off, 
     initial_selection="*", 
     initial_selection_type=hou.geometryType.Points, 
     geometry_types=(hou.geometryType.Points,), 
     hotkey=KeyStart, name="PointSelector")


    return template
Edited by Shadowjonny - Jan. 21, 2020 16:28:32

Attachments:
Screenshot (594).png (991.9 KB)

User Avatar
Member
97 posts
Joined: May 2015
Offline
Ok got something working now
  • Quick Links