Merge branch 'develop' of https://github.com/pypeclub/OpenPype into feature/multiverse

This commit is contained in:
Bo Zhou 2022-03-23 14:09:40 +09:00
commit 0bf37ddffc
259 changed files with 4653 additions and 1939 deletions

View file

@ -1,12 +1,18 @@
import json
from avalon import api, io, pipeline
from avalon import io
from bson.objectid import ObjectId
from openpype.pipeline import (
InventoryAction,
get_representation_context,
get_representation_path_from_context,
)
from openpype.hosts.maya.api.lib import (
maintained_selection,
apply_shaders
)
class ImportModelRender(api.InventoryAction):
class ImportModelRender(InventoryAction):
label = "Import Model Render Sets"
icon = "industry"
@ -35,7 +41,7 @@ class ImportModelRender(api.InventoryAction):
nodes.append(n)
repr_doc = io.find_one({
"_id": io.ObjectId(container["representation"]),
"_id": ObjectId(container["representation"]),
})
version_id = repr_doc["parent"]
@ -73,11 +79,11 @@ class ImportModelRender(api.InventoryAction):
"name": self.look_data_type,
})
context = pipeline.get_representation_context(look_repr["_id"])
maya_file = pipeline.get_representation_path_from_context(context)
context = get_representation_context(look_repr["_id"])
maya_file = get_representation_path_from_context(context)
context = pipeline.get_representation_context(json_repr["_id"])
json_file = pipeline.get_representation_path_from_context(context)
context = get_representation_context(json_repr["_id"])
json_file = get_representation_path_from_context(context)
# Import the look file
with maintained_selection():

View file

@ -1,11 +1,10 @@
from maya import cmds
from avalon import api
from openpype.pipeline import InventoryAction
from openpype.hosts.maya.api.plugin import get_reference_node
class ImportReference(api.InventoryAction):
class ImportReference(InventoryAction):
"""Imports selected reference to inside of the file."""
label = "Import Reference"

View file

@ -2,14 +2,14 @@
"""
from avalon import api
from openpype.pipeline import load
from openpype.hosts.maya.api.lib import (
maintained_selection,
unique_namespace
)
class SetFrameRangeLoader(api.Loader):
class SetFrameRangeLoader(load.LoaderPlugin):
"""Specific loader of Alembic for the avalon.animation family"""
families = ["animation",
@ -43,7 +43,7 @@ class SetFrameRangeLoader(api.Loader):
animationEndTime=end)
class SetFrameRangeWithHandlesLoader(api.Loader):
class SetFrameRangeWithHandlesLoader(load.LoaderPlugin):
"""Specific loader of Alembic for the avalon.animation family"""
families = ["animation",
@ -81,7 +81,7 @@ class SetFrameRangeWithHandlesLoader(api.Loader):
animationEndTime=end)
class ImportMayaLoader(api.Loader):
class ImportMayaLoader(load.LoaderPlugin):
"""Import action for Maya (unmanaged)
Warning:

View file

@ -1,8 +1,11 @@
import os
import clique
from avalon import api
from openpype.api import get_project_settings
from openpype.pipeline import (
load,
get_representation_path
)
import openpype.hosts.maya.api.plugin
from openpype.hosts.maya.api.plugin import get_reference_node
from openpype.hosts.maya.api.lib import (
@ -106,7 +109,7 @@ class AssProxyLoader(openpype.hosts.maya.api.plugin.ReferenceLoader):
node = container["objectName"]
representation["context"].pop("frame", None)
path = api.get_representation_path(representation)
path = get_representation_path(representation)
print(path)
# path = self.fname
print(self.fname)
@ -164,7 +167,7 @@ class AssProxyLoader(openpype.hosts.maya.api.plugin.ReferenceLoader):
type="string")
class AssStandinLoader(api.Loader):
class AssStandinLoader(load.LoaderPlugin):
"""Load .ASS file as standin"""
families = ["ass"]
@ -240,7 +243,7 @@ class AssStandinLoader(api.Loader):
import pymel.core as pm
path = api.get_representation_path(representation)
path = get_representation_path(representation)
files_in_path = os.listdir(os.path.split(path)[0])
sequence = 0

View file

