Beispiel #1
0
    def __init__(self, parent, **kwargs):
        """
        Construction
        """
        # call base init
        super(HoudiniSessionCollector, self).__init__(parent, **kwargs)

        # cache the workfiles app
        self.__workfiles_app = self.parent.engine.apps.get(
            "tk-multi-workfiles2")
        self.houdini_sgtk_outputs = {
            # rops
            hou.ropNodeTypeCategory(): {
                "alembic": "filename",  # alembic cache
                "ifd": "vm_picture",  # mantra render node
            },
        }
        self.houdini_native_outputs = {
            # rops
            hou.ropNodeTypeCategory(): {
                "alembic": "filename",  # alembic cache
                "comp": "copoutput",  # composite
                "ifd": "vm_picture",  # mantra render node
                "opengl": "picture",  # opengl render
                "wren": "wr_picture",  # wren wireframe
            },
        }
    def __init__(self, parent, **kwargs):
        """
        Construction
        """
        # call base init
        super(DDHoudiniSessionCollector, self).__init__(parent, **kwargs)

        self.houdini_sgtk_outputs[
            hou.ropNodeTypeCategory()]["geometry"] = "sopoutput"
        self.houdini_native_outputs[
            hou.ropNodeTypeCategory()]["geometry"] = "sopoutput"
Beispiel #3
0
def findNodeByType(context, pattern):
    import fnmatch

    nodeTypeCategories = {}
    nodeTypeCategories['Object'] = hou.objNodeTypeCategory()
    nodeTypeCategories['Sop'] = hou.sopNodeTypeCategory()
    nodeTypeCategories['Vop'] = hou.vopNodeTypeCategory()
    nodeTypeCategories['Dop'] = hou.dopNodeTypeCategory()
    nodeTypeCategories['Cop2'] = hou.cop2NodeTypeCategory()
    nodeTypeCategories['Chop'] = hou.chopNodeTypeCategory()
    nodeTypeCategories['Shop'] = hou.shopNodeTypeCategory()
    nodeTypeCategories['Driver'] = hou.ropNodeTypeCategory()
    nodeTypeCategories['Top'] = hou.topNodeTypeCategory()
    nodeTypeCategories['Lop'] = hou.lopNodeTypeCategory()

    category = nodeTypeCategories[context]

    nodes = [
        nodetype for nodetypename, nodetype in category.nodeTypes().items()
        if fnmatch.fnmatch(nodetypename, pattern)
    ]

    if nodes:
        return nodes[0]
    else:
        return None
    def _get_exported_alembic_items(self):
        """Scan the file for tk alembic nodes with already exported caches."""

        app = self.parent
        
        # see if the alembicnode app is installed
        alembic_app = app.engine.apps.get("tk-houdini-alembicnode", None)
        if not alembic_app:
            app.log_info(
                "Will not attempt to scan for alembic caches."
                "The 'tk-houdini-alembicnode' app is not installed."
            )
            return []

        # get all the tk alembic nodes in the scene
        tk_alembic_nodes = hou.nodeType(hou.ropNodeTypeCategory(),
            "sgtk_alembic").instances()

        alembic_items = []

        # for each tk alembic node, see if the output file has been 
        # created on disk. The node will have already evaluated the 
        # all th fields, so current version should be correct.
        for tk_alembic_node in tk_alembic_nodes:
            out_path_parm = tk_alembic_node.parm("filename")
            out_path = out_path_parm.menuLabels()[out_path_parm.eval()]

            if os.path.exists(out_path):
                alembic_items.append({
                    "type": "alembic_cache",
                    "name": tk_alembic_node.name(),
                    "other_params": {'path': out_path},
                })

        return alembic_items
Beispiel #5
0
def _setParmInROPChain(rop, parm_name, vals):
    """Set the values for the given parameters in each node of the ROP chain.

    `rop` is the last node in the chain.
    `parm_name` is the name of the parameter or parameter tuple to be set.
    `val` is the parameter values.
    """
    import hou
    rop_stack = [
        rop,
    ]
    visited_rops = []

    while len(rop_stack) > 0:
        cur_rop = rop_stack.pop()

        if type(vals) == type([]) or type(vals) == type(()):
            parm = cur_rop.parmTuple(parm_name)
        else:
            parm = cur_rop.parm(parm_name)

        # Set the parameter if it exists.
        if parm is not None:
            _setParm(parm, vals)

        visited_rops.append(cur_rop)

        # Examine inputs.
        for input_node in cur_rop.inputs():
            if input_node is None:
                continue

            if input_node.type().category() == hou.ropNodeTypeCategory() \
                and input_node not in visited_rops:
                rop_stack.append(input_node)
Beispiel #6
0
def create_rop_in_active_pane(node_type, error_list_obj=None):
    """
    Creates the specified ROP type in the current network pane and moves it to a convenient location

    Args:
        node_type (str): Name of the node type to create. E.g. "ifd"
        error_list_obj (RopErrorList): An instance of RopErrorList class to store any errors or warnings

    Returns:
        hou.RopNode: The new node, or None if failed.
    """
    with ErrorList(error_list_obj) as error_list_obj:

        network_pane = get_network_pane()
        cwd = network_pane.pwd()

        if cwd.childTypeCategory() != hou.ropNodeTypeCategory():
            error_list_obj.add(
                ErrorMessage("Cannot create ROP node in:\n" + cwd.path()))
            return None

        rop_node = cwd.createNode(node_type, exact_type_name=True)
        rop_node.setSelected(True, True)
        rop_node.moveToGoodPosition()
        return rop_node
def high_repair(is_full=False):
    preprocess()
    # High Frequency Pass
    matcher = nodesearch.Name(HDA_name)
    for node in matcher.nodes(hou.node("/obj/"), recursive=True):
        if hou.node(node.path() + "/hf_prepare_3d"):
            node_3d = hou.node(node.path() + "/hf_prepare_3d")
        if hou.node(node.path() + "/hf_optimize_3d"):
            node_op_3d = hou.node(node.path() + "/hf_optimize_3d")
        if hou.node(node.path() + "/hf_prepare_2d"):
            node_2d = hou.node(node.path() + "/hf_prepare_2d")
    '''
  1. Choose 3D Context Region
  '''
    node_3d.bypass(False)
    '''
  2-4. 3D Context Region Optimization
  '''
    node_op_3d.bypass(False)
    '''
  5. Generate 2D Render
  '''
    num_images = len(
        glob.glob(hou.hipFile.name().split(".")[0] + "/*_opening.png"))
    mark_for_destroy = []
    image_paths = []
    cameras = hou.nodeType(hou.objNodeTypeCategory(), "cam").instances()
    for camera in cameras:
        camera_name = camera.name()
        if "oz_camera_" in camera_name and int(filter(
                str.isdigit, camera_name)) > num_images:
            mark_for_destroy.append(camera)
    renders = hou.nodeType(hou.ropNodeTypeCategory(), "ifd").instances()
    for render in renders:
        render_name = render.name()
        if "oz_render_" in render_name:
            if int(filter(str.isdigit, render_name)) <= num_images:
                image_paths.append(render.parm("vm_picture").eval())
                render.render()
            else:
                mark_for_destroy.append(render)
    '''
  6. Map 3D Region -> 2D Render
  7. 2D Repair
  '''
    #render_then_map(image_paths, node_2d)
    render_map_thread = Thread(target=render_then_map,
                               args=(
                                   image_paths,
                                   node_2d,
                                   is_full,
                               ))
    render_map_thread.start()
    '''
  *. Clean-Up
  '''
    for node in mark_for_destroy:
        node.destroy()
    reset_camera_info()
