diff --git a/openpype/hosts/houdini/api/lib.py b/openpype/hosts/houdini/api/lib.py index 964a866a79..711fae7cc4 100644 --- a/openpype/hosts/houdini/api/lib.py +++ b/openpype/hosts/houdini/api/lib.py @@ -548,7 +548,7 @@ def get_template_from_value(key, value): return parm -def get_frame_data(self, node, asset_data=None): +def get_frame_data(node, asset_data=None, log=None): """Get the frame data: start frame, end frame and steps. Args: @@ -561,28 +561,31 @@ def get_frame_data(self, node, asset_data=None): if asset_data is None: asset_data = {} + if log is None: + log = self.log + data = {} if node.parm("trange") is None: - self.log.debug( + log.debug( "Node has no 'trange' parameter: {}".format(node.path()) ) return data if node.evalParm("trange") == 0: - self.log.debug( + log.debug( "Node '{}' has 'Render current frame' set. " "Time range data ignored.".format(node.path()) ) return data data["frameStartHandle"] = node.evalParm("f1") - data["frameStart"] = node.evalParm("f1") + asset_data.get("handleStart", 0) data["handleStart"] = asset_data.get("handleStart", 0) + data["frameStart"] = data["frameStartHandle"] + data["handleStart"] data["frameEndHandle"] = node.evalParm("f2") - data["frameEnd"] = node.evalParm("f2") - asset_data.get("handleEnd", 0) data["handleEnd"] = asset_data.get("handleEnd", 0) + data["frameEnd"] = data["frameEndHandle"] - data["handleEnd"] data["byFrameStep"] = node.evalParm("f3") diff --git a/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py b/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py index edd71bfa39..9933572f4a 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py @@ -126,11 +126,8 @@ class CollectArnoldROPRenderProducts(pyblish.api.InstancePlugin): return path expected_files = [] - start = instance.data.get("frameStartHandle") or \ - instance.data["frameStart"] - - end = instance.data.get("frameEndHandle") or \ - instance.data["frameEnd"] + start = instance.data.get("frameStartHandle") + end = instance.data.get("frameEndHandle") for i in range(int(start), (int(end) + 1)): expected_files.append( diff --git a/openpype/hosts/houdini/plugins/publish/collect_instance_frame_data.py b/openpype/hosts/houdini/plugins/publish/collect_instance_frame_data.py index 97d18f97f0..1426eadda1 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_instance_frame_data.py +++ b/openpype/hosts/houdini/plugins/publish/collect_instance_frame_data.py @@ -21,7 +21,7 @@ class CollectInstanceNodeFrameRange(pyblish.api.InstancePlugin): return asset_data = instance.context.data["assetEntity"]["data"] - frame_data = lib.get_frame_data(self, node, asset_data) + frame_data = lib.get_frame_data(node, asset_data, self.log) if not frame_data: return diff --git a/openpype/hosts/houdini/plugins/publish/collect_instances.py b/openpype/hosts/houdini/plugins/publish/collect_instances.py index 132d297d1d..b2e6107435 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_instances.py +++ b/openpype/hosts/houdini/plugins/publish/collect_instances.py @@ -102,4 +102,4 @@ class CollectInstances(pyblish.api.ContextPlugin): """ - return lib.get_frame_data(self, node) + return lib.get_frame_data(node) diff --git a/openpype/hosts/houdini/plugins/publish/collect_karma_rop.py b/openpype/hosts/houdini/plugins/publish/collect_karma_rop.py index 564b58ebc2..32790dd550 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_karma_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_karma_rop.py @@ -95,11 +95,8 @@ class CollectKarmaROPRenderProducts(pyblish.api.InstancePlugin): return path expected_files = [] - start = instance.data.get("frameStartHandle") or \ - instance.data["frameStart"] - - end = instance.data.get("frameEndHandle") or \ - instance.data["frameEnd"] + start = instance.data.get("frameStartHandle") + end = instance.data.get("frameEndHandle") for i in range(int(start), (int(end) + 1)): expected_files.append( diff --git a/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py b/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py index 5ece889694..daaf87c04c 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py @@ -118,11 +118,8 @@ class CollectMantraROPRenderProducts(pyblish.api.InstancePlugin): return path expected_files = [] - start = instance.data.get("frameStartHandle") or \ - instance.data["frameStart"] - - end = instance.data.get("frameEndHandle") or \ - instance.data["frameEnd"] + start = instance.data.get("frameStartHandle") + end = instance.data.get("frameEndHandle") for i in range(int(start), (int(end) + 1)): expected_files.append( diff --git a/openpype/hosts/houdini/plugins/publish/collect_redshift_rop.py b/openpype/hosts/houdini/plugins/publish/collect_redshift_rop.py index 1705da6a69..5ade67d181 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_redshift_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_redshift_rop.py @@ -132,11 +132,8 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): return path expected_files = [] - start = instance.data.get("frameStartHandle") or \ - instance.data["frameStart"] - - end = instance.data.get("frameEndHandle") or \ - instance.data["frameEnd"] + start = instance.data.get("frameStartHandle") + end = instance.data.get("frameEndHandle") for i in range(int(start), (int(end) + 1)): expected_files.append( diff --git a/openpype/hosts/houdini/plugins/publish/collect_rop_frame_range.py b/openpype/hosts/houdini/plugins/publish/collect_rop_frame_range.py index bf44e019a9..ccaa8b58e0 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_rop_frame_range.py +++ b/openpype/hosts/houdini/plugins/publish/collect_rop_frame_range.py @@ -21,7 +21,7 @@ class CollectRopFrameRange(pyblish.api.InstancePlugin): ropnode = hou.node(node_path) asset_data = instance.context.data["assetEntity"]["data"] - frame_data = lib.get_frame_data(self, ropnode, asset_data) + frame_data = lib.get_frame_data(ropnode, asset_data, self.log) if "frameStart" in frame_data and "frameEnd" in frame_data: diff --git a/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py b/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py index ec87e3eda3..e5c6ec20c4 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py @@ -115,11 +115,8 @@ class CollectVrayROPRenderProducts(pyblish.api.InstancePlugin): return path expected_files = [] - start = instance.data.get("frameStartHandle") or \ - instance.data["frameStart"] - - end = instance.data.get("frameEndHandle") or \ - instance.data["frameEnd"] + start = instance.data.get("frameStartHandle") + end = instance.data.get("frameEndHandle") for i in range(int(start), (int(end) + 1)): expected_files.append( diff --git a/openpype/hosts/houdini/plugins/publish/validate_frame_range.py b/openpype/hosts/houdini/plugins/publish/validate_frame_range.py new file mode 100644 index 0000000000..e1be99dbcf --- /dev/null +++ b/openpype/hosts/houdini/plugins/publish/validate_frame_range.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +import pyblish.api +from openpype.pipeline import PublishValidationError +from openpype.pipeline.publish import RepairAction +from openpype.hosts.houdini.api.action import SelectInvalidAction + +import hou + + +class HotFixAction(RepairAction): + """Set End frame to the minimum valid value.""" + + label = "End frame hotfix" + + +class ValidateFrameRange(pyblish.api.InstancePlugin): + """Validate Frame Range. + + Due to the usage of start and end handles, + then Frame Range must be >= (start handle + end handle) + which results that frameEnd be smaller than frameStart + """ + + order = pyblish.api.ValidatorOrder - 0.1 + hosts = ["houdini"] + label = "Validate Frame Range" + actions = [HotFixAction, SelectInvalidAction] + + def process(self, instance): + + invalid = self.get_invalid(instance) + if invalid: + nodes = [n.path() for n in invalid] + raise PublishValidationError( + "Invalid Frame Range on: {0}".format(nodes), + title="Invalid Frame Range" + ) + + @classmethod + def get_invalid(cls, instance): + + if not instance.data.get("instance_node"): + return + + rop_node = hou.node(instance.data["instance_node"]) + if instance.data["frameStart"] > instance.data["frameEnd"]: + cls.log.error( + "Wrong frame range, please consider handle start and end.\n" + "frameEnd should at least be {}.\n" + "Use \"End frame hotfix\" action to do that." + .format( + instance.data["handleEnd"] + + instance.data["handleStart"] + + instance.data["frameStartHandle"] + ) + ) + return [rop_node] + + @classmethod + def repair(cls, instance): + rop_node = hou.node(instance.data["instance_node"]) + + frame_start = int(instance.data["frameStartHandle"]) + frame_end = int( + instance.data["frameStartHandle"] + + instance.data["handleStart"] + + instance.data["handleEnd"] + ) + + if rop_node.parm("f2").rawValue() == "$FEND": + hou.playbar.setFrameRange(frame_start, frame_end) + hou.playbar.setPlaybackRange(frame_start, frame_end) + hou.setFrame(frame_start) + else: + rop_node.parm("f2").set(frame_end) diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index 5dd16306c3..cd71095920 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -65,12 +65,8 @@ class HoudiniSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline): job_info.BatchName += datetime.now().strftime("%d%m%Y%H%M%S") # Deadline requires integers in frame range - start = instance.data.get("frameStartHandle") or \ - instance.data["frameStart"] - - end = instance.data.get("frameEndHandle") or \ - instance.data["frameEnd"] - + start = instance.data.get("frameStartHandle") + end = instance.data.get("frameEndHandle") frames = "{start}-{end}x{step}".format( start=int(start), end=int(end),