resolve conflict

This commit is contained in:
Kayla Man 2024-06-24 20:00:34 +08:00
commit e0a1d0df9e
23 changed files with 170 additions and 593 deletions

View file

@ -6,7 +6,7 @@ import logging
import hou # noqa
from ayon_core.host import HostBase, IWorkfileHost, ILoadHost, IPublishHost
from ayon_core.tools.utils import host_tools
import pyblish.api
from ayon_core.pipeline import (
@ -23,6 +23,7 @@ from ayon_houdini.api import lib, shelves, creator_node_shelves
from ayon_core.lib import (
register_event_callback,
emit_event,
env_value_to_bool,
)
@ -85,10 +86,9 @@ class HoudiniHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost):
# initialization during start up delays Houdini UI by minutes
# making it extremely slow to launch.
hdefereval.executeDeferred(shelves.generate_shelves)
if not IS_HEADLESS:
import hdefereval # noqa, hdefereval is only available in ui mode
hdefereval.executeDeferred(creator_node_shelves.install)
if env_value_to_bool("AYON_WORKFILE_TOOL_ON_START"):
hdefereval.executeDeferred(lambda: host_tools.show_workfiles(parent=hou.qt.mainWindow()))
def workfile_has_unsaved_changes(self):
return hou.hipFile.hasUnsavedChanges()

View file

@ -1,55 +0,0 @@
# -*- coding: utf-8 -*-
"""Creator plugin for creating pointcache alembics."""
from ayon_houdini.api import plugin
from ayon_core.lib import BoolDef
class CreateMantraIFD(plugin.HoudiniCreator):
"""Mantra .ifd Archive"""
identifier = "io.openpype.creators.houdini.mantraifd"
label = "Mantra IFD"
product_type = "mantraifd"
icon = "gears"
def create(self, product_name, instance_data, pre_create_data):
import hou
instance_data.pop("active", None)
instance_data.update({"node_type": "ifd"})
creator_attributes = instance_data.setdefault(
"creator_attributes", dict())
creator_attributes["farm"] = pre_create_data["farm"]
instance = super(CreateMantraIFD, self).create(
product_name,
instance_data,
pre_create_data)
instance_node = hou.node(instance.get("instance_node"))
filepath = "{}{}".format(
hou.text.expandString("$HIP/pyblish/"),
"{}.$F4.ifd".format(product_name))
parms = {
# Render frame range
"trange": 1,
# Arnold ROP settings
"soho_diskfile": filepath,
"soho_outputmode": 1
}
instance_node.setParms(parms)
# Lock any parameters in this list
to_lock = ["soho_outputmode", "productType", "id"]
self.lock_parameters(instance_node, to_lock)
def get_instance_attr_defs(self):
return [
BoolDef("farm",
label="Submitting to Farm",
default=False)
]
def get_pre_create_attr_defs(self):
attrs = super().get_pre_create_attr_defs()
# Use same attributes as for instance attributes
return attrs + self.get_instance_attr_defs()

View file

@ -12,9 +12,7 @@ class CollectDataforCache(plugin.HoudiniInstancePlugin):
# Run after Collect Frames
order = pyblish.api.CollectorOrder + 0.11
families = ["ass", "pointcache",
"mantraifd", "redshiftproxy",
"vdbcache", "model"]
families = ["ass", "pointcache", "redshiftproxy", "vdbcache", "model"]
targets = ["local", "remote"]
label = "Collect Data for Cache"

View file

