Jump to content

Get parameters with folders structured like object


JJ FX

Recommended Posts

Hi, 

I need to get all parms of a node structured like an object, going from top folder down. Here's a pseudo-code structure I'm looking for:

parm_obj = {
	"name": "parm_name",
	"type": int/float/bool,
	"min": value,
	"max": value,
	"value": some_value
}

folder_obj = {
	"name": "folder_name",
  	"type": tab/collapsable/simple
	"folders": [folder_obj_1, folder_obj_2, ...],
	"parms": [parm_obj_1, parm_obj_2, ...]
}


node_parms_obj = {
	"name": "node name",
	"folders": [folder_obj_1, folder_obj_2, ...],,
	"parms": [parm_obj_1, parm_obj_2, ...]
}

Because folders contain more folders it gets quite tricky. So I need recursive functions for that. But I'm failing so far.

I've looked into docs and I'm surprised that there's no method for that already! Or am I missing something? Maybe there is?

Do you guys have any tips on how to deal with it?

Link to comment
Share on other sites

Here's my solution straight from hell. It's not fully cleaned up yet. Using PrettyPrinter because it's difficult to tell if it's even working. I guess I'd have to plug it into the another endpoint to see if it's working for me.

 

import pprint
pp = pprint.PrettyPrinter(indent=4)


# [1] Settings
node = hou.pwd().input(0) # tested with python sop
excluded_folders = ['Top Folder One', 'Top Folder Two', 'Another Not Used Folder']
use_folders = ['Settings', 'Another Folder Name']


# [2] Defs
#   parm object example
parm_obj_template = {
        "name": "parm_name",
        "label": "parm_label",
        "type": "type",
        "min": 0,
        "max": 0,
        "value": 0
}
#   folder object example
folder_obj_template = {
        "name": "folder_name",
        "label": "parm_label",
        "type": "type",
        "folders": [],
        "parms": []
}

parm_types = [hou.parmTemplateType.Float, hou.parmTemplateType.Int, hou.parmTemplateType.Toggle]
folder_types = [hou.folderType.Collapsible, hou.folderType.Simple, hou.folderType.Tabs]

def __is_parm(parm):
    return parm.type() in parm_types

def __is_folder(parm):
    return parm.type() == hou.parmTemplateType.Folder
    
def __get_parms(folder):
    return [parm for parm in folder.parmTemplates() if parm.type() in parm_types]

def __get_folders(folder):
    return [parm for parm in folder.parmTemplates() if parm.type() == hou.parmTemplateType.Folder]
      
def __get_parm_obj(parm):
    data = {}
    data['name'] = parm.name()
    data['label'] = parm.label()
    data['type'] = parm.type()
    data['min'] = parm.minValue()
    data['max'] = parm.maxValue()
    data['value'] = node.parm(parm.name()).eval()
    return data
    
def __get_folder_obj(folder):
    data = {}
    data['name'] = folder.name()
    data['label'] = folder.label()
    data['type'] = folder.folderType()
    data['parms'] = []
    for parm in __get_parms(folder):
        data['parms'].append(__get_parm_obj(parm)) 
        pass
    data['folders'] = []
    for subfolder in __get_folders(folder):
        if __is_folder(subfolder):
            data['folders'].append(__get_folder_obj(subfolder))
            pass
    return data

    
# [3] Run
group = node.parmTemplateGroup()
top_folders = [folder for folder in group.entries() if folder.type() == hou.parmTemplateType.Folder]
included = [folder for folder in top_folders if folder.label() not in excluded_folders]

def node_obj():
    data = { 'name' : node.name() }
    folders = []
    for folder in included:
        folders.append(__get_folder_obj(folder))
        pass
    data['folders'] = folders
    return data

print('\n-> Start')
pp.pprint(node_obj())
print('End <-')

 

Edited by JJ FX
Link to comment
Share on other sites

  • 6 months later...

Recently I had to revise the code, as it was quite a mess. I had no idea what what going on. So I refactored and here's a much better solution. 

Still I'm only using parmTemplates of Float, Int, Menu, Toggle. Also the code might not work for multiparms. I decided to limit to have only a single disableWhen condition - so there are no detections on that in the code. Rebuilding multi conditionals in the frontend is not straightforward and only confuses the user.

Just import types.py into parms.py and you're good to go.

Parms('your_node').data 

will return a JSON with well structured parameters in folders. Quite cool thing if you want to rebuild the frontend in some web application.

 

parms.py types.py

Edited by JJ FX
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...