diff options
Diffstat (limited to 'release/scripts/bpymodules/meshtools.py')
-rw-r--r-- | release/scripts/bpymodules/meshtools.py | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/release/scripts/bpymodules/meshtools.py b/release/scripts/bpymodules/meshtools.py new file mode 100644 index 00000000000..4ddf6035e59 --- /dev/null +++ b/release/scripts/bpymodules/meshtools.py @@ -0,0 +1,331 @@ +# $Id$ +# +# +---------------------------------------------------------+ +# | Copyright (c) 2001 Anthony D'Agostino | +# | http://www.redrival.com/scorpius | +# | scorpius@netzero.com | +# | September 28, 2002 | +# | Released under the Blender Artistic Licence (BAL) | +# | Import Export Suite v0.5 | +# +---------------------------------------------------------+ +# | Common Functions & Global Variables For All IO Modules | +# +---------------------------------------------------------+ + +import Blender +import sys + +show_progress = 1 # Set to 0 for faster performance +average_vcols = 1 # Off for per-face, On for per-vertex +overwrite_mesh_name = 0 # Set to 0 to increment object-name version + +blender_version = Blender.Get('version') +blender_version_str = `blender_version`[0] + '.' + `blender_version`[1:] + +try: + import operator +except: + msg = "Error: you need a full Python install to run this script." + meshtools.print_boxed(msg) + Blender.Draw.PupMenu("ERROR%t|"+msg) + +# ================================= +# === Append Faces To Face List === +# ================================= +def append_faces(mesh, faces, facesuv, uvcoords): + for i in range(len(faces)): + if not i%100 and show_progress: Blender.Window.DrawProgressBar(float(i)/len(faces), "Generating Faces") + numfaceverts=len(faces[i]) + if numfaceverts <= 4: # This face is a triangle or quad + face = Blender.NMesh.Face() + for j in range(numfaceverts): + index = faces[i][j] + face.v.append(mesh.verts[index]) + if len(uvcoords) > 1: + uvidx = facesuv[i][j] + face.uv.append(uvcoords[uvidx]) + face.mode = 0 + face.col = [Blender.NMesh.Col()]*4 + mesh.faces.append(face) + else: # Triangulate n-sided convex polygon. + a, b, c = 0, 1, 2 # Indices of first triangle. + for j in range(numfaceverts-2): # Number of triangles in polygon. + face = Blender.NMesh.Face() + face.v.append(mesh.verts[faces[i][a]]) + face.v.append(mesh.verts[faces[i][b]]) + face.v.append(mesh.verts[faces[i][c]]) + b = c; c += 1 + mesh.faces.append(face) + #face.smooth = 1 + +# =================================== +# === Append Verts to Vertex List === +# =================================== +def append_verts(mesh, verts, normals): + #print "Number of normals:", len(normals) + #print "Number of verts :", len(verts) + for i in range(len(verts)): + if not i%100 and show_progress: Blender.Window.DrawProgressBar(float(i)/len(verts), "Generating Verts") + x, y, z = verts[i] + mesh.verts.append(Blender.NMesh.Vert(x, y, z)) + if normals: + mesh.verts[i].no[0] = normals[i][0] + mesh.verts[i].no[1] = normals[i][1] + mesh.verts[i].no[2] = normals[i][2] + +# =========================== +# === Create Blender Mesh === +# =========================== +def create_mesh(verts, faces, objname, facesuv=[], uvcoords=[], normals=[]): + if normals: normal_flag = 0 + else: normal_flag = 1 + mesh = Blender.NMesh.GetRaw() + append_verts(mesh, verts, normals) + append_faces(mesh, faces, facesuv, uvcoords) + if not overwrite_mesh_name: + objname = versioned_name(objname) + Blender.NMesh.PutRaw(mesh, objname, normal_flag) # Name the Mesh + Blender.Object.GetSelected()[0].name=objname # Name the Object + Blender.Redraw() + +# ============================== +# === Increment Name Version === +# ============================== +def versioned_name(objname): + existing_names = [] + for object in Blender.Object.Get(): + existing_names.append(object.name) + data = object.data + if data: existing_names.append(data.name) + if objname in existing_names: # don't over-write other names + try: + name, ext = objname.split('.') + except ValueError: + name, ext = objname, '' + try: + num = int(ext) + root = name + except ValueError: + root = objname + for i in xrange(1, 1000): + objname = "%s.%03d" % (root, i) + if objname not in existing_names: + break + return objname + +# =========================== +# === Print Text In A Box === +# =========================== +def print_boxed(text): + lines = text.splitlines() + maxlinelen = max(map(len, lines)) + if sys.platform[:3] == "win": + print chr(218)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(191) + for line in lines: + print chr(179) + ' ' + line.ljust(maxlinelen) + ' ' + chr(179) + print chr(192)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(217) + else: + print '+-' + '-'*maxlinelen + '-+' + for line in lines: print '| ' + line.ljust(maxlinelen) + ' |' + print '+-' + '-'*maxlinelen + '-+' + print '\a\r', # beep when done + +# =============================================== +# === Get euler angles from a rotation matrix === +# =============================================== +def mat2euler(mat): + angle_y = -math.asin(mat[0][2]) + c = math.cos(angle_y) + if math.fabs(c) > 0.005: + angle_x = math.atan2(mat[1][2]/c, mat[2][2]/c) + angle_z = math.atan2(mat[0][1]/c, mat[0][0]/c) + else: + angle_x = 0.0 + angle_z = -math.atan2(mat[1][0], mat[1][1]) + return (angle_x, angle_y, angle_z) + +# ========================== +# === Transpose A Matrix === +# ========================== +def transpose(A): + S = len(A) + T = len(A[0]) + B = [[None]*S for i in range(T)] + for i in range(T): + for j in range(S): + B[i][j] = A[j][i] + return B + +# ======================= +# === Apply Transform === +# ======================= +def apply_transform(vertex, matrix): + x, y, z = vertex + xloc, yloc, zloc = matrix[3][0], matrix[3][1], matrix[3][2] + xcomponent = x*matrix[0][0] + y*matrix[1][0] + z*matrix[2][0] + xloc + ycomponent = x*matrix[0][1] + y*matrix[1][1] + z*matrix[2][1] + yloc + zcomponent = x*matrix[0][2] + y*matrix[1][2] + z*matrix[2][2] + zloc + vertex = [xcomponent, ycomponent, zcomponent] + return vertex + +# ========================= +# === Has Vertex Colors === +# ========================= +def has_vertex_colors(mesh): + # My replacement/workaround for hasVertexColours() + # The docs say: + # "Warning: If a mesh has both vertex colours and textured faces, + # this function will return False. This is due to the way Blender + # deals internally with the vertex colours array (if there are + # textured faces, it is copied to the textured face structure and + # the original array is freed/deleted)." + try: + return mesh.faces[0].col[0] + except: + return 0 + +# =========================== +# === Generate Edge Table === +# =========================== +def generate_edgetable(mesh): + edge_table = {} + numfaces = len(mesh.faces) + + for i in range(numfaces): + if not i%100 and show_progress: + Blender.Window.DrawProgressBar(float(i)/numfaces, "Generating Edge Table") + if len(mesh.faces[i].v) == 4: # Process Quadrilaterals + generate_entry_from_quad(mesh, i, edge_table) + elif len(mesh.faces[i].v) == 3: # Process Triangles + generate_entry_from_tri(mesh, i, edge_table) + else: # Skip This Face + print "Face #", i, "was skipped." + + # === Sort Edge_Table Keys & Add Edge Indices === + i = 0 + keys = edge_table.keys() + keys.sort() + for key in keys: + edge_table[key][6] = i + i += 1 + + # === Replace Tuples With Indices === + for key in keys: + for i in [2,3,4,5]: + if edge_table.has_key(edge_table[key][i]): + edge_table[key][i] = edge_table[edge_table[key][i]][6] + else: + keyrev = (edge_table[key][i][1], edge_table[key][i][0]) + edge_table[key][i] = edge_table[keyrev][6] + + return edge_table + +# ================================ +# === Generate Entry From Quad === +# ================================ +def generate_entry_from_quad(mesh, i, edge_table): + vertex4, vertex3, vertex2, vertex1 = mesh.faces[i].v + + if has_vertex_colors(mesh): + vcolor4, vcolor3, vcolor2, vcolor1 = mesh.faces[i].col + Acol = (vcolor1.r/255.0, vcolor1.g/255.0, vcolor1.b/255.0) + Bcol = (vcolor2.r/255.0, vcolor2.g/255.0, vcolor2.b/255.0) + Ccol = (vcolor3.r/255.0, vcolor3.g/255.0, vcolor3.b/255.0) + Dcol = (vcolor4.r/255.0, vcolor4.g/255.0, vcolor4.b/255.0) + + # === verts are upper case, edges are lower case === + A, B, C, D = vertex1.index, vertex2.index, vertex3.index, vertex4.index + a, b, c, d = (A, B), (B, C), (C, D), (D, A) + + if edge_table.has_key((B, A)): + edge_table[(B, A)][1] = i + edge_table[(B, A)][4] = d + edge_table[(B, A)][5] = b + if has_vertex_colors(mesh): edge_table[(B, A)][8] = Bcol + else: + if has_vertex_colors(mesh): + edge_table[(A, B)] = [i, None, d, b, None, None, None, Bcol, None] + else: + edge_table[(A, B)] = [i, None, d, b, None, None, None] + + if edge_table.has_key((C, B)): + edge_table[(C, B)][1] = i + edge_table[(C, B)][4] = a + edge_table[(C, B)][5] = c + if has_vertex_colors(mesh): edge_table[(C, B)][8] = Ccol + else: + if has_vertex_colors(mesh): + edge_table[(B, C)] = [i, None, a, c, None, None, None, Ccol, None] + else: + edge_table[(B, C)] = [i, None, a, c, None, None, None] + + if edge_table.has_key((D, C)): + edge_table[(D, C)][1] = i + edge_table[(D, C)][4] = b + edge_table[(D, C)][5] = d + if has_vertex_colors(mesh): edge_table[(D, C)][8] = Dcol + else: + if has_vertex_colors(mesh): + edge_table[(C, D)] = [i, None, b, d, None, None, None, Dcol, None] + else: + edge_table[(C, D)] = [i, None, b, d, None, None, None] + + if edge_table.has_key((A, D)): + edge_table[(A, D)][1] = i + edge_table[(A, D)][4] = c + edge_table[(A, D)][5] = a + if has_vertex_colors(mesh): edge_table[(A, D)][8] = Acol + else: + if has_vertex_colors(mesh): + edge_table[(D, A)] = [i, None, c, a, None, None, None, Acol, None] + else: + edge_table[(D, A)] = [i, None, c, a, None, None, None] + +# ==================================== +# === Generate Entry From Triangle === +# ==================================== +def generate_entry_from_tri(mesh, i, edge_table): + vertex3, vertex2, vertex1 = mesh.faces[i].v + + if has_vertex_colors(mesh): + vcolor3, vcolor2, vcolor1, _vcolor4_ = mesh.faces[i].col + Acol = (vcolor1.r/255.0, vcolor1.g/255.0, vcolor1.b/255.0) + Bcol = (vcolor2.r/255.0, vcolor2.g/255.0, vcolor2.b/255.0) + Ccol = (vcolor3.r/255.0, vcolor3.g/255.0, vcolor3.b/255.0) + + # === verts are upper case, edges are lower case === + A, B, C = vertex1.index, vertex2.index, vertex3.index + a, b, c = (A, B), (B, C), (C, A) + + if edge_table.has_key((B, A)): + edge_table[(B, A)][1] = i + edge_table[(B, A)][4] = c + edge_table[(B, A)][5] = b + if has_vertex_colors(mesh): edge_table[(B, A)][8] = Bcol + else: + if has_vertex_colors(mesh): + edge_table[(A, B)] = [i, None, c, b, None, None, None, Bcol, None] + else: + edge_table[(A, B)] = [i, None, c, b, None, None, None] + + if edge_table.has_key((C, B)): + edge_table[(C, B)][1] = i + edge_table[(C, B)][4] = a + edge_table[(C, B)][5] = c + if has_vertex_colors(mesh): edge_table[(C, B)][8] = Ccol + else: + if has_vertex_colors(mesh): + edge_table[(B, C)] = [i, None, a, c, None, None, None, Ccol, None] + else: + edge_table[(B, C)] = [i, None, a, c, None, None, None] + + if edge_table.has_key((A, C)): + edge_table[(A, C)][1] = i + edge_table[(A, C)][4] = b + edge_table[(A, C)][5] = a + if has_vertex_colors(mesh): edge_table[(A, C)][8] = Acol + else: + if has_vertex_colors(mesh): + edge_table[(C, A)] = [i, None, b, a, None, None, None, Acol, None] + else: + edge_table[(C, A)] = [i, None, b, a, None, None, None] + |