Beispiel #8
0
    def get_all_tk_arnold_nodes(cls):
        """
        Returns a list of all tk-houdini-arnoldnode instances in the current
        session.
        """

        # get all instances of tk arnold nodes
        tk_node_type = TkArnoldNodeHandler.TK_ARNOLD_NODE_TYPE
        return hou.nodeType(hou.ropNodeTypeCategory(), tk_node_type).instances()
Beispiel #9
0
    def get_all_tk_mantra_nodes(cls):
        """
        Returns a list of all tk-houdini-mantranode instances in the current
        session.
        """

        # get all instances of tk mantra nodes
        tk_node_type = TkMantraNodeHandler.TK_MANTRA_NODE_TYPE
        return hou.nodeType(hou.ropNodeTypeCategory(), tk_node_type).instances()
Beispiel #10
0
    def get_all_tk_geometry_nodes(cls):
        """
        Returns a list of all tk-houdini-geometrynode instances in the current
        session.
        """

        tk_node_type = TkGeometryNodeHandler.TK_GEOMETRY_NODE_TYPE

        return hou.nodeType(hou.ropNodeTypeCategory(),
                            tk_node_type).instances()
Beispiel #11
0
    def get_all_tk_file_nodes(cls):
        """
        Returns a list of all tk-houdini-filenode instances in the current
        session.
        """

        tk_node_type = TkFileNodeHandler.TK_FILE_NODE_TYPE

        return hou.nodeType(hou.ropNodeTypeCategory(),
                            tk_node_type).instances()
    def process(self, context):

        node_type = hou.nodeType(hou.ropNodeTypeCategory(), 'alembic')
        abc_nodes = node_type.instances()

        for node in list(abc_nodes):

            instance = context.create_instance(name=node.name())
            instance.set_data('family', value='cache')
            instance.set_data('path', value=node.path())
            instance.add(node)
Beispiel #13
0
    def get_nodes():
        """
        Returns a list of all SGTK Mantra nodes.

        :returns: All SGTK Mantra nodes.
        :rtype: List
        """
        node_class = ToolkitMantraNodeHandler.SG_NODE_CLASS
        rop_nodes = hou.nodeType(hou.ropNodeTypeCategory(),
                                 node_class).instances()
        return rop_nodes
Beispiel #14
0
    def get_nodes():
        """
        Returns a list of all SGTK Mantra nodes.

        :returns: All SGTK Mantra nodes.
        :rtype: List
        """
        node_class = ToolkitMantraNodeHandler.SG_NODE_CLASS
        rop_nodes = hou.nodeType(hou.ropNodeTypeCategory(),
                                 node_class).instances()
        return rop_nodes
    def ExistingRenderers(self):
        # add some existing renderers
        renderers = ["ifd"]
        # plugin_renderers = ["Redshift_ROP", "ris::22", "arnold","opengl"]
        plugin_renderers = ["arnold", "ris::22"]

        for node_type in hou.ropNodeTypeCategory().nodeTypes().values():
            for renderer in plugin_renderers:
                if renderer in node_type.name():
                    renderers.append(renderer)

        return renderers
Beispiel #16
0
 def get_nodes(self, class_=None):
     """
     Returns a list of sgtk nodes
     """
     node_class = ToolkitGeometryNodeHandler.SG_NODE_CLASS
     sop = True if not class_ or class_ == 'sop' else False
     rop = True if not class_ or class_ == 'rop' else False
     nodes = []
     if sop:
         nodes += hou.nodeType(hou.sopNodeTypeCategory(),
                               node_class).instances()
     if rop:
         nodes += hou.nodeType(hou.ropNodeTypeCategory(),
                               node_class).instances()
     return nodes
Beispiel #17
0
    def _get_alembic_items(self):
        """Scan the file for tk alembic nodes to potentially publish."""

        app = self.parent
        
        # see if the alembicnode app is installed
        alembic_app = app.engine.apps.get("tk-houdini-alembicnode", None)
        if not alembic_app:
            app.log_info(
                "Will not attempt to scan for alembic caches."
                "The 'tk-houdini-alembicnode' app is not installed."
            )
            return []

        # get all the tk alembic nodes in the scene
        tk_alembic_nodes = hou.nodeType(hou.ropNodeTypeCategory(),
            "sgtk_alembic").instances()

        alembic_items = []

        # add all tk alembic nodes to the list of secondary publish items.
        for tk_alembic_node in tk_alembic_nodes:

            is_bypassed = tk_alembic_node.isBypassed()

            out_path_parm = tk_alembic_node.parm("filename")
            out_path = out_path_parm.menuLabels()[out_path_parm.eval()]

            # normalize the path
            out_path = os.path.normpath(out_path)

            # only select the item if the path exists and the node is not
            # bypassed
            should_select = out_path and os.path.exists(out_path) and \
                not is_bypassed

            alembic_items.append({
                "name": tk_alembic_node.name(),
                "type": "alembic_cache",
                "description": "Full Path: %s" % (tk_alembic_node.path(),),
                "selected": should_select,
                "other_params": {
                    "path": out_path,
                    "node": tk_alembic_node,
                },
            })

        return alembic_items
Beispiel #18
0
    def get_all_tk_alembic_nodes(cls):
        """
        Returns a list of all tk-houdini-alembicnode instances in the current
        session.
        """

        tk_node_type = TkAlembicNodeHandler.TK_ALEMBIC_NODE_TYPE

        # get all instances of tk alembic rop/sop nodes
        tk_alembic_nodes = []
        tk_alembic_nodes.extend(
            hou.nodeType(hou.sopNodeTypeCategory(), tk_node_type).instances())
        tk_alembic_nodes.extend(
            hou.nodeType(hou.ropNodeTypeCategory(), tk_node_type).instances())

        return tk_alembic_nodes
