optional reuse list for meshCalcNormals, which makes decimation abt 5% faster.
authorCampbell Barton <ideasman42@gmail.com>
Sat, 20 May 2006 23:24:26 +0000 (23:24 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 20 May 2006 23:24:26 +0000 (23:24 +0000)
Workaround for a problem where badly predicted positions are further then half the edge length, on these cases just collapse to the weighted middle of teh edge.
Added docs for "PolyReduce" (Uses BPyMesh_Redux) and WIP Docs for AutoTex Layout.
http://mediawiki.blender.org/index.php/Manual/PartXIII/Modelling_Scripts

release/scripts/bpymodules/BPyMesh.py
release/scripts/bpymodules/BPyMesh_redux.py

index 6dbe7ba46fd8648cb70db837620f33dff68e35fe..c955f2165d28c14856eabdd61e6febbe36a15329 100644 (file)
@@ -295,10 +295,12 @@ print len(indices)
 me.faces.extend([[me.verts[ii] for ii in i] for i in indices])
 '''
 
-def meshCalcNormals(me):
+def meshCalcNormals(me, vertNormals=None):
        '''
        takes a mesh and returns very high quality normals 1 normal per vertex.
        The normals should be correct, indipendant of topology
+       
+       vertNormals - a list of vectors at least as long as the number of verts in the mesh
        '''
        Ang= Blender.Mathutils.AngleBetweenVecs
        Vector= Blender.Mathutils.Vector
@@ -306,7 +308,12 @@ def meshCalcNormals(me):
        # Weight the edge normals by total angle difference
        # EDGE METHOD
        
-       vertNormals= [ Vector() for v in xrange(len(me.verts)) ]
+       if not vertNormals:
+               vertNormals= [ Vector() for v in xrange(len(me.verts)) ]
+       else:
+               for v in vertNormals:
+                       v.zero()
+               
        edges={}
        for f in me.faces:
                for i in xrange(len(f.v)):
@@ -350,8 +357,8 @@ def meshCalcNormals(me):
        for ed, v in edges.iteritems():
                vertNormals[ed[0]]+= v[-1]
                vertNormals[ed[1]]+= v[-1]
-       for i, v in enumerate(vertNormals):
-               me.verts[i].no= v
+       for i, v in enumerate(me.verts):
+               v.no= vertNormals[i]
 
 
 
index 56a4f7498725cb83837355ec3fadc73c6fff7531..3f05ba294399297046dcca5d015cfb4c2d865924 100644 (file)
@@ -146,8 +146,11 @@ def redux(ob, REDUX=0.5, BOUNDRY_WEIGHT=5.0, FACE_AREA_WEIGHT=1.0, FACE_TRIANGUL
        
        collapse_edges= collapse_faces= None
        
+       # So meshCalcNormals can avoid making a new list all the time.
+       reuse_vertNormals= [ Vector() for v in xrange(len(me.verts)) ]
+       
        while target_face_count <= len(me.faces):
-               BPyMesh.meshCalcNormals(me)
+               BPyMesh.meshCalcNormals(me, reuse_vertNormals)
                
                if DO_WEIGHTS:
                        groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me)
@@ -279,6 +282,10 @@ def redux(ob, REDUX=0.5, BOUNDRY_WEIGHT=5.0, FACE_AREA_WEIGHT=1.0, FACE_TRIANGUL
                        v1no= ced.v1.co
                        v2no= ced.v2.co
                        
+                       # Basic operation, works fine but not as good as predicting the best place.
+                       #between= ((v1co*w1) + (v2co*w2))
+                       #ced.collapse_loc= between
+                       
                        # Use the vertex weights to bias the new location.
                        w1= vert_weights[ced.v1.index]
                        w2= vert_weights[ced.v2.index]
@@ -292,31 +299,31 @@ def redux(ob, REDUX=0.5, BOUNDRY_WEIGHT=5.0, FACE_AREA_WEIGHT=1.0, FACE_TRIANGUL
                                w2/=wscale
                        
                        length= ced.length
+                       between= (v1co+v2co) * 0.5
+                       
+                       # Collapse
+                       # new_location = between # Replace tricky code below. this code predicts the best collapse location.
+                       
+                       # Make lines at right angles to the normals- these 2 lines will intersect and be
+                       # the point of collapsing.
+                       
+                       # Enlarge so we know they intersect:  ced.length*2
+                       cv1= CrossVecs(v1no, CrossVecs(v1no, v1co-v2co))
+                       cv2= CrossVecs(v2no, CrossVecs(v2no, v2co-v1co))
+                       
+                       # Scale to be less then the edge lengths.
+                       cv1.normalize()
+                       cv2.normalize()
+                       cv1 = cv1 * (length* 0.4)
+                       cv2 = cv2 * (length* 0.4)
+                       
+                       smart_offset_loc= between + (cv1 + cv2)
                        
-                       if 0:
-                               between= ((v1co*w1) + (v2co*w2))
+                       
+                       if (smart_offset_loc-between).length > length/2:
+                               # New collapse loc is way out, just use midpoint.
                                ced.collapse_loc= between
                        else:
-                               between= (v1co+v2co) * 0.5
-                               
-                               # Collapse
-                               # new_location = between # Replace tricky code below. this code predicts the best collapse location.
-                               
-                               # Make lines at right angles to the normals- these 2 lines will intersect and be
-                               # the point of collapsing.
-                               
-                               # Enlarge so we know they intersect:  ced.length*2
-                               cv1= CrossVecs(v1no, CrossVecs(v1no, v1co-v2co))
-                               cv2= CrossVecs(v2no, CrossVecs(v2no, v2co-v1co))
-                               
-                               # Scale to be less then the edge lengths.
-                               cv1.normalize()
-                               cv2.normalize()
-                               cv1 = cv1 * (length* 0.4)
-                               cv2 = cv2 * (length* 0.4)
-                               
-                               smart_offset_loc= between + (cv1 + cv2)
-                               
                                # Now we need to blend between smart_offset_loc and w1/w2
                                # you see were blending between a vert and the edges midpoint, so we cant use a normal weighted blend.
                                if w1 > 0.5: # between v1 and smart_offset_loc