diff --git a/client/ayon_houdini/plugins/create/create_node_preset.py b/client/ayon_houdini/plugins/create/create_node_preset.py new file mode 100644 index 0000000000..042f5d0926 --- /dev/null +++ b/client/ayon_houdini/plugins/create/create_node_preset.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- +"""Creator plugin for creating houdini node presets.""" +from ayon_houdini.api import plugin +import hou + + +def _update_node_parmtemplate(node, defaults): + """update node parm template. + + It adds a new folder parm that includes + filepath and operator node selector. + """ + parm_group = node.parmTemplateGroup() + + # Hide unnecessary parameters + for parm in {"execute", "renderdialog"}: + p = parm_group.find(parm) + p.hide(True) + parm_group.replace(parm, p) + + # Create essential parameters + folder_template = hou.FolderParmTemplate( + name="main", + label="Main", + folder_type=hou.folderType.Tabs + ) + + filepath_template = hou.StringParmTemplate( + name="filepath", + label="Preset File", + num_components=1, + default_value=(defaults.get("filepath", ""),), + string_type=hou.stringParmType.FileReference, + tags= { + "filechooser_pattern" : "*.json", + } + ) + + operatore_template = hou.StringParmTemplate( + name="source_node", + label="Source Node", + num_components=1, + default_value=(defaults.get("source_node", ""),), + string_type=hou.stringParmType.NodeReference, + tags= { + "oprelative" : "." + } + ) + + folder_template.addParmTemplate(filepath_template) + folder_template.addParmTemplate(operatore_template) + + # TODO: make the Main and Extra Tab next to each other. + parm_group.insertBefore((0,), folder_template) + + node.setParmTemplateGroup(parm_group) + + +class CreateNodePreset(plugin.HoudiniCreator): + """NodePreset creator. + + Node Presets capture the parameters of the source node. + """ + identifier = "io.ayon.creators.houdini.node_preset" + label = "Node Preset" + product_type = "node_preset" + icon = "gears" + + def create(self, product_name, instance_data, pre_create_data): + + instance_data.update({"node_type": "null"}) + + instance = super(CreateNodePreset, self).create( + product_name, + instance_data, + pre_create_data) + + instance_node = hou.node(instance.get("instance_node")) + + + filepath = "{}{}".format( + hou.text.expandString("$HIP/pyblish/"), + f"{product_name}.json" + ) + source_node = "" + + if self.selected_nodes: + source_node = self.selected_nodes[0].path() + + defaults= { + "filepath": filepath, + "source_node": source_node + } + _update_node_parmtemplate(instance_node, defaults) + + + def get_pre_create_attr_defs(self): + attrs = super().get_pre_create_attr_defs() + + return attrs + self.get_instance_attr_defs() + + def get_network_categories(self): + return [ + hou.ropNodeTypeCategory() + ] diff --git a/client/ayon_houdini/plugins/publish/extract_render_setup.py b/client/ayon_houdini/plugins/publish/extract_render_setup.py new file mode 100644 index 0000000000..b8c7ecc32f --- /dev/null +++ b/client/ayon_houdini/plugins/publish/extract_render_setup.py @@ -0,0 +1,61 @@ +import os +import hou +import json +import pyblish.api + +from ayon_houdini.api import plugin + + +def getparms(node): + + parameters = node.parms() + parameters += node.spareParms() + param_data = {} + + for param in parameters: + if param.parmTemplate().type().name() == 'FolderSet': + continue + + # Add parameter data to the dictionary + # FIXME: I also evaluate expressions. + param_data[param.name()] = param.eval() + + return param_data + + +class ExtractNodePreset(plugin.HoudiniExtractorPlugin): + """Node Preset Extractor for any node.""" + label = "Extract Node Preset" + order = pyblish.api.ExtractorOrder + + families = ["node_preset"] + targets = ["local", "remote"] + + def process(self, instance: pyblish.api.Instance): + if instance.data.get("farm"): + self.log.debug("Should be processed on farm, skipping.") + return + + instance_node = hou.node(instance.data["instance_node"]) + + source_node = instance_node.parm("source_node").evalAsNode() + json_path = instance_node.evalParm("filepath") + + param_data = getparms(source_node) + node_preset = { + "metadata":{ + "type": source_node.type().name() + }, + "param_data": param_data + } + with open(json_path, "w+") as f: + json.dump(node_preset, fp=f, indent=2, sort_keys=True) + + representation = { + "name": "json", + "ext": "json", + "files": os.path.basename(json_path), + "stagingDir": os.path.dirname(json_path), + } + + instance.data.setdefault("representations", []).append(representation)