From a4c2492d6e011079ebc7f5c0fd70f9673cb01ddf Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 16 Jun 2006 10:59:56 +0000 Subject: Updated this script and added some functions, this wont effect eny existing python tools. added functions pickMeshRayFace(me, orig, dir): pickMeshGroupWeight(me, act_group, orig, dir): pickMeshGroupVCol(me, orig, dir): facePlanerIslands(me): edgeFaceUserCount(me, faces= None): --- release/scripts/bpymodules/BPyMesh.py | 230 ++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) (limited to 'release') diff --git a/release/scripts/bpymodules/BPyMesh.py b/release/scripts/bpymodules/BPyMesh.py index 258cdcc0203..623ca7a9225 100644 --- a/release/scripts/bpymodules/BPyMesh.py +++ b/release/scripts/bpymodules/BPyMesh.py @@ -191,6 +191,236 @@ def getMeshFromObject(ob, container_mesh=None, apply_modifiers=True, vgroups=Tru return mesh +def faceRayIntersect(f, orig, dir): + ''' + Returns face, side + Side is the side of a quad we intersect. + side 0 == 0,1,2 + side 1 == 0,2,3 + ''' + f_v= f.v + isect= Blender.Mathutils.Intersect(f_v[0].co, f_v[1].co, f_v[2].co, dir, orig, 1) # 1==clip + + if isect: + return isect, 0 + + if len(f_v)==4: + isect= Blender.Mathutils.Intersect(f_v[0].co, f_v[2].co, f_v[3].co, dir, orig, 1) # 1==clip + if isect: + return isect, 1 + return False, 0 + + +def pickMeshRayFace(me, orig, dir): + best_dist= 1<<30 + best_isect= best_side= best_face= None + for f in me.faces: + isect, side= faceRayIntersect(f, orig, dir) + if isect: + dist= (isect-orig).length + if disti2: + i1,i2= i2,i1 + return i1, i2 + +def edge_face_users(me): + ''' + Takesa mesh and returns a list aligned with the meshes edges. + Each item is a list of the faces that use the edge + would be the equiv for having ed.face_users as a property + ''' + + face_edges_dict= dict([(sorted_edge_indicies(ed), (ed.index, [])) for ed in me.edges]) + for f in me.faces: + fvi= [v.index for v in f.v]# face vert idx's + for i in xrange(len(f)): + i1= fvi[i] + i2= fvi[i-1] + + if i1>i2: + i1,i2= i2,i1 + + face_edges_dict[i1,i2][1].append(f) + + face_edges= [None] * len(me.edges) + for ed_index, ed_faces in face_edges_dict.itervalues(): + face_edges[ed_index]= ed_faces + + return face_edges + + +def face_edges(me): + ''' + Returns a list alligned to the meshes faces. + each item is a list of lists: that is + face_edges -> face indicies + face_edges[i] -> list referencs local faces v indicies 1,2,3 &| 4 + face_edges[i][j] -> list of faces that this edge uses. + crap this is tricky to explain :/ + ''' + face_edges= [ [None] * len(f) for f in me.faces ] + + face_edges_dict= dict([(sorted_edge_indicies(ed), []) for ed in me.edges]) + for fidx, f in enumerate(me.faces): + fvi= [v.index for v in f.v]# face vert idx's + for i in xrange(len(f)): + i1= fvi[i] + i2= fvi[i-1] + + if i1>i2: + i1,i2= i2,i1 + + edge_face_users= face_edges_dict[i1,i2] + edge_face_users.append(f) + + face_edges[fidx][i]= edge_face_users + + return face_edges + + +def facePlanerIslands(me): + DotVecs= Blender.Mathutils.DotVecs + + def roundvec(v): + return round(v[0], 4), round(v[1], 4), round(v[2], 4) + + face_props= [(cent, no, roundvec(no), DotVecs(cent, no)) for f in me.faces for no, cent in ((f.no, f.cent),)] + + face_edge_users= face_edges(me) + islands= [] + + used_faces= [0] * len(me.faces) + while True: + new_island= False + for i, used_val in enumerate(used_faces): + if used_val==0: + island= set() + island.add(i) + new_island= True + used_faces[i]= 1 + break + + if not new_island: + break + + island_growing= True + while island_growing: + island_growing= False + for fidx1 in list(island): + if used_faces[fidx1]==1: + used_faces[fidx1]= 2 + face_prop1= face_props[fidx1] + for ed in face_edge_users[fidx1]: + for f2 in ed: + fidx2= f2.index + if fidx1 != fidx2 and used_faces[fidx2]==0: + island_growing= True + face_prop2= face_props[fidx2] + # normals are the same? + if face_prop1[2]==face_prop2[2]: + if abs(face_prop1[3] - DotVecs(face_prop1[1], face_prop2[0])) < 0.000001: + used_faces[fidx2]= 1 + island.add(fidx2) + tmp= [me.faces[i] for i in island] + islands.append(tmp) + return islands + +def edgeFaceUserCount(me, faces= None): + ''' + Return an edge aligned list with the count for all the faces that use that edge. - + can spesify a subset of the faces, so only those will be counted. + ''' + if faces==None: + faces= me.faces + max_vert= len(me.verts) + else: + # find the lighest vert index + pass + + edge_users= [0] * len(me.edges) + + edges_idx_dict= dict([(sorted_edge_indicies(ed), ed.index) for ed in me.edges]) + + for f in faces: + fvi= [v.index for v in f.v]# face vert idx's + for i in xrange(len(f)): + i1= fvi[i] + i2= fvi[i-1] + + if i1>i2: + i1,i2= i2,i1 + + edge_users[edges_idx_dict[i1,i2]] += 1 + + return edge_users + #============================================================================# # Takes a face, and a pixel x/y on the image and returns a worldspace x/y/z # -- cgit v1.2.3