From fde5bdf438b64c325a563053eeb4472e1928d893 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 28 Nov 2019 16:22:14 +0100 Subject: [PATCH] add ability to publish and load arnold standin sequence --- pype/plugins/global/publish/integrate_new.py | 2 +- pype/plugins/maya/create/create_ass.py | 18 +++++- pype/plugins/maya/load/load_ass.py | 55 ++++++++++++++++-- pype/plugins/maya/publish/extract_ass.py | 57 ++++++++++++++++--- pype/plugins/maya/publish/extract_assproxy.py | 9 ++- 5 files changed, 122 insertions(+), 19 deletions(-) diff --git a/pype/plugins/global/publish/integrate_new.py b/pype/plugins/global/publish/integrate_new.py index f0619eb776..52dc3a6361 100644 --- a/pype/plugins/global/publish/integrate_new.py +++ b/pype/plugins/global/publish/integrate_new.py @@ -409,7 +409,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): } if sequence_repre and repre.get("frameStart"): - representation['context']['frame'] = repre.get("frameStart") + representation['context']['frame'] = src_padding_exp % repre.get("frameStart") self.log.debug("__ representation: {}".format(representation)) destination_list.append(dst) diff --git a/pype/plugins/maya/create/create_ass.py b/pype/plugins/maya/create/create_ass.py index 84b42e9b20..6d8eda1a40 100644 --- a/pype/plugins/maya/create/create_ass.py +++ b/pype/plugins/maya/create/create_ass.py @@ -1,6 +1,7 @@ from collections import OrderedDict import avalon.maya +from pype.maya import lib from maya import cmds @@ -14,10 +15,21 @@ class CreateAss(avalon.maya.Creator): icon = "cube" defaults = ['Main'] + def __init__(self, *args, **kwargs): + super(CreateAss, self).__init__(*args, **kwargs) + + # Add animation data + self.data.update(lib.collect_animation_data()) + + # Vertex colors with the geometry + self.data["exportSequence"] = False + def process(self): instance = super(CreateAss, self).process() - data = OrderedDict(**self.data) + # data = OrderedDict(**self.data) + + nodes = list() @@ -30,4 +42,6 @@ class CreateAss(avalon.maya.Creator): assProxy = cmds.sets(name="proxy_SET", empty=True) cmds.sets([assContent, assProxy], forceElement=instance) - self.data = data + # self.log.info(data) + # + # self.data = data diff --git a/pype/plugins/maya/load/load_ass.py b/pype/plugins/maya/load/load_ass.py index 2960e4403e..83dd80bd4e 100644 --- a/pype/plugins/maya/load/load_ass.py +++ b/pype/plugins/maya/load/load_ass.py @@ -2,6 +2,7 @@ from avalon import api import pype.maya.plugin import os from pypeapp import config +import clique class AssProxyLoader(pype.maya.plugin.ReferenceLoader): @@ -21,6 +22,13 @@ class AssProxyLoader(pype.maya.plugin.ReferenceLoader): from avalon import maya import pymel.core as pm + version = context['version'] + version_data = version.get("data", {}) + + self.log.info("version_data: {}\n".format(version_data)) + + frameStart = version_data.get("frameStart", None) + try: family = context["representation"]["context"]["family"] except ValueError: @@ -30,7 +38,24 @@ class AssProxyLoader(pype.maya.plugin.ReferenceLoader): groupName = "{}:{}".format(namespace, name) path = self.fname - proxyPath = os.path.splitext(path)[0] + ".ma" + proxyPath_base = os.path.splitext(path)[0] + + if frameStart is not None: + proxyPath_base = os.path.splitext(proxyPath_base)[0] + + publish_folder = os.path.split(path)[0] + files_in_folder = os.listdir(publish_folder) + collections, remainder = clique.assemble(files_in_folder) + + if collections: + hashes = collections[0].padding * '#' + coll = collections[0].format('{head}[index]{tail}') + filename = coll.replace('[index]', hashes) + + path = os.path.join(publish_folder, filename) + + proxyPath = proxyPath_base + ".ma" + self.log.info nodes = cmds.file(proxyPath, namespace=namespace, @@ -147,6 +172,13 @@ class AssStandinLoader(api.Loader): import mtoa.ui.arnoldmenu import pymel.core as pm + version = context['version'] + version_data = version.get("data", {}) + + self.log.info("version_data: {}\n".format(version_data)) + + frameStart = version_data.get("frameStart", None) + asset = context['asset']['name'] namespace = namespace or lib.unique_namespace( asset + "_", @@ -182,6 +214,8 @@ class AssStandinLoader(api.Loader): # Set the standin filepath standinShape.dso.set(self.fname) + if frameStart is not None: + standinShape.useFrameExtension.set(1) nodes = [root, standin] self[:] = nodes @@ -199,14 +233,23 @@ class AssStandinLoader(api.Loader): path = api.get_representation_path(representation) - # Update the standin - members = pm.sets(container['objectName'], query=True) - standins = pm.ls(members, type="AiStandIn", long=True) + files_in_path = os.listdir(os.path.split(path)[0]) + sequence = 0 + collections, remainder = clique.assemble(files_in_path) + if collections: + sequence = 1 - assert len(caches) == 1, "This is a bug" + # Update the standin + standins = list() + members = pm.sets(container['objectName'], query=True) + for member in members: + shape = member.getShape() + if (shape and shape.type() == "aiStandIn"): + standins.append(shape) for standin in standins: - standin.cacheFileName.set(path) + standin.dso.set(path) + standin.useFrameExtension.set(sequence) container = pm.PyNode(container["objectName"]) container.representation.set(str(representation["_id"])) diff --git a/pype/plugins/maya/publish/extract_ass.py b/pype/plugins/maya/publish/extract_ass.py index 1fed6c8dd7..71f3e0d84c 100644 --- a/pype/plugins/maya/publish/extract_ass.py +++ b/pype/plugins/maya/publish/extract_ass.py @@ -20,8 +20,11 @@ class ExtractAssStandin(pype.api.Extractor): def process(self, instance): + sequence = instance.data.get("exportSequence", False) + staging_dir = self.staging_dir(instance) filename = "{}.ass".format(instance.name) + filenames = list() file_path = os.path.join(staging_dir, filename) # Write out .ass file @@ -29,13 +32,47 @@ class ExtractAssStandin(pype.api.Extractor): with avalon.maya.maintained_selection(): self.log.info("Writing: {}".format(instance.data["setMembers"])) cmds.select(instance.data["setMembers"], noExpand=True) - cmds.arnoldExportAss( filename=file_path, - selected=True, - asciiAss=True, - shadowLinks=True, - lightLinks=True, - boundingBox=True - ) + + if sequence: + self.log.info("Extracting ass sequence") + + # Collect the start and end including handles + start = instance.data.get("frameStart", 1) + end = instance.data.get("frameEnd", 1) + handles = instance.data.get("handles", 0) + step = instance.data.get("step", 0) + if handles: + start -= handles + end += handles + + exported_files = cmds.arnoldExportAss(filename=file_path, + selected=True, + asciiAss=True, + shadowLinks=True, + lightLinks=True, + boundingBox=True, + startFrame=start, + endFrame=end, + frameStep=step + ) + for file in exported_files: + filenames.append(os.path.split(file)[1]) + self.log.info("Exported: {}".format(filenames)) + else: + cmds.arnoldExportAss(filename=file_path, + selected=True, + asciiAss=True, + shadowLinks=True, + lightLinks=True, + boundingBox=True + ) + filenames = filename + optionals = [ + "frameStart", "frameEnd", "step", "handles", + "handleEnd", "handleStart" + ] + for key in optionals: + instance.data.pop(key, None) if "representations" not in instance.data: instance.data["representations"] = [] @@ -43,9 +80,13 @@ class ExtractAssStandin(pype.api.Extractor): representation = { 'name': 'ass', 'ext': 'ass', - 'files': filename, + 'files': filenames, "stagingDir": staging_dir } + + if sequence: + representation['frameStart'] = start + instance.data["representations"].append(representation) self.log.info("Extracted instance '%s' to: %s" diff --git a/pype/plugins/maya/publish/extract_assproxy.py b/pype/plugins/maya/publish/extract_assproxy.py index 34c3113e11..59684febe1 100644 --- a/pype/plugins/maya/publish/extract_assproxy.py +++ b/pype/plugins/maya/publish/extract_assproxy.py @@ -43,8 +43,13 @@ class ExtractAssProxy(pype.api.Extractor): # Get only the shape contents we need in such a way that we avoid # taking along intermediateObjects - members = instance.data['proxy'] - members = cmds.ls(members, + proxy = instance.data.get('proxy', None) + + if not proxy: + self.log.info("no proxy mesh") + return + + members = cmds.ls(proxy, dag=True, transforms=True, noIntermediate=True)