Select interior faces, access from the mesh select menu
authorCampbell Barton <ideasman42@gmail.com>
Thu, 5 Nov 2009 12:37:49 +0000 (12:37 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 5 Nov 2009 12:37:49 +0000 (12:37 +0000)
new mesh functions, remove duplicates in uvproject and mesh_skin
- face.edge_keys()
- edge.key()
- mesh.edge_face_count()
- mesh.edge_face_count_dict()

release/scripts/modules/bpy_ext/Mesh.py [new file with mode: 0644]
release/scripts/modules/bpy_ext/__init__.py
release/scripts/op/mesh.py [new file with mode: 0644]
release/scripts/op/mesh_skin.py
release/scripts/op/uvcalc_smart_project.py
release/scripts/ui/space_view3d.py

diff --git a/release/scripts/modules/bpy_ext/Mesh.py b/release/scripts/modules/bpy_ext/Mesh.py
new file mode 100644 (file)
index 0000000..961ff83
--- /dev/null
@@ -0,0 +1,72 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  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 LICENSE BLOCK #####
+
+def ord_ind(i1,i2):
+    if i1<i2: return i1,i2
+    return i2,i1
+    
+def edge_key(ed):
+    v1, v2 = tuple(ed.verts)
+    return ord_ind(v1, v2)
+
+def face_edge_keys(face):
+    verts = tuple(face.verts)
+    if len(verts)==3:
+        return ord_ind(verts[0], verts[1]),  ord_ind(verts[1], verts[2]),  ord_ind(verts[2], verts[0])
+    
+    return ord_ind(verts[0], verts[1]),  ord_ind(verts[1], verts[2]),  ord_ind(verts[2], verts[3]),  ord_ind(verts[3], verts[0])
+
+def mesh_edge_keys(mesh):
+    return [edge_key for face in mesh.faces for edge_key in face.edge_keys()]
+
+def mesh_edge_face_count_dict(mesh, face_edge_keys=None):
+    
+    # Optional speedup
+    if face_edge_keys==None:
+        face_edge_keys = [face.edge_keys() for face in face_list]
+        
+    face_edge_count = {}
+    for face_keys in face_edge_keys:
+        for key in face_keys:
+            try:
+                face_edge_count[key] += 1
+            except:
+                face_edge_count[key] = 1
+    
+    
+    return face_edge_count
+
+def mesh_edge_face_count(mesh, face_edge_keys=None):
+    edge_face_count_dict = mesh.edge_face_count_dict(face_edge_keys)
+    return [edge_face_count_dict.get(ed.key(), 0) for ed in mesh.edges]
+
+import bpy
+
+# * Edge *
+class_obj = bpy.types.MeshEdge
+class_obj.key = edge_key
+
+# * Face *
+class_obj = bpy.types.MeshFace
+class_obj.edge_keys = face_edge_keys
+
+# * Mesh *
+class_obj = bpy.types.Mesh
+class_obj.edge_keys = mesh_edge_keys
+class_obj.edge_face_count = mesh_edge_face_count
+class_obj.edge_face_count_dict = mesh_edge_face_count_dict
index 4198205e54272f7c41c1b6f03f9f5a80f43f3877..435c545dc757d6d005ad1da1546c3c2979f5e95e 100644 (file)
@@ -17,3 +17,4 @@
 # ##### END GPL LICENSE BLOCK #####
 
 import bpy_ext.Object
+import bpy_ext.Mesh
diff --git a/release/scripts/op/mesh.py b/release/scripts/op/mesh.py
new file mode 100644 (file)
index 0000000..8ea9ea0
--- /dev/null
@@ -0,0 +1,71 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  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 LICENSE BLOCK #####
+
+import bpy
+
+def main(context):
+    ob = context.active_object
+    bpy.ops.mesh.selection_type(type='FACE')
+    is_editmode = (ob.mode=='EDIT')
+    if is_editmode:
+        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
+
+    mesh = ob.data
+    
+    face_list = [face for face in mesh.faces]
+    face_edge_keys = [face.edge_keys() for face in face_list]
+
+    edge_face_count = mesh.edge_face_count_dict(face_edge_keys)
+    
+    def test_interior(index):
+        for key in face_edge_keys[index]:
+            if edge_face_count[key] < 3:
+                return False
+        return True
+
+    for index, face in enumerate(face_list):
+        if(test_interior(index)):
+            face.selected = True
+        else:
+            face.selected = False
+
+    if is_editmode:
+        bpy.ops.object.mode_set(mode='EDIT', toggle=False)
+
+class MeshSelectInteriorFaces(bpy.types.Operator):
+    '''Select faces where all edges have more then 2 face users.'''
+
+    bl_idname = "mesh.faces_select_interior"
+    bl_label = "Select Interior Faces"
+    bl_register = True
+    bl_undo = True
+
+    def poll(self, context):
+        ob = context.active_object
+        return (ob and ob.type == 'MESH')
+
+    def execute(self, context):
+        main(context)
+        return ('FINISHED',)
+
+
+# Register the operator
+bpy.ops.add(MeshSelectInteriorFaces)
+
+if __name__ == "__main__":
+    bpy.ops.mesh.faces_select_interior()
index 04543cbef3a670d879226bda80ee7da6d553e8e0..85df6463eb0a78823480ea253ec86802a4857238 100644 (file)
@@ -222,22 +222,6 @@ class edgeLoop(object):
 
 # Returns face edges.
 # face must have edge data.
-
-# Utility funcs for 2.5, make into a module??
-def ord_ind(i1,i2):
-       if i1<i2: return i1,i2
-       return i2,i1
-       
-def edge_key(ed):
-       v1,v2 = tuple(ed.verts)
-       return ord_ind(v1, v2)
-
-def face_edge_keys(f):
-       verts  = tuple(f.verts)
-       if len(verts)==3:
-               return ord_ind(verts[0], verts[1]),  ord_ind(verts[1], verts[2]),  ord_ind(verts[2], verts[0])
-       
-       return ord_ind(verts[0], verts[1]),  ord_ind(verts[1], verts[2]),  ord_ind(verts[2], verts[3]),  ord_ind(verts[3], verts[0])
        
 def mesh_faces_extend(me, faces, mat_idx = 0):
        orig_facetot = len(me.faces)
@@ -272,15 +256,15 @@ def getSelectedEdges(context, me, ob):
        if MESH_MODE == 'FACE':
                context.scene.tool_settings.mesh_selection_mode = 'EDGE'
                # value is [edge, face_sel_user_in]
-               edge_dict=  dict((edge_key(ed), [ed, 0]) for ed in me.edges)
+               edge_dict=  dict((ed.key(), [ed, 0]) for ed in me.edges)
                
                for f in me.faces:
-                       if f.sel:
-                               for edkey in face_edge_keys(f):
+                       if f.selected:
+                               for edkey in f.edge_keys():
                                        edge_dict[edkey][1] += 1
                
                context.scene.tool_settings.mesh_selection_mode = MESH_MODE
-               return [ ed_data[0] for ed_data in edge_dict.itervalues() if ed_data[1] == 1 ]
+               return [ ed_data[0] for ed_data in edge_dict.values() if ed_data[1] == 1 ]
        
        
 
@@ -296,7 +280,7 @@ def getVertLoops(selEdges, me):
        vert_used = [False] * tot
        
        for ed in selEdges:
-               i1, i2 = edge_key(ed)
+               i1, i2 = ed.key()
                vert_siblings[i1].append(i2)
                vert_siblings[i2].append(i1)
        
index 328470a5ec58a42f6a7d00ca975f539830bcc7aa..454cb2f23ecdab75892b1618a11f18604b3dc05c 100644 (file)
@@ -789,23 +789,6 @@ def VectoMat(vec):
        return Matrix([a1[0], a1[1], a1[2]], [a2[0], a2[1], a2[2]], [a3[0], a3[1], a3[2]])
 
 
-# Utility funcs for 2.5, make into a module??
-def ord_ind(i1,i2):
-       if i1<i2: return i1,i2
-       return i2,i1
-       
-def edge_key(ed):
-       v1,v2 = tuple(ed.verts)
-       return ord_ind(v1, v2)
-
-def face_edge_keys(f):
-       verts  = tuple(f.verts)
-       if len(verts)==3:
-               return ord_ind(verts[0], verts[1]),  ord_ind(verts[1], verts[2]),  ord_ind(verts[2], verts[0])
-       
-       return ord_ind(verts[0], verts[1]),  ord_ind(verts[1], verts[2]),  ord_ind(verts[2], verts[3]),  ord_ind(verts[3], verts[0])
-
-
 class thickface(object):
        __slost__= 'v', 'uv', 'no', 'area', 'edge_keys'
        def __init__(self, face, uvface, mesh_verts):
@@ -817,7 +800,7 @@ class thickface(object):
                        
                self.no = face.normal
                self.area = face.area
-               self.edge_keys = face_edge_keys(face)
+               self.edge_keys = face.edge_keys()
 
 global ob
 ob = None
index 1567da12173310dc3d96a4e2b4ef0a342f2e1a56..c19b02ffaf0f7a4fb5cc9305a54ec046d380f90b 100644 (file)
@@ -302,6 +302,7 @@ class VIEW3D_MT_select_edit_mesh(bpy.types.Menu):
         layout.itemO("mesh.select_random", text="Random...")
         layout.itemO("mesh.edges_select_sharp", text="Sharp Edges")
         layout.itemO("mesh.faces_select_linked_flat", text="Linked Flat Faces")
+        layout.itemO("mesh.faces_select_interior", text="Interior Faces")
 
         layout.itemS()