forked from bartvdbraak/blender
Select interior faces, access from the mesh select menu
new mesh functions, remove duplicates in uvproject and mesh_skin - face.edge_keys() - edge.key() - mesh.edge_face_count() - mesh.edge_face_count_dict()
This commit is contained in:
parent
247f72fcc0
commit
be4ceb5fdf
72
release/scripts/modules/bpy_ext/Mesh.py
Normal file
72
release/scripts/modules/bpy_ext/Mesh.py
Normal file
@ -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
|
@ -17,3 +17,4 @@
|
|||||||
# ##### END GPL LICENSE BLOCK #####
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
import bpy_ext.Object
|
import bpy_ext.Object
|
||||||
|
import bpy_ext.Mesh
|
||||||
|
71
release/scripts/op/mesh.py
Normal file
71
release/scripts/op/mesh.py
Normal file
@ -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()
|
@ -222,22 +222,6 @@ class edgeLoop(object):
|
|||||||
|
|
||||||
# Returns face edges.
|
# Returns face edges.
|
||||||
# face must have edge data.
|
# 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):
|
def mesh_faces_extend(me, faces, mat_idx = 0):
|
||||||
orig_facetot = len(me.faces)
|
orig_facetot = len(me.faces)
|
||||||
@ -272,15 +256,15 @@ def getSelectedEdges(context, me, ob):
|
|||||||
if MESH_MODE == 'FACE':
|
if MESH_MODE == 'FACE':
|
||||||
context.scene.tool_settings.mesh_selection_mode = 'EDGE'
|
context.scene.tool_settings.mesh_selection_mode = 'EDGE'
|
||||||
# value is [edge, face_sel_user_in]
|
# 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:
|
for f in me.faces:
|
||||||
if f.sel:
|
if f.selected:
|
||||||
for edkey in face_edge_keys(f):
|
for edkey in f.edge_keys():
|
||||||
edge_dict[edkey][1] += 1
|
edge_dict[edkey][1] += 1
|
||||||
|
|
||||||
context.scene.tool_settings.mesh_selection_mode = MESH_MODE
|
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
|
vert_used = [False] * tot
|
||||||
|
|
||||||
for ed in selEdges:
|
for ed in selEdges:
|
||||||
i1, i2 = edge_key(ed)
|
i1, i2 = ed.key()
|
||||||
vert_siblings[i1].append(i2)
|
vert_siblings[i1].append(i2)
|
||||||
vert_siblings[i2].append(i1)
|
vert_siblings[i2].append(i1)
|
||||||
|
|
||||||
|
@ -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]])
|
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):
|
class thickface(object):
|
||||||
__slost__= 'v', 'uv', 'no', 'area', 'edge_keys'
|
__slost__= 'v', 'uv', 'no', 'area', 'edge_keys'
|
||||||
def __init__(self, face, uvface, mesh_verts):
|
def __init__(self, face, uvface, mesh_verts):
|
||||||
@ -817,7 +800,7 @@ class thickface(object):
|
|||||||
|
|
||||||
self.no = face.normal
|
self.no = face.normal
|
||||||
self.area = face.area
|
self.area = face.area
|
||||||
self.edge_keys = face_edge_keys(face)
|
self.edge_keys = face.edge_keys()
|
||||||
|
|
||||||
global ob
|
global ob
|
||||||
ob = None
|
ob = None
|
||||||
|
@ -302,6 +302,7 @@ class VIEW3D_MT_select_edit_mesh(bpy.types.Menu):
|
|||||||
layout.itemO("mesh.select_random", text="Random...")
|
layout.itemO("mesh.select_random", text="Random...")
|
||||||
layout.itemO("mesh.edges_select_sharp", text="Sharp Edges")
|
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_linked_flat", text="Linked Flat Faces")
|
||||||
|
layout.itemO("mesh.faces_select_interior", text="Interior Faces")
|
||||||
|
|
||||||
layout.itemS()
|
layout.itemS()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user