mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
Merge pull request #41 from ynput/enhancement/OP-7075_Validate-Camera-Attributes
This commit is contained in:
commit
c5b4e7062a
4 changed files with 169 additions and 1 deletions
42
client/ayon_core/hosts/max/api/action.py
Normal file
42
client/ayon_core/hosts/max/api/action.py
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
from pymxs import runtime as rt
|
||||||
|
|
||||||
|
import pyblish.api
|
||||||
|
|
||||||
|
from ayon_core.pipeline.publish import get_errored_instances_from_context
|
||||||
|
|
||||||
|
|
||||||
|
class SelectInvalidAction(pyblish.api.Action):
|
||||||
|
"""Select invalid objects in Blender when a publish plug-in failed."""
|
||||||
|
label = "Select Invalid"
|
||||||
|
on = "failed"
|
||||||
|
icon = "search"
|
||||||
|
|
||||||
|
def process(self, context, plugin):
|
||||||
|
errored_instances = get_errored_instances_from_context(context,
|
||||||
|
plugin=plugin)
|
||||||
|
|
||||||
|
# Get the invalid nodes for the plug-ins
|
||||||
|
self.log.info("Finding invalid nodes...")
|
||||||
|
invalid = list()
|
||||||
|
for instance in errored_instances:
|
||||||
|
invalid_nodes = plugin.get_invalid(instance)
|
||||||
|
if invalid_nodes:
|
||||||
|
if isinstance(invalid_nodes, (list, tuple)):
|
||||||
|
invalid.extend(invalid_nodes)
|
||||||
|
else:
|
||||||
|
self.log.warning(
|
||||||
|
"Failed plug-in doesn't have any selectable objects."
|
||||||
|
)
|
||||||
|
|
||||||
|
if not invalid:
|
||||||
|
self.log.info("No invalid nodes found.")
|
||||||
|
return
|
||||||
|
invalid_names = [obj.name for obj in invalid if not isinstance(obj, tuple)]
|
||||||
|
if not invalid_names:
|
||||||
|
invalid_names = [obj.name for obj, _ in invalid]
|
||||||
|
invalid = [obj for obj, _ in invalid]
|
||||||
|
self.log.info(
|
||||||
|
"Selecting invalid objects: %s", ", ".join(invalid_names)
|
||||||
|
)
|
||||||
|
|
||||||
|
rt.Select(invalid)
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
import pyblish.api
|
||||||
|
from pymxs import runtime as rt
|
||||||
|
|
||||||
|
from ayon_core.pipeline.publish import (
|
||||||
|
RepairAction,
|
||||||
|
OptionalPyblishPluginMixin,
|
||||||
|
PublishValidationError
|
||||||
|
)
|
||||||
|
from ayon_core.hosts.max.api.action import SelectInvalidAction
|
||||||
|
|
||||||
|
|
||||||
|
class ValidateCameraAttributes(OptionalPyblishPluginMixin,
|
||||||
|
pyblish.api.InstancePlugin):
|
||||||
|
"""Validates Camera has no invalid attribute properties
|
||||||
|
or values.(For 3dsMax Cameras only)
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
order = pyblish.api.ValidatorOrder
|
||||||
|
families = ['camera']
|
||||||
|
hosts = ['max']
|
||||||
|
label = 'Validate Camera Attributes'
|
||||||
|
actions = [SelectInvalidAction, RepairAction]
|
||||||
|
optional = True
|
||||||
|
|
||||||
|
DEFAULTS = ["fov", "nearrange", "farrange",
|
||||||
|
"nearclip", "farclip"]
|
||||||
|
CAM_TYPE = ["Freecamera", "Targetcamera",
|
||||||
|
"Physical"]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_invalid(cls, instance):
|
||||||
|
invalid = []
|
||||||
|
if rt.units.DisplayType != rt.Name("Generic"):
|
||||||
|
cls.log.warning(
|
||||||
|
"Generic Type is not used as a scene unit\n\n"
|
||||||
|
"sure you tweak the settings with your own values\n\n"
|
||||||
|
"before validation.")
|
||||||
|
cameras = instance.data["members"]
|
||||||
|
project_settings = instance.context.data["project_settings"].get("max")
|
||||||
|
cam_attr_settings = (
|
||||||
|
project_settings["publish"]["ValidateCameraAttributes"]
|
||||||
|
)
|
||||||
|
for camera in cameras:
|
||||||
|
if str(rt.ClassOf(camera)) not in cls.CAM_TYPE:
|
||||||
|
cls.log.debug(
|
||||||
|
"Skipping camera created from external plugin..")
|
||||||
|
continue
|
||||||
|
for attr in cls.DEFAULTS:
|
||||||
|
default_value = cam_attr_settings.get(attr)
|
||||||
|
if default_value == float(0):
|
||||||
|
cls.log.debug(
|
||||||
|
f"the value of {attr} in setting set to"
|
||||||
|
" zero. Skipping the check.")
|
||||||
|
continue
|
||||||
|
if round(rt.getProperty(camera, attr), 1) != default_value:
|
||||||
|
cls.log.error(
|
||||||
|
f"Invalid attribute value for {camera.name}:{attr} "
|
||||||
|
f"(should be: {default_value}))")
|
||||||
|
invalid.append(camera)
|
||||||
|
|
||||||
|
return invalid
|
||||||
|
|
||||||
|
def process(self, instance):
|
||||||
|
if not self.is_active(instance.data):
|
||||||
|
self.log.debug("Skipping Validate Camera Attributes.")
|
||||||
|
return
|
||||||
|
invalid = self.get_invalid(instance)
|
||||||
|
|
||||||
|
if invalid:
|
||||||
|
raise PublishValidationError(
|
||||||
|
"Invalid camera attributes found. See log.")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def repair(cls, instance):
|
||||||
|
invalid_cameras = cls.get_invalid(instance)
|
||||||
|
project_settings = instance.context.data["project_settings"].get("max")
|
||||||
|
cam_attr_settings = (
|
||||||
|
project_settings["publish"]["ValidateCameraAttributes"]
|
||||||
|
)
|
||||||
|
for camera in invalid_cameras:
|
||||||
|
for attr in cls.DEFAULTS:
|
||||||
|
expected_value = cam_attr_settings.get(attr)
|
||||||
|
if expected_value == float(0):
|
||||||
|
cls.log.debug(
|
||||||
|
f"the value of {attr} in setting set to zero.")
|
||||||
|
continue
|
||||||
|
rt.setProperty(camera, attr, expected_value)
|
||||||
|
|
@ -56,6 +56,16 @@
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"attributes": {}
|
"attributes": {}
|
||||||
},
|
},
|
||||||
|
"ValidateCameraAttributes": {
|
||||||
|
"enabled": true,
|
||||||
|
"optional": true,
|
||||||
|
"active": false,
|
||||||
|
"fov": 45.0,
|
||||||
|
"nearrange": 0.0,
|
||||||
|
"farrange": 1000.0,
|
||||||
|
"nearclip": 1.0,
|
||||||
|
"farclip": 1000.0
|
||||||
|
},
|
||||||
"ValidateLoadedPlugin": {
|
"ValidateLoadedPlugin": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,17 @@ class ValidateAttributesModel(BaseSettingsModel):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
class ValidateCameraAttributesModel(BaseSettingsModel):
|
||||||
|
enabled: bool = SettingsField(title="Enabled")
|
||||||
|
optional: bool = SettingsField(title="Optional")
|
||||||
|
active: bool = SettingsField(title="Active")
|
||||||
|
fov: float = SettingsField(0.0, title="Focal Length")
|
||||||
|
nearrange: float = SettingsField(0.0, title="Near Range")
|
||||||
|
farrange: float = SettingsField(0.0, title="Far Range")
|
||||||
|
nearclip: float = SettingsField(0.0, title="Near Clip")
|
||||||
|
farclip: float = SettingsField(0.0, title="Far Clip")
|
||||||
|
|
||||||
|
|
||||||
class FamilyMappingItemModel(BaseSettingsModel):
|
class FamilyMappingItemModel(BaseSettingsModel):
|
||||||
families: list[str] = SettingsField(
|
families: list[str] = SettingsField(
|
||||||
default_factory=list,
|
default_factory=list,
|
||||||
|
|
@ -63,7 +74,14 @@ class PublishersModel(BaseSettingsModel):
|
||||||
default_factory=ValidateAttributesModel,
|
default_factory=ValidateAttributesModel,
|
||||||
title="Validate Attributes"
|
title="Validate Attributes"
|
||||||
)
|
)
|
||||||
|
ValidateCameraAttributes: ValidateCameraAttributesModel = SettingsField(
|
||||||
|
default_factory=ValidateCameraAttributesModel,
|
||||||
|
title="Validate Camera Attributes",
|
||||||
|
description=(
|
||||||
|
"If the value of the camera attributes set to 0, "
|
||||||
|
"the system automatically skips checking it"
|
||||||
|
)
|
||||||
|
)
|
||||||
ValidateLoadedPlugin: ValidateLoadedPluginModel = SettingsField(
|
ValidateLoadedPlugin: ValidateLoadedPluginModel = SettingsField(
|
||||||
default_factory=ValidateLoadedPluginModel,
|
default_factory=ValidateLoadedPluginModel,
|
||||||
title="Validate Loaded Plugin"
|
title="Validate Loaded Plugin"
|
||||||
|
|
@ -101,6 +119,16 @@ DEFAULT_PUBLISH_SETTINGS = {
|
||||||
"enabled": False,
|
"enabled": False,
|
||||||
"attributes": "{}"
|
"attributes": "{}"
|
||||||
},
|
},
|
||||||
|
"ValidateCameraAttributes": {
|
||||||
|
"enabled": True,
|
||||||
|
"optional": True,
|
||||||
|
"active": False,
|
||||||
|
"fov": 45.0,
|
||||||
|
"nearrange": 0.0,
|
||||||
|
"farrange": 1000.0,
|
||||||
|
"nearclip": 1.0,
|
||||||
|
"farclip": 1000.0
|
||||||
|
},
|
||||||
"ValidateLoadedPlugin": {
|
"ValidateLoadedPlugin": {
|
||||||
"enabled": False,
|
"enabled": False,
|
||||||
"optional": True,
|
"optional": True,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue