From 3bd768f4fc70883af4b322909207b81f544c87e6 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 18 Jun 2024 16:32:15 +0800 Subject: [PATCH] implement cache family --- .../plugins/create/create_ornatrix_cache.py | 57 +++++++++++- .../plugins/publish/collect_ornatrix_cache.py | 38 ++++++++ .../plugins/publish/extract_ornatrix_cache.py | 87 +++++++++++++++++++ .../plugins/publish/validate_frame_range.py | 3 +- 4 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 server_addon/maya/client/ayon_maya/plugins/publish/collect_ornatrix_cache.py create mode 100644 server_addon/maya/client/ayon_maya/plugins/publish/extract_ornatrix_cache.py diff --git a/server_addon/maya/client/ayon_maya/plugins/create/create_ornatrix_cache.py b/server_addon/maya/client/ayon_maya/plugins/create/create_ornatrix_cache.py index bc973394cb..91cdb44440 100644 --- a/server_addon/maya/client/ayon_maya/plugins/create/create_ornatrix_cache.py +++ b/server_addon/maya/client/ayon_maya/plugins/create/create_ornatrix_cache.py @@ -2,10 +2,11 @@ from ayon_maya.api import ( lib, plugin ) +from ayon_core.lib import BoolDef, NumberDef class CreateOxCache(plugin.MayaCreator): - """Output for procedural plugin nodes of Yeti """ + """Output for procedural plugin nodes of Ornatrix """ identifier = "io.openpype.creators.maya.OxCache" label = "Ornatrix Cache" @@ -15,8 +16,60 @@ class CreateOxCache(plugin.MayaCreator): def get_instance_attr_defs(self): # Add animation data without step and handles - remove = {"step", "handleStart", "handleEnd"} + remove = {"handleStart", "handleEnd"} defs = [attr_def for attr_def in lib.collect_animation_defs() if attr_def.key not in remove] + defs.extend( + [ + BoolDef("renderVersion", + label="Use Render Version", + default=True), + BoolDef("upDirection", + label="Up Direction", + default=True), + BoolDef("useWorldCoordinates", + label="Use World Coordinates", + default=False), + BoolDef("exportStrandData", + label="Export Strand Data", + default=True), + BoolDef("exportSurfacePositions", + label="Export Surface Positions", + default=False), + BoolDef("oneObjectPerFile", + label="One Object Per File", + default=False), + BoolDef("exportStrandIds", + label="Export Strand Ids", + default=True), + BoolDef("exportStrandGroups", + label="Export Strand Groups", + default=True), + BoolDef("exportWidths", + label="Export Widths", + default=True), + BoolDef("exportTextureCoordinates", + label="Export Texture Coordinates", + default=True), + BoolDef("exportVelocities", + label="Export Velocities", + default=False), + BoolDef("exportNormals", + label="Export Normals", + default=False), + BoolDef("velocityIntervalCenter", + label="Velocity Interval Center", + default=False), + NumberDef("velocityIntervalLength", + label="Velocity Interval Length", + default=0.5), + BoolDef("unrealEngineExport", + label="Unreal Engine Export", + default=False), + BoolDef("exportEachStrandAsSeparateObject", + label="Export Each Strand As Separate Object", + default=False) + ] + ) return defs diff --git a/server_addon/maya/client/ayon_maya/plugins/publish/collect_ornatrix_cache.py b/server_addon/maya/client/ayon_maya/plugins/publish/collect_ornatrix_cache.py new file mode 100644 index 0000000000..f9d8fce2d1 --- /dev/null +++ b/server_addon/maya/client/ayon_maya/plugins/publish/collect_ornatrix_cache.py @@ -0,0 +1,38 @@ +import pyblish.api +from ayon_maya.api import lib +from ayon_maya.api import plugin +from maya import cmds + + +class CollectOxCache(plugin.MayaInstancePlugin): + """Collect all information of the Ornatrix caches + + """ + + order = pyblish.api.CollectorOrder + 0.45 + label = "Collect Ornatrix Cache" + families = ["OxRig", "OxCache"] + + def process(self, instance): + + settings = {"nodes": []} + ox_shapes = cmds.ls(instance[:], shapes=True, long=True) + 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)} + ox_cache_nodes = [ + ox_node for ox_node in cmds.listConnections(ox_shape, destination=True) + if cmds.nodeType(ox_node) == "HairFromGuidesNode" + ] + # transfer cache file + shape_data = { + "transform": transform_data, + "name": ox_shapes, + "cbId": lib.get_id(ox_shape), + "ox_nodes": ox_cache_nodes, + "cache_file_attribute": ["{}.cacheFilePath".format(ox_node) + for ox_node in ox_cache_nodes] + } + settings["nodes"].append(shape_data) + instance.data["cachesettings"] = settings diff --git a/server_addon/maya/client/ayon_maya/plugins/publish/extract_ornatrix_cache.py b/server_addon/maya/client/ayon_maya/plugins/publish/extract_ornatrix_cache.py new file mode 100644 index 0000000000..6e5e6193e9 --- /dev/null +++ b/server_addon/maya/client/ayon_maya/plugins/publish/extract_ornatrix_cache.py @@ -0,0 +1,87 @@ +import os +import json +from ayon_maya.api import lib +from ayon_maya.api import plugin +from maya import cmds + + +class ExtractOxCache(plugin.MayaExtractorPlugin): + """Producing Ornatrix cache files using scene time range. + + This will extract Ornatrix cache file sequence and fur settings. + """ + + label = "Extract Ornatrix Cache" + families = ["OxRig", "OxCache"] + + def process(self, instance): + # Define extract output file path + ox_nodes = cmds.ls(instance[:], long=True) + dirname = self.staging_dir(instance) + attr_values = instance.data["creator_attributes"] + # Start writing the files for snap shot + # will be replace by the Yeti node name + ox_abc_path = os.path.join(dirname, "{}ornatrix.abc".format( + instance.name)) + ox_export_option = self.ox_option(attr_values) + with lib.maintained_selection(): + cmds.select(ox_nodes, noExpand=True) + cmds.file(ox_abc_path, + force=True, + exportSelected=True, + typ="Ornatrix Alembic", + options=ox_export_option) + + settings = instance.data["cachesettings"] + self.log.debug("Writing metadata file") + cachesettings_path = os.path.join(dirname, "ornatrix.cachesettings") + with open(cachesettings_path, "w") as fp: + json.dump(settings, fp, ensure_ascii=False) + + # build representations + if "representations" not in instance.data: + instance.data["representations"] = [] + + instance.data["representations"].append( + { + 'name': 'abc', + 'ext': 'abc', + 'files': os.path.basename(ox_abc_path), + 'stagingDir': dirname + } + ) + + instance.data["representations"].append( + { + 'name': 'cachesettings', + 'ext': 'cachesettings', + 'files': os.path.basename(cachesettings_path), + 'stagingDir': dirname + } + ) + + self.log.debug("Extracted {} to {}".format(instance, dirname)) + + def ox_option(self, attr_values): + """Get Ornatrix export options + + Args: + instance (pyblish.api.Instance): Instance + + Returns: + str: export options command + """ + ox_export_options = [] + for key, value in attr_values.items(): + export_option = None + if key == "frameStart": + export_option = "fromTime={}".format(int(value)) + elif key == "frameEnd": + export_option = "toTime={}".format(int(value)) + elif isinstance(key, bool): + export_option = "{}={}".format(key, int(value)) + else: + export_option = "{}={}".format(key, value) + ox_export_options.append(export_option) + ox_export_option = ";".join(ox_export_options) + return ox_export_option diff --git a/server_addon/maya/client/ayon_maya/plugins/publish/validate_frame_range.py b/server_addon/maya/client/ayon_maya/plugins/publish/validate_frame_range.py index 90bdef4107..46e1d41255 100644 --- a/server_addon/maya/client/ayon_maya/plugins/publish/validate_frame_range.py +++ b/server_addon/maya/client/ayon_maya/plugins/publish/validate_frame_range.py @@ -32,7 +32,8 @@ class ValidateFrameRange(plugin.MayaInstancePlugin, "proxyAbc", "renderlayer", "review", - "yeticache"] + "yeticache", + "OxCache"] optional = True actions = [RepairAction] exclude_product_types = []