diff --git a/openpype/hosts/houdini/api/lib.py b/openpype/hosts/houdini/api/lib.py index 72f1c8e71f..5a087ea276 100644 --- a/openpype/hosts/houdini/api/lib.py +++ b/openpype/hosts/houdini/api/lib.py @@ -542,3 +542,37 @@ def maintained_selection(): if previous_selection: for node in previous_selection: node.setSelected(on=True) + + +def reset_framerange(): + """Set frame range to current asset""" + + asset_name = api.Session["AVALON_ASSET"] + asset = io.find_one({"name": asset_name, "type": "asset"}) + + frame_start = asset["data"].get("frameStart") + frame_end = asset["data"].get("frameEnd") + # Backwards compatibility + if frame_start is None or frame_end is None: + frame_start = asset["data"].get("edit_in") + frame_end = asset["data"].get("edit_out") + + if frame_start is None or frame_end is None: + log.warning("No edit information found for %s" % asset_name) + return + + handles = asset["data"].get("handles") or 0 + handle_start = asset["data"].get("handleStart") + if handle_start is None: + handle_start = handles + + handle_end = asset["data"].get("handleEnd") + if handle_end is None: + handle_end = handles + + frame_start -= int(handle_start) + frame_end += int(handle_end) + + hou.playbar.setFrameRange(frame_start, frame_end) + hou.playbar.setPlaybackRange(frame_start, frame_end) + hou.setFrame(frame_start) diff --git a/openpype/hosts/houdini/api/pipeline.py b/openpype/hosts/houdini/api/pipeline.py index c3dbdc5ef5..1c08e72d65 100644 --- a/openpype/hosts/houdini/api/pipeline.py +++ b/openpype/hosts/houdini/api/pipeline.py @@ -4,6 +4,7 @@ import logging import contextlib import hou +import hdefereval import pyblish.api import avalon.api @@ -66,9 +67,10 @@ def install(): sys.path.append(hou_pythonpath) - # Set asset FPS for the empty scene directly after launch of Houdini - # so it initializes into the correct scene FPS - _set_asset_fps() + # Set asset settings for the empty scene directly after launch of Houdini + # so it initializes into the correct scene FPS, Frame Range, etc. + # todo: make sure this doesn't trigger when opening with last workfile + _set_context_settings() def uninstall(): @@ -279,18 +281,49 @@ def on_open(*args): def on_new(_): """Set project resolution and fps when create a new file""" + + if hou.hipFile.isLoadingHipFile(): + # This event also triggers when Houdini opens a file due to the + # new event being registered to 'afterClear'. As such we can skip + # 'new' logic if the user is opening a file anyway + log.debug("Skipping on new callback due to scene being opened.") + return + log.info("Running callback on new..") - _set_asset_fps() + _set_context_settings() + + # It seems that the current frame always gets reset to frame 1 on + # new scene. So we enforce current frame to be at the start of the playbar + # with execute deferred + def _enforce_start_frame(): + start = hou.playbar.playbackRange()[0] + hou.setFrame(start) + + hdefereval.executeDeferred(_enforce_start_frame) -def _set_asset_fps(): - """Set Houdini scene FPS to the default required for current asset""" +def _set_context_settings(): + """Apply the project settings from the project definition + + Settings can be overwritten by an asset if the asset.data contains + any information regarding those settings. + + Examples of settings: + fps + resolution + renderer + + Returns: + None + """ # Set new scene fps fps = get_asset_fps() print("Setting scene FPS to %i" % fps) lib.set_scene_fps(fps) + lib.reset_framerange() + def on_pyblish_instance_toggled(instance, new_value, old_value): """Toggle saver tool passthrough states on instance toggles.""" diff --git a/openpype/hosts/houdini/startup/MainMenuCommon.xml b/openpype/hosts/houdini/startup/MainMenuCommon.xml index b8c7f93d76..abfa3f136e 100644 --- a/openpype/hosts/houdini/startup/MainMenuCommon.xml +++ b/openpype/hosts/houdini/startup/MainMenuCommon.xml @@ -66,6 +66,14 @@ host_tools.show_workfiles(parent) ]]> + + + + +