Beispiel #19
0
    def get_all_tk_geometry_nodes(cls):
        """
        Returns a list of all tk-houdini-geometrynode instances in the current
        session.
        """

        tk_node_type = ToolkitGeometryNodeHandler.SG_NODE_CLASS

        # get all instances of tk geometry rop/sop nodes
        tk_geometry_nodes = []
        tk_geometry_nodes.extend(
            hou.nodeType(hou.sopNodeTypeCategory(), tk_node_type).instances())
        tk_geometry_nodes.extend(
            hou.nodeType(hou.ropNodeTypeCategory(), tk_node_type).instances())

        return tk_geometry_nodes
    def get_all_tk_alembic_nodes(cls):
        """
        Returns a list of all tk-houdini-alembicnode instances in the current
        session.
        """

        tk_node_type = TkAlembicNodeHandler.TK_ALEMBIC_NODE_TYPE

        # get all instances of tk alembic rop/sop nodes
        tk_alembic_nodes = []
        tk_alembic_nodes.extend(
            hou.nodeType(hou.sopNodeTypeCategory(),
                         tk_node_type).instances())
        tk_alembic_nodes.extend(
            hou.nodeType(hou.ropNodeTypeCategory(),
                         tk_node_type).instances())

        return tk_alembic_nodes
Beispiel #21
0
    def display_caching_nodes(self):
        self.listModel.clear()
        self.opening_file()

        # Get instances type for caching
        out_render = hou.nodeType(hou.ropNodeTypeCategory(), "geometry")
        rendering_node = out_render.instances()

        # Get SOP filecache node
        sop_render = hou.nodeType(hou.sopNodeTypeCategory(), "rop_geometry")
        geometry_node = sop_render.instances()

        # Create empty dictionnary containing the render nodes and add the nodes
        self._add_dic(rendering_node, "ROP", self.rendering_nodes)
        self._add_dic(geometry_node, "SOP", self.rendering_nodes)

        # Update QComboBox
        i = 0
        self.nodeType.clear()
        for key, value in self.rendering_nodes.items():
            self.nodeType.insertItem(i, key)
            i += 1
        self._update_list()
Beispiel #22
0
    def convert_to_regular_file_nodes(cls, app):
        """Convert Toolkit file nodes to regular file nodes.

        :param app: The calling Toolkit Application

        """

        tk_node_type = TkFileNodeHandler.TK_FILE_NODE_TYPE

        # determine the surface operator type for this class of node
        sop_types = hou.sopNodeTypeCategory().nodeTypes()
        sop_type = sop_types[tk_node_type]

        # determine the render operator type for this class of node
        rop_types = hou.ropNodeTypeCategory().nodeTypes()
        rop_type = rop_types[tk_node_type]

        # get all instances of tk file rop/sop nodes
        tk_file_nodes = []
        tk_file_nodes.extend(
            hou.nodeType(hou.sopNodeTypeCategory(), tk_node_type).instances())
        tk_file_nodes.extend(
            hou.nodeType(hou.ropNodeTypeCategory(), tk_node_type).instances())

        if not tk_file_nodes:
            app.log_debug("No Toolkit file Nodes found for conversion.")
            return

        # iterate over all the tk file nodes and attempt to convert them
        for tk_file_node in tk_file_nodes:

            # determine the corresponding, built-in operator type
            if tk_file_node.type() == sop_type:
                file_operator = cls.HOU_SOP_GEOMETRY_TYPE
            else:
                app.log_warning("Unknown type for node '%s': %s'" %
                                (tk_file_node.name(), tk_file_node.type()))
                continue

            # create a new, regular file node
            file_node = tk_file_node.parent().createNode(file_operator)

            # copy the file parms value to the new node
            filename = _get_output_menu_label(
                tk_file_node.parm(cls.NODE_OUTPUT_PATH_PARM))
            file_node.parm(cls.NODE_OUTPUT_PATH_PARM).set(filename)

            # copy across knob values
            _copy_parm_values(tk_file_node,
                              file_node,
                              excludes=[cls.NODE_OUTPUT_PATH_PARM])

            # store the file output profile name in the user data so that we
            # can retrieve it later.
            output_profile_parm = tk_file_node.parm(cls.TK_OUTPUT_PROFILE_PARM)

            # copy the inputs and move the outputs
            _copy_inputs(tk_file_node, file_node)
            if file_operator == cls.HOU_SOP_GEOMETRY_TYPE:
                _save_outputs_to_user_data(tk_file_node, file_node)

            # make the new node the same color
            file_node.setColor(tk_file_node.color())

            # remember the name and position of the original tk file node
            tk_file_node_name = tk_file_node.name()
            tk_file_node_pos = tk_file_node.position()

            # destroy the original tk file node
            tk_file_node.destroy()

            # name and reposition the new, regular file node to match the
            # original
            file_node.setName(tk_file_node_name)
            file_node.setPosition(tk_file_node_pos)

            app.log_debug("Converted: Tk file node '%s' to file node." %
                          (tk_file_node_name, ))
    def convert_back_to_tk_alembic_nodes(cls, app):
        """Convert Alembic nodes back to Toolkit Alembic nodes.

        :param app: The calling Toolkit Application

        Note: only converts nodes that had previously been Toolkit Alembic
        nodes.

        """

        # get all rop/sop alembic nodes in the session
        alembic_nodes = []
        alembic_nodes.extend(hou.nodeType(hou.sopNodeTypeCategory(),
            cls.HOU_SOP_ALEMBIC_TYPE).instances())
        alembic_nodes.extend(hou.nodeType(hou.ropNodeTypeCategory(),
            cls.HOU_ROP_ALEMBIC_TYPE).instances())

        if not alembic_nodes:
            app.log_debug("No Alembic Nodes found for conversion.")
            return

        # the tk node type we'll be converting to
        tk_node_type = TkAlembicNodeHandler.TK_ALEMBIC_NODE_TYPE

        # iterate over all the alembic nodes and attempt to convert them
        for alembic_node in alembic_nodes:

            # get the user data dictionary stored on the node
            user_dict = alembic_node.userDataDict()

            # get the output_profile from the dictionary
            tk_output_profile_name = user_dict.get(
                cls.TK_OUTPUT_PROFILE_NAME_KEY)

            if not tk_output_profile_name:
                app.log_warning(
                    "Almbic node '%s' does not have an output profile name. "
                    "Can't convert to Tk Alembic node. Continuing." %
                    (alembic_node.name(),)
                )
                continue

            # create a new, Toolkit Alembic node:
            tk_alembic_node = alembic_node.parent().createNode(tk_node_type)

            # find the index of the stored name on the new tk alembic node
            # and set that item in the menu.
            try:
                output_profile_parm = tk_alembic_node.parm(
                    TkAlembicNodeHandler.TK_OUTPUT_PROFILE_PARM)
                output_profile_index = output_profile_parm.menuLabels().index(
                    tk_output_profile_name)
                output_profile_parm.set(output_profile_index)
            except ValueError:
                app.log_warning("No output profile found named: %s" % 
                    (tk_output_profile_name,))

            # copy over all parameter values except the output path 
            _copy_parm_values(alembic_node, tk_alembic_node,
                excludes=[cls.NODE_OUTPUT_PATH_PARM])

            # copy the inputs and move the outputs
            _copy_inputs(alembic_node, tk_alembic_node)

            # determine the built-in operator type
            if alembic_node.type().name() == cls.HOU_SOP_ALEMBIC_TYPE:
                _restore_outputs_from_user_data(alembic_node, tk_alembic_node)
            elif alembic_node.type().name() == cls.HOU_ROP_ALEMBIC_TYPE:
                _move_outputs(alembic_node, tk_alembic_node)

            # make the new node the same color. the profile will set a color, 
            # but do this just in case the user changed the color manually
            # prior to the conversion.
            tk_alembic_node.setColor(alembic_node.color())

            # remember the name and position of the original alembic node
            alembic_node_name = alembic_node.name()
            alembic_node_pos = alembic_node.position()

            # destroy the original alembic node
            alembic_node.destroy()

            # name and reposition the new, regular alembic node to match the
            # original
            tk_alembic_node.setName(alembic_node_name)
            tk_alembic_node.setPosition(alembic_node_pos)

            app.log_debug("Converted: Alembic node '%s' to TK Alembic node."
                % (alembic_node_name,))
