forked from bartvdbraak/blender
add length average option to 'Follow Active Quads' unwrap, gives nicer results.
This commit is contained in:
parent
6fabbcb4dd
commit
ab913fe15d
@ -26,6 +26,7 @@ from bpy.types import Operator
|
||||
|
||||
|
||||
def extend(obj, operator, EXTEND_MODE):
|
||||
|
||||
import bmesh
|
||||
me = obj.data
|
||||
# script will fail without UVs
|
||||
@ -46,12 +47,12 @@ def extend(obj, operator, EXTEND_MODE):
|
||||
|
||||
faces = [f for f in bm.faces if f.select and len(f.verts) == 4]
|
||||
|
||||
for f in faces:
|
||||
f.tag = False
|
||||
f_act.tag = True
|
||||
|
||||
|
||||
# our own local walker
|
||||
def walk_face_init(faces, f_act):
|
||||
for f in faces:
|
||||
f.tag = False
|
||||
f_act.tag = True
|
||||
|
||||
def walk_face(f):
|
||||
# all faces in this list must be tagged
|
||||
f.tag = True
|
||||
@ -73,6 +74,30 @@ def extend(obj, operator, EXTEND_MODE):
|
||||
faces_a, faces_b = faces_b, faces_a
|
||||
faces_b.clear()
|
||||
|
||||
def walk_edgeloop(l):
|
||||
"""
|
||||
Could make this a generic function
|
||||
"""
|
||||
e_first = l.edge
|
||||
e = None
|
||||
while True:
|
||||
e = l.edge
|
||||
yield e
|
||||
|
||||
# don't step past non-manifold edges
|
||||
if e.is_manifold:
|
||||
# welk around the quad and then onto the next face
|
||||
l = l.link_loop_radial_next
|
||||
if len(l.face.verts) == 4:
|
||||
l = l.link_loop_next.link_loop_next
|
||||
if l.edge is e_first:
|
||||
break
|
||||
else:
|
||||
break
|
||||
else:
|
||||
break
|
||||
|
||||
|
||||
def extrapolate_uv(fac,
|
||||
l_a_outer, l_a_inner,
|
||||
l_b_outer, l_b_inner):
|
||||
@ -119,7 +144,9 @@ def extend(obj, operator, EXTEND_MODE):
|
||||
l_a_uv = [l[uv_act].uv for l in l_a]
|
||||
l_b_uv = [l[uv_act].uv for l in l_b]
|
||||
|
||||
if EXTEND_MODE == 'LENGTH':
|
||||
if EXTEND_MODE == 'LENGTH_AVERAGE':
|
||||
fac = edge_lengths[l_b[2].edge.index][0] / edge_lengths[l_a[1].edge.index][0]
|
||||
elif EXTEND_MODE == 'LENGTH':
|
||||
a0, b0, c0 = l_a[3].vert.co, l_a[0].vert.co, l_b[3].vert.co
|
||||
a1, b1, c1 = l_a[2].vert.co, l_a[1].vert.co, l_b[2].vert.co
|
||||
|
||||
@ -140,6 +167,40 @@ def extend(obj, operator, EXTEND_MODE):
|
||||
l_a_uv[2], l_a_uv[1],
|
||||
l_b_uv[2], l_b_uv[1])
|
||||
|
||||
# -------------------------------------------
|
||||
# Calculate average length per loop if needed
|
||||
|
||||
if EXTEND_MODE == 'LENGTH_AVERAGE':
|
||||
bm.edges.index_update()
|
||||
edge_lengths = [None] * len(bm.edges)
|
||||
|
||||
for f in faces:
|
||||
# we know its a quad
|
||||
l_quad = f.loops[:]
|
||||
l_pair_a = (l_quad[0], l_quad[2])
|
||||
l_pair_b = (l_quad[1], l_quad[3])
|
||||
|
||||
for l_pair in (l_pair_a, l_pair_b):
|
||||
if edge_lengths[l_pair[0].edge.index] is None:
|
||||
|
||||
edge_length_store = [-1.0]
|
||||
edge_length_accum = 0.0
|
||||
edge_length_total = 0
|
||||
|
||||
for l in l_pair:
|
||||
if edge_lengths[l.edge.index] is None:
|
||||
for e in walk_edgeloop(l):
|
||||
if edge_lengths[e.index] is None:
|
||||
edge_lengths[e.index] = edge_length_store
|
||||
edge_length_accum += e.calc_length()
|
||||
edge_length_total += 1
|
||||
|
||||
edge_length_store[0] = edge_length_accum / edge_length_total
|
||||
|
||||
# done with average length
|
||||
# ------------------------
|
||||
|
||||
walk_face_init(faces, f_act)
|
||||
for f_triple in walk_face(f_act):
|
||||
apply_uv(*f_triple)
|
||||
|
||||
@ -162,8 +223,10 @@ class FollowActiveQuads(Operator):
|
||||
name="Edge Length Mode",
|
||||
description="Method to space UV edge loops",
|
||||
items=(('EVEN', "Even", "Space all UVs evenly"),
|
||||
('LENGTH', "Length", "Average space UVs edge length of each loop")),
|
||||
default='LENGTH',
|
||||
('LENGTH', "Length", "Average space UVs edge length of each loop"),
|
||||
('LENGTH_AVERAGE', "Length Average", "Average space UVs edge length of each loop"),
|
||||
),
|
||||
default='LENGTH_AVERAGE',
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
@ -188,7 +188,7 @@ static bool buildNavMesh(const RecastData *recastParams, int nverts, float *vert
|
||||
|
||||
/* zero dimensions cause zero alloc later on [#33758] */
|
||||
if (width <= 0 || height <= 0) {
|
||||
BKE_report(reports, RPT_ERROR, "Object has no volume");
|
||||
BKE_report(reports, RPT_ERROR, "Object has a width or height of zero");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user