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):
|
def extend(obj, operator, EXTEND_MODE):
|
||||||
|
|
||||||
import bmesh
|
import bmesh
|
||||||
me = obj.data
|
me = obj.data
|
||||||
# script will fail without UVs
|
# 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]
|
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
|
# 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):
|
def walk_face(f):
|
||||||
# all faces in this list must be tagged
|
# all faces in this list must be tagged
|
||||||
f.tag = True
|
f.tag = True
|
||||||
@ -73,6 +74,30 @@ def extend(obj, operator, EXTEND_MODE):
|
|||||||
faces_a, faces_b = faces_b, faces_a
|
faces_a, faces_b = faces_b, faces_a
|
||||||
faces_b.clear()
|
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,
|
def extrapolate_uv(fac,
|
||||||
l_a_outer, l_a_inner,
|
l_a_outer, l_a_inner,
|
||||||
l_b_outer, l_b_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_a_uv = [l[uv_act].uv for l in l_a]
|
||||||
l_b_uv = [l[uv_act].uv for l in l_b]
|
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
|
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
|
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_a_uv[2], l_a_uv[1],
|
||||||
l_b_uv[2], l_b_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):
|
for f_triple in walk_face(f_act):
|
||||||
apply_uv(*f_triple)
|
apply_uv(*f_triple)
|
||||||
|
|
||||||
@ -162,8 +223,10 @@ class FollowActiveQuads(Operator):
|
|||||||
name="Edge Length Mode",
|
name="Edge Length Mode",
|
||||||
description="Method to space UV edge loops",
|
description="Method to space UV edge loops",
|
||||||
items=(('EVEN', "Even", "Space all UVs evenly"),
|
items=(('EVEN', "Even", "Space all UVs evenly"),
|
||||||
('LENGTH', "Length", "Average space UVs edge length of each loop")),
|
('LENGTH', "Length", "Average space UVs edge length of each loop"),
|
||||||
default='LENGTH',
|
('LENGTH_AVERAGE', "Length Average", "Average space UVs edge length of each loop"),
|
||||||
|
),
|
||||||
|
default='LENGTH_AVERAGE',
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -188,7 +188,7 @@ static bool buildNavMesh(const RecastData *recastParams, int nverts, float *vert
|
|||||||
|
|
||||||
/* zero dimensions cause zero alloc later on [#33758] */
|
/* zero dimensions cause zero alloc later on [#33758] */
|
||||||
if (width <= 0 || height <= 0) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user