Beispiel #24
0
# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit 
# Source Code License included in this distribution package. See LICENSE.
# By accessing, using, copying or modifying this work you indicate your 
# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights 
# not expressly granted therein are reserved by Shotgun Software Inc.

import os
import hou
import sgtk

HookBaseClass = sgtk.get_hook_baseclass()

# A dict of dicts organized by category, type and output file parm
_HOUDINI_OUTPUTS = {
    # rops
    hou.ropNodeTypeCategory(): {
        "alembic": "filename",    # alembic cache
        "comp": "copoutput",      # composite
        "ifd": "vm_picture",      # mantra render node
        "opengl": "picture",      # opengl render
        "wren": "wr_picture",     # wren wireframe
    },
}


class HoudiniSessionCollector(HookBaseClass):
    """
    Collector that operates on the current houdini session. Should inherit from
    the basic collector hook.
    """
Beispiel #25
0
    def convert_geometry_to_sg_nodes(self):
        """
        Utility function to convert all Geometry nodes to Shotgun
        Geometry nodes (only converts Geometry nodes that were previously
        Shotgun Geometry nodes)

        # Example use:
        import sgtk
        eng = sgtk.platform.current_engine()
        app = eng.apps["tk-houdini-geometrynode"]
        # Convert previously converted Geometry nodes back to
        # Shotgun Geometry nodes:
        app.convert_from_geometry_nodes()
        """

        # get geometry nodes:
        sop_nodes = hou.nodeType(hou.sopNodeTypeCategory(),
                                 'rop_geometry').instances()
        rop_nodes = hou.nodeType(hou.ropNodeTypeCategory(),
                                 'geometry').instances()
        nodes = sop_nodes + rop_nodes
        for n in nodes:
            try:
                user_dict = n.userDataDict()

                profile = user_dict.get('tk_profile_name')

                if not profile:
                    # can't convert to a Shotgun Geometry Node
                    # as we have missing parameters!
                    continue

                # set as selected:
                # wn.setSelected(True)
                node_name = n.name()
                node_pos = n.position()

                self._app.log_debug('Converting node: {0}'.format(n.name()))
                self._app.log_debug('path: {0}'.format(n.path()))

                # create new Shotgun Geometry node:
                node_class = ToolkitGeometryNodeHandler.SG_NODE_CLASS
                new_sg_n = n.parent().createNode(node_class)

                # set the profile
                try:
                    parm = new_sg_n.parm(
                        ToolkitGeometryNodeHandler.PARM_CONFIG)
                    index = parm.menuLabels().index(profile)
                    parm.set(index)
                except ValueError:
                    pass

                # copy across and knob values from the internal geometry node.
                exclude = ['sopoutput']
                self.__copy_parm_values(n, new_sg_n, exclude)

                # Copy inputs and move outputs
                self.__copy_inputs_to_node(n, new_sg_n)
                self.__move_outputs_to_node(n, new_sg_n)
                self.__move_outputs_from_user_data_to_node(n, new_sg_n)
                self.__copy_color(n, new_sg_n)

                # delete original node:
                n.destroy()

                # rename new node:
                new_sg_n.setName(node_name)
                new_sg_n.setPosition(node_pos)
            except Exception as err:
                self._app.log_warning(err)
                msg = 'Problems converting node: {0}'.format(n.path())
                self._app.log_warning(msg)
Beispiel #26
0
def isActive():
    return hou.nodeType(hou.ropNodeTypeCategory(), "arnold") is not None
Beispiel #27
0
    def convert_alembic_to_sg_nodes(self):
        """
        Utility function to convert all Alembic nodes to Shotgun
        Alembic nodes (only converts Alembic nodes that were previously
        Shotgun Alembic nodes)

        # Example use:
        import sgtk
        eng = sgtk.platform.current_engine()
        app = eng.apps["tk-houdini-alembicnode"]
        # Convert previously converted Alembic nodes back to
        # Shotgun Alembic nodes:
        app.convert_from_alembic_nodes()
        """

        # get alembic nodes:
        sop_nodes = hou.nodeType(hou.sopNodeTypeCategory(),
                                 'rop_alembic').instances()
        rop_nodes = hou.nodeType(hou.ropNodeTypeCategory(),
                                 'alembic').instances()
        nodes = sop_nodes + rop_nodes
        for n in nodes:

            user_dict = n.userDataDict()

            profile = user_dict.get('tk_profile_name')

            if not profile:
                # can't convert to a Shotgun Alembic Node
                # as we have missing parameters!
                continue

            # set as selected:
            # wn.setSelected(True)
            node_name = n.name()
            node_pos = n.position()

            # create new Shotgun Alembic node:
            node_class = ToolkitAlembicNodeHandler.SG_NODE_CLASS
            new_sg_n = n.parent().createNode(node_class)

            # set the profile
            try:
                parm = new_sg_n.parm(ToolkitAlembicNodeHandler.PARM_CONFIG)
                index = parm.menuLabels().index(profile)
                parm.set(index)
            except ValueError:
                pass

            # copy across and knob values from the internal write node.
            exclude = ['filename']
            self.__copy_parm_values(n, new_sg_n, exclude)

            # Copy inputs and move outputs
            self.__copy_inputs_to_node(n, new_sg_n)
            self.__move_outputs_to_node(n, new_sg_n)
            self.__copy_color(n, new_sg_n)

            # delete original node:
            n.destroy()

            # rename new node:
            new_sg_n.setName(node_name)
            new_sg_n.setPosition(node_pos)
