refactor blender Validators

This commit is contained in:
Kaa Maurice 2022-08-11 15:39:03 +02:00
parent 6d3d52c05c
commit 6cba799c46
8 changed files with 66 additions and 58 deletions

View file

@ -1,9 +1,11 @@
from typing import List
import mathutils
import bpy
import pyblish.api
import openpype.hosts.blender.api.action
from openpype.api import ValidateContentsOrder
from openpype.hosts.blender.api.action import SelectInvalidAction
class ValidateCameraZeroKeyframe(pyblish.api.InstancePlugin):
@ -14,21 +16,21 @@ class ValidateCameraZeroKeyframe(pyblish.api.InstancePlugin):
in Unreal and Blender.
"""
order = openpype.api.ValidateContentsOrder
order = ValidateContentsOrder
hosts = ["blender"]
families = ["camera"]
category = "geometry"
version = (0, 1, 0)
label = "Zero Keyframe"
actions = [openpype.hosts.blender.api.action.SelectInvalidAction]
actions = [SelectInvalidAction]
_identity = mathutils.Matrix()
@classmethod
def get_invalid(cls, instance) -> List:
@staticmethod
def get_invalid(instance) -> List:
invalid = []
for obj in [obj for obj in instance]:
if obj.type == "CAMERA":
for obj in set(instance):
if isinstance(obj, bpy.types.Object) and obj.type == "CAMERA":
if obj.animation_data and obj.animation_data.action:
action = obj.animation_data.action
frames_set = set()
@ -45,4 +47,5 @@ class ValidateCameraZeroKeyframe(pyblish.api.InstancePlugin):
invalid = self.get_invalid(instance)
if invalid:
raise RuntimeError(
f"Object found in instance is not in Object Mode: {invalid}")
f"Camera must have a keyframe at frame 0: {invalid}"
)

View file

@ -3,18 +3,19 @@ from typing import List
import bpy
import pyblish.api
import openpype.hosts.blender.api.action
from openpype.api import ValidateContentsOrder
from openpype.hosts.blender.api.action import SelectInvalidAction
class ValidateMeshHasUvs(pyblish.api.InstancePlugin):
"""Validate that the current mesh has UV's."""
order = pyblish.api.ValidatorOrder
order = ValidateContentsOrder
hosts = ["blender"]
families = ["model"]
category = "geometry"
label = "Mesh Has UV's"
actions = [openpype.hosts.blender.api.action.SelectInvalidAction]
actions = [SelectInvalidAction]
optional = True
@staticmethod
@ -33,20 +34,20 @@ class ValidateMeshHasUvs(pyblish.api.InstancePlugin):
@classmethod
def get_invalid(cls, instance) -> List:
invalid = []
# TODO (jasper): only check objects in the collection that will be published?
for obj in [
obj for obj in instance]:
for obj in set(instance):
try:
if obj.type == 'MESH':
# Make sure we are in object mode.
bpy.ops.object.mode_set(mode='OBJECT')
if not cls.has_uvs(obj):
invalid.append(obj)
except:
except RuntimeError:
continue
return invalid
def process(self, instance):
invalid = self.get_invalid(instance)
if invalid:
raise RuntimeError(f"Meshes found in instance without valid UV's: {invalid}")
raise RuntimeError(
f"Meshes found in instance without valid UV's: {invalid}"
)

View file

@ -3,29 +3,26 @@ from typing import List
import bpy
import pyblish.api
import openpype.hosts.blender.api.action
from openpype.api import ValidateContentsOrder
from openpype.hosts.blender.api.action import SelectInvalidAction
class ValidateMeshNoNegativeScale(pyblish.api.Validator):
"""Ensure that meshes don't have a negative scale."""
order = pyblish.api.ValidatorOrder
order = ValidateContentsOrder
hosts = ["blender"]
families = ["model"]
label = "Mesh No Negative Scale"
actions = [openpype.hosts.blender.api.action.SelectInvalidAction]
actions = [SelectInvalidAction]
@staticmethod
def get_invalid(instance) -> List:
invalid = []
# TODO (jasper): only check objects in the collection that will be published?
for obj in [
obj for obj in bpy.data.objects if obj.type == 'MESH'
]:
if any(v < 0 for v in obj.scale):
invalid.append(obj)
return invalid
for obj in set(instance):
if isinstance(obj, bpy.types.Object) and obj.type == 'MESH':
if any(v < 0 for v in obj.scale):
invalid.append(obj)
def process(self, instance):
invalid = self.get_invalid(instance)

View file