@ -1,7 +1,10 @@
from avalon import api
from openpype.pipeline import (
load,
remove_container
)
class AssemblyLoader(api.Loader):
class AssemblyLoader(load.LoaderPlugin):
families = ["assembly"]
representations = ["json"]
@ -48,13 +51,11 @@ class AssemblyLoader(api.Loader):
def update(self, container, representation):
from openpype import setdress
return setdress.update_package(container,
representation)
return setdress.update_package(container, representation)
def remove(self, container):
"""Remove all sub containers"""
from avalon import api
from openpype import setdress
import maya.cmds as cmds
@ -63,7 +64,7 @@ class AssemblyLoader(api.Loader):
for member_container in member_containers:
self.log.info("Removing container %s",
member_container['objectName'])
api.remove(member_container)
remove_container(member_container)
# Remove alembic hierarchy reference
# TODO: Check whether removing all contained references is safe enough

View file

@ -1,10 +1,14 @@
from maya import cmds, mel
from avalon import api, io
from avalon import io
from openpype.pipeline import (
load,
get_representation_path
)
from openpype.hosts.maya.api.pipeline import containerise
from openpype.hosts.maya.api.lib import unique_namespace
class AudioLoader(api.Loader):
class AudioLoader(load.LoaderPlugin):
"""Specific loader of audio."""
families = ["audio"]
@ -51,7 +55,7 @@ class AudioLoader(api.Loader):
assert audio_node is not None, "Audio node not found."
path = api.get_representation_path(representation)
path = get_representation_path(representation)
audio_node.filename.set(path)
cmds.setAttr(
container["objectName"] + ".representation",

View file

@ -1,9 +1,13 @@
import os
from avalon import api
from openpype.pipeline import (
load,
get_representation_path
)
from openpype.api import get_project_settings
class GpuCacheLoader(api.Loader):
class GpuCacheLoader(load.LoaderPlugin):
"""Load model Alembic as gpuCache"""
families = ["model"]
@ -73,7 +77,7 @@ class GpuCacheLoader(api.Loader):
import maya.cmds as cmds
path = api.get_representation_path(representation)
path = get_representation_path(representation)
# Update the cache
members = cmds.sets(container['objectName'], query=True)

View file

@ -1,6 +1,10 @@
from Qt import QtWidgets, QtCore
from avalon import api, io
from avalon import io
from openpype.pipeline import (
load,
get_representation_path
)
from openpype.hosts.maya.api.pipeline import containerise
from openpype.hosts.maya.api.lib import unique_namespace
@ -74,7 +78,7 @@ class CameraWindow(QtWidgets.QDialog):
self.close()
class ImagePlaneLoader(api.Loader):
class ImagePlaneLoader(load.LoaderPlugin):
"""Specific loader of plate for image planes on selected camera."""
families = ["image", "plate", "render"]
@ -203,7 +207,7 @@ class ImagePlaneLoader(api.Loader):
assert image_plane_shape is not None, "Image plane not found."
path = api.get_representation_path(representation)
path = get_representation_path(representation)
image_plane_shape.imageName.set(path)
cmds.setAttr(
container["objectName"] + ".representation",

View file

@ -5,7 +5,8 @@ from collections import defaultdict
from Qt import QtWidgets
from avalon import api, io
from avalon import io
from openpype.pipeline import get_representation_path
import openpype.hosts.maya.api.plugin
from openpype.hosts.maya.api import lib
from openpype.widgets.message_window import ScrollMessageBox
@ -77,7 +78,7 @@ class LookLoader(openpype.hosts.maya.api.plugin.ReferenceLoader):
})
# Load relationships
shader_relation = api.get_representation_path(json_representation)
shader_relation = get_representation_path(json_representation)
with open(shader_relation, "r") as f:
json_data = json.load(f)

View file