def _all_job_nodes():
    return hou.nodeType(
        hou.ropNodeTypeCategory(),
        "conductor::job::0.1").instances()
    def _get_rendered_image_items(self):
        """Scan the file for tk mantra nodes to potentially publish."""

        app = self.parent

        # see if the mantranode app is installed
        mantra_app = app.engine.apps.get("tk-houdini-mantranode", None)
        if not mantra_app:
            app.log_info(
                "Will not attempt to scan for rendered images."
                "The 'tk-houdini-mantranode' app is not installed."
            )
            return []

        # find all the tk mantra nodes
        tk_mantra_nodes = hou.nodeType(hou.ropNodeTypeCategory(),
            "sgtk_mantra").instances()

        render_items = []

        # get the current version from the work file
        work_template = mantra_app.get_template("work_file_template")
        scene_name = str(hou.hipFile.name())
        scene_path = os.path.abspath(scene_name)
        fields = work_template.get_fields(scene_path)
        cur_version = fields["version"]
        fields["SEQ"] = "FORMAT: %d"

        # get the output_profiles for the app. More efficient to do this here
        # than to repeat this logic per item in the secondary publish hook.
        output_profiles = {}
        for output_profile in mantra_app.get_setting("output_profiles"):
            name = output_profile["name"]
            output_profiles[name] = output_profile

        # for each mantra node, see which output profile is selected.
        # get the template for the selected profile. the validation hook will
        # check see if there are any images on disk matching the pattern
        for tk_mantra_node in tk_mantra_nodes:

            output_profile_parm = tk_mantra_node.parm("sgtk_output_profile")
            output_profile_name = \
                output_profile_parm.menuLabels()[output_profile_parm.eval()]
            output_profile = output_profiles[output_profile_name]
            output_template = mantra_app.get_template_by_name(
                output_profile["output_render_template"])

            is_bypassed = tk_mantra_node.isBypassed()

            paths = mantra_app.engine.tank.abstract_paths_from_template(
                output_template, fields)

            # normalize the paths
            paths = [os.path.normpath(p) for p in paths]

            # only select the item if the output path exists and the node is
            # not bypassed.
            should_select = len(paths) == 1 and not is_bypassed

            render_items.append({
                "type": "rendered_image",
                "name": tk_mantra_node.name(),
                "description": "Full Path: %s" % (tk_mantra_node.path(),),
                "selected": should_select,
                "other_params": {
                    "paths": paths,
                    "node": tk_mantra_node,
                },
            })

        return render_items
Beispiel #30
0
    def convert_back_to_tk_mantra_nodes(cls, app):
        """Convert Mantra nodes back to Toolkit Mantra nodes.

        :param app: The calling Toolkit Application

        Note: only converts nodes that had previously been Toolkit Mantra
        nodes.

        """

        # get all instances of the built-in mantra nodes
        mantra_nodes = hou.nodeType(hou.ropNodeTypeCategory(),
                                    cls.HOU_MANTRA_NODE_TYPE).instances()

        if not mantra_nodes:
            app.log_debug("No Mantra Nodes found for conversion.")
            return

        # iterate over all the mantra nodes and attempt to convert them
        for mantra_node in mantra_nodes:

            # get the user data dictionary stored on the node
            user_dict = mantra_node.userDataDict()

            # get the output_profile from the dictionary
            tk_output_profile_name = user_dict.get(
                cls.TK_OUTPUT_PROFILE_NAME_KEY)

            if not tk_output_profile_name:
                app.log_warning(
                    "Mantra node '%s' does not have an output profile name. "
                    "Can't convert to Tk Mantra node. Continuing." %
                    (mantra_node.name(), ))
                continue

            # create new Shotgun Write node:
            tk_node_type = TkMantraNodeHandler.TK_MANTRA_NODE_TYPE
            tk_mantra_node = mantra_node.parent().createNode(tk_node_type)

            # find the index of the stored name on the new tk mantra node
            # and set that item in the menu.
            try:
                output_profile_parm = tk_mantra_node.parm(
                    TkMantraNodeHandler.TK_OUTPUT_PROFILE_PARM)
                output_profile_index = output_profile_parm.menuLabels().index(
                    tk_output_profile_name)
                output_profile_parm.set(output_profile_index)
            except ValueError:
                app.log_warning("No output profile found named: %s" %
                                (tk_output_profile_name, ))

            # copy over all parameter values except the output path
            _copy_parm_values(mantra_node, tk_mantra_node, excludes=[])

            # explicitly copy AOV settings to the new tk mantra node
            plane_numbers = _get_extra_plane_numbers(mantra_node)
            for plane_number in plane_numbers:
                plane_parm_name = cls.TK_EXTRA_PLANES_NAME % (plane_number, )
                aov_name = user_dict.get(plane_parm_name)
                tk_mantra_node.parm(plane_parm_name).set(aov_name)

            # copy the inputs and move the outputs
            _copy_inputs(mantra_node, tk_mantra_node)
            _move_outputs(mantra_node, tk_mantra_node)

            # make the new node the same color. the profile will set a color,
            # but do this just in case the user changed the color manually
            # prior to the conversion.
            tk_mantra_node.setColor(mantra_node.color())

            # remember the name and position of the original mantra node
            mantra_node_name = mantra_node.name()
            mantra_node_pos = mantra_node.position()

            # destroy the original mantra node
            mantra_node.destroy()

            # name and reposition the new, regular mantra node to match the
            # original
            tk_mantra_node.setName(mantra_node_name)
            tk_mantra_node.setPosition(mantra_node_pos)

            app.log_debug("Converted: Mantra node '%s' to TK Mantra node." %
                          (mantra_node_name, ))
def _all_submitter_nodes():
    return hou.nodeType(
        hou.ropNodeTypeCategory(),
        "conductor::submitter::0.1").instances()