@ -9,9 +9,7 @@ class CollectChunkSize(plugin.HoudiniInstancePlugin,
"""Collect chunk size for cache submission to Deadline."""
order = pyblish.api.CollectorOrder + 0.05
families = ["ass", "pointcache",
"vdbcache", "mantraifd",
"redshiftproxy", "model"]
families = ["ass", "pointcache", "vdbcache", "redshiftproxy", "model"]
targets = ["local", "remote"]
label = "Collect Chunk Size"
chunk_size = 999999

View file

@ -15,9 +15,8 @@ class CollectFrames(plugin.HoudiniInstancePlugin):
# this plugin runs after CollectRopFrameRange
order = pyblish.api.CollectorOrder + 0.1
label = "Collect Frames"
families = ["vdbcache", "imagesequence", "ass",
"mantraifd", "redshiftproxy", "review",
"pointcache"]
families = ["camera", "vdbcache", "imagesequence", "ass",
"redshiftproxy", "review", "pointcache", "fbx"]
def process(self, instance):
@ -60,7 +59,10 @@ class CollectFrames(plugin.HoudiniInstancePlugin):
# todo: `frames` currently conflicts with "explicit frames" for a
# for a custom frame list. So this should be refactored.
instance.data.update({"frames": result})
instance.data.update({
"frames": result,
"stagingDir": os.path.dirname(output)
})
@staticmethod
def create_file_list(match, start_frame, end_frame):

View file

@ -1,51 +0,0 @@
import os
import hou
import pyblish.api
from ayon_houdini.api import plugin
from ayon_houdini.api.lib import render_rop
class ExtractAlembic(plugin.HoudiniExtractorPlugin):
order = pyblish.api.ExtractorOrder
label = "Extract Alembic"
families = ["abc", "camera"]
targets = ["local", "remote"]
def process(self, instance):
if instance.data.get("farm"):
self.log.debug("Should be processed on farm, skipping.")
return
ropnode = hou.node(instance.data["instance_node"])
# Get the filename from the filename parameter
output = ropnode.evalParm("filename")
staging_dir = os.path.dirname(output)
instance.data["stagingDir"] = staging_dir
if instance.data.get("frames"):
# list of files
files = instance.data["frames"]
else:
# single file
files = os.path.basename(output)
# We run the render
self.log.info("Writing alembic '%s' to '%s'" % (files,
staging_dir))
render_rop(ropnode)
if "representations" not in instance.data:
instance.data["representations"] = []
representation = {
'name': 'abc',
'ext': 'abc',
'files': files,
"stagingDir": staging_dir,
}
instance.data["representations"].append(representation)

View file

@ -1,63 +0,0 @@
import os
import hou
import pyblish.api
from ayon_houdini.api import plugin
from ayon_houdini.api.lib import render_rop
class ExtractAss(plugin.HoudiniExtractorPlugin):
order = pyblish.api.ExtractorOrder + 0.1
label = "Extract Ass"
families = ["ass"]
targets = ["local", "remote"]
def process(self, instance):
if instance.data.get("farm"):
self.log.debug("Should be processed on farm, skipping.")
return
ropnode = hou.node(instance.data["instance_node"])
# Get the filename from the filename parameter
# `.evalParm(parameter)` will make sure all tokens are resolved
output = ropnode.evalParm("ar_ass_file")
staging_dir = os.path.dirname(output)
instance.data["stagingDir"] = staging_dir
file_name = os.path.basename(output)
# We run the render
self.log.info("Writing ASS '%s' to '%s'" % (file_name, staging_dir))
render_rop(ropnode)
# Unfortunately user interrupting the extraction does not raise an
# error and thus still continues to the integrator. To capture that
# we make sure all files exist
files = instance.data["frames"]
missing = []
for file_name in files:
full_path = os.path.normpath(os.path.join(staging_dir, file_name))
if not os.path.exists(full_path):
missing.append(full_path)
if missing:
raise RuntimeError("Failed to complete Arnold ass extraction. "
"Missing output files: {}".format(missing))
if "representations" not in instance.data:
instance.data["representations"] = []
# Allow ass.gz extension as well
ext = "ass.gz" if file_name.endswith(".ass.gz") else "ass"
representation = {
'name': 'ass',
'ext': ext,
"files": files,
"stagingDir": staging_dir,
"frameStart": instance.data["frameStartHandle"],
"frameEnd": instance.data["frameEndHandle"],
}
instance.data["representations"].append(representation)

View file

@ -1,51 +0,0 @@
import os
import hou
import pyblish.api
from ayon_houdini.api import lib, plugin
class ExtractBGEO(plugin.HoudiniExtractorPlugin):
order = pyblish.api.ExtractorOrder
label = "Extract BGEO"
families = ["bgeo"]
def process(self, instance):
if instance.data.get("farm"):
self.log.debug("Should be processed on farm, skipping.")
return
ropnode = hou.node(instance.data["instance_node"])
# Get the filename from the filename parameter
output = ropnode.evalParm("sopoutput")
staging_dir, file_name = os.path.split(output)
instance.data["stagingDir"] = staging_dir
# We run the render
self.log.info("Writing bgeo files '{}' to '{}'.".format(
file_name, staging_dir))
# write files
lib.render_rop(ropnode)
output = instance.data["frames"]
_, ext = lib.splitext(
output[0], allowed_multidot_extensions=[
".ass.gz", ".bgeo.sc", ".bgeo.gz",
".bgeo.lzma", ".bgeo.bz2"])
if "representations" not in instance.data:
instance.data["representations"] = []
representation = {
"name": "bgeo",
"ext": ext.lstrip("."),
"files": output,
"stagingDir": staging_dir,
"frameStart": instance.data["frameStartHandle"],
"frameEnd": instance.data["frameEndHandle"]
}
instance.data["representations"].append(representation)

View file

@ -1,58 +0,0 @@
import os
import hou
import pyblish.api
from ayon_core.pipeline import publish
from ayon_houdini.api import plugin
from ayon_houdini.api.lib import render_rop, splitext
class ExtractComposite(plugin.HoudiniExtractorPlugin,
publish.ColormanagedPyblishPluginMixin):
order = pyblish.api.ExtractorOrder
label = "Extract Composite (Image Sequence)"
families = ["imagesequence"]
def process(self, instance):
ropnode = hou.node(instance.data["instance_node"])
# Get the filename from the copoutput parameter
# `.evalParm(parameter)` will make sure all tokens are resolved
output = ropnode.evalParm("copoutput")
staging_dir = os.path.dirname(output)
instance.data["stagingDir"] = staging_dir
file_name = os.path.basename(output)
self.log.info("Writing comp '%s' to '%s'" % (file_name, staging_dir))
render_rop(ropnode)
output = instance.data["frames"]
_, ext = splitext(output[0], [])
ext = ext.lstrip(".")
if "representations" not in instance.data:
instance.data["representations"] = []
representation = {
"name": ext,
"ext": ext,
"files": output,
"stagingDir": staging_dir,
"frameStart": instance.data["frameStartHandle"],
"frameEnd": instance.data["frameEndHandle"],
}
if ext.lower() == "exr":
# Inject colorspace with 'scene_linear' as that's the
# default Houdini working colorspace and all extracted
# OpenEXR images should be in that colorspace.
# https://www.sidefx.com/docs/houdini/render/linear.html#image-formats
self.set_representation_colorspace(
representation, instance.context,
colorspace="scene_linear"
)
instance.data["representations"].append(representation)

View file

@ -1,51 +0,0 @@
# -*- coding: utf-8 -*-
"""Fbx Extractor for houdini. """
import os
import hou
import pyblish.api
from ayon_houdini.api import plugin
from ayon_houdini.api.lib import render_rop
class ExtractFBX(plugin.HoudiniExtractorPlugin):
label = "Extract FBX"
families = ["fbx"]
order = pyblish.api.ExtractorOrder + 0.1
def process(self, instance):
# get rop node
ropnode = hou.node(instance.data.get("instance_node"))
output_file = ropnode.evalParm("sopoutput")
# get staging_dir and file_name
staging_dir = os.path.normpath(os.path.dirname(output_file))
file_name = os.path.basename(output_file)
# render rop
self.log.debug("Writing FBX '%s' to '%s'", file_name, staging_dir)
render_rop(ropnode)
# prepare representation
representation = {
"name": "fbx",
"ext": "fbx",
"files": file_name,
"stagingDir": staging_dir
}
# A single frame may also be rendered without start/end frame.
if "frameStartHandle" in instance.data and "frameEndHandle" in instance.data: # noqa
representation["frameStart"] = instance.data["frameStartHandle"]
representation["frameEnd"] = instance.data["frameEndHandle"]
# set value type for 'representations' key to list
if "representations" not in instance.data:
instance.data["representations"] = []
# update instance data
instance.data["stagingDir"] = staging_dir
instance.data["representations"].append(representation)

View file

@ -1,49 +0,0 @@
import os
import hou
import pyblish.api
from ayon_houdini.api import plugin
class ExtractMantraIFD(plugin.HoudiniExtractorPlugin):
order = pyblish.api.ExtractorOrder
label = "Extract Mantra ifd"
families = ["mantraifd"]
targets = ["local", "remote"]
def process(self, instance):
if instance.data.get("farm"):
self.log.debug("Should be processed on farm, skipping.")
return
ropnode = hou.node(instance.data.get("instance_node"))
output = ropnode.evalParm("soho_diskfile")
staging_dir = os.path.dirname(output)
instance.data["stagingDir"] = staging_dir
files = instance.data["frames"]
missing_frames = [
frame
for frame in instance.data["frames"]
if not os.path.exists(
os.path.normpath(os.path.join(staging_dir, frame)))
]
if missing_frames:
raise RuntimeError("Failed to complete Mantra ifd extraction. "
"Missing output files: {}".format(
missing_frames))
if "representations" not in instance.data:
instance.data["representations"] = []
representation = {
'name': 'ifd',
'ext': 'ifd',
'files': files,
"stagingDir": staging_dir,
"frameStart": instance.data["frameStart"],
"frameEnd": instance.data["frameEnd"],
}
instance.data["representations"].append(representation)

View file

@ -1,69 +0,0 @@
import os
import hou
import pyblish.api
from ayon_core.pipeline import publish
from ayon_houdini.api import plugin
from ayon_houdini.api.lib import render_rop
class ExtractOpenGL(plugin.HoudiniExtractorPlugin,
publish.ColormanagedPyblishPluginMixin):
order = pyblish.api.ExtractorOrder - 0.01
label = "Extract OpenGL"
families = ["review"]
def process(self, instance):
ropnode = hou.node(instance.data.get("instance_node"))
# This plugin is triggered when marking render as reviewable.
# Therefore, this plugin will run on over wrong instances.
# TODO: Don't run this plugin on wrong instances.
# This plugin should run only on review product type
# with instance node of opengl type.
if ropnode.type().name() != "opengl":
self.log.debug("Skipping OpenGl extraction. Rop node {} "
"is not an OpenGl node.".format(ropnode.path()))
return
output = ropnode.evalParm("picture")
staging_dir = os.path.normpath(os.path.dirname(output))
instance.data["stagingDir"] = staging_dir
file_name = os.path.basename(output)
self.log.info("Extracting '%s' to '%s'" % (file_name,
staging_dir))
render_rop(ropnode)
output = instance.data["frames"]
tags = ["review"]
if not instance.data.get("keepImages"):
tags.append("delete")
representation = {
"name": instance.data["imageFormat"],
"ext": instance.data["imageFormat"],
"files": output,
"stagingDir": staging_dir,
"frameStart": instance.data["frameStartHandle"],
"frameEnd": instance.data["frameEndHandle"],
"tags": tags,
"preview": True,
"camera_name": instance.data.get("review_camera")
}
if ropnode.evalParm("colorcorrect") == 2: # OpenColorIO enabled
colorspace = ropnode.evalParm("ociocolorspace")
# inject colorspace data
self.set_representation_colorspace(
representation, instance.context,
colorspace=colorspace
)
if "representations" not in instance.data:
instance.data["representations"] = []
instance.data["representations"].append(representation)

View file

@ -1,52 +0,0 @@
import os
import hou
import pyblish.api
from ayon_houdini.api import plugin
from ayon_houdini.api.lib import render_rop
class ExtractRedshiftProxy(plugin.HoudiniExtractorPlugin):
order = pyblish.api.ExtractorOrder + 0.1
label = "Extract Redshift Proxy"
families = ["redshiftproxy"]
targets = ["local", "remote"]
def process(self, instance):
if instance.data.get("farm"):
self.log.debug("Should be processed on farm, skipping.")
return
ropnode = hou.node(instance.data.get("instance_node"))
# Get the filename from the filename parameter
# `.evalParm(parameter)` will make sure all tokens are resolved
output = ropnode.evalParm("RS_archive_file")
staging_dir = os.path.normpath(os.path.dirname(output))
instance.data["stagingDir"] = staging_dir
file_name = os.path.basename(output)
self.log.info("Writing Redshift Proxy '%s' to '%s'" % (file_name,
staging_dir))
render_rop(ropnode)
output = instance.data["frames"]
if "representations" not in instance.data:
instance.data["representations"] = []
representation = {
"name": "rs",
"ext": "rs",
"files": output,
"stagingDir": staging_dir,
}
# A single frame may also be rendered without start/end frame.
if "frameStartHandle" in instance.data and "frameEndHandle" in instance.data: # noqa
representation["frameStart"] = instance.data["frameStartHandle"]
representation["frameEnd"] = instance.data["frameEndHandle"]
instance.data["representations"].append(representation)

View file

@ -0,0 +1,150 @@
import os
import hou
import pyblish.api
from ayon_core.pipeline import publish
from ayon_houdini.api import plugin
from ayon_houdini.api.lib import render_rop, splitext
class ExtractROP(plugin.HoudiniExtractorPlugin):
"""Generic Extractor for any ROP node."""
label = "Extract ROP"
order = pyblish.api.ExtractorOrder
families = ["abc", "camera", "bgeo", "pointcache", "fbx",
"vdbcache", "ass", "redshiftproxy", "mantraifd"]
targets = ["local", "remote"]
def process(self, instance: pyblish.api.Instance):
if instance.data.get("farm"):
self.log.debug("Should be processed on farm, skipping.")
return
rop_node = hou.node(instance.data["instance_node"])
files = instance.data["frames"]
first_file = files[0] if isinstance(files, (list, tuple)) else files
_, ext = splitext(
first_file, allowed_multidot_extensions=[
".ass.gz", ".bgeo.sc", ".bgeo.gz",
".bgeo.lzma", ".bgeo.bz2"]
)
ext = ext.lstrip(".")
self.log.debug(f"Rendering {rop_node.path()} to {first_file}..")
render_rop(rop_node)
self.validate_expected_frames(instance)
# In some cases representation name is not the the extension
# TODO: Preferably we remove this very specific naming
product_type = instance.data["productType"]
name = {
"bgeo": "bgeo",
"rs": "rs",
"ass": "ass"
}.get(product_type, ext)
representation = {
"name": name,
"ext": ext,
"files": instance.data["frames"],
"stagingDir": instance.data["stagingDir"],
"frameStart": instance.data["frameStartHandle"],
"frameEnd": instance.data["frameEndHandle"],
}
self.update_representation_data(instance, representation)
instance.data.setdefault("representations", []).append(representation)
def validate_expected_frames(self, instance: pyblish.api.Instance):
"""
Validate all expected files in `instance.data["frames"]` exist in
the staging directory.
"""
filenames = instance.data["frames"]
staging_dir = instance.data["stagingDir"]
if isinstance(filenames, str):
# Single frame
filenames = [filenames]
missing_filenames = [
filename for filename in filenames
if not os.path.isfile(os.path.join(staging_dir, filename))
]
if missing_filenames:
raise RuntimeError(f"Missing frames: {missing_filenames}")
def update_representation_data(self,
instance: pyblish.api.Instance,
representation: dict):
"""Allow subclass to override the representation data in-place"""
pass
class ExtractOpenGL(ExtractROP,
publish.ColormanagedPyblishPluginMixin):
order = pyblish.api.ExtractorOrder - 0.01
label = "Extract OpenGL"
families = ["review"]
def process(self, instance):
# This plugin is triggered when marking render as reviewable.
# Therefore, this plugin will run over wrong instances.
# TODO: Don't run this plugin on wrong instances.
# This plugin should run only on review product type
# with instance node of opengl type.
instance_node = instance.data.get("instance_node")
if not instance_node:
self.log.debug("Skipping instance without instance node.")
return
rop_node = hou.node(instance_node)
if rop_node.type().name() != "opengl":
self.log.debug("Skipping OpenGl extraction. Rop node {} "
"is not an OpenGl node.".format(rop_node.path()))
return
super(ExtractOpenGL, self).process(instance)
def update_representation_data(self,
instance: pyblish.api.Instance,
representation: dict):
tags = ["review"]
if not instance.data.get("keepImages"):
tags.append("delete")
representation.update({
# TODO: Avoid this override?
"name": instance.data["imageFormat"],
"ext": instance.data["imageFormat"],
"tags": tags,
"preview": True,
"camera_name": instance.data.get("review_camera")
})
class ExtractComposite(ExtractROP,
publish.ColormanagedPyblishPluginMixin):
label = "Extract Composite (Image Sequence)"
families = ["imagesequence"]
def update_representation_data(self,
instance: pyblish.api.Instance,
representation: dict):
if representation["ext"].lower() != "exr":
return
# Inject colorspace with 'scene_linear' as that's the
# default Houdini working colorspace and all extracted
# OpenEXR images should be in that colorspace.
# https://www.sidefx.com/docs/houdini/render/linear.html#image-formats
self.set_representation_colorspace(
representation, instance.context,
colorspace="scene_linear"
)

View file

@ -1,46 +0,0 @@
import os
import hou
import pyblish.api
from ayon_houdini.api import plugin
from ayon_houdini.api.lib import render_rop
class ExtractVDBCache(plugin.HoudiniExtractorPlugin):
order = pyblish.api.ExtractorOrder + 0.1
label = "Extract VDB Cache"
families = ["vdbcache"]
def process(self, instance):
if instance.data.get("farm"):
self.log.debug("Should be processed on farm, skipping.")
return
ropnode = hou.node(instance.data["instance_node"])
# Get the filename from the filename parameter
# `.evalParm(parameter)` will make sure all tokens are resolved
sop_output = ropnode.evalParm("sopoutput")
staging_dir = os.path.normpath(os.path.dirname(sop_output))
instance.data["stagingDir"] = staging_dir
file_name = os.path.basename(sop_output)
self.log.info("Writing VDB '%s' to '%s'" % (file_name, staging_dir))
render_rop(ropnode)
output = instance.data["frames"]
if "representations" not in instance.data:
instance.data["representations"] = []
representation = {
"name": "vdb",
"ext": "vdb",
"files": output,
"stagingDir": staging_dir,
"frameStart": instance.data["frameStartHandle"],
"frameEnd": instance.data["frameEndHandle"],
}
instance.data["representations"].append(representation)

View file

@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-
"""Package declaring AYON addon 'houdini' version."""
__version__ = "0.3.2"
__version__ = "0.3.4"

View file

@ -1,6 +1,6 @@
name = "houdini"
title = "Houdini"
version = "0.3.2"
version = "0.3.4"
client_dir = "ayon_houdini"

View file

@ -51,9 +51,6 @@ class CreatePluginsModel(BaseSettingsModel):
CreateKarmaROP: CreatorModel = SettingsField(
default_factory=CreatorModel,
title="Create Karma ROP")
CreateMantraIFD: CreatorModel = SettingsField(
default_factory=CreatorModel,
title="Create Mantra IFD")
CreateMantraROP: CreatorModel = SettingsField(
default_factory=CreatorModel,
title="Create Mantra ROP")
@ -119,10 +116,6 @@ DEFAULT_HOUDINI_CREATE_SETTINGS = {
"enabled": True,
"default_variants": ["Main"]
},
"CreateMantraIFD": {
"enabled": True,
"default_variants": ["Main"]
},
"CreateMantraROP": {
"enabled": True,
"default_variants": ["Main"]

View file

@ -12,7 +12,6 @@ from .pipeline import (
MayaHost,
)
from .plugin import (
Creator,
Loader
)
@ -45,7 +44,6 @@ __all__ = [
"containerise",
"MayaHost",
"Creator",
"Loader",
# Workfiles API

View file

@ -1733,7 +1733,7 @@ def is_valid_reference_node(reference_node):
"""
# maya 2022 is missing `isValidReference` so the check needs to be
# done in different way.
if cmds.about(version=True) < 2023:
if int(cmds.about(version=True)) < 2023:
try:
cmds.referenceQuery(reference_node, filename=True)
return True

View file

@ -15,10 +15,9 @@ from ayon_core.pipeline import (
Anatomy,
AutoCreator,
CreatedInstance,
Creator as NewCreator,
Creator,
CreatorError,
HiddenCreator,
LegacyCreator,
LoaderPlugin,
get_current_project_name,
get_representation_path,
@ -70,22 +69,6 @@ def get_reference_node_parents(*args, **kwargs):
return lib.get_reference_node_parents(*args, **kwargs)
class Creator(LegacyCreator):
defaults = ['Main']
def process(self):
nodes = list()
with lib.undo_chunk():
if (self.options or {}).get("useSelection"):
nodes = cmds.ls(selection=True)
instance = cmds.sets(nodes, name=self.name)
lib.imprint(instance, self.data)
return instance
@six.add_metaclass(ABCMeta)
class MayaCreatorBase(object):
@ -274,7 +257,7 @@ class MayaCreatorBase(object):
@six.add_metaclass(ABCMeta)
class MayaCreator(NewCreator, MayaCreatorBase):
class MayaCreator(Creator, MayaCreatorBase):
settings_category = "maya"
@ -381,7 +364,7 @@ def ensure_namespace(namespace):
return cmds.namespace(add=namespace)
class RenderlayerCreator(NewCreator, MayaCreatorBase):
class RenderlayerCreator(Creator, MayaCreatorBase):
"""Creator which creates an instance per renderlayer in the workfile.
Create and manages renderlayer product per renderLayer in workfile.

View file

@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-
"""Package declaring AYON addon 'maya' version."""
__version__ = "0.2.5"
__version__ = "0.2.7"

View file

@ -1,6 +1,6 @@
name = "maya"
title = "Maya"
version = "0.2.5"
version = "0.2.7"
client_dir = "ayon_maya"
ayon_required_addons = {