Skip to content

validate_unreal_staticmesh_naming

Validator for correct naming of Static Meshes.

ValidateUnrealStaticMeshName

Bases: MayaInstancePlugin, OptionalPyblishPluginMixin

Validate name of Unreal Static Mesh

Unreals naming convention states that staticMesh should start with SM prefix - SM_[Name]_## (Eg. SM_sube_01).These prefixes can be configured in Settings UI. This plugin also validates other types of meshes - collision meshes:

UBX_[RenderMeshName]*: Boxes are created with the Box objects type in Max or with the Cube polygonal primitive in Maya. You cannot move the vertices around or deform it in any way to make it something other than a rectangular prism, or else it will not work.

UCP_[RenderMeshName]*: Capsules are created with the Capsule object type. The capsule does not need to have many segments (8 is a good number) at all because it is converted into a true capsule for collision. Like boxes, you should not move the individual vertices around.

USP_[RenderMeshName]*: Spheres are created with the Sphere object type. The sphere does not need to have many segments (8 is a good number) at all because it is converted into a true sphere for collision. Like boxes, you should not move the individual vertices around.

UCX_[RenderMeshName]*: Convex objects can be any completely closed convex 3D shape. For example, a box can also be a convex object

This validator also checks if collision mesh [RenderMeshName] matches one of SM_[RenderMeshName].

Source code in client/ayon_maya/plugins/publish/validate_unreal_staticmesh_naming.py
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
class ValidateUnrealStaticMeshName(plugin.MayaInstancePlugin,
                                   OptionalPyblishPluginMixin):
    """Validate name of Unreal Static Mesh

    Unreals naming convention states that staticMesh should start with `SM`
    prefix - SM_[Name]_## (Eg. SM_sube_01).These prefixes can be configured
    in Settings UI. This plugin also validates other types of
    meshes - collision meshes:

    UBX_[RenderMeshName]*:
                             Boxes are created with the Box objects type in
                             Max or with the Cube polygonal primitive in Maya.
                             You cannot move the vertices around or deform it
                             in any way to make it something other than a
                             rectangular prism, or else it will not work.

    UCP_[RenderMeshName]*:
                             Capsules are created with the Capsule object type.
                             The capsule does not need to have many segments
                             (8 is a good number) at all because it is
                             converted into a true capsule for collision. Like
                             boxes, you should not move the individual
                             vertices around.

    USP_[RenderMeshName]*:
                             Spheres are created with the Sphere object type.
                             The sphere does not need to have many segments
                             (8 is a good number) at all because it is
                             converted into a true sphere for collision. Like
                             boxes, you should not move the individual
                             vertices around.

    UCX_[RenderMeshName]*:
                             Convex objects can be any completely closed
                             convex 3D shape. For example, a box can also be
                             a convex object

    This validator also checks if collision mesh [RenderMeshName] matches one
    of SM_[RenderMeshName].

    """
    optional = True
    order = ValidateContentsOrder
    families = ["staticMesh"]
    label = "Unreal Static Mesh Name"
    actions = [ayon_maya.api.action.SelectInvalidAction]
    regex_mesh = r"(?P<renderName>.*))"
    regex_collision = r"(?P<renderName>.*)"

    @classmethod
    def get_invalid(cls, instance):

        invalid = []

        collision_prefixes = (
            instance.context.data["project_settings"]
            ["maya"]
            ["create"]
            ["CreateUnrealStaticMesh"]
            ["collision_prefixes"]
        )

        if cls.validate_mesh:
            # compile regex for testing names
            regex_mesh = "{}{}".format(
                ("_" + cls.static_mesh_prefix) or "", cls.regex_mesh
            )
            sm_r = re.compile(regex_mesh)
            if not sm_r.match(instance.data.get("productName")):
                cls.log.error("Mesh doesn't comply with name validation.")
                return True

        if cls.validate_collision:
            collision_set = instance.data.get("collisionMembers", None)
            # soft-fail is there are no collision objects
            if not collision_set:
                cls.log.warning("No collision objects to validate.")
                return False

            regex_collision = "{}{}_(\\d+)".format(
                "(?P<prefix>({}))_".format(
                    "|".join("{0}".format(p) for p in collision_prefixes)
                ) or "", cls.regex_collision
            )

            cl_r = re.compile(regex_collision)

            folder_name = instance.data["folderEntity"]["name"]
            mesh_name = "{}{}".format(folder_name,
                                      instance.data.get("variant", []))

            for obj in collision_set:
                cl_m = cl_r.match(obj)
                if not cl_m:
                    cls.log.error("{} is invalid".format(obj))
                    invalid.append(obj)
                else:
                    expected_collision = "{}_{}".format(
                        cl_m.group("prefix"),
                        mesh_name
                    )

                    if not obj.startswith(expected_collision):

                        cls.log.error(
                            "Collision object name doesn't match "
                            "static mesh name"
                        )
                        cls.log.error("{}_{} != {}_{}*".format(
                            cl_m.group("prefix"),
                            cl_m.group("renderName"),
                            cl_m.group("prefix"),
                            mesh_name,
                        ))
                        invalid.append(obj)

        return invalid

    def process(self, instance):
        if not self.is_active(instance.data):
            return

        if not self.validate_mesh and not self.validate_collision:
            self.log.debug("Validation of both mesh and collision names"
                           "is disabled.")
            return

        if not instance.data.get("collisionMembers", None):
            self.log.debug("There are no collision objects to validate")
            return

        invalid = self.get_invalid(instance)

        if invalid:
            raise PublishValidationError("Model naming is invalid. See log.")