@ -1,7 +1,10 @@
from typing import List
import bpy
import pyblish.api
import openpype.hosts.blender.api.action
from openpype.api import ValidateContentsOrder
from openpype.hosts.blender.api.action import SelectInvalidAction
class ValidateNoColonsInName(pyblish.api.InstancePlugin):
@ -12,20 +15,20 @@ class ValidateNoColonsInName(pyblish.api.InstancePlugin):
"""
order = openpype.api.ValidateContentsOrder
order = ValidateContentsOrder
hosts = ["blender"]
families = ["model", "rig"]
version = (0, 1, 0)
label = "No Colons in names"
actions = [openpype.hosts.blender.api.action.SelectInvalidAction]
actions = [SelectInvalidAction]
@classmethod
@staticmethod
def get_invalid(cls, instance) -> List:
invalid = []
for obj in [obj for obj in instance]:
for obj in set(instance):
if ':' in obj.name:
invalid.append(obj)
if obj.type == 'ARMATURE':
if isinstance(obj, bpy.types.Object) and obj.type == 'ARMATURE':
for bone in obj.data.bones:
if ':' in bone.name:
invalid.append(obj)

View file

@ -1,7 +1,9 @@
from typing import List
import bpy
import pyblish.api
import openpype.hosts.blender.api.action
from openpype.hosts.blender.api.action import SelectInvalidAction
class ValidateObjectIsInObjectMode(pyblish.api.InstancePlugin):
@ -12,20 +14,16 @@ class ValidateObjectIsInObjectMode(pyblish.api.InstancePlugin):
families = ["model", "rig", "layout"]
category = "geometry"
label = "Validate Object Mode"
actions = [openpype.hosts.blender.api.action.SelectInvalidAction]
actions = [SelectInvalidAction]
optional = False
@classmethod
@staticmethod
def get_invalid(cls, instance) -> List:
invalid = []
for obj in [obj for obj in instance]:
try:
if obj.type == 'MESH' or obj.type == 'ARMATURE':
# Check if the object is in object mode.
if not obj.mode == 'OBJECT':
invalid.append(obj)
except Exception:
continue
for obj in set(instance):
if isinstance(obj, bpy.types.Object):
if not obj.mode == 'OBJECT':
invalid.append(obj)
return invalid
def process(self, instance):

View file

@ -1,9 +1,11 @@
from typing import List
import mathutils
import bpy
import pyblish.api
import openpype.hosts.blender.api.action
from openpype.api import ValidateContentsOrder
from openpype.hosts.blender.api.action import SelectInvalidAction
class ValidateTransformZero(pyblish.api.InstancePlugin):
@ -15,21 +17,24 @@ class ValidateTransformZero(pyblish.api.InstancePlugin):
"""
order = openpype.api.ValidateContentsOrder
order = ValidateContentsOrder
hosts = ["blender"]
families = ["model"]
category = "geometry"
version = (0, 1, 0)
label = "Transform Zero"
actions = [openpype.hosts.blender.api.action.SelectInvalidAction]
actions = [SelectInvalidAction]
_identity = mathutils.Matrix()
@classmethod
def get_invalid(cls, instance) -> List:
invalid = []
for obj in [obj for obj in instance]:
if obj.matrix_basis != cls._identity:
for obj in set(instance):
if (
isinstance(obj, bpy.types.Object)
and obj.matrix_basis != cls._identity
):
invalid.append(obj)
return invalid
@ -37,4 +42,6 @@ class ValidateTransformZero(pyblish.api.InstancePlugin):
invalid = self.get_invalid(instance)
if invalid:
raise RuntimeError(
f"Object found in instance is not in Object Mode: {invalid}")
"Object found in instance has not"
f" transform to zero: {invalid}"
)

View file

@ -14,6 +14,11 @@
"optional": true,
"active": true
},
"ValidateMeshNoNegativeScale": {
"enabled": true,
"optional": false,
"active": true
},
"ValidateTransformZero": {
"enabled": true,
"optional": false,
@ -23,7 +28,6 @@
"enabled": true,
"optional": true,
"active": true,
"pack_images": true,
"families": [
"model",
"camera",

View file

@ -18,15 +18,10 @@
}
]
},
{
"type": "collapsible-wrap",
"label": "Model",
"children": [
{
"type": "label",
"label": "Validators"
},
{
"type": "schema_template",
"name": "template_publish_plugin",
@ -76,7 +71,7 @@
"key": "families",
"label": "Families",
"type": "list",
"object_type": "task-types-enum"
"object_type": "text"
}
]
},
@ -86,7 +81,7 @@
"template_data": [
{
"key": "ExtractFBX",
"label": "Extract FBX (model and rig)",
"label": "Extract FBX (model and rig)"
},
{
"key": "ExtractABC",