Beispiel #32
0
    def convert_back_to_tk_alembic_nodes(cls, app):
        """Convert Alembic nodes back to Toolkit Alembic nodes.

        :param app: The calling Toolkit Application

        Note: only converts nodes that had previously been Toolkit Alembic
        nodes.

        """

        # get all rop/sop alembic nodes in the session
        alembic_nodes = []
        alembic_nodes.extend(
            hou.nodeType(hou.sopNodeTypeCategory(),
                         cls.HOU_SOP_ALEMBIC_TYPE).instances())
        alembic_nodes.extend(
            hou.nodeType(hou.ropNodeTypeCategory(),
                         cls.HOU_ROP_ALEMBIC_TYPE).instances())

        if not alembic_nodes:
            app.log_debug("No Alembic Nodes found for conversion.")
            return

        # the tk node type we'll be converting to
        tk_node_type = TkAlembicNodeHandler.TK_ALEMBIC_NODE_TYPE

        # iterate over all the alembic nodes and attempt to convert them
        for alembic_node in alembic_nodes:

            # get the user data dictionary stored on the node
            user_dict = alembic_node.userDataDict()

            # get the output_profile from the dictionary
            tk_output_profile_name = user_dict.get(
                cls.TK_OUTPUT_PROFILE_NAME_KEY)

            if not tk_output_profile_name:
                app.log_warning(
                    "Almbic node '%s' does not have an output profile name. "
                    "Can't convert to Tk Alembic node. Continuing." %
                    (alembic_node.name(), ))
                continue

            # create a new, Toolkit Alembic node:
            tk_alembic_node = alembic_node.parent().createNode(tk_node_type)

            # find the index of the stored name on the new tk alembic node
            # and set that item in the menu.
            try:
                output_profile_parm = tk_alembic_node.parm(
                    TkAlembicNodeHandler.TK_OUTPUT_PROFILE_PARM)
                output_profile_index = output_profile_parm.menuLabels().index(
                    tk_output_profile_name)
                output_profile_parm.set(output_profile_index)
            except ValueError:
                app.log_warning("No output profile found named: %s" %
                                (tk_output_profile_name, ))

            # copy over all parameter values except the output path
            _copy_parm_values(alembic_node,
                              tk_alembic_node,
                              excludes=[cls.NODE_OUTPUT_PATH_PARM])

            # copy the inputs and move the outputs
            _copy_inputs(alembic_node, tk_alembic_node)

            # determine the built-in operator type
            if alembic_node.type().name() == cls.HOU_SOP_ALEMBIC_TYPE:
                _restore_outputs_from_user_data(alembic_node, tk_alembic_node)
            elif alembic_node.type().name() == cls.HOU_ROP_ALEMBIC_TYPE:
                _move_outputs(alembic_node, tk_alembic_node)

            # make the new node the same color. the profile will set a color,
            # but do this just in case the user changed the color manually
            # prior to the conversion.
            tk_alembic_node.setColor(alembic_node.color())

            # remember the name and position of the original alembic node
            alembic_node_name = alembic_node.name()
            alembic_node_pos = alembic_node.position()

            # destroy the original alembic node
            alembic_node.destroy()

            # name and reposition the new, regular alembic node to match the
            # original
            tk_alembic_node.setName(alembic_node_name)
            tk_alembic_node.setPosition(alembic_node_pos)

            app.log_debug("Converted: Alembic node '%s' to TK Alembic node." %
                          (alembic_node_name, ))
Beispiel #33
0
    def convert_sg_to_alembic_nodes(self):
        """
        Utility function to convert all Shotgun Alembic nodes to regular
        Alembic nodes.

        # Example use:
        import sgtk
        eng = sgtk.platform.current_engine()
        app = eng.apps["tk-houdini-alembicnode"]
        # Convert Shotgun Alembic nodes to Alembic nodes:
        app.convert_to_alembic_nodes()
        """

        # get sgtk alembic nodes:
        sg_nodes = self.get_nodes()
        for sg_n in sg_nodes:
            sop_types = hou.sopNodeTypeCategory().nodeTypes()
            sop_type = sop_types[ToolkitAlembicNodeHandler.SG_NODE_CLASS]
            rop_types = hou.ropNodeTypeCategory().nodeTypes()
            rop_type = rop_types[ToolkitAlembicNodeHandler.SG_NODE_CLASS]
            is_sop = sg_n.type() == sop_type
            is_rop = sg_n.type() == rop_type

            # set as selected:
            node_name = sg_n.name()
            node_pos = sg_n.position()

            # create new regular Alembic node:

            if is_sop:
                alembic_operator = 'rop_alembic'
            elif is_rop:
                alembic_operator = 'alembic'
            else:
                continue

            new_n = sg_n.parent().createNode(alembic_operator)

            # copy across file parms:
            filename = self.__get_menu_label(sg_n.parm('filename'))
            new_n.parm('filename').set(filename)

            # copy across any knob values from the internal alembic node.
            # parmTuples
            exclude = ['filename']
            self.__copy_parm_values(sg_n, new_n, exclude)

            # Store Toolkit specific information on write node
            # so that we can reverse this process later

            # Profile Name
            new_n.setUserData('tk_profile_name',
                              self.get_node_profile_name(sg_n))

            # Copy inputs and move outputs
            self.__copy_color(sg_n, new_n)
            self.__copy_inputs_to_node(sg_n, new_n)
            if is_rop:
                self.__move_outputs_to_node(sg_n, new_n)
            elif is_sop:
                self.__move_outputs_from_node_to_user_data(sg_n, new_n)

            # delete original node:
            sg_n.destroy()

            # rename new node:
            new_n.setName(node_name)
            new_n.setPosition(node_pos)
