mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-26 22:02:15 +01:00
🎨 workfile auto-creator
This commit is contained in:
parent
7a2e6bdf78
commit
c27f4cbbf4
3 changed files with 124 additions and 46 deletions
|
|
@ -35,6 +35,9 @@ class Creator(LegacyCreator):
|
|||
when hovering over a node. The information is visible under the name of
|
||||
the node.
|
||||
|
||||
Deprecated:
|
||||
This creator is deprecated and will be removed in future version.
|
||||
|
||||
"""
|
||||
defaults = ['Main']
|
||||
|
||||
|
|
@ -91,12 +94,35 @@ class Creator(LegacyCreator):
|
|||
sys.exc_info()[2])
|
||||
|
||||
|
||||
@six.add_metaclass(ABCMeta)
|
||||
class HoudiniCreator(NewCreator):
|
||||
selected_nodes = []
|
||||
class HoudiniCreatorBase(object):
|
||||
@staticmethod
|
||||
def cache_instances(shared_data):
|
||||
"""Cache instances for Creators to shared data.
|
||||
|
||||
Create `houdini_cached_instances` key when needed in shared data and
|
||||
fill it with all collected instances from the scene under its
|
||||
respective creator identifiers.
|
||||
|
||||
Args:
|
||||
Dict[str, Any]: Shared data.
|
||||
|
||||
Return:
|
||||
Dict[str, Any]: Shared data dictionary.
|
||||
|
||||
"""
|
||||
if shared_data.get("houdini_cached_instances") is None:
|
||||
shared_data["houdini_cached_instances"] = {}
|
||||
cached_instances = lsattr("id", "pyblish.avalon.instance")
|
||||
for i in cached_instances:
|
||||
creator_id = i.parm("creator_identifier").eval()
|
||||
if creator_id not in shared_data["houdini_cached_instances"]:
|
||||
shared_data["houdini_cached_instances"][creator_id] = [i]
|
||||
else:
|
||||
shared_data["houdini_cached_instances"][creator_id].append(i) # noqa
|
||||
return shared_data
|
||||
|
||||
@staticmethod
|
||||
def _create_instance_node(
|
||||
def create_instance_node(
|
||||
node_name, parent,
|
||||
node_type="geometry"):
|
||||
# type: (str, str, str) -> hou.Node
|
||||
|
|
@ -117,6 +143,11 @@ class HoudiniCreator(NewCreator):
|
|||
instance_node.moveToGoodPosition()
|
||||
return instance_node
|
||||
|
||||
|
||||
@six.add_metaclass(ABCMeta)
|
||||
class HoudiniCreator(NewCreator, HoudiniCreatorBase):
|
||||
selected_nodes = []
|
||||
|
||||
def create(self, subset_name, instance_data, pre_create_data):
|
||||
try:
|
||||
if pre_create_data.get("use_selection"):
|
||||
|
|
@ -127,7 +158,7 @@ class HoudiniCreator(NewCreator):
|
|||
if node_type is None:
|
||||
node_type = "geometry"
|
||||
|
||||
instance_node = self._create_instance_node(
|
||||
instance_node = self.create_instance_node(
|
||||
subset_name, "/out", node_type)
|
||||
|
||||
instance_data["instance_node"] = instance_node.path()
|
||||
|
|
@ -163,20 +194,7 @@ class HoudiniCreator(NewCreator):
|
|||
|
||||
def collect_instances(self):
|
||||
# cache instances if missing
|
||||
if self.collection_shared_data.get("houdini_cached_instances") is None:
|
||||
self.log.info("Caching instances ...")
|
||||
self.collection_shared_data["houdini_cached_instances"] = {}
|
||||
cached_instances = lsattr("id", "pyblish.avalon.instance")
|
||||
for i in cached_instances:
|
||||
creator_id = i.parm("creator_identifier").eval()
|
||||
if creator_id not in self.collection_shared_data[
|
||||
"houdini_cached_instances"]:
|
||||
self.collection_shared_data["houdini_cached_instances"][
|
||||
creator_id] = [i]
|
||||
else:
|
||||
self.collection_shared_data["houdini_cached_instances"][
|
||||
creator_id].append(i)
|
||||
|
||||
self.cache_instances(self.collection_shared_data)
|
||||
for instance in self.collection_shared_data["houdini_cached_instances"].get(self.identifier, []): # noqa
|
||||
created_instance = CreatedInstance.from_existing(
|
||||
read(instance), self
|
||||
|
|
|
|||
76
openpype/hosts/houdini/plugins/create/create_workfile.py
Normal file
76
openpype/hosts/houdini/plugins/create/create_workfile.py
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Creator plugin for creating workfiles."""
|
||||
from openpype.hosts.houdini.api import plugin
|
||||
from openpype.hosts.houdini.api.lib import read
|
||||
from openpype.pipeline import CreatedInstance, AutoCreator
|
||||
from openpype.pipeline.legacy_io import Session
|
||||
from openpype.client import get_asset_by_name
|
||||
|
||||
|
||||
class CreateWorkfile(plugin.HoudiniCreatorBase, AutoCreator):
|
||||
"""Workfile auto-creator."""
|
||||
identifier = "io.openpype.creators.houdini.workfile"
|
||||
label = "Workfile"
|
||||
family = "workfile"
|
||||
icon = "gears"
|
||||
|
||||
default_variant = "Main"
|
||||
|
||||
def create(self):
|
||||
variant = self.default_variant
|
||||
current_instance = next(
|
||||
(
|
||||
instance for instance in self.create_context.instances
|
||||
if instance.creator_identifier == self.identifier
|
||||
), None)
|
||||
|
||||
project_name = self.project_name
|
||||
asset_name = Session["AVALON_ASSET"]
|
||||
task_name = Session["AVALON_TASK"]
|
||||
host_name = Session["AVALON_APP"]
|
||||
|
||||
if current_instance is None:
|
||||
asset_doc = get_asset_by_name(project_name, asset_name)
|
||||
subset_name = self.get_subset_name(
|
||||
variant, task_name, asset_doc, project_name, host_name
|
||||
)
|
||||
data = {
|
||||
"asset": asset_name,
|
||||
"task": task_name,
|
||||
"variant": variant
|
||||
}
|
||||
data.update(
|
||||
self.get_dynamic_data(
|
||||
variant, task_name, asset_doc,
|
||||
project_name, host_name, current_instance)
|
||||
)
|
||||
|
||||
new_instance = CreatedInstance(
|
||||
self.family, subset_name, data, self
|
||||
)
|
||||
self._add_instance_to_context(new_instance)
|
||||
|
||||
# Update instance context if is not the same
|
||||
elif (
|
||||
current_instance["asset"] != asset_name
|
||||
or current_instance["task"] != task_name
|
||||
):
|
||||
asset_doc = get_asset_by_name(project_name, asset_name)
|
||||
subset_name = self.get_subset_name(
|
||||
variant, task_name, asset_doc, project_name, host_name
|
||||
)
|
||||
current_instance["asset"] = asset_name
|
||||
current_instance["task"] = task_name
|
||||
current_instance["subset"] = subset_name
|
||||
|
||||
def collect_instances(self):
|
||||
self.cache_instances(self.collection_shared_data)
|
||||
for instance in self.collection_shared_data["houdini_cached_instances"].get(self.identifier, []): # noqa
|
||||
created_instance = CreatedInstance.from_existing(
|
||||
read(instance), self
|
||||
)
|
||||
self._add_instance_to_context(created_instance)
|
||||
|
||||
def update_instances(self, update_list):
|
||||
pass
|
||||
|
||||
|
|
@ -5,19 +5,20 @@ from openpype.pipeline import legacy_io
|
|||
import pyblish.api
|
||||
|
||||
|
||||
class CollectHoudiniCurrentFile(pyblish.api.ContextPlugin):
|
||||
class CollectHoudiniCurrentFile(pyblish.api.InstancePlugin):
|
||||
"""Inject the current working file into context"""
|
||||
|
||||
order = pyblish.api.CollectorOrder - 0.01
|
||||
label = "Houdini Current File"
|
||||
hosts = ["houdini"]
|
||||
family = ["workfile"]
|
||||
|
||||
def process(self, context):
|
||||
def process(self, instance):
|
||||
"""Inject the current working file"""
|
||||
|
||||
current_file = hou.hipFile.path()
|
||||
if not os.path.exists(current_file):
|
||||
# By default Houdini will even point a new scene to a path.
|
||||
# By default, Houdini will even point a new scene to a path.
|
||||
# However if the file is not saved at all and does not exist,
|
||||
# we assume the user never set it.
|
||||
filepath = ""
|
||||
|
|
@ -34,43 +35,26 @@ class CollectHoudiniCurrentFile(pyblish.api.ContextPlugin):
|
|||
"saved correctly."
|
||||
)
|
||||
|
||||
context.data["currentFile"] = current_file
|
||||
instance.context.data["currentFile"] = current_file
|
||||
|
||||
folder, file = os.path.split(current_file)
|
||||
filename, ext = os.path.splitext(file)
|
||||
|
||||
task = legacy_io.Session["AVALON_TASK"]
|
||||
|
||||
data = {}
|
||||
|
||||
# create instance
|
||||
instance = context.create_instance(name=filename)
|
||||
subset = 'workfile' + task.capitalize()
|
||||
|
||||
data.update({
|
||||
"subset": subset,
|
||||
"asset": os.getenv("AVALON_ASSET", None),
|
||||
"label": subset,
|
||||
"publish": True,
|
||||
"family": 'workfile',
|
||||
"families": ['workfile'],
|
||||
instance.data.update({
|
||||
"setMembers": [current_file],
|
||||
"frameStart": context.data['frameStart'],
|
||||
"frameEnd": context.data['frameEnd'],
|
||||
"handleStart": context.data['handleStart'],
|
||||
"handleEnd": context.data['handleEnd']
|
||||
"frameStart": instance.context.data['frameStart'],
|
||||
"frameEnd": instance.context.data['frameEnd'],
|
||||
"handleStart": instance.context.data['handleStart'],
|
||||
"handleEnd": instance.context.data['handleEnd']
|
||||
})
|
||||
|
||||
data['representations'] = [{
|
||||
instance.data['representations'] = [{
|
||||
'name': ext.lstrip("."),
|
||||
'ext': ext.lstrip("."),
|
||||
'files': file,
|
||||
"stagingDir": folder,
|
||||
}]
|
||||
|
||||
instance.data.update(data)
|
||||
|
||||
self.log.info('Collected instance: {}'.format(file))
|
||||
self.log.info('Scene path: {}'.format(current_file))
|
||||
self.log.info('staging Dir: {}'.format(folder))
|
||||
self.log.info('subset: {}'.format(subset))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue