This repository has been archived by the owner on Sep 20, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 129
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
250 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# -*- coding: utf-8 -*- | ||
"""Creator of Redshift proxy subset types.""" | ||
|
||
from pype.hosts.maya import plugin, lib | ||
|
||
|
||
class CreateRedshiftProxy(plugin.Creator): | ||
"""Create instance of Redshift Proxy subset.""" | ||
|
||
name = "redshiftproxy" | ||
label = "Redshift Proxy" | ||
family = "redshiftproxy" | ||
icon = "gears" | ||
|
||
def __init__(self, *args, **kwargs): | ||
super(CreateRedshiftProxy, self).__init__(*args, **kwargs) | ||
|
||
animation_data = lib.collect_animation_data() | ||
|
||
self.data["animation"] = False | ||
self.data["proxyFrameStart"] = animation_data["frameStart"] | ||
self.data["proxyFrameEnd"] = animation_data["frameEnd"] | ||
self.data["proxyFrameStep"] = animation_data["step"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
# -*- coding: utf-8 -*- | ||
"""Loader for Redshift proxy.""" | ||
import os | ||
from avalon.maya import lib | ||
from avalon import api | ||
from pype.api import config | ||
|
||
import maya.cmds as cmds | ||
import clique | ||
|
||
|
||
class RedshiftProxyLoader(api.Loader): | ||
"""Load Redshift proxy""" | ||
|
||
families = ["redshiftproxy"] | ||
representations = ["rs"] | ||
|
||
label = "Import Redshift Proxy" | ||
order = -10 | ||
icon = "code-fork" | ||
color = "orange" | ||
|
||
def load(self, context, name=None, namespace=None, options=None): | ||
"""Plugin entry point.""" | ||
|
||
from avalon.maya.pipeline import containerise | ||
from pype.hosts.maya.lib import namespaced | ||
|
||
try: | ||
family = context["representation"]["context"]["family"] | ||
except ValueError: | ||
family = "redshiftproxy" | ||
|
||
asset_name = context['asset']["name"] | ||
namespace = namespace or lib.unique_namespace( | ||
asset_name + "_", | ||
prefix="_" if asset_name[0].isdigit() else "", | ||
suffix="_", | ||
) | ||
|
||
# Ensure Redshift for Maya is loaded. | ||
cmds.loadPlugin("redshift4maya", quiet=True) | ||
|
||
with lib.maintained_selection(): | ||
cmds.namespace(addNamespace=namespace) | ||
with namespaced(namespace, new=False): | ||
nodes, group_node = self.create_rs_proxy( | ||
name, self.fname) | ||
|
||
self[:] = nodes | ||
if not nodes: | ||
return | ||
|
||
# colour the group node | ||
presets = config.get_presets(project=os.environ['AVALON_PROJECT']) | ||
colors = presets['plugins']['maya']['load']['colors'] | ||
c = colors.get(family) | ||
if c is not None: | ||
cmds.setAttr("{0}.useOutlinerColor".format(group_node), 1) | ||
cmds.setAttr("{0}.outlinerColor".format(group_node), | ||
c[0], c[1], c[2]) | ||
|
||
return containerise( | ||
name=name, | ||
namespace=namespace, | ||
nodes=nodes, | ||
context=context, | ||
loader=self.__class__.__name__) | ||
|
||
def update(self, container, representation): | ||
|
||
node = container['objectName'] | ||
assert cmds.objExists(node), "Missing container" | ||
|
||
members = cmds.sets(node, query=True) or [] | ||
rs_meshes = cmds.ls(members, type="RedshiftProxyMesh") | ||
assert rs_meshes, "Cannot find RedshiftProxyMesh in container" | ||
|
||
filename = api.get_representation_path(representation) | ||
|
||
for rs_mesh in rs_meshes: | ||
cmds.setAttr("{}.fileName".format(rs_mesh), | ||
filename, | ||
type="string") | ||
|
||
# Update metadata | ||
cmds.setAttr("{}.representation".format(node), | ||
str(representation["_id"]), | ||
type="string") | ||
|
||
def remove(self, container): | ||
|
||
# Delete container and its contents | ||
if cmds.objExists(container['objectName']): | ||
members = cmds.sets(container['objectName'], query=True) or [] | ||
cmds.delete([container['objectName']] + members) | ||
|
||
# Remove the namespace, if empty | ||
namespace = container['namespace'] | ||
if cmds.namespace(exists=namespace): | ||
members = cmds.namespaceInfo(namespace, listNamespace=True) | ||
if not members: | ||
cmds.namespace(removeNamespace=namespace) | ||
else: | ||
self.log.warning("Namespace not deleted because it " | ||
"still has members: %s", namespace) | ||
|
||
def switch(self, container, representation): | ||
self.update(container, representation) | ||
|
||
def create_rs_proxy(self, name, path): | ||
"""Creates Redshift Proxies showing a proxy object. | ||
Args: | ||
name (str): Proxy name. | ||
path (str): Path to proxy file. | ||
Returns: | ||
(str, str): Name of mesh with Redshift proxy and its parent | ||
transform. | ||
""" | ||
rs_mesh = cmds.createNode( | ||
'RedshiftProxyMesh', name="{}_RS".format(name)) | ||
mesh_shape = cmds.createNode("mesh", name="{}_GEOShape".format(name)) | ||
|
||
cmds.setAttr("{}.fileName".format(rs_mesh), | ||
path, | ||
type="string") | ||
|
||
cmds.connectAttr("{}.outMesh".format(rs_mesh), | ||
"{}.inMesh".format(mesh_shape)) | ||
|
||
group_node = cmds.group(empty=True, name="{}_GRP".format(name)) | ||
mesh_transform = cmds.listRelatives(mesh_shape, | ||
parent=True, fullPath=True) | ||
cmds.parent(mesh_transform, group_node) | ||
nodes = [rs_mesh, mesh_shape, group_node] | ||
|
||
# determine if we need to enable animation support | ||
files_in_folder = os.listdir(os.path.dirname(path)) | ||
collections, remainder = clique.assemble(files_in_folder) | ||
|
||
if collections: | ||
cmds.setAttr("{}.useFrameExtension".format(rs_mesh), 1) | ||
|
||
return nodes, group_node |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# -*- coding: utf-8 -*- | ||
"""Redshift Proxy extractor.""" | ||
import os | ||
import math | ||
|
||
import avalon.maya | ||
import pype.api | ||
|
||
from maya import cmds | ||
|
||
|
||
class ExtractRedshiftProxy(pype.api.Extractor): | ||
"""Extract the content of the instance to a redshift proxy file.""" | ||
|
||
label = "Redshift Proxy (.rs)" | ||
hosts = ["maya"] | ||
families = ["redshiftproxy"] | ||
|
||
def process(self, instance): | ||
"""Extractor entry point.""" | ||
|
||
staging_dir = self.staging_dir(instance) | ||
file_name = "{}.rs".format(instance.name) | ||
file_path = os.path.join(staging_dir, file_name) | ||
|
||
anim_on = instance.data["animation"] | ||
rs_options = "exportConnectivity=0;enableCompression=1;keepUnused=0;" | ||
repr_files = file_name | ||
|
||
if not anim_on: | ||
# Remove animation information because it is not required for | ||
# non-animated subsets | ||
instance.data.pop("proxyFrameStart", None) | ||
instance.data.pop("proxyFrameEnd", None) | ||
|
||
else: | ||
start_frame = instance.data["proxyFrameStart"] | ||
end_frame = instance.data["proxyFrameEnd"] | ||
rs_options = "{}startFrame={};endFrame={};frameStep={};".format( | ||
rs_options, start_frame, | ||
end_frame, instance.data["proxyFrameStep"] | ||
) | ||
|
||
root, ext = os.path.splitext(file_path) | ||
# Padding is taken from number of digits of the end_frame. | ||
# Not sure where Redshift is taking it. | ||
repr_files = [ | ||
"{}.{}{}".format(root, str(frame).rjust(int(math.log10(int(end_frame)) + 1), "0"), ext) # noqa: E501 | ||
for frame in range( | ||
int(start_frame), | ||
int(end_frame) + 1, | ||
int(instance.data["proxyFrameStep"]))] | ||
# vertex_colors = instance.data.get("vertexColors", False) | ||
|
||
# Write out rs file | ||
self.log.info("Writing: '%s'" % file_path) | ||
with avalon.maya.maintained_selection(): | ||
cmds.select(instance.data["setMembers"], noExpand=True) | ||
cmds.file(file_path, | ||
pr=False, | ||
force=True, | ||
type="Redshift Proxy", | ||
exportSelected=True, | ||
options=rs_options) | ||
|
||
if "representations" not in instance.data: | ||
instance.data["representations"] = [] | ||
|
||
self.log.debug("Files: {}".format(repr_files)) | ||
|
||
representation = { | ||
'name': 'rs', | ||
'ext': 'rs', | ||
'files': repr_files, | ||
"stagingDir": staging_dir, | ||
} | ||
instance.data["representations"].append(representation) | ||
|
||
self.log.info("Extracted instance '%s' to: %s" | ||
% (instance.name, staging_dir)) |