diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_no_animation.py b/client/ayon_core/hosts/max/plugins/publish/validate_no_animation.py new file mode 100644 index 0000000000..9f859a1b28 --- /dev/null +++ b/client/ayon_core/hosts/max/plugins/publish/validate_no_animation.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +import pyblish.api +from pymxs import runtime as rt +from ayon_core.pipeline import ( + PublishValidationError, + OptionalPyblishPluginMixin +) +from ayon_core.hosts.max.api.action import SelectInvalidAction + + +class ValidateNoAnimation(pyblish.api.InstancePlugin, + OptionalPyblishPluginMixin): + """Validates No Animation + + Ensure no keyframes on nodes in the Instance + """ + + order = pyblish.api.ValidatorOrder + families = ["model"] + hosts = ["max"] + optional = True + label = "Validate No Animation" + actions = [SelectInvalidAction] + + def process(self, instance): + if not self.is_active(instance.data): + return + invalid = self.get_invalid(instance) + if invalid: + bullet_point_invalid_statement = "\n".join( + "- {}: {}".format(obj, message) + for obj, message in invalid + ) + raise PublishValidationError( + "Keyframes found on:\n\n{0}".format( + bullet_point_invalid_statement) + , + title="Keyframes on model" + ) + + @staticmethod + def get_invalid(instance): + invalid = [] + selected_objects = instance.data["members"] + for sel in selected_objects: + sel_pos_ctl = rt.getPropertyController( + sel.controller, 'Position') + ctl_count = (sel_pos_ctl.keys).count + if len(ctl_count) > 0: + invalid.append( + (sel), f"Object Position(s) has {ctl_count} keyframe(s)") + sel_rot_ctl = rt.getPropertyController( + sel.controller, "Rotation" + ) + ctl_count = (sel_rot_ctl.keys).count + if len(ctl_count) > 0: + invalid.append( + (sel), f"Object Rotation(s) has {ctl_count} keyframe(s)") + sel_scale_ctl = rt.getPropertyController( + sel.controller, "Scale" + ) + ctl_count = (sel_scale_ctl.keys).count + if len(ctl_count) > 0: + invalid.append( + (sel), f"Object Rotation(s) has {ctl_count} keyframe(s)") + + return invalid diff --git a/server_addon/max/server/settings/publishers.py b/server_addon/max/server/settings/publishers.py index 5e28c1b467..8f9f1009f4 100644 --- a/server_addon/max/server/settings/publishers.py +++ b/server_addon/max/server/settings/publishers.py @@ -82,6 +82,10 @@ class PublishersModel(BaseSettingsModel): "the system automatically skips checking it" ) ) + ValidateNoAnimation: BasicValidateModel = SettingsField( + default_factory=BasicValidateModel, + title="Validate No Animation" + ) ValidateLoadedPlugin: ValidateLoadedPluginModel = SettingsField( default_factory=ValidateLoadedPluginModel, title="Validate Loaded Plugin" @@ -134,6 +138,11 @@ DEFAULT_PUBLISH_SETTINGS = { "optional": True, "family_plugins_mapping": [] }, + "ValidateNoAnimation": { + "enabled": True, + "optional": True, + "active": False, + }, "ExtractModelObj": { "enabled": True, "optional": True, diff --git a/server_addon/max/server/version.py b/server_addon/max/server/version.py index 1276d0254f..0a8da88258 100644 --- a/server_addon/max/server/version.py +++ b/server_addon/max/server/version.py @@ -1 +1 @@ -__version__ = "0.1.5" +__version__ = "0.1.6"