Stoped a list that didint need to be made.

~20% faster and memory saved by re-using the face and edge lists and their classes each pass rather then __init__'ing new ones.
Stupid mistake- was only collapsing edges with UV's
This commit is contained in:
2006-05-18 14:13:47 +00:00
parent 24c3187afe
commit 2f337b6e62

View File

@@ -106,6 +106,9 @@ def redux(ob, REDUX=0.5, BOUNDRY_WEIGHT=5.0, FACE_AREA_WEIGHT=1.0, FACE_TRIANGUL
class collapseEdge(object):
__slots__ = 'length', 'key', 'faces', 'collapse_loc', 'v1', 'v2','uv1', 'uv2', 'col1', 'col2', 'collapse_weight'
def __init__(self, ed):
self.init_from_edge(ed) # So we can re-use the classes without using more memory.
def init_from_edge(self, ed):
self.key= ed_key(ed)
self.length= ed.length
self.faces= []
@@ -125,6 +128,9 @@ def redux(ob, REDUX=0.5, BOUNDRY_WEIGHT=5.0, FACE_AREA_WEIGHT=1.0, FACE_TRIANGUL
class collapseFace(object):
__slots__ = 'verts', 'normal', 'area', 'index', 'orig_uv', 'orig_col', 'uv', 'col' # , 'collapse_edge_count'
def __init__(self, f):
self.init_from_face(f)
def init_from_face(self, f):
self.verts= f.v
self.normal= f.no
self.area= f.area
@@ -134,8 +140,6 @@ def redux(ob, REDUX=0.5, BOUNDRY_WEIGHT=5.0, FACE_AREA_WEIGHT=1.0, FACE_TRIANGUL
self.uv= f.uv
self.orig_col= [col_key(col) for col in f.col]
self.col= f.col
#self.collapse_edge_count= 0 # used so we know how many edges of the face are collapsed.
for v in me.verts:
v.hide=0
@@ -158,13 +162,27 @@ def redux(ob, REDUX=0.5, BOUNDRY_WEIGHT=5.0, FACE_AREA_WEIGHT=1.0, FACE_TRIANGUL
edges= me.edges
faces= me.faces
DOUBLE_CHECK= [0]*len(verts)
# if DEBUG: DOUBLE_CHECK= [0]*len(verts)
for v in verts:
v.sel= False
collapse_faces= [collapseFace(f) for f in faces]
collapse_edges= [collapseEdge(ed) for ed in edges]
if not collapse_faces: # Initialize the list.
collapse_faces= [collapseFace(f) for f in faces]
collapse_edges= [collapseEdge(ed) for ed in edges]
else:
for i, ed in enumerate(edges):
collapse_edges[i].init_from_edge(ed)
# Faster then slicing
for ii in xrange(len(collapse_edges)-(i+1)):
collapse_edges.pop()
for i, f in enumerate(faces):
collapse_faces[i].init_from_face(f)
# Faster then slicing
for ii in xrange(len(collapse_faces)-(i+1)):
collapse_faces.pop()
collapse_edges_dict= dict( [(ced.key, ced) for ced in collapse_edges] )
# Store verts edges.
@@ -466,7 +484,7 @@ def redux(ob, REDUX=0.5, BOUNDRY_WEIGHT=5.0, FACE_AREA_WEIGHT=1.0, FACE_TRIANGUL
uvs_mixed= [ uv_key_mix(edge_my_uvs[iii], edge_other_uvs[iii], my_weight, other_weight) for iii in xrange(len(edge_my_uvs)) ]
cols_mixed= [ col_key_mix(edge_my_cols[iii], edge_other_cols[iii], my_weight, other_weight) for iii in xrange(len(edge_my_cols)) ]
#print 'FACE, USWERS', len(vert_face_users[v.index])
for face_vert_index, cfa in vert_face_users[v.index]:
if len(cfa.verts)==3 and cfa not in ced.faces: # if the face is apart of this edge then dont bother finding the uvs since the face will be removed anyway.
@@ -498,25 +516,14 @@ def redux(ob, REDUX=0.5, BOUNDRY_WEIGHT=5.0, FACE_AREA_WEIGHT=1.0, FACE_TRIANGUL
# DEBUG! if DEBUG: rd()
# Execute the collapse
ced.v1.sel= ced.v2.sel= True
ced.v1.co= ced.v2.co= ced.collapse_loc
# DEBUG! if DEBUG: rd()
if current_face_count <= target_face_count:
ced.collapse_loc= None
break
'''
# Execute the collapse
for ced in collapse_edges:
# Since the list is ordered we can stop once the first non collapsed edge if sound.
if not ced.collapse_loc:
break
ced.v1.sel= ced.v2.sel= True
# Execute the collapse
ced.v1.sel= ced.v2.sel= True # Select so remove doubles removed the edges and faces that use it
ced.v1.co= ced.v2.co= ced.collapse_loc
'''
# DEBUG! if DEBUG: rd()
if current_face_count <= target_face_count:
break
# Copy weights back to the mesh before we remove doubles.
if DO_WEIGHTS:
BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict)
@@ -524,17 +531,9 @@ def redux(ob, REDUX=0.5, BOUNDRY_WEIGHT=5.0, FACE_AREA_WEIGHT=1.0, FACE_TRIANGUL
doubles= me.remDoubles(0.0001)
me= ob.getData(mesh=1)
current_face_count= len(me.faces)
#break
if doubles==0: # should never happen.
if current_face_count <= target_face_count or not doubles: # not doubles shoule never happen.
break
if current_face_count <= target_face_count:
ced.collapse_loc= None
break
# Cleanup. BUGGY?
me.update()
Blender.Mesh.Mode(OLD_MESH_MODE)
@@ -546,7 +545,7 @@ def main():
scn= Blender.Scene.GetCurrent()
active_ob= scn.getActiveObject()
t= Blender.sys.time()
redux(active_ob, 0.4)
redux(active_ob, 0.5)
print '%.4f' % (Blender.sys.time()-t)
if __name__=='__main__':