def update(self, container, representation): import maya.cmds as cmds from avalon import io from reveries.maya import pipeline from reveries.utils import get_representation_path_ members = cmds.sets(container["objectName"], query=True) standins = cmds.ls(members, type="aiStandIn", long=True) if not standins: raise Exception("No Arnold Stand-In node, this is a bug.") parents = io.parenthood(representation) self.package_path = get_representation_path_(representation, parents) entry_path, use_sequence = self.retrive(representation) if not entry_path.endswith(".ass"): raise Exception("Not a Arnold Stand-In file, this is a bug: " "%s" % entry_path) for standin in standins: # This would allow all copies getting updated together cmds.setAttr(standin + ".dso", entry_path, type="string") cmds.setAttr(standin + ".useFrameExtension", use_sequence) # Update container version, subset, asset, _ = parents pipeline.update_container(container, asset, subset, version, representation)
def update_dependency(container): """Update subset data and references This is for updating dependencies and relink them to assets in current project for the loaded subset that was originally moved from other project. You need to manually update the representation id value in container before using this function. """ representation_id = cmds.getAttr(container + ".representation") representation_id = io.ObjectId(representation_id) representation = io.find_one({"_id": representation_id}) if representation is None: raise Exception("Representation not found.") version, subset, asset, project = io.parenthood(representation) cmds.setAttr(container + ".assetId", str(asset["_id"]), type="string") cmds.setAttr(container + ".subsetId", str(subset["_id"]), type="string") cmds.setAttr(container + ".versionId", str(version["_id"]), type="string") # Update Reference path reference_node = next( iter(cmds.ls(cmds.sets(container, query=True), type="reference")), None) if reference_node is None: # No reference to update return package_path = get_representation_path_(representation, (version, subset, asset, project)) file_type = representation["name"] if file_type == "FBXCache": file_type = "FBX" elif file_type in ("GPUCache", "LookDev"): file_type = "MayaAscii" file_name = representation["data"]["entryFileName"] entry_path = os.path.join(package_path, file_name) if not os.path.isfile(entry_path): raise IOError("File Not Found: {!r}".format(entry_path)) entry_path = env_embedded_path(entry_path) cmds.file(entry_path, loadReference=reference_node, type=file_type, defaultExtensions=False)
def get_relationship(look): representation_id = io.ObjectId(look["representation"]) representation = io.find_one({"_id": representation_id}) parents = io.parenthood(representation) package_path = get_representation_path_(representation, parents) file_name = representation["data"]["linkFname"] relationship = os.path.join(package_path, file_name) return relationship
def get_asset_data(objectId): document = io.find_one({"_id": io.ObjectId(objectId)}) document_type = document["type"] if document_type == "representation": version, subset, asset, _ = io.parenthood(document) elif document_type == "asset": asset = document else: print("Could not fetch enough data") return return asset
def update(self, container, representation): node = container["node"] # Update the file path parents = io.parenthood(representation) self.package_path = get_representation_path_(representation, parents) file_path = self.file_path(representation) file_path = file_path.replace("\\", "/") node.setParms({"ar_filename": file_path}) # Update attribute node.setParms({"representation": str(representation["_id"])})
def update(self, container, representation): node = container["node"] # Update the file path parents = io.parenthood(representation) self.package_path = get_representation_path_(representation, parents) file_path = self.file_path(representation) file_path = file_path.replace("\\", "/") # Update attributes node.setParms({"fileName": file_path, "representation": str(representation["_id"])}) # Rebuild node.parm("buildHierarchy").pressButton()
def _copy_representations(self, representation_id): """Copy all documents and files of representation and dependencies""" # Representation representation = self._find_one({"_id": representation_id}) if not representation: representation = io.find_one({"_id": representation_id}) self._insert_one(representation) # Version version = io.find_one({"_id": representation["parent"]}) if not self._find_one({"_id": version["_id"]}): self._insert_one(version) # Subset subset = io.find_one({"_id": version["parent"]}) if not self._find_one({"_id": subset["_id"]}): self._insert_one(subset) # Asset asset = io.find_one({"_id": subset["parent"]}) if not self._find_one({"_id": asset["_id"]}): asset["parent"] = self._project["_id"] self._insert_one(asset) # Asset Visual Parent parent_id = asset["data"]["visualParent"] if parent_id: parent_id = io.ObjectId(parent_id) if not self._find_one({"_id": parent_id}): parent_asset = io.find_one({"_id": parent_id}) parent_asset["parent"] = self._project["_id"] self._insert_one(parent_asset) # Dependencies for dependency_id in version["data"]["dependencies"]: dependency_id = io.ObjectId(dependency_id) for representation_ in io.find({"parent": dependency_id}): self._copy_representations(representation_["_id"]) # Copy package parents = io.parenthood(representation) src_package = get_representation_path_(representation, parents) parents = parents[:-1] + [self._project] representation["data"]["reprRoot"] = self._project["data"].get("root") dst_package = get_representation_path_(representation, parents) self._copy_dir(src_package, dst_package)
def update_package_version(container, version): """ Update package by version number Args: container (dict): container data of the container node version (int): the new version number of the package Returns: None """ # Versioning (from `core.maya.pipeline`) current_representation = io.find_one( {"_id": io.ObjectId(container["representation"])}) assert current_representation is not None, "This is a bug" version_, subset, asset, project = io.parenthood(current_representation) if version == -1: new_version = io.find_one({ "type": "version", "parent": subset["_id"] }, sort=[("name", -1)]) else: new_version = io.find_one({ "type": "version", "parent": subset["_id"], "name": version, }) assert new_version is not None, "This is a bug" # Get the new representation (new file) new_representation = io.find_one({ "type": "representation", "parent": new_version["_id"], "name": current_representation["name"] }) update_package(container, new_representation)
def _post_process(self, name, namespace, context, data): import os from maya import cmds from avalon import maya, io # Task-dependent post-process if os.getenv("AVALON_TASK") != "animate": return self.log.info( "No animation instance created due to task != animate") # Find associated rig to these curves try: dependency = context["representation"]["dependencies"][0] except (KeyError, IndexError): return self.log.warning("No dependencies found for %s" % name) dependency = io.find_one({"_id": io.ObjectId(dependency)}) _, _, dependency, _ = io.parenthood(dependency) # TODO(marcus): We are hardcoding the name "out_SET" here. # Better register this keyword, so that it can be used # elsewhere, such as in the Integrator plug-in, # without duplication. output = next((node for node in self if node.endswith("out_SET")), None) controls = next( (node for node in self if node.endswith("controls_SET")), None) assert output, "No out_SET in rig, this is a bug." assert controls, "No controls_SET in rig, this is a bug." with maya.maintained_selection(): cmds.select([output, controls], noExpand=True) dependencies = [context["representation"]["_id"]] name = "anim" + dependency["name"].title() + "_" # TODO(marcus): Hardcoding the family here, better separate this. maya.create( name=maya.unique_name(name, suffix="_SET"), family="ava.animation", options={"useSelection": True}, data={"dependencies": " ".join(str(d) for d in dependencies)})
def update(self, container, representation): node = container["node"] try: alembic_node = next(n for n in node.children() if n.type().name() == "alembic") except StopIteration: self.log.error("Could not find node of type `alembic`") return # Update the file path parents = io.parenthood(representation) self.package_path = get_representation_path_(representation, parents) file_path = self.file_path(representation) file_path = file_path.replace("\\", "/") if file_path.endswith(".ma"): file_path = file_path.rsplit("ma", 1)[0] + "abc" alembic_node.setParms({"fileName": file_path}) # Update attribute node.setParms({"representation": str(representation["_id"])})
def switch_item(container, asset_name=None, subset_name=None, representation_name=None): """Switch container asset, subset or representation of a container by name. It'll always switch to the latest version - of course a different approach could be implemented. Args: container (dict): data of the item to switch with asset_name (str): name of the asset subset_name (str): name of the subset representation_name (str): name of the representation Returns: dict """ if all(not x for x in [asset_name, subset_name, representation_name]): raise ValueError( "Must have at least one change provided to switch.") # Collect any of current asset, subset and representation if not provided # so we can use the original name from those. if any(not x for x in [asset_name, subset_name, representation_name]): _id = io.ObjectId(container["representation"]) representation = io.find_one({"type": "representation", "_id": _id}) version, subset, asset, project = io.parenthood(representation) if asset_name is None: asset_name = asset["name"] if subset_name is None: subset_name = subset["name"] if representation_name is None: representation_name = representation["name"] # Find the new one asset = io.find_one({"name": asset_name, "type": "asset"}) assert asset, ("Could not find asset in the database with the name " "'%s'" % asset_name) subset = io.find_one({"name": subset_name, "type": "subset", "parent": asset["_id"]}) assert subset, ("Could not find subset in the database with the name " "'%s'" % subset_name) version = io.find_one({"type": "version", "parent": subset["_id"]}, sort=[("name", -1)]) assert version, "Could not find a version for {}.{}".format( asset_name, subset_name ) representation = io.find_one({"name": representation_name, "type": "representation", "parent": version["_id"]}) assert representation, ( "Could not find representation in the database with" " the name '%s'" % representation_name) api.switch(container, representation) return representation
def load(Loader, representation, name=None, namespace=None, data=None): """Load asset via database Deprecated; this functionality is replaced by `api.load()` Arguments: Loader (api.Loader): The loader to process in host Maya. representation (dict, io.ObjectId or str): Address to representation name (str, optional): Use pre-defined name namespace (str, optional): Use pre-defined namespace data (dict, optional): Additional settings dictionary """ from avalon.vendor import six from avalon import io from avalon.maya import lib from avalon.maya.pipeline import containerise assert representation is not None, "This is a bug" if isinstance(representation, (six.string_types, io.ObjectId)): representation = io.find_one({"_id": io.ObjectId(str(representation))}) version, subset, asset, project = io.parenthood(representation) assert all([representation, version, subset, asset, project]), ( "This is a bug" ) context = { "project": project, "asset": asset, "subset": subset, "version": version, "representation": representation, } # Ensure data is a dictionary when no explicit data provided if data is None: data = dict() assert isinstance(data, dict), "Data must be a dictionary" name = name or subset["name"] namespace = namespace or lib.unique_namespace( asset["name"] + "_", prefix="_" if asset["name"][0].isdigit() else "", suffix="_", ) # TODO(roy): add compatibility check, see `tools.cbloader.lib` Loader.log.info( "Running '%s' on '%s'" % (Loader.__name__, asset["name"]) ) try: loader = Loader(context) with lib.maintained_selection(): loader.process(name, namespace, context, data) except OSError as e: log.info("WARNING: %s" % e) return list() # Only containerize if any nodes were loaded by the Loader nodes = loader[:] if not nodes: return return containerise( name=name, namespace=namespace, nodes=loader[:], context=context, loader=Loader.__name__)
def update(container, version=-1): """Update `container` to `version` Deprecated; this functionality is replaced by `api.update()` This function relies on a container being referenced. At the time of this writing, all assets - models, rigs, animations, shaders - are referenced and should pose no problem. But should there be an asset that isn't referenced then this function will need to see an update. Arguments: container (avalon-core:container-1.0): Container to update, from `host.ls()`. version (int, optional): Update the container to this version. If no version is passed, the latest is assumed. """ from avalon import io from avalon import api node = container["objectName"] # Assume asset has been referenced reference_node = next((node for node in cmds.sets(node, query=True) if cmds.nodeType(node) == "reference"), None) assert reference_node, ("Imported container not supported; " "container must be referenced.") current_representation = io.find_one({ "_id": io.ObjectId(container["representation"]) }) assert current_representation is not None, "This is a bug" version_, subset, asset, project = io.parenthood(current_representation) if version == -1: new_version = io.find_one({ "type": "version", "parent": subset["_id"] }, sort=[("name", -1)]) else: new_version = io.find_one({ "type": "version", "parent": subset["_id"], "name": version, }) new_representation = io.find_one({ "type": "representation", "parent": new_version["_id"], "name": current_representation["name"] }) assert new_version is not None, "This is a bug" template_publish = project["config"]["template"]["publish"] fname = template_publish.format(**{ "root": api.registered_root(), "project": project["name"], "asset": asset["name"], "silo": asset["silo"], "subset": subset["name"], "version": new_version["name"], "representation": current_representation["name"], }) file_type = { "ma": "mayaAscii", "mb": "mayaBinary", "abc": "Alembic" }.get(new_representation["name"]) assert file_type, ("Unsupported representation: %s" % new_representation) assert os.path.exists(fname), "%s does not exist." % fname cmds.file(fname, loadReference=reference_node, type=file_type) # Update metadata cmds.setAttr(container["objectName"] + ".representation", str(new_representation["_id"]), type="string")
def __get_package_path(representation): parents = io.parenthood(representation) return get_representation_path_(representation, parents)