diff --git a/.gitignore b/.gitignore index 4df4a70..d4d9f36 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,5 @@ test *.pyc # Project settings -.idea/ \ No newline at end of file +.idea/ +.vscode diff --git a/app.py b/app.py index 1f73fbb..26eab85 100644 --- a/app.py +++ b/app.py @@ -36,14 +36,19 @@ def execute_render(self, node, network): def submit_to_farm(self, node, network): self.handler.submit_to_farm(node, network) - def copy_to_clipboard(self, node, network): + def copy_to_clipboard(self, node, network=None): self.handler.copy_to_clipboard(node, network) @staticmethod def get_all_renderman_nodes(): # Get all nodes from node type sgtk_hdprman - lop_nodes = hou.lopNodeTypeCategory().nodeType("sgtk_hdprman").instances() - nodes = lop_nodes + hou.ropNodeTypeCategory().nodeType("sgtk_ris").instances() + lop_nodes = ( + hou.lopNodeTypeCategory().nodeType("sgtk_hdprman").instances() + ) + nodes = ( + lop_nodes + + hou.ropNodeTypeCategory().nodeType("sgtk_ris").instances() + ) return nodes @staticmethod @@ -61,5 +66,5 @@ def get_publish_template(self): @staticmethod def get_render_name(node): - name = node.parm('name').eval() - return name \ No newline at end of file + name = node.parm("name").eval() + return name diff --git a/otls/sgtk_renderman.otl b/otls/sgtk_renderman.otl index a771807..e23c17a 100644 Binary files a/otls/sgtk_renderman.otl and b/otls/sgtk_renderman.otl differ diff --git a/otls/sgtk_ris.otl b/otls/sgtk_ris.otl index f8a7926..764e346 100644 Binary files a/otls/sgtk_ris.otl and b/otls/sgtk_ris.otl differ diff --git a/python/tk_houdini_renderman/farm_dialog.py b/python/tk_houdini_renderman/farm_dialog.py index cf79ca0..1013a22 100644 --- a/python/tk_houdini_renderman/farm_dialog.py +++ b/python/tk_houdini_renderman/farm_dialog.py @@ -32,7 +32,16 @@ class FarmSubmission(QtWidgets.QWidget): - def __init__(self, app, node, submission_name, priority, framerange, network, parent=None): + def __init__( + self, + app, + node, + submission_name, + priority, + framerange, + network, + parent=None, + ): QtWidgets.QWidget.__init__(self, parent) self.setWindowTitle("Submit to Farm") self.app = app @@ -95,7 +104,9 @@ def __submit_to_farm(self): houdini_file = hou.hipFile.name() houdini_version = hou.applicationVersion() - houdini_version = str(houdini_version[0]) + "." + str(houdini_version[1]) + houdini_version = ( + str(houdini_version[0]) + "." + str(houdini_version[1]) + ) file_parameter = "picture" render_filepath = self.node.parm(file_parameter).eval() @@ -103,9 +114,13 @@ def __submit_to_farm(self): output_directory = os.path.dirname(render_filepath) output_filename = os.path.basename(render_filepath) - render_rop_node = os.path.join(self.node.path(), "rop_usdrender").replace( - os.sep, "/" - ) + if self.network == "lop": + render_rop_node = os.path.join(self.node.path(), "rop_usdrender") + render_rop_node = render_rop_node.replace(os.sep, "/") + + else: + render_rop_node = os.path.join(self.node.path(), "ris1") + render_rop_node = render_rop_node.replace(os.sep, "/") deadline_path = os.getenv("DEADLINE_PATH") diff --git a/python/tk_houdini_renderman/handler.py b/python/tk_houdini_renderman/handler.py index 822cd92..58d7553 100644 --- a/python/tk_houdini_renderman/handler.py +++ b/python/tk_houdini_renderman/handler.py @@ -30,7 +30,7 @@ class TkRenderManNodeHandler(object): def __init__(self, app): - # Set global variables + """Set global variables""" self.app = app self.sg = self.app.shotgun @@ -51,7 +51,9 @@ def submit_to_farm(self, node, network): # Determine basic variables for submission file_name = hou.hipFile.name() - file_name = os.path.basename(file_name).split(".")[0] + " (%s)" % render_name + file_name = ( + os.path.basename(file_name).split(".")[0] + " (%s)" % render_name + ) # Determine framerange framerange_type = node.parm("trange").eval() @@ -64,12 +66,15 @@ def submit_to_farm(self, node, network): print(current_frame) framerange = str(current_frame) + "-" + str(current_frame) - # Open node so it will work on the farm even if the node is not installed + # Open node so it will work on the farm + # even if the node is not installed node.allowEditingOfContents() - # Start submission panel global submission - submission = FarmSubmission(self.app, node, file_name, "50", framerange, network=network) + # Start submission panel + submission = FarmSubmission( + self.app, node, file_name, "50", framerange, network=network + ) submission.show() def execute_render(self, node, network): @@ -93,12 +98,28 @@ def execute_render(self, node, network): else: node.node("ris1").parm("execute").pressButton() - def copy_to_clipboard(self, node, network): - # Function to copy the path directly to the clipboard, currently only Windows is supported + def copy_to_clipboard(self, node, network=None): + """Function to copy the path directly to the clipboard, + currently only Windows is supported + + Args: + node (attribute): node to get clipboard from + """ + + # Function to copy the path directly to the clipboard, + # currently only Windows is supported if platform.system() == "Windows": - render_path = node.parm("picture").eval() + + if network == "rop": + parameter = "ri_display_0" + else: + parameter = "picture" + + render_path = node.parm(parameter).eval() render_path = os.path.dirname(render_path).replace("/", os.sep) - copy_to_clipboard = 'echo|set /p="' + render_path.strip() + '"| clip' + copy_to_clipboard = ( + 'echo|set /p="' + render_path.strip() + '"| clip' + ) os.system(copy_to_clipboard) else: self.app.logger.debug( @@ -107,12 +128,14 @@ def copy_to_clipboard(self, node, network): @staticmethod def __validate_node(node, network): - # This function will make sure all the paramaters are filled in and setup correctly. + # This function will make sure all the parameters + # are filled in and setup correctly. # First we'll check if there is a name render_name = node.parm("name").eval() if render_name == "": hou.ui.displayMessage( - "Name is not defined, please set the name parameter before submitting.", + "Name is not defined, please set the name " + "parameter before submitting.", severity=hou.severityType.Error, ) return False @@ -123,7 +146,8 @@ def __validate_node(node, network): if len(inputs) <= 0: hou.ui.displayMessage( "Node doesn't have input, please connect this " - "ShotGrid RenderMan render node to the stage to render.", + "ShotGrid RenderMan render node to " + "the stage to render.", severity=hou.severityType.Error, ) return False @@ -146,7 +170,8 @@ def __calculate_path(self, node, network): evaluate_parm = True - # Because RenderMan in the rop network uses different parameter names, we need to change some bits + # Because RenderMan in the rop network uses different + # parameter names, we need to change some bits if network == "rop": camera = node.parm("camera").eval() @@ -169,7 +194,7 @@ def __calculate_path(self, node, network): # Set fields fields = work_template.get_fields(current_filepath) fields["SEQ"] = "FORMAT: $F" - fields["name"] = node.parm("name").eval() + fields["output"] = node.parm("name").eval() if evaluate_parm is True: fields["width"] = node.parm(resolution_x_field).eval() fields["height"] = node.parm(resolution_y_field).eval() @@ -206,7 +231,12 @@ def __calculate_filter_path(self, node, filter): def __apply_path(self, node, render_path, network): # Set render path on specified node - parameter = "picture" + + if network == "lop": + parameter = "picture" + else: + parameter = "ri_display_0" + node.parm(parameter).set(render_path) self.app.logger.debug("Set render path on %s" % str(node)) @@ -227,21 +257,24 @@ def __check_filters(node): # Process display filters filters = [] - # Go trough every tab and check if the parameters match the requirements + # Go trough every tab and check if the + # parameters match the requirements for number in tabs: - # We have two types, the display filters and sample filters. Basically the same in terms of the way they + # We have two types, the display filters and sample filters. + # Basically the same in terms of the way they # are created, so its just doing the same operation for both filter_types = ["displayfilter", "samplefilter"] for filter in filter_types: # Get the correct group name filter_type = filter + str(number) - filter_name = hou.encode("ri:" + filter_type + ":name") + filter_name = hou.encode("ri:%s:name" % filter_type) # Get the ordered dropdown parameter value filter_name = node.parm(filter_name).eval() - # Only add to the filters list if the ordered dropdown parameters is anything else than "None" + # Only add to the filters list if the ordered dropdown + # parameters is anything else than "None" if filter_name != "None": filter_type = {"group": filter_type, "value": filter_name} filters.append(filter_type) @@ -250,14 +283,17 @@ def __check_filters(node): return filters def __set_filter_filename(self, node, filters): - # This function will process the filter specfied, and populate the path if it is possible to do + # This function will process the filter specfied, and + # populate the path if it is possible to do for item in filters: # Look at our dictionary and get the keys/values supplied group = item.get("group") value = item.get("value") # Build the paramater name - parameter_name = hou.encode("ri:" + group + ":" + value + ":filename") + parameter_name = hou.encode( + "ri:" + group + ":" + value + ":filename" + ) parameter = node.parm(parameter_name) # If there is no "filename" parameter, skip this one @@ -268,7 +304,8 @@ def __set_filter_filename(self, node, filters): parameter.set(render_path) def get_filters_output(self, node): - # This function will check every item in the filters group, and return the file paths that are in there + # This function will check every item in the filters group, + # and return the file paths that are in there filters = self.__check_filters(node) filter_passes = [] for item in filters: @@ -277,14 +314,17 @@ def get_filters_output(self, node): value = item.get("value") # Build the paramater name - parameter_name = hou.encode("ri:" + group + ":" + value + ":filename") + parameter_name = hou.encode( + "ri:" + group + ":" + value + ":filename" + ) parameter = node.parm(parameter_name) # If there is no "filename" parameter, skip this one if parameter is None: continue - # Build a dictionary per item, containing the name of the filter and the path where the file is rendered to + # Build a dictionary per item, containing the name of the + # filter and the path where the file is rendered to rendered_filter = {"name": value, "path": parameter.eval()} # Add the dictionary to the main filter_passes list @@ -294,11 +334,14 @@ def get_filters_output(self, node): return filter_passes def get_published_status(self, node): - # This function will check on ShotGrid if there is a publish with exactly the same name on the project. If - # there is a publish existing it will return a "True" value, otherwise a "False" value + # This function will check on ShotGrid if there is a publish + # with exactly the same name on the project. If + # there is a publish existing it will return a "True" value, + # otherwise a "False" value sg = self.sg - # Define the regex to detect the Houdini "$F4" expressions (or other numbers to define the padding) + # Define the regex to detect the Houdini "$F4" expressions + # (or other numbers to define the padding) regex = r"[$][fF]\d" # Get the raw string from the picture parameter @@ -313,7 +356,9 @@ def get_published_status(self, node): padding_length = padding_length.group(0) # Replace $F4 with %04d format - file_name = file_path.replace(frame_match, "%0" + str(padding_length) + "d") + file_name = file_path.replace( + frame_match, "%0" + str(padding_length) + "d" + ) file_name = os.path.basename(file_name) # Get current project ID @@ -330,10 +375,12 @@ def get_published_status(self, node): # Search on ShotGrid published_file = sg.find_one("PublishedFile", filters) - # If there is no publish, it will return a None value. So set the variable is_published to "False" + # If there is no publish, it will return a None value. + # So set the variable is_published to "False" if published_file is None: is_published = False - # If the value is not None, there is a publish with the same name. So set the variable is_published to "True + # If the value is not None, there is a publish with the + # same name. So set the variable is_published to "True else: is_published = True