Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release/scripts/mesh_cleanup.py')
-rw-r--r--release/scripts/mesh_cleanup.py456
1 files changed, 0 insertions, 456 deletions
diff --git a/release/scripts/mesh_cleanup.py b/release/scripts/mesh_cleanup.py
deleted file mode 100644
index 27adca335cb..00000000000
--- a/release/scripts/mesh_cleanup.py
+++ /dev/null
@@ -1,456 +0,0 @@
-#!BPY
-"""
-Name: 'Clean Meshes'
-Blender: 245
-Group: 'Mesh'
-Tooltip: 'Clean unused data from all selected mesh objects.'
-"""
-
-__author__ = "Campbell Barton aka ideasman42"
-__url__ = ["www.blender.org", "blenderartists.org", "www.python.org"]
-__version__ = "0.1"
-__bpydoc__ = """\
-Clean Meshes
-
-Cleans unused data from selected meshes
-"""
-
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# Script copyright (C) Campbell J Barton
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-# --------------------------------------------------------------------------
-
-
-from Blender import *
-import bpy
-from Blender.Mathutils import TriangleArea
-
-import Blender
-import BPyMesh
-dict2MeshWeight= BPyMesh.dict2MeshWeight
-meshWeight2Dict= BPyMesh.meshWeight2Dict
-
-def rem_free_verts(me):
- vert_users= [0] * len(me.verts)
- for f in me.faces:
- for v in f:
- vert_users[v.index]+=1
-
- for e in me.edges:
- for v in e: # loop on edge verts
- vert_users[v.index]+=1
-
- verts_free= [i for i, users in enumerate(vert_users) if not users]
-
- if verts_free:
- pass
- me.verts.delete(verts_free)
- return len(verts_free)
-
-def rem_free_edges(me, limit=None):
- ''' Only remove based on limit if a limit is set, else remove all '''
-
- edgeDict= {} # will use a set when python 2.4 is standard.
-
- for f in me.faces:
- for edkey in f.edge_keys:
- edgeDict[edkey] = None
-
- edges_free= []
- for e in me.edges:
- if not edgeDict.has_key(e.key):
- edges_free.append(e)
-
- if limit != None:
- edges_free= [e for e in edges_free if e.length <= limit]
-
- me.edges.delete(edges_free)
- return len(edges_free)
-
-def rem_area_faces(me, limit=0.001):
- ''' Faces that have an area below the limit '''
- rem_faces= [f for f in me.faces if f.area <= limit]
- if rem_faces:
- me.faces.delete( 0, rem_faces )
- return len(rem_faces)
-
-def rem_perimeter_faces(me, limit=0.001):
- ''' Faces whos combine edge length is below the limit '''
- def faceEdLen(f):
- v= f.v
- if len(v) == 3:
- return\
- (v[0].co-v[1].co).length +\
- (v[1].co-v[2].co).length +\
- (v[2].co-v[0].co).length
- else: # 4
- return\
- (v[0].co-v[1].co).length +\
- (v[1].co-v[2].co).length +\
- (v[2].co-v[3].co).length +\
- (v[3].co-v[0].co).length
- rem_faces= [f for f in me.faces if faceEdLen(f) <= limit]
- if rem_faces:
- me.faces.delete( 0, rem_faces )
- return len(rem_faces)
-
-def rem_unused_materials(me):
- materials= me.materials
- len_materials= len(materials)
- if len_materials < 2:
- return 0
-
- rem_materials= 0
-
- material_users= dict( [(i,0) for i in xrange(len_materials)] )
-
- for f in me.faces:
- f_mat = f.mat
- # Make sure the face index isnt too big. this happens sometimes.
- if f_mat >= len_materials:
- f_mat = f.mat = 0
- material_users[f_mat] += 1
-
- # mat_idx_subtract= 0
- # reindex_mapping= dict( [(i,0) for i in xrange(len_materials)] )
-
- reindex_mapping_ls = range(len_materials)
- for i in range(len_materials-1, -1, -1):
- if material_users[i] == 0:
- del reindex_mapping_ls[i]
- del materials[i]
- rem_materials+=1
-
- reindex_mapping= {}
-
- for i, mat in enumerate(reindex_mapping_ls):
- reindex_mapping[mat] = i
-
- for f in me.faces:
- f.mat= reindex_mapping[f.mat]
-
- me.materials= materials
- return rem_materials
-
-
-def rem_free_groups(me, groupNames, vWeightDict):
- ''' cound how many vert users a group has and remove unused groups '''
- rem_groups = 0
- groupUserDict= dict([(group,0) for group in groupNames])
-
- for vertexWeight in vWeightDict:
- for group, weight in vertexWeight.iteritems():
- groupUserDict[group] += 1
-
- i=len(groupNames)
- while i:
- i-=1
- group= groupNames[i]
- if groupUserDict[group] == 0:
- del groupNames[i]
- print '\tremoving, vgroup', group
- rem_groups+=1
- return rem_groups
-
-def rem_zero_weights(me, limit, groupNames, vWeightDict):
- ''' remove verts from a group when their weight is zero.'''
- rem_vweight_count= 0
- for vertexWeight in vWeightDict:
- items= vertexWeight.items()
- for group, weight in items:
- if weight < limit:
- del vertexWeight[group]
- rem_vweight_count+= 1
-
- return rem_vweight_count
-
-
-def normalize_vweight(me, groupNames, vWeightDict):
- for vertexWeight in vWeightDict:
- unit= 0.0
- for group, weight in vertexWeight.iteritems():
- unit+= weight
-
- if unit != 1.0 and unit != 0.0:
- for group, weight in vertexWeight.iteritems():
- vertexWeight[group]= weight/unit
-
-def isnan(f):
- fstring = str(f).lower()
- if 'nan' in fstring:
- return True
- if 'inf' in fstring:
- return True
-
- return False
-
-def fix_nan_verts__internal(me):
- rem_nan = 0
- for v in me.verts:
- co = v.co
- for i in (0,1,2):
- if isnan(co[i]):
- co[i] = 0.0
- rem_nan += 1
- return rem_nan
-
-def fix_nan_verts(me):
- rem_nan = 0
- key = me.key
- if key:
- # Find the object, and get a mesh thats thinked to the oblink.
- # this is a bit crap but needed to set the active key.
- me_oblink = None
- for ob in bpy.data.objects:
- me_oblink = ob.getData(mesh=1)
- if me_oblink == me:
- me = me_oblink
- break
- if not me_oblink:
- ob = None
-
- if key and ob:
- blocks = key.blocks
- # print blocks
- orig_pin = ob.pinShape
- orig_shape = ob.activeShape
- orig_relative = key.relative
- ob.pinShape = True
- for i, block in enumerate(blocks):
- ob.activeShape = i+1
- ob.makeDisplayList()
- rem_nan += fix_nan_verts__internal(me)
- me.update(block.name) # get the new verts
- ob.pinShape = orig_pin
- ob.activeShape = orig_shape
- key.relative = orig_relative
-
- else: # No keys, simple operation
- rem_nan = fix_nan_verts__internal(me)
-
- return rem_nan
-
-def fix_nan_uvs(me):
- rem_nan = 0
- if me.faceUV:
- orig_uvlayer = me.activeUVLayer
- for uvlayer in me.getUVLayerNames():
- me.activeUVLayer = uvlayer
- for f in me.faces:
- for uv in f.uv:
- for i in (0,1):
- if isnan(uv[i]):
- uv[i] = 0.0
- rem_nan += 1
- me.activeUVLayer = orig_uvlayer
- return rem_nan
-
-
-def has_vcol(me):
- for f in me.faces:
- for col in f.col:
- if not (255 == col.r == col.g == col.b):
- return True
- return False
-
-def rem_white_vcol_layers(me):
- vcols_removed = 0
- if me.vertexColors:
- for col in me.getColorLayerNames():
- me.activeColorLayer = col
- if not has_vcol(me):
- me.removeColorLayer(col)
- vcols_removed += 1
-
- return vcols_removed
-
-
-def main():
- sce= bpy.data.scenes.active
- obsel= list(sce.objects.context)
- actob= sce.objects.active
-
- is_editmode= Window.EditMode()
-
- # Edit mode object is not active, add it to the list.
- if is_editmode and (not actob.sel):
- obsel.append(actob)
-
-
- #====================================#
- # Popup menu to select the functions #
- #====================================#
-
- CLEAN_ALL_DATA= Draw.Create(0)
- CLEAN_VERTS_FREE= Draw.Create(1)
- CLEAN_EDGE_NOFACE= Draw.Create(0)
- CLEAN_EDGE_SMALL= Draw.Create(0)
- CLEAN_FACE_PERIMETER= Draw.Create(0)
- CLEAN_FACE_SMALL= Draw.Create(0)
-
- CLEAN_MATERIALS= Draw.Create(0)
- CLEAN_WHITE_VCOL_LAYERS= Draw.Create(0)
- CLEAN_GROUP= Draw.Create(0)
- CLEAN_VWEIGHT= Draw.Create(0)
- CLEAN_WEIGHT_NORMALIZE= Draw.Create(0)
- limit= Draw.Create(0.01)
-
- CLEAN_NAN_VERTS= Draw.Create(0)
- CLEAN_NAN_UVS= Draw.Create(0)
-
- # Get USER Options
-
- pup_block= [\
- ('Verts: free', CLEAN_VERTS_FREE, 'Remove verts that are not used by an edge or a face.'),\
- ('Edges: free', CLEAN_EDGE_NOFACE, 'Remove edges that are not in a face.'),\
- ('Edges: short', CLEAN_EDGE_SMALL, 'Remove edges that are below the length limit.'),\
- ('Faces: small perimeter', CLEAN_FACE_PERIMETER, 'Remove faces below the perimeter limit.'),\
- ('Faces: small area', CLEAN_FACE_SMALL, 'Remove faces below the area limit (may remove faces stopping T-face artifacts).'),\
- ('limit: ', limit, 0.001, 1.0, 'Limit for the area and length tests above (a higher limit will remove more data).'),\
- ('Material Clean', CLEAN_MATERIALS, 'Remove unused materials.'),\
- ('Color Layers', CLEAN_WHITE_VCOL_LAYERS, 'Remove vertex color layers that are totaly white'),\
- ('VGroup Clean', CLEAN_GROUP, 'Remove vertex groups that have no verts using them.'),\
- ('Weight Clean', CLEAN_VWEIGHT, 'Remove zero weighted verts from groups (limit is zero threshold).'),\
- ('WeightNormalize', CLEAN_WEIGHT_NORMALIZE, 'Make the sum total of vertex weights accross vgroups 1.0 for each vertex.'),\
- 'Clean NAN values',\
- ('NAN Verts', CLEAN_NAN_VERTS, 'Make NAN or INF verts (0,0,0)'),\
- ('NAN UVs', CLEAN_NAN_UVS, 'Make NAN or INF UVs (0,0)'),\
- '',\
- ('All Mesh Data', CLEAN_ALL_DATA, 'Warning! Operate on ALL mesh objects in your Blend file. Use with care'),\
- ]
-
- if not Draw.PupBlock('Clean Selected Meshes...', pup_block):
- return
-
- CLEAN_VERTS_FREE= CLEAN_VERTS_FREE.val
- CLEAN_EDGE_NOFACE= CLEAN_EDGE_NOFACE.val
- CLEAN_EDGE_SMALL= CLEAN_EDGE_SMALL.val
- CLEAN_FACE_PERIMETER= CLEAN_FACE_PERIMETER.val
- CLEAN_FACE_SMALL= CLEAN_FACE_SMALL.val
- CLEAN_MATERIALS= CLEAN_MATERIALS.val
- CLEAN_WHITE_VCOL_LAYERS= CLEAN_WHITE_VCOL_LAYERS.val
- CLEAN_GROUP= CLEAN_GROUP.val
- CLEAN_VWEIGHT= CLEAN_VWEIGHT.val
- CLEAN_WEIGHT_NORMALIZE= CLEAN_WEIGHT_NORMALIZE.val
- limit= limit.val
- CLEAN_ALL_DATA= CLEAN_ALL_DATA.val
- CLEAN_NAN_VERTS= CLEAN_NAN_VERTS.val
- CLEAN_NAN_UVS= CLEAN_NAN_UVS.val
-
- if is_editmode: Window.EditMode(0)
-
- if CLEAN_ALL_DATA:
- if CLEAN_GROUP or CLEAN_VWEIGHT or CLEAN_WEIGHT_NORMALIZE:
- # For groups we need the objects linked to the mesh
- meshes= [ob.getData(mesh=1) for ob in bpy.data.objects if ob.type == 'Mesh' if not ob.lib]
- else:
- meshes= bpy.data.meshes
- else:
- meshes= [ob.getData(mesh=1) for ob in obsel if ob.type == 'Mesh']
-
- tot_meshes = len(meshes) # so we can decrement libdata
- rem_face_count= rem_edge_count= rem_vert_count= rem_material_count= rem_vcol_layer_count= rem_group_count= rem_vweight_count= fix_nan_vcount= fix_nan_uvcount= 0
- if not meshes:
- if is_editmode: Window.EditMode(1)
- Draw.PupMenu('No meshes to clean')
-
- Blender.Window.WaitCursor(1)
- bpy.data.meshes.tag = False
- for me in meshes:
-
- # Dont touch the same data twice
- if me.tag:
- tot_meshes -= 1
- continue
- me.tag = True
-
- if me.lib:
- tot_meshes -= 1
- continue
-
- if me.multires:
- multires_level_orig = me.multiresDrawLevel
- me.multiresDrawLevel = 1
- print 'Warning, cannot perform destructive operations on multires mesh:', me.name
- else:
- if CLEAN_FACE_SMALL:
- rem_face_count += rem_area_faces(me, limit)
-
- if CLEAN_FACE_PERIMETER:
- rem_face_count += rem_perimeter_faces(me, limit)
-
- if CLEAN_EDGE_SMALL: # for all use 2- remove all edges.
- rem_edge_count += rem_free_edges(me, limit)
-
- if CLEAN_EDGE_NOFACE:
- rem_edge_count += rem_free_edges(me)
-
- if CLEAN_VERTS_FREE:
- rem_vert_count += rem_free_verts(me)
-
- if CLEAN_MATERIALS:
- rem_material_count += rem_unused_materials(me)
-
- if CLEAN_WHITE_VCOL_LAYERS:
- rem_vcol_layer_count += rem_white_vcol_layers(me)
-
- if CLEAN_VWEIGHT or CLEAN_GROUP or CLEAN_WEIGHT_NORMALIZE:
- groupNames, vWeightDict= meshWeight2Dict(me)
-
- if CLEAN_VWEIGHT:
- rem_vweight_count += rem_zero_weights(me, limit, groupNames, vWeightDict)
-
- if CLEAN_GROUP:
- rem_group_count += rem_free_groups(me, groupNames, vWeightDict)
- pass
-
- if CLEAN_WEIGHT_NORMALIZE:
- normalize_vweight(me, groupNames, vWeightDict)
-
- # Copy back to mesh vertex groups.
- dict2MeshWeight(me, groupNames, vWeightDict)
-
- if CLEAN_NAN_VERTS:
- fix_nan_vcount = fix_nan_verts(me)
-
- if CLEAN_NAN_UVS:
- fix_nan_uvcount = fix_nan_uvs(me)
-
- # restore multires.
- if me.multires:
- me.multiresDrawLevel = multires_level_orig
-
- Blender.Window.WaitCursor(0)
- if is_editmode: Window.EditMode(0)
- stat_string= 'Removed from ' + str(tot_meshes) + ' Mesh(es)%t|'
-
- if CLEAN_VERTS_FREE: stat_string+= 'Verts: %i|' % rem_vert_count
- if CLEAN_EDGE_SMALL or CLEAN_EDGE_NOFACE: stat_string+= 'Edges: %i|' % rem_edge_count
- if CLEAN_FACE_SMALL or CLEAN_FACE_PERIMETER: stat_string+= 'Faces: %i|' % rem_face_count
- if CLEAN_MATERIALS: stat_string+= 'Materials: %i|' % rem_material_count
- if CLEAN_WHITE_VCOL_LAYERS: stat_string+= 'Color Layers: %i|' % rem_vcol_layer_count
- if CLEAN_VWEIGHT: stat_string+= 'VWeights: %i|' % rem_vweight_count
- if CLEAN_GROUP: stat_string+= 'VGroups: %i|' % rem_group_count
- if CLEAN_NAN_VERTS: stat_string+= 'Vert Nan Fix: %i|' % fix_nan_vcount
- if CLEAN_NAN_UVS: stat_string+= 'UV Nan Fix: %i|' % fix_nan_uvcount
- Draw.PupMenu(stat_string)
-
-
-if __name__ == '__main__':
- main() \ No newline at end of file