fix [#36081] ngones causes problems with lightmap packing

This commit is contained in:
Campbell Barton
2013-09-11 09:55:44 +00:00
parent b551476dbd
commit 441bb19357

View File

@@ -24,15 +24,16 @@ import mathutils
class prettyface(object): class prettyface(object):
__slots__ = ("uv", __slots__ = (
"width", "uv",
"height", "width",
"children", "height",
"xoff", "children",
"yoff", "xoff",
"has_parent", "yoff",
"rot", "has_parent",
) "rot",
)
def __init__(self, data): def __init__(self, data):
self.has_parent = False self.has_parent = False
@@ -94,8 +95,43 @@ class prettyface(object):
# cos = [v.co for v in data] # cos = [v.co for v in data]
cos = [data.id_data.vertices[v].co for v in data.vertices] # XXX25 cos = [data.id_data.vertices[v].co for v in data.vertices] # XXX25
self.width = ((cos[0] - cos[1]).length + (cos[2] - cos[3]).length) / 2.0 if len(self.uv) == 4:
self.height = ((cos[1] - cos[2]).length + (cos[0] - cos[3]).length) / 2.0 self.width = ((cos[0] - cos[1]).length + (cos[2] - cos[3]).length) / 2.0
self.height = ((cos[1] - cos[2]).length + (cos[0] - cos[3]).length) / 2.0
else:
# ngon, note:
# for ngons to calculate the width/height we need to do the
# whole projection, unlike other faces
# we store normalized UV's in the faces coords to avoid
# calculating the projection and rotating it twice.
no = data.normal
r = no.rotation_difference(mathutils.Vector((0.0, 0.0, 1.0)))
cos_2d = [(r * co).xy for co in cos]
# print(cos_2d)
angle = mathutils.geometry.box_fit_2d(cos_2d)
mat = mathutils.Matrix.Rotation(angle, 2)
cos_2d = [(mat * co) for co in cos_2d]
xs = [co.x for co in cos_2d]
ys = [co.y for co in cos_2d]
xmin = min(xs)
ymin = min(ys)
xmax = max(xs)
ymax = max(ys)
xspan = xmax - xmin
yspan = ymax - ymin
self.width = xspan
self.height = yspan
# ngons work different, we store projected result
# in UV's to avoid having to re-project later.
for i, co in enumerate(cos_2d):
self.uv[i][:] = ((co.x - xmin) / xspan,
(co.y - ymin) / yspan)
self.children = [] self.children = []
@@ -105,7 +141,7 @@ class prettyface(object):
self.width, self.height = self.height, self.width self.width, self.height = self.height, self.width
self.xoff, self.yoff = self.yoff, self.xoff # not needed? self.xoff, self.yoff = self.yoff, self.xoff # not needed?
self.rot = not self.rot # only for tri pairs. self.rot = not self.rot # only for tri pairs and ngons.
# print("spinning") # print("spinning")
for pf in self.children: for pf in self.children:
pf.spin() pf.spin()
@@ -178,10 +214,19 @@ class prettyface(object):
set_uv(f, (x2, y2), (x2, y1 + margin_h), (x1 + margin_w, y2)) set_uv(f, (x2, y2), (x2, y1 + margin_h), (x1 + margin_w, y2))
else: # 1 QUAD else: # 1 QUAD
uv[1][:] = x1, y1 if len(uv) == 4:
uv[2][:] = x1, y2 uv[1][:] = x1, y1
uv[3][:] = x2, y2 uv[2][:] = x1, y2
uv[0][:] = x2, y1 uv[3][:] = x2, y2
uv[0][:] = x2, y1
else:
# NGon
xspan = x2 - x1
yspan = y2 - y1
for uvco in uv:
x, y = uvco
uvco[:] = ((x1 + (x * xspan)),
(y1 + (y * yspan)))
def __hash__(self): def __hash__(self):
# None unique hash # None unique hash
@@ -244,7 +289,7 @@ def lightmap_uvpack(meshes,
print("\tWarning, less then 4 faces, skipping") print("\tWarning, less then 4 faces, skipping")
continue continue
pretty_faces = [prettyface(f) for f in face_sel if f.loop_total == 4] pretty_faces = [prettyface(f) for f in face_sel if f.loop_total >= 4]
# Do we have any triangles? # Do we have any triangles?
if len(pretty_faces) != len(face_sel): if len(pretty_faces) != len(face_sel):