Beispiel #34
0
    def renderIfdSubmit(self, me, background=True, rrControl=True):
        # get input nodes
        nodes = me.inputAncestors()
        paths = []

        # get parameters from the node
        mem = me.evalParm("mem")
        priority = me.evalParm("priority")
        maxClients = me.evalParm("maxClients")
        rrSubmitter = me.evalParm("rrSubmitter")
        dry = me.evalParm("dry")

        # keep only mantra nodes
        nodesNew = []
        for node in nodes:
            if node.type() == hou.nodeType(hou.ropNodeTypeCategory(), "ifd"):
                nodesNew.append(node)
        nodes = nodesNew

        # enable IFD saving parameter, derive ifd path from image path and save path to list
        for node in nodes:
            try:
                pathImg = node.parm("vm_picture").unexpandedString()
                #pathImg = pathImg.split("/")
                ##pathImg.insert(len(pathImg)-1, "ifd")
                #pathImg[-2] = pathImg[-2] + "_ifd"
                #pathImg = "/".join(pathImg)
                #pathImg = pathImg.split(".")
                #pathImg[-1] = "ifd"
                #pathImg = ".".join(pathImg)
                pathImg = ifdPath(pathImg)
                node.parm("soho_diskfile").set(pathImg)
            except:
                #node.parm("soho_diskfile").setExpression("hou.session.hpipe.idPath(hou.node(\"" + oldPath + "\"), \"deep\", src=\"ifd\" )", language=hou.exprLanguage.Python)
                pass
            node.parm("soho_outputmode").set(1)
            firstFrame = node.evalParm("f1")
            pathCurrent = node.parm("soho_diskfile").evalAtFrame(firstFrame)
            paths.append(pathCurrent)
            # enable and set post render script
            if background:
                script = self.submitToRR(file=pathCurrent,
                                         mem=mem,
                                         priority=priority,
                                         maxClients=maxClients,
                                         rrSubmitter=False,
                                         dry=True)
                script = "unix \'" + script.replace(
                    "\\", "/"
                ) + " >>& //bigfoot/jellyfish/00_pipeline/houdini/renderfarm.log\'"
                node.setParms({
                    "tpostrender": 1,
                    "lpostrender": "hscript",
                    "postrender": script
                })

        # execute in background / normal
        if not dry:
            if background:
                hou.hipFile.save()
                for node in nodes:
                    node.parm("executebackground").pressButton()
            else:
                for node in nodes:
                    node.render()

        # disable IFD generation parameter and send to RR if not background
        for i, node in enumerate(nodes):
            node.parm("soho_outputmode").set(0)
            if not background:
                self.submitToRR(file=paths[i],
                                mem=mem,
                                priority=priority,
                                maxClients=maxClients,
                                rrSubmitter=rrSubmitter,
                                dry=dry,
                                log=True)
            else:
                node.setParms({"tpostrender": 0})

        # run rrControl
        if rrControl:
            subprocess.Popen(self.rr_root + "rrControl.exe " + self.rr_ui[1])
    def process(self, context):

        # Find nodes by class.
        nodes = []

        node_type = hou.nodeType("Driver/ifd")
        nodes.extend(node_type.instances())

        node_type = hou.nodeType(hou.ropNodeTypeCategory(), "alembic")
        nodes.extend(node_type.instances())

        node_type = hou.nodeType(hou.ropNodeTypeCategory(), "dop")
        nodes.extend(node_type.instances())

        node_type = hou.nodeType(hou.ropNodeTypeCategory(), 'geometry')
        nodes.extend(node_type.instances())

        # Categorize nodes based on whether they are in a network box starting
        # with "remote".
        nodes_local = list(nodes)
        for box in hou.node("out").networkBoxes():
            if box.name().lower().startswith("remote"):
                for node in box.nodes():
                    if node in nodes_local:
                        nodes_local.remove(node)

        # Creating instances per node.
        for node in nodes:

            # Haven't figured out distributed simulation yet, so ignoring it as
            # a special case.
            if node.type().name() == "dop" and node not in nodes_local:
                continue

            instance = context.create_instance(name=node.name())
            instance.data["publish"] = not node.isBypassed()
            instance.add(node)

            # Determine node type specifics.
            node_type = ""
            category = ""
            output_parm = ""

            if node.type().name() == "ifd":
                node_type = "mantra"
                category = "img"
                output_parm = "vm_picture"

                # Rendering *.ifd files.
                if node.parm("soho_outputmode").eval():
                    category = "render"
                    output_parm = "soho_diskfile"

            if node.type().name() == "alembic":
                node_type = "alembic"
                category = "cache"
                output_parm = "filename"

            if node.type().name() == "dop":
                node_type = "dynamics"
                category = "cache"
                output_parm = "dopoutput"

            if node.type().name() == "geometry":
                node_type = "geometry"
                category = "cache"
                output_parm = "sopoutput"

            # Get expected output files.
            files = []
            if node.parm("trange").eval() == 0:
                frame = int(hou.frame())
                files.append(node.parm(output_parm).evalAtFrame(frame))
            else:
                start = node.parm("f1").eval()
                end = node.parm("f2").eval()
                step = node.parm("f3").eval()
                for frame in range(int(start), int(end) + 1, int(step)):
                    files.append(node.parm(output_parm).evalAtFrame(frame))

            # Except for alembic output that only ever outputs to a single file
            if node_type == "alembic":
                files = [files[0]]

            # Get extension
            ext = os.path.splitext(files[0])[1]
            # Special case for *.bgeo.sc files since it was two "extensions".
            if files[0].endswith(".bgeo.sc"):
                ext = ".bgeo.sc"

            # Create output collection.
            collections = clique.assemble(files, minimum_items=1)[0]
            collection = None
            for col in collections:
                if col.format("{tail}") == ext:
                    collection = col

            instance.data["collection"] = collection

            # Assigning families.
            families = [node_type, category, ext[1:]]
            label = node.name() + " - " + category
            if node in nodes_local:
                families += ["local"]
                instance.data["label"] = label + " - local"
            else:
                families += ["remote"]
                instance.data["label"] = label + " - remote"

            instance.data["families"] = families
            instance.data["family"] = category
Beispiel #36
0
# This work is provided "AS IS" and subject to the Shotgun Pipeline Toolkit
# Source Code License included in this distribution package. See LICENSE.
# By accessing, using, copying or modifying this work you indicate your
# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights
# not expressly granted therein are reserved by Shotgun Software Inc.

import os
import hou
import sgtk

HookBaseClass = sgtk.get_hook_baseclass()

# A dict of dicts organized by category, type and output file parm
_HOUDINI_OUTPUTS = {
    # rops
    hou.ropNodeTypeCategory(): {
        "alembic": "filename",  # alembic cache
        "comp": "copoutput",  # composite
        "ifd": "vm_picture",  # mantra render node
        "opengl": "picture",  # opengl render
        "wren": "wr_picture",  # wren wireframe
    },
}


class HoudiniSessionCollector(HookBaseClass):
    """
    Collector that operates on the current houdini session. Should inherit from
    the basic collector hook.
    """
    @property
