mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
[Automated] Merged develop into main
This commit is contained in:
commit
9722fa248b
28 changed files with 421 additions and 46 deletions
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
|
@ -35,6 +35,7 @@ body:
|
|||
label: Version
|
||||
description: What version are you running? Look to OpenPype Tray
|
||||
options:
|
||||
- 3.17.2-nightly.3
|
||||
- 3.17.2-nightly.2
|
||||
- 3.17.2-nightly.1
|
||||
- 3.17.1
|
||||
|
|
@ -134,7 +135,6 @@ body:
|
|||
- 3.14.10
|
||||
- 3.14.10-nightly.9
|
||||
- 3.14.10-nightly.8
|
||||
- 3.14.10-nightly.7
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ def failed_json_default(value):
|
|||
|
||||
|
||||
class ServerCreateOperation(CreateOperation):
|
||||
"""Opeartion to create an entity.
|
||||
"""Operation to create an entity.
|
||||
|
||||
Args:
|
||||
project_name (str): On which project operation will happen.
|
||||
|
|
@ -634,7 +634,7 @@ class ServerUpdateOperation(UpdateOperation):
|
|||
|
||||
|
||||
class ServerDeleteOperation(DeleteOperation):
|
||||
"""Opeartion to delete an entity.
|
||||
"""Operation to delete an entity.
|
||||
|
||||
Args:
|
||||
project_name (str): On which project operation will happen.
|
||||
|
|
@ -647,7 +647,7 @@ class ServerDeleteOperation(DeleteOperation):
|
|||
self._session = session
|
||||
|
||||
if entity_type == "asset":
|
||||
entity_type == "folder"
|
||||
entity_type = "folder"
|
||||
|
||||
elif entity_type == "hero_version":
|
||||
entity_type = "version"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import subprocess
|
|||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
|
||||
|
||||
class LaunchFoundryAppsWindows(PreLaunchHook):
|
||||
class LaunchNewConsoleApps(PreLaunchHook):
|
||||
"""Foundry applications have specific way how to launch them.
|
||||
|
||||
Nuke is executed "like" python process so it is required to pass
|
||||
|
|
@ -13,13 +13,15 @@ class LaunchFoundryAppsWindows(PreLaunchHook):
|
|||
|
||||
# Should be as last hook because must change launch arguments to string
|
||||
order = 1000
|
||||
app_groups = {"nuke", "nukeassist", "nukex", "hiero", "nukestudio"}
|
||||
app_groups = {
|
||||
"nuke", "nukeassist", "nukex", "hiero", "nukestudio", "mayapy"
|
||||
}
|
||||
platforms = {"windows"}
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
# Change `creationflags` to CREATE_NEW_CONSOLE
|
||||
# - on Windows nuke will create new window using its console
|
||||
# - on Windows some apps will create new window using its console
|
||||
# Set `stdout` and `stderr` to None so new created console does not
|
||||
# have redirected output to DEVNULL in build
|
||||
self.launch_context.kwargs.update({
|
||||
|
|
@ -31,7 +31,7 @@ class InstallPySideToBlender(PreLaunchHook):
|
|||
|
||||
def inner_execute(self):
|
||||
# Get blender's python directory
|
||||
version_regex = re.compile(r"^[2-3]\.[0-9]+$")
|
||||
version_regex = re.compile(r"^[2-4]\.[0-9]+$")
|
||||
|
||||
platform = system().lower()
|
||||
executable = self.launch_context.executable.executable_path
|
||||
|
|
|
|||
|
|
@ -26,8 +26,7 @@ class CacheModelLoader(plugin.AssetLoader):
|
|||
Note:
|
||||
At least for now it only supports Alembic files.
|
||||
"""
|
||||
|
||||
families = ["model", "pointcache"]
|
||||
families = ["model", "pointcache", "animation"]
|
||||
representations = ["abc"]
|
||||
|
||||
label = "Load Alembic"
|
||||
|
|
@ -53,16 +52,12 @@ class CacheModelLoader(plugin.AssetLoader):
|
|||
def _process(self, libpath, asset_group, group_name):
|
||||
plugin.deselect_all()
|
||||
|
||||
collection = bpy.context.view_layer.active_layer_collection.collection
|
||||
|
||||
relative = bpy.context.preferences.filepaths.use_relative_paths
|
||||
bpy.ops.wm.alembic_import(
|
||||
filepath=libpath,
|
||||
relative_path=relative
|
||||
)
|
||||
|
||||
parent = bpy.context.scene.collection
|
||||
|
||||
imported = lib.get_selection()
|
||||
|
||||
# Children must be linked before parents,
|
||||
|
|
@ -79,6 +74,10 @@ class CacheModelLoader(plugin.AssetLoader):
|
|||
objects.reverse()
|
||||
|
||||
for obj in objects:
|
||||
# Unlink the object from all collections
|
||||
collections = obj.users_collection
|
||||
for collection in collections:
|
||||
collection.objects.unlink(obj)
|
||||
name = obj.name
|
||||
obj.name = f"{group_name}:{name}"
|
||||
if obj.type != 'EMPTY':
|
||||
|
|
@ -90,7 +89,7 @@ class CacheModelLoader(plugin.AssetLoader):
|
|||
material_slot.material.name = f"{group_name}:{name_mat}"
|
||||
|
||||
if not obj.get(AVALON_PROPERTY):
|
||||
obj[AVALON_PROPERTY] = dict()
|
||||
obj[AVALON_PROPERTY] = {}
|
||||
|
||||
avalon_info = obj[AVALON_PROPERTY]
|
||||
avalon_info.update({"container_name": group_name})
|
||||
|
|
@ -99,6 +98,18 @@ class CacheModelLoader(plugin.AssetLoader):
|
|||
|
||||
return objects
|
||||
|
||||
def _link_objects(self, objects, collection, containers, asset_group):
|
||||
# Link the imported objects to any collection where the asset group is
|
||||
# linked to, except the AVALON_CONTAINERS collection
|
||||
group_collections = [
|
||||
collection
|
||||
for collection in asset_group.users_collection
|
||||
if collection != containers]
|
||||
|
||||
for obj in objects:
|
||||
for collection in group_collections:
|
||||
collection.objects.link(obj)
|
||||
|
||||
def process_asset(
|
||||
self, context: dict, name: str, namespace: Optional[str] = None,
|
||||
options: Optional[Dict] = None
|
||||
|
|
@ -120,18 +131,21 @@ class CacheModelLoader(plugin.AssetLoader):
|
|||
group_name = plugin.asset_name(asset, subset, unique_number)
|
||||
namespace = namespace or f"{asset}_{unique_number}"
|
||||
|
||||
avalon_containers = bpy.data.collections.get(AVALON_CONTAINERS)
|
||||
if not avalon_containers:
|
||||
avalon_containers = bpy.data.collections.new(
|
||||
name=AVALON_CONTAINERS)
|
||||
bpy.context.scene.collection.children.link(avalon_containers)
|
||||
containers = bpy.data.collections.get(AVALON_CONTAINERS)
|
||||
if not containers:
|
||||
containers = bpy.data.collections.new(name=AVALON_CONTAINERS)
|
||||
bpy.context.scene.collection.children.link(containers)
|
||||
|
||||
asset_group = bpy.data.objects.new(group_name, object_data=None)
|
||||
avalon_containers.objects.link(asset_group)
|
||||
containers.objects.link(asset_group)
|
||||
|
||||
objects = self._process(libpath, asset_group, group_name)
|
||||
|
||||
bpy.context.scene.collection.objects.link(asset_group)
|
||||
# Link the asset group to the active collection
|
||||
collection = bpy.context.view_layer.active_layer_collection.collection
|
||||
collection.objects.link(asset_group)
|
||||
|
||||
self._link_objects(objects, asset_group, containers, asset_group)
|
||||
|
||||
asset_group[AVALON_PROPERTY] = {
|
||||
"schema": "openpype:container-2.0",
|
||||
|
|
@ -207,7 +221,11 @@ class CacheModelLoader(plugin.AssetLoader):
|
|||
mat = asset_group.matrix_basis.copy()
|
||||
self._remove(asset_group)
|
||||
|
||||
self._process(str(libpath), asset_group, object_name)
|
||||
objects = self._process(str(libpath), asset_group, object_name)
|
||||
|
||||
containers = bpy.data.collections.get(AVALON_CONTAINERS)
|
||||
self._link_objects(objects, asset_group, containers, asset_group)
|
||||
|
||||
asset_group.matrix_basis = mat
|
||||
|
||||
metadata["libpath"] = str(libpath)
|
||||
|
|
|
|||
|
|
@ -95,6 +95,8 @@ class MayaHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost):
|
|||
self.log.info("Installing callbacks ... ")
|
||||
register_event_callback("init", on_init)
|
||||
|
||||
_set_project()
|
||||
|
||||
if lib.IS_HEADLESS:
|
||||
self.log.info((
|
||||
"Running in headless mode, skipping Maya save/open/new"
|
||||
|
|
@ -103,7 +105,6 @@ class MayaHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost):
|
|||
|
||||
return
|
||||
|
||||
_set_project()
|
||||
self._register_callbacks()
|
||||
|
||||
menu.install(project_settings)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ class PreCopyMel(PreLaunchHook):
|
|||
|
||||
Hook `GlobalHostDataHook` must be executed before this hook.
|
||||
"""
|
||||
app_groups = {"maya"}
|
||||
app_groups = {"maya", "mayapy"}
|
||||
launch_types = {LaunchTypes.local}
|
||||
|
||||
def execute(self):
|
||||
|
|
|
|||
117
openpype/hosts/maya/plugins/publish/validate_resolution.py
Normal file
117
openpype/hosts/maya/plugins/publish/validate_resolution.py
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
import pyblish.api
|
||||
from openpype.pipeline import (
|
||||
PublishValidationError,
|
||||
OptionalPyblishPluginMixin
|
||||
)
|
||||
from maya import cmds
|
||||
from openpype.pipeline.publish import RepairAction
|
||||
from openpype.hosts.maya.api import lib
|
||||
from openpype.hosts.maya.api.lib import reset_scene_resolution
|
||||
|
||||
|
||||
class ValidateResolution(pyblish.api.InstancePlugin,
|
||||
OptionalPyblishPluginMixin):
|
||||
"""Validate the render resolution setting aligned with DB"""
|
||||
|
||||
order = pyblish.api.ValidatorOrder
|
||||
families = ["renderlayer"]
|
||||
hosts = ["maya"]
|
||||
label = "Validate Resolution"
|
||||
actions = [RepairAction]
|
||||
optional = True
|
||||
|
||||
def process(self, instance):
|
||||
if not self.is_active(instance.data):
|
||||
return
|
||||
invalid = self.get_invalid_resolution(instance)
|
||||
if invalid:
|
||||
raise PublishValidationError(
|
||||
"Render resolution is invalid. See log for details.",
|
||||
description=(
|
||||
"Wrong render resolution setting. "
|
||||
"Please use repair button to fix it.\n\n"
|
||||
"If current renderer is V-Ray, "
|
||||
"make sure vraySettings node has been created."
|
||||
)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_invalid_resolution(cls, instance):
|
||||
width, height, pixelAspect = cls.get_db_resolution(instance)
|
||||
current_renderer = instance.data["renderer"]
|
||||
layer = instance.data["renderlayer"]
|
||||
invalid = False
|
||||
if current_renderer == "vray":
|
||||
vray_node = "vraySettings"
|
||||
if cmds.objExists(vray_node):
|
||||
current_width = lib.get_attr_in_layer(
|
||||
"{}.width".format(vray_node), layer=layer)
|
||||
current_height = lib.get_attr_in_layer(
|
||||
"{}.height".format(vray_node), layer=layer)
|
||||
current_pixelAspect = lib.get_attr_in_layer(
|
||||
"{}.pixelAspect".format(vray_node), layer=layer
|
||||
)
|
||||
else:
|
||||
cls.log.error(
|
||||
"Can't detect VRay resolution because there is no node "
|
||||
"named: `{}`".format(vray_node)
|
||||
)
|
||||
return True
|
||||
else:
|
||||
current_width = lib.get_attr_in_layer(
|
||||
"defaultResolution.width", layer=layer)
|
||||
current_height = lib.get_attr_in_layer(
|
||||
"defaultResolution.height", layer=layer)
|
||||
current_pixelAspect = lib.get_attr_in_layer(
|
||||
"defaultResolution.pixelAspect", layer=layer
|
||||
)
|
||||
if current_width != width or current_height != height:
|
||||
cls.log.error(
|
||||
"Render resolution {}x{} does not match "
|
||||
"asset resolution {}x{}".format(
|
||||
current_width, current_height,
|
||||
width, height
|
||||
))
|
||||
invalid = True
|
||||
if current_pixelAspect != pixelAspect:
|
||||
cls.log.error(
|
||||
"Render pixel aspect {} does not match "
|
||||
"asset pixel aspect {}".format(
|
||||
current_pixelAspect, pixelAspect
|
||||
))
|
||||
invalid = True
|
||||
return invalid
|
||||
|
||||
@classmethod
|
||||
def get_db_resolution(cls, instance):
|
||||
asset_doc = instance.data["assetEntity"]
|
||||
project_doc = instance.context.data["projectEntity"]
|
||||
for data in [asset_doc["data"], project_doc["data"]]:
|
||||
if (
|
||||
"resolutionWidth" in data and
|
||||
"resolutionHeight" in data and
|
||||
"pixelAspect" in data
|
||||
):
|
||||
width = data["resolutionWidth"]
|
||||
height = data["resolutionHeight"]
|
||||
pixelAspect = data["pixelAspect"]
|
||||
return int(width), int(height), float(pixelAspect)
|
||||
|
||||
# Defaults if not found in asset document or project document
|
||||
return 1920, 1080, 1.0
|
||||
|
||||
@classmethod
|
||||
def repair(cls, instance):
|
||||
# Usually without renderlayer overrides the renderlayers
|
||||
# all share the same resolution value - so fixing the first
|
||||
# will have fixed all the others too. It's much faster to
|
||||
# check whether it's invalid first instead of switching
|
||||
# into all layers individually
|
||||
if not cls.get_invalid_resolution(instance):
|
||||
cls.log.debug(
|
||||
"Nothing to repair on instance: {}".format(instance)
|
||||
)
|
||||
return
|
||||
layer_node = instance.data['setMembers']
|
||||
with lib.renderlayer(layer_node):
|
||||
reset_scene_resolution()
|
||||
|
|
@ -17,7 +17,7 @@ class SetFrameRangeLoader(load.LoaderPlugin):
|
|||
"yeticache",
|
||||
"pointcache"]
|
||||
representations = ["*"]
|
||||
extension = {"*"}
|
||||
extensions = {"*"}
|
||||
|
||||
label = "Set frame range"
|
||||
order = 11
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class LoadBackdropNodes(load.LoaderPlugin):
|
|||
|
||||
families = ["workfile", "nukenodes"]
|
||||
representations = ["*"]
|
||||
extension = {"nk"}
|
||||
extensions = {"nk"}
|
||||
|
||||
label = "Import Nuke Nodes"
|
||||
order = 0
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class AlembicCameraLoader(load.LoaderPlugin):
|
|||
|
||||
families = ["camera"]
|
||||
representations = ["*"]
|
||||
extension = {"abc"}
|
||||
extensions = {"abc"}
|
||||
|
||||
label = "Load Alembic Camera"
|
||||
icon = "camera"
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class LoadEffects(load.LoaderPlugin):
|
|||
|
||||
families = ["effect"]
|
||||
representations = ["*"]
|
||||
extension = {"json"}
|
||||
extensions = {"json"}
|
||||
|
||||
label = "Load Effects - nodes"
|
||||
order = 0
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class LoadEffectsInputProcess(load.LoaderPlugin):
|
|||
|
||||
families = ["effect"]
|
||||
representations = ["*"]
|
||||
extension = {"json"}
|
||||
extensions = {"json"}
|
||||
|
||||
label = "Load Effects - Input Process"
|
||||
order = 0
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class LoadGizmo(load.LoaderPlugin):
|
|||
|
||||
families = ["gizmo"]
|
||||
representations = ["*"]
|
||||
extension = {"gizmo"}
|
||||
extensions = {"gizmo"}
|
||||
|
||||
label = "Load Gizmo"
|
||||
order = 0
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class LoadGizmoInputProcess(load.LoaderPlugin):
|
|||
|
||||
families = ["gizmo"]
|
||||
representations = ["*"]
|
||||
extension = {"gizmo"}
|
||||
extensions = {"gizmo"}
|
||||
|
||||
label = "Load Gizmo - Input Process"
|
||||
order = 0
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ class MatchmoveLoader(load.LoaderPlugin):
|
|||
|
||||
families = ["matchmove"]
|
||||
representations = ["*"]
|
||||
extension = {"py"}
|
||||
extensions = {"py"}
|
||||
|
||||
defaults = ["Camera", "Object"]
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class AlembicModelLoader(load.LoaderPlugin):
|
|||
|
||||
families = ["model", "pointcache", "animation"]
|
||||
representations = ["*"]
|
||||
extension = {"abc"}
|
||||
extensions = {"abc"}
|
||||
|
||||
label = "Load Alembic"
|
||||
icon = "cube"
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class LinkAsGroup(load.LoaderPlugin):
|
|||
|
||||
families = ["workfile", "nukenodes"]
|
||||
representations = ["*"]
|
||||
extension = {"nk"}
|
||||
extensions = {"nk"}
|
||||
|
||||
label = "Load Precomp"
|
||||
order = 0
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import os
|
||||
import shutil
|
||||
import filecmp
|
||||
|
||||
from openpype.client.entities import get_representations
|
||||
from openpype.lib.applications import PreLaunchHook, LaunchTypes
|
||||
|
|
@ -194,3 +195,69 @@ class CopyLastPublishedWorkfile(PreLaunchHook):
|
|||
self.data["last_workfile_path"] = local_workfile_path
|
||||
# Keep source filepath for further path conformation
|
||||
self.data["source_filepath"] = last_published_workfile_path
|
||||
|
||||
# Get resources directory
|
||||
resources_dir = os.path.join(
|
||||
os.path.dirname(local_workfile_path), 'resources'
|
||||
)
|
||||
# Make resource directory if it doesn't exist
|
||||
if not os.path.exists(resources_dir):
|
||||
os.mkdir(resources_dir)
|
||||
|
||||
# Copy resources to the local resources directory
|
||||
for file in workfile_representation['files']:
|
||||
# Get resource main path
|
||||
resource_main_path = anatomy.fill_root(file["path"])
|
||||
|
||||
# Get resource file basename
|
||||
resource_basename = os.path.basename(resource_main_path)
|
||||
|
||||
# Only copy if the resource file exists, and it's not the workfile
|
||||
if (
|
||||
not os.path.exists(resource_main_path)
|
||||
or resource_basename == os.path.basename(
|
||||
last_published_workfile_path
|
||||
)
|
||||
):
|
||||
continue
|
||||
|
||||
# Get resource path in workfile folder
|
||||
resource_work_path = os.path.join(
|
||||
resources_dir, resource_basename
|
||||
)
|
||||
|
||||
# Check if the resource file already exists in the resources folder
|
||||
if os.path.exists(resource_work_path):
|
||||
# Check if both files are the same
|
||||
if filecmp.cmp(resource_main_path, resource_work_path):
|
||||
self.log.warning(
|
||||
'Resource "{}" already exists.'
|
||||
.format(resource_basename)
|
||||
)
|
||||
continue
|
||||
else:
|
||||
# Add `.old` to existing resource path
|
||||
resource_path_old = resource_work_path + '.old'
|
||||
if os.path.exists(resource_work_path + '.old'):
|
||||
for i in range(1, 100):
|
||||
p = resource_path_old + '%02d' % i
|
||||
if not os.path.exists(p):
|
||||
# Rename existing resource file to
|
||||
# `resource_name.old` + 2 digits
|
||||
shutil.move(resource_work_path, p)
|
||||
break
|
||||
else:
|
||||
self.log.warning(
|
||||
'There are a hundred old files for '
|
||||
'resource "{}". '
|
||||
'Perhaps is it time to clean up your '
|
||||
'resources folder'
|
||||
.format(resource_basename)
|
||||
)
|
||||
continue
|
||||
else:
|
||||
# Rename existing resource file to `resource_name.old`
|
||||
shutil.move(resource_work_path, resource_path_old)
|
||||
|
||||
# Copy resource file to workfile resources folder
|
||||
shutil.copy(resource_main_path, resources_dir)
|
||||
|
|
|
|||
|
|
@ -107,17 +107,18 @@ def get_time_data_from_instance_or_context(instance):
|
|||
TimeData: dataclass holding time information.
|
||||
|
||||
"""
|
||||
context = instance.context
|
||||
return TimeData(
|
||||
start=(instance.data.get("frameStart") or
|
||||
instance.context.data.get("frameStart")),
|
||||
end=(instance.data.get("frameEnd") or
|
||||
instance.context.data.get("frameEnd")),
|
||||
fps=(instance.data.get("fps") or
|
||||
instance.context.data.get("fps")),
|
||||
handle_start=(instance.data.get("handleStart") or
|
||||
instance.context.data.get("handleStart")), # noqa: E501
|
||||
handle_end=(instance.data.get("handleEnd") or
|
||||
instance.context.data.get("handleEnd"))
|
||||
start=instance.data.get("frameStart", context.data.get("frameStart")),
|
||||
end=instance.data.get("frameEnd", context.data.get("frameEnd")),
|
||||
fps=instance.data.get("fps", context.data.get("fps")),
|
||||
step=instance.data.get("byFrameStep", instance.data.get("step", 1)),
|
||||
handle_start=instance.data.get(
|
||||
"handleStart", context.data.get("handleStart")
|
||||
),
|
||||
handle_end=instance.data.get(
|
||||
"handleEnd", context.data.get("handleEnd")
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -829,6 +829,11 @@
|
|||
"redshift_render_attributes": [],
|
||||
"renderman_render_attributes": []
|
||||
},
|
||||
"ValidateResolution": {
|
||||
"enabled": true,
|
||||
"optional": true,
|
||||
"active": true
|
||||
},
|
||||
"ValidateCurrentRenderLayerIsRenderable": {
|
||||
"enabled": true,
|
||||
"optional": false,
|
||||
|
|
|
|||
|
|
@ -114,6 +114,65 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"mayapy": {
|
||||
"enabled": true,
|
||||
"label": "MayaPy",
|
||||
"icon": "{}/app_icons/maya.png",
|
||||
"host_name": "maya",
|
||||
"environment": {
|
||||
"MAYA_DISABLE_CLIC_IPM": "Yes",
|
||||
"MAYA_DISABLE_CIP": "Yes",
|
||||
"MAYA_DISABLE_CER": "Yes",
|
||||
"PYMEL_SKIP_MEL_INIT": "Yes",
|
||||
"LC_ALL": "C"
|
||||
},
|
||||
"variants": {
|
||||
"2024": {
|
||||
"use_python_2": false,
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Autodesk\\Maya2024\\bin\\mayapy.exe"
|
||||
],
|
||||
"darwin": [],
|
||||
"linux": [
|
||||
"/usr/autodesk/maya2024/bin/mayapy"
|
||||
]
|
||||
},
|
||||
"arguments": {
|
||||
"windows": [
|
||||
"-I"
|
||||
],
|
||||
"darwin": [],
|
||||
"linux": [
|
||||
"-I"
|
||||
]
|
||||
},
|
||||
"environment": {}
|
||||
},
|
||||
"2023": {
|
||||
"use_python_2": false,
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Autodesk\\Maya2023\\bin\\mayapy.exe"
|
||||
],
|
||||
"darwin": [],
|
||||
"linux": [
|
||||
"/usr/autodesk/maya2023/bin/mayapy"
|
||||
]
|
||||
},
|
||||
"arguments": {
|
||||
"windows": [
|
||||
"-I"
|
||||
],
|
||||
"darwin": [],
|
||||
"linux": [
|
||||
"-I"
|
||||
]
|
||||
},
|
||||
"environment": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"3dsmax": {
|
||||
"enabled": true,
|
||||
"label": "3ds max",
|
||||
|
|
|
|||
|
|
@ -431,6 +431,10 @@
|
|||
"type": "schema_template",
|
||||
"name": "template_publish_plugin",
|
||||
"template_data": [
|
||||
{
|
||||
"key": "ValidateResolution",
|
||||
"label": "Validate Resolution Settings"
|
||||
},
|
||||
{
|
||||
"key": "ValidateCurrentRenderLayerIsRenderable",
|
||||
"label": "Validate Current Render Layer Has Renderable Camera"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"type": "dict",
|
||||
"key": "mayapy",
|
||||
"label": "Autodesk MayaPy",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled",
|
||||
"label": "Enabled"
|
||||
},
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_unchangables"
|
||||
},
|
||||
{
|
||||
"key": "environment",
|
||||
"label": "Environment",
|
||||
"type": "raw-json"
|
||||
},
|
||||
{
|
||||
"type": "dict-modifiable",
|
||||
"key": "variants",
|
||||
"collapsible_key": true,
|
||||
"use_label_wrap": false,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant_items"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -9,6 +9,10 @@
|
|||
"type": "schema",
|
||||
"name": "schema_maya"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_mayapy"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_3dsmax"
|
||||
|
|
|
|||
|
|
@ -109,6 +109,55 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"maya": {
|
||||
"enabled": true,
|
||||
"label": "Maya",
|
||||
"icon": "{}/app_icons/maya.png",
|
||||
"host_name": "maya",
|
||||
"environment": "{\n \"MAYA_DISABLE_CLIC_IPM\": \"Yes\",\n \"MAYA_DISABLE_CIP\": \"Yes\",\n \"MAYA_DISABLE_CER\": \"Yes\",\n \"PYMEL_SKIP_MEL_INIT\": \"Yes\",\n \"LC_ALL\": \"C\"\n}\n",
|
||||
"variants": [
|
||||
{
|
||||
"name": "2024",
|
||||
"label": "2024",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Autodesk\\Maya2024\\bin\\mayapy.exe"
|
||||
],
|
||||
"darwin": [],
|
||||
"linux": [
|
||||
"/usr/autodesk/maya2024/bin/mayapy"
|
||||
]
|
||||
},
|
||||
"arguments": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
"linux": []
|
||||
},
|
||||
"environment": "{\n \"MAYA_VERSION\": \"2024\"\n}",
|
||||
"use_python_2": false
|
||||
},
|
||||
{
|
||||
"name": "2023",
|
||||
"label": "2023",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Autodesk\\Maya2023\\bin\\mayapy.exe"
|
||||
],
|
||||
"darwin": [],
|
||||
"linux": [
|
||||
"/usr/autodesk/maya2023/bin/mayapy"
|
||||
]
|
||||
},
|
||||
"arguments": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
"linux": []
|
||||
},
|
||||
"environment": "{\n \"MAYA_VERSION\": \"2023\"\n}",
|
||||
"use_python_2": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"adsk_3dsmax": {
|
||||
"enabled": true,
|
||||
"label": "3ds Max",
|
||||
|
|
|
|||
|
|
@ -433,6 +433,10 @@ class PublishersModel(BaseSettingsModel):
|
|||
default_factory=ValidateRenderSettingsModel,
|
||||
title="Validate Render Settings"
|
||||
)
|
||||
ValidateResolution: BasicValidateModel = Field(
|
||||
default_factory=BasicValidateModel,
|
||||
title="Validate Resolution Setting"
|
||||
)
|
||||
ValidateCurrentRenderLayerIsRenderable: BasicValidateModel = Field(
|
||||
default_factory=BasicValidateModel,
|
||||
title="Validate Current Render Layer Has Renderable Camera"
|
||||
|
|
@ -902,6 +906,11 @@ DEFAULT_PUBLISH_SETTINGS = {
|
|||
"redshift_render_attributes": [],
|
||||
"renderman_render_attributes": []
|
||||
},
|
||||
"ValidateResolution": {
|
||||
"enabled": True,
|
||||
"optional": True,
|
||||
"active": True
|
||||
},
|
||||
"ValidateCurrentRenderLayerIsRenderable": {
|
||||
"enabled": True,
|
||||
"optional": False,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring addon version."""
|
||||
__version__ = "0.1.4"
|
||||
__version__ = "0.1.5"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue