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 | class ValidateMeshUVSetMap1(plugin.MayaInstancePlugin,
OptionalPyblishPluginMixin):
"""Validate model's default set exists and is named 'map1'.
In Maya meshes by default have a uv set named "map1" that cannot be
deleted. It can be renamed however, introducing some issues with some
renderers. As such we ensure the first (default) UV set index is named
"map1".
"""
order = ValidateMeshOrder
families = ['model']
optional = True
label = "Mesh has map1 UV Set"
actions = [ayon_maya.api.action.SelectInvalidAction,
RepairAction]
@classmethod
def get_invalid(cls, instance):
meshes = cmds.ls(instance, type='mesh', long=True)
invalid = []
for mesh in meshes:
# Get existing mapping of uv sets by index
indices = cmds.polyUVSet(mesh, query=True, allUVSetsIndices=True)
maps = cmds.polyUVSet(mesh, query=True, allUVSets=True)
if not indices or not maps:
cls.log.warning("Mesh has no UV set: %s", mesh)
invalid.append(mesh)
continue
mapping = dict(zip(indices, maps))
# Get the uv set at index zero.
name = mapping[0]
if name != "map1":
invalid.append(mesh)
return invalid
def process(self, instance):
"""Process all the nodes in the instance 'objectSet'"""
if not self.is_active(instance.data):
return
invalid = self.get_invalid(instance)
if invalid:
invalid_list = "\n".join(f"- {node}" for node in invalid)
raise PublishValidationError(
"Meshes found without 'map1' UV set:\n"
"{0}".format(invalid_list),
description=self.get_description()
)
@classmethod
def repair(cls, instance):
"""Rename uv map at index zero to map1"""
for mesh in cls.get_invalid(instance):
# Get existing mapping of uv sets by index
indices = cmds.polyUVSet(mesh, query=True, allUVSetsIndices=True)
maps = cmds.polyUVSet(mesh, query=True, allUVSets=True)
if not indices or not maps:
# No UV set exist at all, create a `map1` uv set
# This may fail silently if the mesh has no geometry at all
cmds.polyUVSet(mesh, create=True, uvSet="map1")
continue
mapping = dict(zip(indices, maps))
# Ensure there is no uv set named map1 to avoid
# a clash on renaming the "default uv set" to map1
existing = set(maps)
if "map1" in existing:
# Find a unique name index
i = 2
while True:
name = "map{0}".format(i)
if name not in existing:
break
i += 1
cls.log.warning("Renaming clashing uv set name on mesh"
" %s to '%s'", mesh, name)
cmds.polyUVSet(mesh,
rename=True,
uvSet="map1",
newUVSet=name)
# Rename the initial index to map1
original = mapping[0]
cmds.polyUVSet(mesh,
rename=True,
uvSet=original,
newUVSet="map1")
@staticmethod
def get_description():
return inspect.cleandoc("""### Mesh found without map1 uv set
A mesh must have a default UV set named `map1` to adhere to the default
mesh behavior of Maya meshes.
There may be meshes that:
- Have no UV set
- Have no `map1` uv set but are using a different name
- Have a `map1` uv set, but it's not the default (first index)
#### Repair
Using repair will try to make the first UV set the `map1` uv set. If it
does not exist yet it will be created or renames the current first
UV set to `map1`.
""")
|