Beispiel #37
0
    def convert_sg_to_geometry_nodes(self):
        """
        Utility function to convert all Shotgun Geometry nodes to regular
        Geometry nodes.

        # Example use:
        import sgtk
        eng = sgtk.platform.current_engine()
        app = eng.apps["tk-houdini-geometrynode"]
        # Convert Shotgun Geometry nodes to Geometry nodes:
        app.convert_to_geometry_nodes()
        """

        # get sgtk geometry nodes:
        sg_nodes = self.get_nodes()
        for sg_n in sg_nodes:
            try:
                sop_types = hou.sopNodeTypeCategory().nodeTypes()
                sop_type = sop_types[ToolkitGeometryNodeHandler.SG_NODE_CLASS]
                rop_types = hou.ropNodeTypeCategory().nodeTypes()
                rop_type = rop_types[ToolkitGeometryNodeHandler.SG_NODE_CLASS]
                is_sop = sg_n.type() == sop_type
                is_rop = sg_n.type() == rop_type

                # set as selected:
                node_name = sg_n.name()
                node_pos = sg_n.position()

                self._app.log_debug('Converting node: {0}'.format(sg_n.name()))
                self._app.log_debug('path: {0}'.format(sg_n.path()))

                # create new regular Geometry node:

                if is_sop:
                    geometry_operator = 'rop_geometry'
                elif is_rop:
                    geometry_operator = 'geometry'
                else:
                    continue

                new_n = sg_n.parent().createNode(geometry_operator)

                # copy across file parms:
                filename = self.__get_menu_label(sg_n.parm('sopoutput'))
                new_n.parm('sopoutput').set(filename)

                # copy across any knob values from the internal geometry node.
                # parmTuples
                exclude = ['sopoutput']
                self.__copy_parm_values(sg_n, new_n, exclude)

                # Store Toolkit specific information on geometry node
                # so that we can reverse this process later

                # Profile Name
                new_n.setUserData('tk_profile_name',
                                  self.get_node_profile_name(sg_n))

                # Copy inputs and move outputs
                self.__copy_inputs_to_node(sg_n, new_n)
                if is_rop:
                    self.__move_outputs_to_node(sg_n, new_n)
                elif is_sop:
                    self.__move_outputs_from_node_to_user_data(sg_n, new_n)
                self.__copy_color(sg_n, new_n)

                # delete original node:
                sg_n.destroy()

                # rename new node:
                new_n.setName(node_name)
                new_n.setPosition(node_pos)
            except Exception as err:
                self._app.log_warning(err)
                msg = 'Problems converting node: {0}'.format(sg_n.path())
                self._app.log_warning(msg)
    def convert_to_regular_alembic_nodes(cls, app):
        """Convert Toolkit Alembic nodes to regular Alembic nodes.

        :param app: The calling Toolkit Application

        """

        tk_node_type = TkAlembicNodeHandler.TK_ALEMBIC_NODE_TYPE

        # determine the surface operator type for this class of node
        sop_types = hou.sopNodeTypeCategory().nodeTypes()
        sop_type = sop_types[tk_node_type]

        # determine the render operator type for this class of node
        rop_types = hou.ropNodeTypeCategory().nodeTypes()
        rop_type = rop_types[tk_node_type]

        # get all instances of tk alembic rop/sop nodes
        tk_alembic_nodes = []
        tk_alembic_nodes.extend(
            hou.nodeType(hou.sopNodeTypeCategory(), tk_node_type).instances())
        tk_alembic_nodes.extend(
            hou.nodeType(hou.ropNodeTypeCategory(), tk_node_type).instances())

        if not tk_alembic_nodes:
            app.log_debug("No Toolkit Alembic Nodes found for conversion.")
            return

        # iterate over all the tk alembic nodes and attempt to convert them
        for tk_alembic_node in tk_alembic_nodes:

            # determine the corresponding, built-in operator type
            if tk_alembic_node.type() == sop_type:
                alembic_operator = cls.HOU_SOP_ALEMBIC_TYPE
            elif tk_alembic_node.type() == rop_type:
                alembic_operator = cls.HOU_ROP_ALEMBIC_TYPE
            else:
                app.log_warning("Unknown type for node '%s': %s'" %
                    (tk_alembic_node.name(), tk_alembic_node.type()))
                continue

            # create a new, regular Alembic node
            alembic_node = tk_alembic_node.parent().createNode(alembic_operator)

            # copy the file parms value to the new node
            filename = _get_output_menu_label(
                tk_alembic_node.parm(cls.NODE_OUTPUT_PATH_PARM))
            alembic_node.parm(cls.NODE_OUTPUT_PATH_PARM).set(filename)

            # copy across knob values
            _copy_parm_values(tk_alembic_node, alembic_node,
                excludes=[cls.NODE_OUTPUT_PATH_PARM])

            # store the alembic output profile name in the user data so that we
            # can retrieve it later.
            output_profile_parm = tk_alembic_node.parm(
                cls.TK_OUTPUT_PROFILE_PARM)
            tk_output_profile_name = \
                output_profile_parm.menuLabels()[output_profile_parm.eval()]
            alembic_node.setUserData(cls.TK_OUTPUT_PROFILE_NAME_KEY, 
                tk_output_profile_name)

            # copy the inputs and move the outputs
            _copy_inputs(tk_alembic_node, alembic_node)
            if alembic_operator == cls.HOU_SOP_ALEMBIC_TYPE:
                _save_outputs_to_user_data(tk_alembic_node, alembic_node)
            elif alembic_operator == cls.HOU_ROP_ALEMBIC_TYPE:
                _move_outputs(tk_alembic_node, alembic_node)

            # make the new node the same color
            alembic_node.setColor(tk_alembic_node.color())

            # remember the name and position of the original tk alembic node
            tk_alembic_node_name = tk_alembic_node.name()
            tk_alembic_node_pos = tk_alembic_node.position()

            # destroy the original tk alembic node
            tk_alembic_node.destroy()

            # name and reposition the new, regular alembic node to match the
            # original
            alembic_node.setName(tk_alembic_node_name)
            alembic_node.setPosition(tk_alembic_node_pos)

            app.log_debug("Converted: Tk Alembic node '%s' to Alembic node."
                % (tk_alembic_node_name,))
def isActive():
    return hou.nodeType(hou.ropNodeTypeCategory(), "Redshift_ROP")
Beispiel #40
0
    def convert_mantra_to_sg_nodes(self):
        """
        Utility function to convert all Mantra nodes to Shotgun
        Mantra nodes (only converts Mantra nodes that were previously
        Shotgun Mantra nodes)

        # Example use:
        import sgtk
        eng = sgtk.platform.current_engine()
        app = eng.apps["tk-houdini-mantranode"]
        # Convert previously converted Mantra nodes back to
        # Shotgun Mantra nodes:
        app.convert_from_write_nodes()
        """

        # get write nodes:
        nodes = hou.nodeType(hou.ropNodeTypeCategory(), 'ifd').instances()
        for n in nodes:

            user_dict = n.userDataDict()

            profile = user_dict.get('tk_profile_name')

            if not profile:
                # can't convert to a Shotgun Mantra Node
                # as we have missing parameters!
                continue

            node_name = n.name()
            node_pos = n.position()

            # create new Shotgun Write node:
            node_class = ToolkitMantraNodeHandler.SG_NODE_CLASS
            new_sg_n = n.parent().createNode(node_class)

            # set the profile
            try:
                parm = new_sg_n.parm(ToolkitMantraNodeHandler.PARM_CONFIG)
                index = parm.menuLabels().index(profile)
                parm.set(index)
            except ValueError:
                pass

            # copy across and knob values from the internal write node.
            exclude = []
            self.__copy_parm_values(n, new_sg_n, exclude)

            # explicitly copy some settings to the new Shotgun Mantra Node:
            # AOV Names
            nums = self.__get_all_extra_plane_numbers(n)
            for num in nums:
                parm_name = 'sgtk__aov_name{0}'.format(num)
                user_data_name = 'tk_aov_name{0}'.format(num)
                aov_name = user_dict.get(user_data_name)
                new_sg_n.parm(parm_name).set(aov_name)

            # Copy inputs and move outputs
            self.__copy_inputs_to_node(n, new_sg_n)
            self.__move_outputs_to_node(n, new_sg_n)
            self.__copy_color(n, new_sg_n)

            # delete original node:
            n.destroy()

            # rename new node:
            new_sg_n.setName(node_name)
            new_sg_n.setPosition(node_pos)