home *** CD-ROM | disk | FTP | other *** search
/ Windows News 2005 November / WNnov2005.iso / Windows / Equipement / Blender / blender-2.37a-windows.exe / $_5_ / .blender / scripts / bpymodules / meshtools.py < prev    next >
Text File  |  2005-03-21  |  12KB  |  332 lines

  1. # $Id: meshtools.py,v 1.1 2005/03/21 05:26:52 ianwill Exp $
  2. #
  3. # +---------------------------------------------------------+
  4. # | Copyright (c) 2001 Anthony D'Agostino                   |
  5. # | http://www.redrival.com/scorpius                        |
  6. # | scorpius@netzero.com                                    |
  7. # | September 28, 2002                                      |
  8. # | Released under the Blender Artistic Licence (BAL)       |
  9. # | Import Export Suite v0.5                                |
  10. # +---------------------------------------------------------+
  11. # | Common Functions & Global Variables For All IO Modules  |
  12. # +---------------------------------------------------------+
  13.  
  14. import Blender
  15. import sys
  16.  
  17. show_progress = 1            # Set to 0 for faster performance
  18. average_vcols = 1            # Off for per-face, On for per-vertex
  19. overwrite_mesh_name = 0     # Set to 0 to increment object-name version
  20.  
  21. blender_version = Blender.Get('version')
  22. blender_version_str = `blender_version`[0] + '.' + `blender_version`[1:]
  23.  
  24. try:
  25.     import operator
  26. except:
  27.     msg = "Error: you need a full Python install to run this script."
  28.     meshtools.print_boxed(msg)
  29.     Blender.Draw.PupMenu("ERROR%t|"+msg)
  30.  
  31. # =================================
  32. # === Append Faces To Face List ===
  33. # =================================
  34. def append_faces(mesh, faces, facesuv, uvcoords):
  35.     for i in range(len(faces)):
  36.         if not i%100 and show_progress: Blender.Window.DrawProgressBar(float(i)/len(faces), "Generating Faces")
  37.         numfaceverts=len(faces[i])
  38.         if numfaceverts <= 4:                # This face is a triangle or quad
  39.             face = Blender.NMesh.Face()
  40.             for j in range(numfaceverts):
  41.                 index = faces[i][j]
  42.                 face.v.append(mesh.verts[index])
  43.                 if len(uvcoords) > 1:
  44.                     uvidx = facesuv[i][j]
  45.                     face.uv.append(uvcoords[uvidx])
  46.                     face.mode = 0
  47.                     face.col = [Blender.NMesh.Col()]*4
  48.             mesh.faces.append(face)
  49.         else:                                # Triangulate n-sided convex polygon.
  50.             a, b, c = 0, 1, 2                # Indices of first triangle.
  51.             for j in range(numfaceverts-2): # Number of triangles in polygon.
  52.                 face = Blender.NMesh.Face()
  53.                 face.v.append(mesh.verts[faces[i][a]])
  54.                 face.v.append(mesh.verts[faces[i][b]])
  55.                 face.v.append(mesh.verts[faces[i][c]])
  56.                 b = c; c += 1
  57.                 mesh.faces.append(face)
  58.         #face.smooth = 1
  59.  
  60. # ===================================
  61. # === Append Verts to Vertex List ===
  62. # ===================================
  63. def append_verts(mesh, verts, normals):
  64.     #print "Number of normals:", len(normals)
  65.     #print "Number of verts  :", len(verts)
  66.     for i in range(len(verts)):
  67.         if not i%100 and show_progress: Blender.Window.DrawProgressBar(float(i)/len(verts), "Generating Verts")
  68.         x, y, z = verts[i]
  69.         mesh.verts.append(Blender.NMesh.Vert(x, y, z))
  70.         if normals:
  71.             mesh.verts[i].no[0] = normals[i][0]
  72.             mesh.verts[i].no[1] = normals[i][1]
  73.             mesh.verts[i].no[2] = normals[i][2]
  74.  
  75. # ===========================
  76. # === Create Blender Mesh ===
  77. # ===========================
  78. def create_mesh(verts, faces, objname, facesuv=[], uvcoords=[], normals=[]):
  79.     if normals: normal_flag = 0
  80.     else: normal_flag = 1
  81.     mesh = Blender.NMesh.GetRaw()
  82.     append_verts(mesh, verts, normals)
  83.     append_faces(mesh, faces, facesuv, uvcoords)
  84.     if not overwrite_mesh_name:
  85.         objname = versioned_name(objname)
  86.     Blender.NMesh.PutRaw(mesh, objname, normal_flag)    # Name the Mesh
  87.     Blender.Object.GetSelected()[0].name=objname        # Name the Object
  88.     Blender.Redraw()
  89.  
  90. # ==============================
  91. # === Increment Name Version ===
  92. # ==============================
  93. def versioned_name(objname):
  94.     existing_names = []
  95.     for object in Blender.Object.Get():
  96.         existing_names.append(object.name)
  97.         data = object.data
  98.         if data: existing_names.append(data.name)
  99.     if objname in existing_names: # don't over-write other names
  100.         try:
  101.             name, ext = objname.split('.')
  102.         except ValueError:
  103.             name, ext = objname, ''
  104.         try:
  105.             num = int(ext)
  106.             root = name
  107.         except ValueError:
  108.             root = objname
  109.         for i in xrange(1, 1000):
  110.             objname = "%s.%03d" % (root, i)
  111.             if objname not in existing_names:
  112.                 break
  113.     return objname
  114.  
  115. # ===========================
  116. # === Print Text In A Box ===
  117. # ===========================
  118. def print_boxed(text):
  119.     lines = text.splitlines()
  120.     maxlinelen = max(map(len, lines))
  121.     if sys.platform[:3] == "win":
  122.         print chr(218)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(191)
  123.         for line in lines:
  124.             print chr(179) + ' ' + line.ljust(maxlinelen) + ' ' + chr(179)
  125.         print chr(192)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(217)
  126.     else:
  127.         print '+-' + '-'*maxlinelen + '-+'
  128.         for line in lines: print '| ' + line.ljust(maxlinelen) + ' |'
  129.         print '+-' + '-'*maxlinelen + '-+'
  130.     print '\a\r', # beep when done
  131.  
  132. # ===============================================
  133. # === Get euler angles from a rotation matrix ===
  134. # ===============================================
  135. def mat2euler(mat):
  136.     angle_y = -math.asin(mat[0][2])
  137.     c = math.cos(angle_y)
  138.     if math.fabs(c) > 0.005:
  139.         angle_x = math.atan2(mat[1][2]/c, mat[2][2]/c)
  140.         angle_z = math.atan2(mat[0][1]/c, mat[0][0]/c)
  141.     else:
  142.         angle_x = 0.0
  143.         angle_z = -math.atan2(mat[1][0], mat[1][1])
  144.     return (angle_x, angle_y, angle_z)
  145.  
  146. # ==========================
  147. # === Transpose A Matrix ===
  148. # ==========================
  149. def transpose(A):
  150.     S = len(A)
  151.     T = len(A[0])
  152.     B = [[None]*S for i in range(T)]
  153.     for i in range(T):
  154.         for j in range(S):
  155.             B[i][j] = A[j][i]
  156.     return B
  157.  
  158. # =======================
  159. # === Apply Transform ===
  160. # =======================
  161. def apply_transform(vertex, matrix):
  162.     x, y, z = vertex
  163.     xloc, yloc, zloc = matrix[3][0], matrix[3][1], matrix[3][2]
  164.     xcomponent = x*matrix[0][0] + y*matrix[1][0] + z*matrix[2][0] + xloc
  165.     ycomponent = x*matrix[0][1] + y*matrix[1][1] + z*matrix[2][1] + yloc
  166.     zcomponent = x*matrix[0][2] + y*matrix[1][2] + z*matrix[2][2] + zloc
  167.     vertex = [xcomponent, ycomponent, zcomponent]
  168.     return vertex
  169.  
  170. # =========================
  171. # === Has Vertex Colors ===
  172. # =========================
  173. def has_vertex_colors(mesh):
  174.     # My replacement/workaround for hasVertexColours()
  175.     # The docs say:
  176.     # "Warning: If a mesh has both vertex colours and textured faces,
  177.     # this function will return False. This is due to the way Blender
  178.     # deals internally with the vertex colours array (if there are
  179.     # textured faces, it is copied to the textured face structure and
  180.     # the original array is freed/deleted)."
  181.     try:
  182.         return mesh.faces[0].col[0]
  183.     except:
  184.         return 0
  185.  
  186. # ===========================
  187. # === Generate Edge Table ===
  188. # ===========================
  189. def generate_edgetable(mesh):
  190.     edge_table = {}
  191.     numfaces = len(mesh.faces)
  192.  
  193.     for i in range(numfaces):
  194.         if not i%100 and show_progress:
  195.             Blender.Window.DrawProgressBar(float(i)/numfaces, "Generating Edge Table")
  196.         if len(mesh.faces[i].v) == 4:    # Process Quadrilaterals
  197.             generate_entry_from_quad(mesh, i, edge_table)
  198.         elif len(mesh.faces[i].v) == 3: # Process Triangles
  199.             generate_entry_from_tri(mesh, i, edge_table)
  200.         else:                            # Skip This Face
  201.             print "Face #", i, "was skipped."
  202.  
  203.     # === Sort Edge_Table Keys & Add Edge Indices ===
  204.     i = 0
  205.     keys = edge_table.keys()
  206.     keys.sort()
  207.     for key in keys:
  208.         edge_table[key][6] = i
  209.         i += 1
  210.  
  211.     # === Replace Tuples With Indices ===
  212.     for key in keys:
  213.         for i in [2,3,4,5]:
  214.             if edge_table.has_key(edge_table[key][i]):
  215.                 edge_table[key][i] = edge_table[edge_table[key][i]][6]
  216.             else:
  217.                 keyrev = (edge_table[key][i][1], edge_table[key][i][0])
  218.                 edge_table[key][i] = edge_table[keyrev][6]
  219.  
  220.     return edge_table
  221.  
  222. # ================================
  223. # === Generate Entry From Quad ===
  224. # ================================
  225. def generate_entry_from_quad(mesh, i, edge_table):
  226.     vertex4, vertex3, vertex2, vertex1 = mesh.faces[i].v
  227.  
  228.     if has_vertex_colors(mesh):
  229.         vcolor4, vcolor3, vcolor2, vcolor1 = mesh.faces[i].col
  230.         Acol = (vcolor1.r/255.0, vcolor1.g/255.0, vcolor1.b/255.0)
  231.         Bcol = (vcolor2.r/255.0, vcolor2.g/255.0, vcolor2.b/255.0)
  232.         Ccol = (vcolor3.r/255.0, vcolor3.g/255.0, vcolor3.b/255.0)
  233.         Dcol = (vcolor4.r/255.0, vcolor4.g/255.0, vcolor4.b/255.0)
  234.  
  235.     # === verts are upper case, edges are lower case ===
  236.     A, B, C, D = vertex1.index, vertex2.index, vertex3.index, vertex4.index
  237.     a, b, c, d = (A, B), (B, C), (C, D), (D, A)
  238.  
  239.     if edge_table.has_key((B, A)):
  240.         edge_table[(B, A)][1] = i
  241.         edge_table[(B, A)][4] = d
  242.         edge_table[(B, A)][5] = b
  243.         if has_vertex_colors(mesh): edge_table[(B, A)][8] = Bcol
  244.     else:
  245.         if has_vertex_colors(mesh):
  246.             edge_table[(A, B)] = [i, None, d, b, None, None, None, Bcol, None]
  247.         else:
  248.             edge_table[(A, B)] = [i, None, d, b, None, None, None]
  249.  
  250.     if edge_table.has_key((C, B)):
  251.         edge_table[(C, B)][1] = i
  252.         edge_table[(C, B)][4] = a
  253.         edge_table[(C, B)][5] = c
  254.         if has_vertex_colors(mesh): edge_table[(C, B)][8] = Ccol
  255.     else:
  256.         if has_vertex_colors(mesh):
  257.             edge_table[(B, C)] = [i, None, a, c, None, None, None, Ccol, None]
  258.         else:
  259.             edge_table[(B, C)] = [i, None, a, c, None, None, None]
  260.  
  261.     if edge_table.has_key((D, C)):
  262.         edge_table[(D, C)][1] = i
  263.         edge_table[(D, C)][4] = b
  264.         edge_table[(D, C)][5] = d
  265.         if has_vertex_colors(mesh): edge_table[(D, C)][8] = Dcol
  266.     else:
  267.         if has_vertex_colors(mesh):
  268.             edge_table[(C, D)] = [i, None, b, d, None, None, None, Dcol, None]
  269.         else:
  270.             edge_table[(C, D)] = [i, None, b, d, None, None, None]
  271.  
  272.     if edge_table.has_key((A, D)):
  273.         edge_table[(A, D)][1] = i
  274.         edge_table[(A, D)][4] = c
  275.         edge_table[(A, D)][5] = a
  276.         if has_vertex_colors(mesh): edge_table[(A, D)][8] = Acol
  277.     else:
  278.         if has_vertex_colors(mesh):
  279.             edge_table[(D, A)] = [i, None, c, a, None, None, None, Acol, None]
  280.         else:
  281.             edge_table[(D, A)] = [i, None, c, a, None, None, None]
  282.  
  283. # ====================================
  284. # === Generate Entry From Triangle ===
  285. # ====================================
  286. def generate_entry_from_tri(mesh, i, edge_table):
  287.     vertex3, vertex2, vertex1 = mesh.faces[i].v
  288.  
  289.     if has_vertex_colors(mesh):
  290.         vcolor3, vcolor2, vcolor1, _vcolor4_ = mesh.faces[i].col
  291.         Acol = (vcolor1.r/255.0, vcolor1.g/255.0, vcolor1.b/255.0)
  292.         Bcol = (vcolor2.r/255.0, vcolor2.g/255.0, vcolor2.b/255.0)
  293.         Ccol = (vcolor3.r/255.0, vcolor3.g/255.0, vcolor3.b/255.0)
  294.  
  295.     # === verts are upper case, edges are lower case ===
  296.     A, B, C = vertex1.index, vertex2.index, vertex3.index
  297.     a, b, c = (A, B), (B, C), (C, A)
  298.  
  299.     if edge_table.has_key((B, A)):
  300.         edge_table[(B, A)][1] = i
  301.         edge_table[(B, A)][4] = c
  302.         edge_table[(B, A)][5] = b
  303.         if has_vertex_colors(mesh): edge_table[(B, A)][8] = Bcol
  304.     else:
  305.         if has_vertex_colors(mesh):
  306.             edge_table[(A, B)] = [i, None, c, b, None, None, None, Bcol, None]
  307.         else:
  308.             edge_table[(A, B)] = [i, None, c, b, None, None, None]
  309.  
  310.     if edge_table.has_key((C, B)):
  311.         edge_table[(C, B)][1] = i
  312.         edge_table[(C, B)][4] = a
  313.         edge_table[(C, B)][5] = c
  314.         if has_vertex_colors(mesh): edge_table[(C, B)][8] = Ccol
  315.     else:
  316.         if has_vertex_colors(mesh):
  317.             edge_table[(B, C)] = [i, None, a, c, None, None, None, Ccol, None]
  318.         else:
  319.             edge_table[(B, C)] = [i, None, a, c, None, None, None]
  320.  
  321.     if edge_table.has_key((A, C)):
  322.         edge_table[(A, C)][1] = i
  323.         edge_table[(A, C)][4] = b
  324.         edge_table[(A, C)][5] = a
  325.         if has_vertex_colors(mesh): edge_table[(A, C)][8] = Acol
  326.     else:
  327.         if has_vertex_colors(mesh):
  328.             edge_table[(C, A)] = [i, None, b, a, None, None, None, Acol, None]
  329.         else:
  330.             edge_table[(C, A)] = [i, None, b, a, None, None, None]
  331.  
  332.