From 483f28cfaff846f74fd49cb73b9f45fe843011fe Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 5 Dec 2010 19:22:35 +0000 Subject: [PATCH] Optimize the Blender exporter to process face islands when creating strips Display a progress bar while exporting --- mesh_export.py | 121 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 95 insertions(+), 26 deletions(-) diff --git a/mesh_export.py b/mesh_export.py index 1e0047dc..b2d75d6b 100644 --- a/mesh_export.py +++ b/mesh_export.py @@ -15,6 +15,16 @@ import Blender def make_edge_key(i1, i2): return (min(i1, i2), max(i1, i2)) +progress_range = (0.0, 1.0, "") + +def set_progress(value): + Blender.Window.DrawProgressBar(progress_range[0]+progress_range[1]*value, progress_range[2]) + +def set_progress_range(low, high, text): + global progress_range + progress_range = (low, high-low, text) + set_progress(0.0) + class Edge: def __init__(self, me): @@ -191,7 +201,8 @@ class Mesh: def split_vertices(self, find_group_func, debug): groups = [] - for v in self.verts: + for i in range(len(self.verts)): + v = self.verts[i] for f in v.faces: f.flag = False @@ -202,6 +213,8 @@ class Mesh: groups.append(vg) + set_progress(i*0.5/len(self.verts)) + for i in range(len(self.verts)): if len(groups[i])==1: continue @@ -248,6 +261,8 @@ class Mesh: f.verts[f.verts.index(self.verts[i])] = v v.faces.append(f) + set_progress(0.5+i*0.5/len(self.verts)) + def split_smooth(self, debug = False): self.split_vertices(self.find_smooth_group, debug) @@ -455,12 +470,45 @@ class Exporter: for f in mesh.faces: f.flag = False + faces_done = 0 strips = [] + loose = [] + + cache = None + if self.optimize_cache: + cache = VertexCache(self.cache_size) + island = [] + island_strips = [] while 1: + if not island: + queue = [] + for f in mesh.faces: + if not f.flag: + f.flag = True + queue.append(f) + break + + if not queue: + break + + while queue: + f = queue[0] + del queue[0] + island.append(f) + + for e in f.edges: + other = e.other_face(f) + if other and not other.flag: + other.flag = True + queue.append(other) + + for f in island: + f.flag = False + best = 5 face = None - for f in mesh.faces: + for f in island: if f.flag: continue score = 0 @@ -473,42 +521,54 @@ class Exporter: best = score if not face: - break + while island_strips: + best = 0 + if cache: + best_hits = 0 + for i in range(len(island_strips)): + hits = cache.test_strip(island_strips[i]) + if hits>best_hits: + best = i + best_hits = hits + + s = island_strips[best] + del island_strips[best] + strips.append(s) + + if cache: + cache.fetch_strip(s) + + faces_done += len(island) + set_progress(float(faces_done)/len(mesh.faces)) + + loose += [f for f in island if not f.flag] + for f in island: + f.flag = True + + island = [] + island_strips = [] + continue strip = mesh.create_strip(face, self.max_strip_len, self.strip_debug) if strip: - strips.append(strip) - - loose = [f for f in mesh.faces if not f.flag] + island_strips.append(strip) if self.debug: print "%d strips:"%len(strips) for i in range(len(strips)): print " %d: %d indices"%(i, len(strips[i])) - print "%d loose faces"%len([f for f in mesh.faces if not f.flag]) + print "%d loose faces"%len(loose) nind = sum([len(s) for s in strips])+sum([len(f.verts) for f in loose]) print "%d indices total"%nind - if self.use_degen_tris and strips: - big_strip = [] - - cache = None + if cache: + cache = VertexCache(self.cache_size) total_hits = 0 - if self.optimize_cache: - cache = VertexCache(self.cache_size) - - while strips: - best = 0 - if cache: - best_hits = 0 - for i in range(len(strips)): - hits = cache.test_strip(strips[i]) - if hits>best_hits: - best = i - best_hits = hits - s = strips[best] + if self.use_degen_tris and strips: + big_strip = [] + for s in strips: if big_strip: glue = [big_strip[-1], s[0]] if len(big_strip)%2: @@ -522,19 +582,19 @@ class Exporter: if cache: total_hits += cache.fetch_strip(s) - del strips[best] - for f in loose: if len(big_strip)%2: order = (-1, -2, 0, 1) else: order = (0, 1, -1, -2) verts = [f.verts[i] for i in order[:len(f.verts)]] + if big_strip: glue = [big_strip[-1], verts[0]] big_strip += glue if cache: total_hits += cache.fetch_strip(glue) + big_strip += verts if cache: total_hits += cache.fetch_strip(verts) @@ -564,6 +624,8 @@ class Exporter: if o.getType()!="Mesh": raise Exception, "Can only export Mesh data" + Blender.Window.DrawProgressBar(0.0, "Preparing"); + mesh = Blender.Mesh.New("export_tmp") mesh.getFromObject(objs[0]) mesh = Mesh(mesh) @@ -580,6 +642,7 @@ class Exporter: ntris = sum([len(f.verts)-2 for f in mesh.faces]) print "Starting with %d vertices, %d faces (%d triangles) and %d edges"%(len(mesh.verts), len(mesh.faces), ntris, len(mesh.edges)) + set_progress_range(0.05, 0.35, "Smoothing") mesh.split_smooth(self.split_debug) if self.debug: @@ -591,6 +654,7 @@ class Exporter: mesh.generate_material_uv() if mesh.faceUV: + set_progress_range(0.35, 0.65, "Splitting UVs") mesh.split_uv(self.split_debug) if self.debug: print "After UV splitting %d vertices and %d edges"%(len(mesh.verts), len(mesh.edges)) @@ -599,11 +663,14 @@ class Exporter: if self.tbn_vecs: mesh.compute_tbn() + set_progress_range(0.65, 0.95, "Creating strips") strips = [] loose = mesh.faces if self.use_strips: strips, loose = self.stripify(mesh) + Blender.Window.DrawProgressBar(0.95, "Writing file"); + if self.object: self.out_file.begin("mesh") @@ -690,6 +757,8 @@ class Exporter: self.out_file.end() self.out_file.end() + Blender.Window.DrawProgressBar(1.0, "Done") + class FrontEnd: def __init__(self): -- 2.43.0