38 lines
1.3 KiB
Python
38 lines
1.3 KiB
Python
import numpy as np
|
|
|
|
from ... import config
|
|
from ...core import Check, Issue, contexts
|
|
from ...core.mesh import loop_polygon_index, polygon_arrays
|
|
|
|
|
|
class UVCheck(Check):
|
|
id = "uvs"
|
|
label = "UVs"
|
|
description = "Every mesh has a UV map and no UV coordinate is negative."
|
|
category = "UVs"
|
|
contexts = contexts.ASSET
|
|
|
|
def run(self, ctx):
|
|
for ob in ctx.objects("MESH"):
|
|
me = ob.data
|
|
if not len(me.polygons):
|
|
continue
|
|
if not me.uv_layers:
|
|
yield Issue.for_id(f"{ob.name}: no UV map", ob)
|
|
continue
|
|
|
|
_, totals, _ = polygon_arrays(me)
|
|
poly_of_loop = loop_polygon_index(totals)
|
|
for layer in me.uv_layers:
|
|
uv = np.empty(len(me.loops) * 2, dtype=np.float32)
|
|
layer.uv.foreach_get("vector", uv)
|
|
negative = (uv.reshape(-1, 2) < -config.UV_NEGATIVE_TOLERANCE).any(axis=1)
|
|
if negative.any():
|
|
faces = np.unique(poly_of_loop[negative])
|
|
yield Issue.for_id(
|
|
f"{ob.name}: UV map '{layer.name}' has negative UVs on {faces.size} face(s)",
|
|
ob,
|
|
elements=faces.tolist(),
|
|
element_type="FACE",
|
|
)
|