mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-02 00:44:52 +01:00
implement ornatrix cache loader
This commit is contained in:
parent
14f12b4e7a
commit
0d02b9f956
4 changed files with 137 additions and 8 deletions
|
|
@ -0,0 +1,130 @@
|
|||
import json
|
||||
import os
|
||||
from ayon_core.pipeline import get_representation_path
|
||||
from ayon_maya.api import lib
|
||||
from ayon_maya.api.pipeline import containerise
|
||||
from ayon_maya.api import plugin
|
||||
from maya import cmds, mel
|
||||
|
||||
|
||||
class OxCacheLoader(plugin.Loader):
|
||||
"""Load Ornatrix Cache with one or more Yeti nodes"""
|
||||
|
||||
product_types = {"oxcache", "oxrig"}
|
||||
representations = {"abc"}
|
||||
|
||||
label = "Load Ornatrix Cache"
|
||||
order = -9
|
||||
icon = "code-fork"
|
||||
color = "orange"
|
||||
|
||||
def load(self, context, name=None, namespace=None, data=None):
|
||||
"""Loads a .fursettings file defining how to load .abc into
|
||||
HairGuideFromMesh nodes
|
||||
|
||||
The .fursettings file defines what the node names should be and also
|
||||
what "cbId" attribute they should receive to match the original source
|
||||
and allow published looks to also work for Ornatrix rigs and its caches.
|
||||
|
||||
"""
|
||||
# Build namespace
|
||||
folder_name = context["folder"]["name"]
|
||||
if namespace is None:
|
||||
namespace = self.create_namespace(folder_name)
|
||||
|
||||
# Ensure Onratrix is loaded
|
||||
if not cmds.pluginInfo("Ornatrix.mll", query=True, loaded=True):
|
||||
cmds.loadPlugin("Ornatrix.mll", quiet=True)
|
||||
|
||||
path = self.filepath_from_context(context)
|
||||
settings = self.read_settings(path)
|
||||
# read the fursettings
|
||||
nodes = []
|
||||
for setting in settings["nodes"]:
|
||||
nodes.extend(self.create_node(namespace, path, setting))
|
||||
|
||||
self[:] = nodes
|
||||
|
||||
return containerise(
|
||||
name=name,
|
||||
namespace=namespace,
|
||||
nodes=nodes,
|
||||
context=context,
|
||||
loader=self.__class__.__name__
|
||||
)
|
||||
|
||||
def remove(self, container):
|
||||
|
||||
namespace = container["namespace"]
|
||||
nodes = container["nodes"]
|
||||
|
||||
self.log.info("Removing '%s' from Maya.." % container["name"])
|
||||
|
||||
nodes = cmds.ls(nodes, long=True)
|
||||
|
||||
try:
|
||||
cmds.delete(nodes)
|
||||
except ValueError:
|
||||
# Already implicitly deleted by Maya upon removing reference
|
||||
pass
|
||||
|
||||
cmds.namespace(removeNamespace=namespace, deleteNamespaceContent=True)
|
||||
|
||||
def update(self, container, context):
|
||||
repre_entity = context["representation"]
|
||||
nodes = container["nodes"]
|
||||
|
||||
path = get_representation_path(repre_entity)
|
||||
for node in nodes:
|
||||
if cmds.ls(node, type="HairFromGuidesNode"):
|
||||
cmds.setAttr(f"{node}.cacheFilePath", path)
|
||||
|
||||
|
||||
def switch(self, container, context):
|
||||
self.update(container, context)
|
||||
|
||||
# helper functions
|
||||
def create_namespace(self, folder_name):
|
||||
"""Create a unique namespace
|
||||
Args:
|
||||
asset (dict): asset information
|
||||
|
||||
"""
|
||||
|
||||
asset_name = "{}_".format(folder_name)
|
||||
prefix = "_" if asset_name[0].isdigit() else ""
|
||||
namespace = lib.unique_namespace(
|
||||
asset_name,
|
||||
prefix=prefix,
|
||||
suffix="_"
|
||||
)
|
||||
|
||||
return namespace
|
||||
|
||||
def create_node(self, namespace, filepath, node_settings):
|
||||
nodes = []
|
||||
orig_guide_name = node_settings["name"]
|
||||
orig_shape_name = node_settings["shape"]["name"]
|
||||
mesh_shape_name = "{}:{}".format(namespace, orig_shape_name)
|
||||
guide_name = "{}:{}".format(namespace, orig_guide_name)
|
||||
mesh_shape_node = cmds.ls(guide_name, type="mesh")
|
||||
if not mesh_shape_node:
|
||||
mesh_shape_node = cmds.createNode("mesh", name=guide_name)
|
||||
hair_guide_node = cmds.ls(guide_name, type="HairFromGuidesNode")
|
||||
if not hair_guide_node:
|
||||
hair_guide_node = cmds.createNode(
|
||||
"HairFromGuidesNode", name=guide_name)
|
||||
|
||||
lib.set_id(hair_guide_node, node_settings["cbId"])
|
||||
mel.eval(f"OxAddStrandOperator {mesh_shape_name} {guide_name};")
|
||||
cmds.setAttr(f"{guide_name}.cacheFilePath", filepath)
|
||||
nodes.append(hair_guide_node)
|
||||
return nodes
|
||||
|
||||
def read_setting(self, path):
|
||||
path_no_ext, _ = os.path.splitext(path)
|
||||
settings_path = f"{path_no_ext}.cachesettings"
|
||||
with open(settings_path, "r") as fp:
|
||||
setting_attributes = json.load(fp)
|
||||
|
||||
return setting_attributes
|
||||
|
|
@ -54,7 +54,7 @@ class OxRigLoader(plugin.ReferenceLoader):
|
|||
groupName=group_name
|
||||
)
|
||||
|
||||
color = plugin.get_load_color_for_product_type("OxRig")
|
||||
color = plugin.get_load_color_for_product_type("oxrig")
|
||||
if color is not None:
|
||||
red, green, blue = color
|
||||
cmds.setAttr(group_name + ".useOutlinerColor", 1)
|
||||
|
|
|
|||
|
|
@ -18,14 +18,16 @@ class CollectOxCache(plugin.MayaInstancePlugin):
|
|||
for ox_shape in ox_shapes:
|
||||
# Get transform data
|
||||
parent = cmds.listRelatives(ox_shape, parent=True)[0]
|
||||
transform_data = {"name": parent, "cbId": lib.get_id(parent)}
|
||||
mesh_shape_data = {"name": parent, "cbId": lib.get_id(parent)}
|
||||
ox_cache_nodes = [
|
||||
ox_node for ox_node in cmds.listConnections(ox_shape, destination=True)
|
||||
if cmds.nodeType(ox_node) == "HairFromGuidesNode"
|
||||
]
|
||||
# transfer cache file
|
||||
if not lib.get_id(ox_shape):
|
||||
return
|
||||
shape_data = {
|
||||
"transform": transform_data,
|
||||
"shape": mesh_shape_data,
|
||||
"name": ox_shapes,
|
||||
"cbId": lib.get_id(ox_shape),
|
||||
"ox_nodes": ox_cache_nodes,
|
||||
|
|
|
|||
|
|
@ -39,9 +39,7 @@ class ColorsSetting(BaseSettingsModel):
|
|||
(99, 206, 220, 1.0), title="Yeti Cache:")
|
||||
yetiRig: ColorRGBA_uint8 = SettingsField(
|
||||
(0, 205, 125, 1.0), title="Yeti Rig:")
|
||||
oxCache: ColorRGBA_uint8 = SettingsField(
|
||||
(156, 234, 195, 1.0), title="Ornatrix Cache:")
|
||||
oxRig: ColorRGBA_uint8 = SettingsField(
|
||||
oxrig: ColorRGBA_uint8 = SettingsField(
|
||||
(206, 234, 195, 1.0), title="Ornatrix Rig:")
|
||||
# model: ColorRGB_float = SettingsField(
|
||||
# (0.82, 0.52, 0.12), title="Model:"
|
||||
|
|
@ -253,8 +251,7 @@ DEFAULT_LOADERS_SETTING = {
|
|||
"vrayscene_layer": [255, 150, 12, 1.0],
|
||||
"yeticache": [99, 206, 220, 1.0],
|
||||
"yetiRig": [0, 205, 125, 1.0],
|
||||
"oxCache": [156, 234, 195, 1.0],
|
||||
"oxRig": [206, 234, 195, 1.0]
|
||||
"oxrig": [206, 234, 195, 1.0]
|
||||
# "model": [0.82, 0.52, 0.12],
|
||||
# "rig": [0.23, 0.89, 0.92],
|
||||
# "pointcache": [0.37, 0.82, 0.12],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue