Lightmap unwrap improvements - performance improvement #113720
|
@ -296,28 +296,57 @@ def lightmap_uvpack(
|
|||
tri_lengths = [trylens(f) for f in face_sel if f.loop_total == 3]
|
||||
del trylens
|
||||
|
||||
def trilensdiff(t1, t2):
|
||||
return (abs(t1[1][t1[2][0]] - t2[1][t2[2][0]]) +
|
||||
abs(t1[1][t1[2][1]] - t2[1][t2[2][1]]) +
|
||||
abs(t1[1][t1[2][2]] - t2[1][t2[2][2]]))
|
||||
# To add triangles into the lightmap pack triangles are grouped in pairs to fill rectangular areas.
|
||||
# In the following for each triangle we add the sorted triangle edge lengths (3d point) into a kd-Tree
|
||||
# then iterate over all triangles and search for pairs of triangles by looking for the closest
|
||||
# sorted triangle point.
|
||||
# Additionally clusters of similar/equal triangles are parsed by searching for ranges in a second step
|
||||
kd = mathutils.kdtree.KDTree(len(tri_lengths))
|
||||
for i, (f, lens, o) in enumerate(tri_lengths):
|
||||
vector = (lens[o[0]], lens[o[1]], lens[o[2]])
|
||||
kd.insert(vector, i)
|
||||
kd.balance()
|
||||
|
||||
while tri_lengths:
|
||||
tri1 = tri_lengths.pop()
|
||||
added_ids = [False] * len(tri_lengths)
|
||||
wm = bpy.context.window_manager
|
||||
num_tri_pairs = int(len(tri_lengths) / 2)
|
||||
wm.progress_begin(0, num_tri_pairs) # log unwrap progress
|
||||
pairs_added = 0
|
||||
tri_equality_threshold = 0.00001 # add multiple pairs at once that are within this threshold
|
||||
for i in range(len(tri_lengths)):
|
||||
if added_ids[i]:
|
||||
continue
|
||||
tri1 = tri_lengths[i]
|
||||
(f1, lens1, lo1) = tri1
|
||||
|
||||
if not tri_lengths:
|
||||
sorted_l = (lens1[lo1[0]], lens1[lo1[1]], lens1[lo1[2]])
|
||||
added_ids[i] = True
|
||||
vec, nearest, dist = kd.find(sorted_l, filter=lambda idx: not added_ids[idx])
|
||||
if not nearest or nearest < 0:
|
||||
pretty_faces.append(prettyface((tri1, None)))
|
||||
break
|
||||
tri2 = tri_lengths[nearest]
|
||||
pretty_faces.append(prettyface((tri1, tri2)))
|
||||
pairs_added = pairs_added + 1
|
||||
added_ids[nearest] = True
|
||||
|
||||
best_tri_index = -1
|
||||
best_tri_diff = 100000000.0
|
||||
# look in threshold proximity to add all similar/equal tris in one go.
|
||||
# this code is not necessary but acts as a shortcut (~9% performance improvement)
|
||||
|
||||
if dist < tri_equality_threshold:
|
||||
cluster_tri_ids = [idx for _, idx, _ in kd.find_range(sorted_l, tri_equality_threshold) if
|
||||
not added_ids[idx]]
|
||||
|
||||
for i, tri2 in enumerate(tri_lengths):
|
||||
diff = trilensdiff(tri1, tri2)
|
||||
if diff < best_tri_diff:
|
||||
best_tri_index = i
|
||||
best_tri_diff = diff
|
||||
if len(cluster_tri_ids) > 1:
|
||||
for ci in range(0, len(cluster_tri_ids) - (len(cluster_tri_ids) % 2), 2):
|
||||
pretty_faces.append(prettyface((tri_lengths[cluster_tri_ids[ci]],
|
||||
tri_lengths[cluster_tri_ids[ci + 1]])))
|
||||
added_ids[cluster_tri_ids[ci]] = added_ids[cluster_tri_ids[ci + 1]] = True
|
||||
pairs_added = pairs_added + 1
|
||||
|
||||
pretty_faces.append(prettyface((tri1, tri_lengths.pop(best_tri_index))))
|
||||
if i % 100 == 0:
|
||||
wm.progress_update(i)
|
||||
Sebastian Witt
commented
I added some progress tracking. I am not too sure if this is desirable. It could be done without any wm.progress, with progress but no prints or with both. I added some progress tracking. I am not too sure if this is desirable. It could be done without any wm.progress, with progress but no prints or with both.
|
||||
print(f"Unwrap progress {int((100 * pairs_added / num_tri_pairs))}%")
|
||||
wm.progress_end()
|
||||
|
||||
# Get the min, max and total areas
|
||||
max_area = 0.0
|
||||
|
|
Loading…
Reference in New Issue
It's not clear why the disabled code is useful to add. Either there should be a description of what the code does that's useful and why it's currently disabled, or remove it.
Thanks @ideasman42 ! I forgot to reenable that branch after benchmarking. It is not necessary from a functionality perspective. It just skips parts of the triangle pair matching with an additional kd lookup to match all triangles that are the same (within a threshold).
From testing it seems to be ~9% speedup depending on how many similar triangles there are.
In practise this is 1.34s vs 1.46s - it doesn't really matter at that point and comes with the cost of code complexity.
I am happy to leave it in or remove it.
The new commit is with the if branch/shortcut enabled.