diff options
Diffstat (limited to 'release/scripts/mesh_poly_reduce_grid.py')
-rw-r--r-- | release/scripts/mesh_poly_reduce_grid.py | 351 |
1 files changed, 0 insertions, 351 deletions
diff --git a/release/scripts/mesh_poly_reduce_grid.py b/release/scripts/mesh_poly_reduce_grid.py deleted file mode 100644 index 2903909027a..00000000000 --- a/release/scripts/mesh_poly_reduce_grid.py +++ /dev/null @@ -1,351 +0,0 @@ -#!BPY -""" -Name: 'Poly Reduce Selection (Unsubsurf)' -Blender: 245 -Group: 'Mesh' -Tooltip: 'predictable mesh simplifaction maintaining face loops' -""" - -from Blender import Scene, Mesh, Window, sys -import BPyMessages -import bpy - -# ***** 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 ***** -# -------------------------------------------------------------------------- - - -def my_mesh_util(me): - me_verts = me.verts - - vert_faces = [ [] for v in me_verts] - vert_faces_corner = [ [] for v in me_verts] - - - # Ignore topology where there are not 2 faces connected to an edge. - edge_count = {} - for f in me.faces: - for edkey in f.edge_keys: - try: - edge_count[edkey] += 1 - except: - edge_count[edkey] = 1 - - for edkey, count in edge_count.iteritems(): - - # Ignore verts that connect to edges with more than 2 faces. - if count != 2: - vert_faces[edkey[0]] = None - vert_faces[edkey[1]] = None - # Done - - - - def faces_set_verts(face_ls): - unique_verts = set() - for f in face_ls: - for v in f: - unique_verts.add(v.index) - return unique_verts - - for f in me.faces: - for corner, v in enumerate(f): - i = v.index - if vert_faces[i] != None: - vert_faces[i].append(f) - vert_faces_corner[i].append( corner ) - - grid_data_ls = [] - - for vi, face_ls in enumerate(vert_faces): - if face_ls != None: - if len(face_ls) == 4: - if face_ls[0].sel and face_ls[1].sel and face_ls[2].sel and face_ls[3].sel: - # Support triangles also - unique_vert_count = len(faces_set_verts(face_ls)) - quads = 0 - for f in face_ls: - if len(f) ==4: - quads += 1 - if unique_vert_count==5+quads: # yay we have a grid - grid_data_ls.append( (vi, face_ls) ) - - elif len(face_ls) == 3: - if face_ls[0].sel and face_ls[1].sel and face_ls[2].sel: - unique_vert_count = len(faces_set_verts(face_ls)) - if unique_vert_count==4: # yay we have 3 triangles to make into a bigger triangle - grid_data_ls.append( (vi, face_ls) ) - - - - # Now sort out which grid faces to use - - - # This list will be used for items we can convert, vertex is key, faces are values - grid_data_dict = {} - - if not grid_data_ls: - print "doing nothing" - return - - # quick lookup for the opposing corner of a qiad - quad_diag_mapping = 2,3,0,1 - - verts_used = [0] * len(me_verts) # 0 == untouched, 1==should touch, 2==touched - verts_used[grid_data_ls[0][0]] = 1 # start touching 1! - - # From the corner vert, get the 2 edges that are not the corner or its opposing vert, this edge will make a new face - quad_edge_mapping = (1,3), (2,0), (1,3), (0,2) # hi-low, low-hi order is intended - tri_edge_mapping = (1,2), (0,2), (0,1) - - done_somthing = True - while done_somthing: - done_somthing = False - grid_data_ls_index = -1 - - for vi, face_ls in grid_data_ls: - grid_data_ls_index += 1 - if len(face_ls) == 3: - grid_data_dict[vi] = face_ls - grid_data_ls.pop( grid_data_ls_index ) - break - elif len(face_ls) == 4: - # print vi - if verts_used[vi] == 1: - verts_used[vi] = 2 # dont look at this again. - done_somthing = True - - grid_data_dict[vi] = face_ls - - # Tag all faces verts as used - - for i, f in enumerate(face_ls): - # i == face index on vert, needed to recall which corner were on. - v_corner = vert_faces_corner[vi][i] - fv =f.v - - if len(f) == 4: - v_other = quad_diag_mapping[v_corner] - # get the 2 other corners - corner1, corner2 = quad_edge_mapping[v_corner] - if verts_used[fv[v_other].index] == 0: - verts_used[fv[v_other].index] = 1 # TAG for touching! - else: - corner1, corner2 = tri_edge_mapping[v_corner] - - verts_used[fv[corner1].index] = 2 # Dont use these, they are - verts_used[fv[corner2].index] = 2 - - - # remove this since we have used it. - grid_data_ls.pop( grid_data_ls_index ) - - break - - if done_somthing == False: - # See if there are any that have not even been tagged, (probably on a different island), then tag them. - - for vi, face_ls in grid_data_ls: - if verts_used[vi] == 0: - verts_used[vi] = 1 - done_somthing = True - break - - - # Now we have all the areas we will fill, calculate corner triangles we need to fill in. - new_faces = [] - quad_del_vt_map = (1,2,3), (0,2,3), (0,1,3), (0,1,2) - for vi, face_ls in grid_data_dict.iteritems(): - for i, f in enumerate(face_ls): - if len(f) == 4: - # i == face index on vert, needed to recall which corner were on. - v_corner = vert_faces_corner[vi][i] - v_other = quad_diag_mapping[v_corner] - fv =f.v - - #print verts_used[fv[v_other].index] - #if verts_used[fv[v_other].index] != 2: # DOSNT WORK ALWAYS - - if 1: # THIS IS LAzY - some of these faces will be removed after adding. - # Ok we are removing half of this face, add the other half - - # This is probably slower - # new_faces.append( [fv[ii].index for ii in (0,1,2,3) if ii != v_corner ] ) - - # do this instead - new_faces.append( (fv[quad_del_vt_map[v_corner][0]], fv[quad_del_vt_map[v_corner][1]], fv[quad_del_vt_map[v_corner][2]]) ) - - del grid_data_ls - - - # me.sel = 0 - def faceCombine4(vi, face_ls): - edges = [] - - for i, f in enumerate(face_ls): - fv = f.v - v_corner = vert_faces_corner[vi][i] - if len(f)==4: ed = quad_edge_mapping[v_corner] - else: ed = tri_edge_mapping[v_corner] - - edges.append( [fv[ed[0]].index, fv[ed[1]].index] ) - - # get the face from the edges - face = edges.pop() - while len(face) != 4: - # print len(edges), edges, face - for ed_idx, ed in enumerate(edges): - if face[-1] == ed[0] and (ed[1] != face[0]): - face.append(ed[1]) - elif face[-1] == ed[1] and (ed[0] != face[0]): - face.append(ed[0]) - else: - continue - - edges.pop(ed_idx) # we used the edge alredy - break - - return face - - for vi, face_ls in grid_data_dict.iteritems(): - if len(face_ls) == 4: - new_faces.append( faceCombine4(vi, face_ls) ) - #pass - if len(face_ls) == 3: # 3 triangles - face = list(faces_set_verts(face_ls)) - face.remove(vi) - new_faces.append( face ) - - - # Now remove verts surounded by 3 triangles - - - - # print new_edges - # me.faces.extend(new_faces, ignoreDups=True) - - ''' - faces_remove = [] - for vi, face_ls in grid_data_dict.iteritems(): - faces_remove.extend(face_ls) - ''' - - orig_facelen = len(me.faces) - - orig_faces = list(me.faces) - me.faces.extend(new_faces, ignoreDups=True) - new_faces = list(me.faces)[len(orig_faces):] - - - - - - if me.faceUV: - uvnames = me.getUVLayerNames() - act_uvlay = me.activeUVLayer - - vert_faces_uvs = [] - vert_faces_images = [] - - - act_uvlay = me.activeUVLayer - - for uvlay in uvnames: - me.activeUVLayer = uvlay - vert_faces_uvs[:] = [None] * len(me.verts) - vert_faces_images[:] = vert_faces_uvs[:] - - for i,f in enumerate(orig_faces): - img = f.image - fv = f.v - uv = f.uv - mat = f.mat - for i,v in enumerate(fv): - vi = v.index - vert_faces_uvs[vi] = uv[i] # no nice averaging - vert_faces_images[vi] = img - - - # Now copy UVs across - for f in new_faces: - fi = [v.index for v in f.v] - f.image = vert_faces_images[fi[0]] - uv = f.uv - for i,vi in enumerate(fi): - uv[i][:] = vert_faces_uvs[vi] - - if len(me.materials) > 1: - vert_faces_mats = [None] * len(me.verts) - for i,f in enumerate(orig_faces): - mat = f.mat - for i,v in enumerate(f.v): - vi = v.index - vert_faces_mats[vi] = mat - - # Now copy UVs across - for f in new_faces: - print vert_faces_mats[f.v[0].index] - f.mat = vert_faces_mats[f.v[0].index] - - - me.verts.delete(grid_data_dict.keys()) - - # me.faces.delete(1, faces_remove) - - if me.faceUV: - me.activeUVLayer = act_uvlay - - me.calcNormals() - -def main(): - - # Gets the current scene, there can be many scenes in 1 blend file. - sce = bpy.data.scenes.active - - # Get the active object, there can only ever be 1 - # and the active object is always the editmode object. - ob_act = sce.objects.active - - if not ob_act or ob_act.type != 'Mesh': - BPyMessages.Error_NoMeshActive() - return - - is_editmode = Window.EditMode() - if is_editmode: Window.EditMode(0) - - Window.WaitCursor(1) - me = ob_act.getData(mesh=1) # old NMesh api is default - t = sys.time() - - # Run the mesh editing function - my_mesh_util(me) - - # Restore editmode if it was enabled - if is_editmode: Window.EditMode(1) - - # Timing the script is a good way to be aware on any speed hits when scripting - print 'My Script finished in %.2f seconds' % (sys.time()-t) - Window.WaitCursor(0) - - -# This lets you can import the script without running it -if __name__ == '__main__': - main() - |