@ -1,8 +1,8 @@
from avalon import api
from maya import mel
from openpype.pipeline import load
class MatchmoveLoader(api.Loader):
class MatchmoveLoader(load.LoaderPlugin):
"""
This will run matchmove script to create track in scene.

View file

@ -5,8 +5,11 @@ import clique
import maya.cmds as cmds
from avalon import api
from openpype.api import get_project_settings
from openpype.pipeline import (
load,
get_representation_path
)
from openpype.hosts.maya.api.lib import (
namespaced,
maintained_selection,
@ -15,7 +18,7 @@ from openpype.hosts.maya.api.lib import (
from openpype.hosts.maya.api.pipeline import containerise
class RedshiftProxyLoader(api.Loader):
class RedshiftProxyLoader(load.LoaderPlugin):
"""Load Redshift proxy"""
families = ["redshiftproxy"]
@ -78,7 +81,7 @@ class RedshiftProxyLoader(api.Loader):
rs_meshes = cmds.ls(members, type="RedshiftProxyMesh")
assert rs_meshes, "Cannot find RedshiftProxyMesh in container"
filename = api.get_representation_path(representation)
filename = get_representation_path(representation)
for rs_mesh in rs_meshes:
cmds.setAttr("{}.fileName".format(rs_mesh),

View file

@ -121,18 +121,10 @@ class ReferenceLoader(openpype.hosts.maya.api.plugin.ReferenceLoader):
if family == "rig":
self._post_process_rig(name, namespace, context, options)
else:
if "translate" in options:
cmds.setAttr(group_name + ".t", *options["translate"])
return new_nodes
def load(self, context, name=None, namespace=None, options=None):
container = super(ReferenceLoader, self).load(
context, name, namespace, options)
# clean containers if present to AVALON_CONTAINERS
self._organize_containers(self[:], container[0])
def switch(self, container, representation):
self.update(container, representation)

View file

@ -7,10 +7,13 @@ instance.
"""
import json
import six
import sys
import six
from avalon import api
from openpype.pipeline import (
load,
get_representation_path
)
from openpype.hosts.maya.api import lib
from openpype.hosts.maya.api.pipeline import containerise
@ -18,7 +21,7 @@ from maya import cmds
import maya.app.renderSetup.model.renderSetup as renderSetup
class RenderSetupLoader(api.Loader):
class RenderSetupLoader(load.LoaderPlugin):
"""Load json preset for RenderSetup overwriting current one."""
families = ["rendersetup"]
@ -87,7 +90,7 @@ class RenderSetupLoader(api.Loader):
"Render setup setting will be overwritten by new version. All "
"setting specified by user not included in loaded version "
"will be lost.")
path = api.get_representation_path(representation)
path = get_representation_path(representation)
with open(path, "r") as file:
try:
renderSetup.instance().decode(

View file

@ -1,9 +1,10 @@
import os
from avalon import api
from openpype.api import get_project_settings
from openpype.pipeline import load
class LoadVDBtoRedShift(api.Loader):
class LoadVDBtoRedShift(load.LoaderPlugin):
"""Load OpenVDB in a Redshift Volume Shape"""
families = ["vdbcache"]

View file

@ -1,6 +1,10 @@
import os
from avalon import api
from openpype.api import get_project_settings
from openpype.pipeline import (
load,
get_representation_path
)
from maya import cmds
@ -69,7 +73,7 @@ def _fix_duplicate_vvg_callbacks():
matched.add(callback)
class LoadVDBtoVRay(api.Loader):
class LoadVDBtoVRay(load.LoaderPlugin):
families = ["vdbcache"]
representations = ["vdb"]
@ -252,7 +256,7 @@ class LoadVDBtoVRay(api.Loader):
def update(self, container, representation):
path = api.get_representation_path(representation)
path = get_representation_path(representation)
# Find VRayVolumeGrid
members = cmds.sets(container['objectName'], query=True)

View file

@ -7,10 +7,16 @@ loader will use them instead of native vray vrmesh format.
"""
import os
from bson.objectid import ObjectId
import maya.cmds as cmds
from avalon import api, io
from avalon import io
from openpype.api import get_project_settings
from openpype.pipeline import (
load,
get_representation_path
)
from openpype.hosts.maya.api.lib import (
maintained_selection,
namespaced,
@ -19,7 +25,7 @@ from openpype.hosts.maya.api.lib import (
from openpype.hosts.maya.api.pipeline import containerise
class VRayProxyLoader(api.Loader):
class VRayProxyLoader(load.LoaderPlugin):
"""Load VRay Proxy with Alembic or VrayMesh."""
families = ["vrayproxy", "model", "pointcache", "animation"]
@ -100,7 +106,10 @@ class VRayProxyLoader(api.Loader):
assert vraymeshes, "Cannot find VRayMesh in container"
# get all representations for this version
filename = self._get_abc(representation["parent"]) or api.get_representation_path(representation) # noqa: E501
filename = (
self._get_abc(representation["parent"])
or get_representation_path(representation)
)
for vray_mesh in vraymeshes:
cmds.setAttr("{}.fileName".format(vray_mesh),
@ -179,13 +188,13 @@ class VRayProxyLoader(api.Loader):
abc_rep = io.find_one(
{
"type": "representation",
"parent": io.ObjectId(version_id),
"parent": ObjectId(version_id),
"name": "abc"
})
if abc_rep:
self.log.debug("Found, we'll link alembic to vray proxy.")
file_name = api.get_representation_path(abc_rep)
file_name = get_representation_path(abc_rep)
self.log.debug("File: {}".format(self.fname))
return file_name

View file

@ -1,8 +1,11 @@
# -*- coding: utf-8 -*-
import os
import maya.cmds as cmds # noqa
from avalon import api
from openpype.api import get_project_settings
from openpype.pipeline import (
load,
get_representation_path
)
from openpype.hosts.maya.api.lib import (
maintained_selection,
namespaced,
@ -11,7 +14,7 @@ from openpype.hosts.maya.api.lib import (
from openpype.hosts.maya.api.pipeline import containerise
class VRaySceneLoader(api.Loader):
class VRaySceneLoader(load.LoaderPlugin):
"""Load Vray scene"""
families = ["vrayscene_layer"]
@ -78,7 +81,7 @@ class VRaySceneLoader(api.Loader):
vraymeshes = cmds.ls(members, type="VRayScene")
assert vraymeshes, "Cannot find VRayScene in container"
filename = api.get_representation_path(representation)
filename = get_representation_path(representation)
for vray_mesh in vraymeshes:
cmds.setAttr("{}.FilePath".format(vray_mesh),

View file

@ -7,13 +7,17 @@ from pprint import pprint
from maya import cmds
from avalon import api, io
from avalon import io
from openpype.api import get_project_settings
from openpype.pipeline import (
load,
get_representation_path
)
from openpype.hosts.maya.api import lib
from openpype.hosts.maya.api.pipeline import containerise
class YetiCacheLoader(api.Loader):
class YetiCacheLoader(load.LoaderPlugin):
families = ["yeticache", "yetiRig"]
representations = ["fur"]
@ -121,8 +125,8 @@ class YetiCacheLoader(api.Loader):
"cannot find fursettings representation"
)
settings_fname = api.get_representation_path(fur_settings)
path = api.get_representation_path(representation)
settings_fname = get_representation_path(fur_settings)
path = get_representation_path(representation)
# Get all node data
with open(settings_fname, "r") as fp:
settings = json.load(fp)

View file

@ -6,7 +6,7 @@ from maya import cmds
import openpype.api
from openpype.hosts.maya.api.lib import maintained_selection
from avalon.pipeline import AVALON_CONTAINER_ID
from openpype.pipeline import AVALON_CONTAINER_ID
class ExtractMayaSceneRaw(openpype.api.Extractor):
@ -58,16 +58,11 @@ class ExtractMayaSceneRaw(openpype.api.Extractor):
else:
members = instance[:]
loaded_containers = None
if set(self.add_for_families).intersection(
set(instance.data.get("families")),
set(instance.data.get("family").lower())):
loaded_containers = self._add_loaded_containers(members)
selection = members
if loaded_containers:
self.log.info(loaded_containers)
selection += loaded_containers
if set(self.add_for_families).intersection(
set(instance.data.get("families", []))) or \
instance.data.get("family") in self.add_for_families:
selection += self._get_loaded_containers(members)
# Perform extraction
self.log.info("Performing extraction ...")
@ -97,15 +92,15 @@ class ExtractMayaSceneRaw(openpype.api.Extractor):
self.log.info("Extracted instance '%s' to: %s" % (instance.name, path))
@staticmethod
def _add_loaded_containers(members):
def _get_loaded_containers(members):
# type: (list) -> list
refs_to_include = [
cmds.referenceQuery(ref, referenceNode=True)
for ref in members
if cmds.referenceQuery(ref, isNodeReferenced=True)
]
refs_to_include = {
cmds.referenceQuery(node, referenceNode=True)
for node in members
if cmds.referenceQuery(node, isNodeReferenced=True)
}
refs_to_include = set(refs_to_include)
members_with_refs = refs_to_include.union(members)
obj_sets = cmds.ls("*.id", long=True, type="objectSet", recursive=True,
objectsOnly=True)
@ -121,7 +116,7 @@ class ExtractMayaSceneRaw(openpype.api.Extractor):
continue
set_content = set(cmds.sets(obj_set, query=True))
if set_content.intersection(refs_to_include):
if set_content.intersection(members_with_refs):
loaded_containers.append(obj_set)
return loaded_containers

View file

@ -32,8 +32,8 @@ class ValidateOutRelatedNodeIds(pyblish.api.InstancePlugin):
# if a deformer has been created on the shape
invalid = self.get_invalid(instance)
if invalid:
raise RuntimeError("Nodes found with non-related "
"asset IDs: {0}".format(invalid))
raise RuntimeError("Nodes found with mismatching "
"IDs: {0}".format(invalid))
@classmethod
def get_invalid(cls, instance):
@ -65,7 +65,7 @@ class ValidateOutRelatedNodeIds(pyblish.api.InstancePlugin):
invalid.append(node)
continue
history_id = lib.get_id_from_history(node)
history_id = lib.get_id_from_sibling(node)
if history_id is not None and node_id != history_id:
invalid.append(node)
@ -76,7 +76,7 @@ class ValidateOutRelatedNodeIds(pyblish.api.InstancePlugin):
for node in cls.get_invalid(instance):
# Get the original id from history
history_id = lib.get_id_from_history(node)
history_id = lib.get_id_from_sibling(node)
if not history_id:
cls.log.error("Could not find ID in history for '%s'", node)
continue

View file

@ -48,7 +48,7 @@ class ValidateNodeIdsDeformedShape(pyblish.api.InstancePlugin):
invalid = []
for shape in shapes:
history_id = lib.get_id_from_history(shape)
history_id = lib.get_id_from_sibling(shape)
if history_id:
current_id = lib.get_id(shape)
if current_id != history_id:
@ -61,7 +61,7 @@ class ValidateNodeIdsDeformedShape(pyblish.api.InstancePlugin):
for node in cls.get_invalid(instance):
# Get the original id from history
history_id = lib.get_id_from_history(node)
history_id = lib.get_id_from_sibling(node)
if not history_id:
cls.log.error("Could not find ID in history for '%s'", node)
continue

View file

@ -24,6 +24,7 @@ class ValidateRigOutSetNodeIds(pyblish.api.InstancePlugin):
openpype.hosts.maya.api.action.SelectInvalidAction,
openpype.api.RepairAction
]
allow_history_only = False
def process(self, instance):
"""Process all meshes"""
@ -32,8 +33,8 @@ class ValidateRigOutSetNodeIds(pyblish.api.InstancePlugin):
# if a deformer has been created on the shape
invalid = self.get_invalid(instance)
if invalid:
raise RuntimeError("Nodes found with non-related "
"asset IDs: {0}".format(invalid))
raise RuntimeError("Nodes found with mismatching "
"IDs: {0}".format(invalid))
@classmethod
def get_invalid(cls, instance):
@ -51,10 +52,13 @@ class ValidateRigOutSetNodeIds(pyblish.api.InstancePlugin):
noIntermediate=True)
for shape in shapes:
history_id = lib.get_id_from_history(shape)
if history_id:
sibling_id = lib.get_id_from_sibling(
shape,
history_only=cls.allow_history_only
)
if sibling_id:
current_id = lib.get_id(shape)
if current_id != history_id:
if current_id != sibling_id:
invalid.append(shape)
return invalid
@ -63,10 +67,13 @@ class ValidateRigOutSetNodeIds(pyblish.api.InstancePlugin):
def repair(cls, instance):
for node in cls.get_invalid(instance):
# Get the original id from history
history_id = lib.get_id_from_history(node)
if not history_id:
cls.log.error("Could not find ID in history for '%s'", node)
# Get the original id from sibling
sibling_id = lib.get_id_from_sibling(
node,
history_only=cls.allow_history_only
)
if not sibling_id:
cls.log.error("Could not find ID in siblings for '%s'", node)
continue
lib.set_id(node, history_id, overwrite=True)
lib.set_id(node, sibling_id, overwrite=True)