mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge pull request #31 from ynput/feature/houdini_allow_taking_snapshoots
Houdini: Extract active view as thumbnail when no thumbnail set
This commit is contained in:
commit
1ece2defc9
2 changed files with 131 additions and 0 deletions
|
|
@ -1001,6 +1001,82 @@ def add_self_publish_button(node):
|
|||
node.setParmTemplateGroup(template)
|
||||
|
||||
|
||||
def get_scene_viewer():
|
||||
"""
|
||||
Return an instance of a visible viewport.
|
||||
|
||||
There may be many, some could be closed, any visible are current
|
||||
|
||||
Returns:
|
||||
Optional[hou.SceneViewer]: A scene viewer, if any.
|
||||
"""
|
||||
panes = hou.ui.paneTabs()
|
||||
panes = [x for x in panes if x.type() == hou.paneTabType.SceneViewer]
|
||||
panes = sorted(panes, key=lambda x: x.isCurrentTab())
|
||||
if panes:
|
||||
return panes[-1]
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def sceneview_snapshot(
|
||||
sceneview,
|
||||
filepath="$HIP/thumbnails/$HIPNAME.$F4.jpg",
|
||||
frame_start=None,
|
||||
frame_end=None):
|
||||
"""Take a snapshot of your scene view.
|
||||
|
||||
It takes snapshot of your scene view for the given frame range.
|
||||
So, it's capable of generating snapshots image sequence.
|
||||
It works in different Houdini context e.g. Objects, Solaris
|
||||
|
||||
Example:
|
||||
This is how the function can be used::
|
||||
|
||||
from ayon_core.hosts.houdini.api import lib
|
||||
sceneview = hou.ui.paneTabOfType(hou.paneTabType.SceneViewer)
|
||||
lib.sceneview_snapshot(sceneview)
|
||||
|
||||
Notes:
|
||||
.png output will render poorly, so use .jpg.
|
||||
|
||||
How it works:
|
||||
Get the current sceneviewer (may be more than one or hidden)
|
||||
and screengrab the perspective viewport to a file in the
|
||||
publish location to be picked up with the publish.
|
||||
|
||||
Credits:
|
||||
https://www.sidefx.com/forum/topic/42808/?page=1#post-354796
|
||||
|
||||
Args:
|
||||
sceneview (hou.SceneViewer): The scene view pane from which you want
|
||||
to take a snapshot.
|
||||
filepath (str): thumbnail filepath. it expects `$F4` token
|
||||
when frame_end is bigger than frame_star other wise
|
||||
each frame will override its predecessor.
|
||||
frame_start (int): the frame at which snapshot starts
|
||||
frame_end (int): the frame at which snapshot ends
|
||||
"""
|
||||
|
||||
if frame_start is None:
|
||||
frame_start = hou.frame()
|
||||
if frame_end is None:
|
||||
frame_end = frame_start
|
||||
|
||||
if not isinstance(sceneview, hou.SceneViewer):
|
||||
log.debug("Wrong Input. {} is not of type hou.SceneViewer."
|
||||
.format(sceneview))
|
||||
return
|
||||
viewport = sceneview.curViewport()
|
||||
|
||||
flip_settings = sceneview.flipbookSettings().stash()
|
||||
flip_settings.frameRange((frame_start, frame_end))
|
||||
flip_settings.output(filepath)
|
||||
flip_settings.outputToMPlay(False)
|
||||
sceneview.flipbook(viewport, flip_settings)
|
||||
log.debug("A snapshot of sceneview has been saved to: {}".format(filepath))
|
||||
|
||||
|
||||
def update_content_on_context_change():
|
||||
"""Update all Creator instances to current asset"""
|
||||
host = registered_host()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
import pyblish.api
|
||||
import tempfile
|
||||
from ayon_core.pipeline import publish
|
||||
from ayon_core.hosts.houdini.api import lib
|
||||
from ayon_core.hosts.houdini.api.pipeline import IS_HEADLESS
|
||||
|
||||
|
||||
class ExtractActiveViewThumbnail(publish.Extractor):
|
||||
"""Set instance thumbnail to a screengrab of current active viewport.
|
||||
|
||||
This makes it so that if an instance does not have a thumbnail set yet that
|
||||
it will get a thumbnail of the currently active view at the time of
|
||||
publishing as a fallback.
|
||||
|
||||
"""
|
||||
order = pyblish.api.ExtractorOrder + 0.49
|
||||
label = "Extract Active View Thumbnail"
|
||||
families = ["workfile"]
|
||||
hosts = ["houdini"]
|
||||
|
||||
def process(self, instance):
|
||||
if IS_HEADLESS:
|
||||
self.log.debug(
|
||||
"Skip extraction of active view thumbnail, due to being in"
|
||||
"headless mode."
|
||||
)
|
||||
return
|
||||
|
||||
thumbnail = instance.data.get("thumbnailPath")
|
||||
if thumbnail:
|
||||
# A thumbnail was already set for this instance
|
||||
return
|
||||
|
||||
view_thumbnail = self.get_view_thumbnail(instance)
|
||||
if not view_thumbnail:
|
||||
return
|
||||
self.log.debug("Setting instance thumbnail path to: {}"
|
||||
.format(view_thumbnail)
|
||||
)
|
||||
instance.data["thumbnailPath"] = view_thumbnail
|
||||
|
||||
def get_view_thumbnail(self, instance):
|
||||
|
||||
sceneview = lib.get_scene_viewer()
|
||||
if sceneview is None:
|
||||
self.log.debug("Skipping Extract Active View Thumbnail"
|
||||
" because no scene view was detected.")
|
||||
return
|
||||
|
||||
with tempfile.NamedTemporaryFile("w", suffix=".jpg", delete=False) as tmp:
|
||||
lib.sceneview_snapshot(sceneview, tmp.name)
|
||||
thumbnail_path = tmp.name
|
||||
|
||||
instance.context.data["cleanupFullPaths"].append(thumbnail_path)
|
||||
return thumbnail_path
|
||||
Loading…
Add table
Add a link
Reference in a new issue