Skip to content

Commit

Permalink
Fix for object level RenderMan and added new render path option (outp…
Browse files Browse the repository at this point in the history
…ut) as in Nuke
  • Loading branch information
gillesvink committed Aug 25, 2022
1 parent fcb328a commit bd92803
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 41 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ test
*.pyc

# Project settings
.idea/
.idea/
.vscode
15 changes: 10 additions & 5 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -61,5 +66,5 @@ def get_publish_template(self):

@staticmethod
def get_render_name(node):
name = node.parm('name').eval()
return name
name = node.parm("name").eval()
return name
Binary file modified otls/sgtk_renderman.otl
Binary file not shown.
Binary file modified otls/sgtk_ris.otl
Binary file not shown.
25 changes: 20 additions & 5 deletions python/tk_houdini_renderman/farm_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -95,17 +104,23 @@ 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()

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")

Expand Down
107 changes: 77 additions & 30 deletions python/tk_houdini_renderman/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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()
Expand All @@ -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):
Expand All @@ -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(
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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()

Expand All @@ -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()
Expand Down Expand Up @@ -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))

Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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:
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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

Expand Down

0 comments on commit bd92803

Please sign in to comment.