Logo Search packages:      
Sourcecode: blender version File versions

DirectXExporter.py

#!BPY

""" Registration info for Blender menus:
Name: 'DirectX (.x)...'
Blender: 234
Group: 'Export'
Submenu: 'Only mesh data...' mesh
Submenu: 'Animation(not armature yet)...' anim
Tip: 'Export to DirectX text file format'
"""

__author__ = "Arben (Ben) Omari"
__url__ = ("blender", "elysiun", "Author's site, http://www.omariben.too.it")
__version__ = "1.0"

__bpydoc__ = """\
This script exports Blender uv-textured meshes with animation frame keys to
DirectX 7's text file format.

Usage:

Run the script and check console for possible warning messages.

Supported:<br>
    UV-textured meshes with animation frame (location, rotation) keys.

Known issues:<br>
    Some DX format viewers don't support Material names with dots
('.') in them.

Notes:<br>
    Check author's site or the elYsiun forum for a new beta version of the
DX exporter.
"""


# $Id: DirectXExporter.py,v 1.6 2004/11/07 16:31:13 ianwill Exp $
#
# DirectX.py version 1.0
# Copyright (C) 2003  Arben OMARI -- omariarben@everyday.com  
#
# 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.

# This script export meshes created with Blender in DirectX file format
# it exports meshes,materials,normals,texturecoords and and animations

# Grab the latest version here :www.omariben.too.it

import Blender
from Blender import Types, Object, NMesh, Material
#import string
from math import *



      
#***********************************************
#***********************************************
#                EXPORTER
#***********************************************
#***********************************************

class xExport:
      def __init__(self, filename):
            self.file = open(filename, "w")

      #***********************************************
      #  Export animations
      #***********************************************
      def exportAnim(self):
            tex = []
            print "exporting ..."
            self.writeHeader()
            for name in Object.Get():
                  obj = name.getData()
                  if type(obj) == Types.NMeshType :
                              
                        self.writeFrames(name, obj)   
                        self.writeMeshcoord(name, obj )
                        self.writeMeshMaterialList(name, obj, tex)
                        self.writeMeshNormals(name, obj)
                        self.writeMeshTextureCoords(name, obj)
                        self.file.write("}\n")
                        self.file.write("}\n")
                        self.writeAnimation(name, obj)
                  
            self.writeEnd()

      #***********************************************
      #  Export geometry
      #***********************************************
      def exportTex(self):
            tex = []
            print "exporting ..."
            self.writeHeader()
            for name in Object.Get():
                  obj = name.getData()
                  if type(obj) == Types.NMeshType :         
                        self.writeMeshcoord(name, obj )
                        self.writeMeshMaterialList(name, obj, tex)
                        self.writeMeshNormals(name, obj)
                        self.writeMeshTextureCoords(name, obj)
                        self.file.write("}\n")

            self.writeEnd()
    
      #***********************************************
      #HEADER
      #***********************************************  
      def writeHeader(self):
            self.file.write("xof 0302txt 0064\n")
            self.file.write("\n")
            self.file.write("Header{\n")
            self.file.write("1;0;1;\n")
            self.file.write("}\n")

      #***********************************************
      #CLOSE FILE
      #***********************************************
      def writeEnd(self):
            self.file.close()
            print "... finished"
      
            

      #***********************************************
      #EXPORT TEXTURES
      #***********************************************
      def writeTextures(self,name, tex):
            mesh = name.data
            for face in mesh.faces:
                  if face.image and face.image.name not in tex:
                        tex.append(face.image.name)
                        

      #***********************************************
      #EXPORT MESH DATA
      #***********************************************
      def writeMeshcoord(self, name, obj ):
            
            self.file.write("Mesh Mesh_%s {\n" % (name.name))    
            numfaces=len(obj.faces)
            #POSITION
            loc = name.getMatrix()
            x = loc[3][0]
            y = loc[3][1]
            z = loc[3][2]
            #VERTICES NUMBER
            mesh = name.data
            numvert = 0
            for face in mesh.faces:
                  numvert = numvert + len(face.v)
            self.file.write("%s;\n" % (numvert))
            #VERTICES COORDINATES
            counter = 0
            for face in mesh.faces:
                  counter += 1
                  if counter == numfaces:
                        if len(face.v) == 4:
                              self.file.write("%s; %s; %s;,\n" % ((face.v[0].co[0] + x), face.v[0].co[1] + y, face.v[0].co[2] + z))
                              self.file.write("%s; %s; %s;,\n" % ((face.v[1].co[0] + x), face.v[1].co[1] + y, face.v[1].co[2] + z))       
                              self.file.write("%s; %s; %s;,\n" % ((face.v[2].co[0] + x), face.v[2].co[1] + y, face.v[2].co[2] + z))
                              self.file.write("%s; %s; %s;;\n" % ((face.v[3].co[0] + x), face.v[3].co[1] + y, face.v[3].co[2] + z))
                        elif len(face.v) == 3 :
                              self.file.write("%s; %s; %s;,\n" % ((face.v[0].co[0] + x), face.v[0].co[1] + y, face.v[0].co[2] + z))
                              self.file.write("%s; %s; %s;,\n" % ((face.v[1].co[0] + x), face.v[1].co[1] + y, face.v[1].co[2] + z))       
                              self.file.write("%s; %s; %s;;\n" % ((face.v[2].co[0] + x), face.v[2].co[1] + y, face.v[2].co[2] + z))
                              
                  else :
                        if len(face.v) == 4:
                              self.file.write("%s; %s; %s;,\n" % ((face.v[0].co[0] + x), face.v[0].co[1] + y, face.v[0].co[2] + z))
                              self.file.write("%s; %s; %s;,\n" % ((face.v[1].co[0] + x), face.v[1].co[1] + y, face.v[1].co[2] + z))       
                              self.file.write("%s; %s; %s;,\n" % ((face.v[2].co[0] + x), face.v[2].co[1] + y, face.v[2].co[2] + z))
                              self.file.write("%s; %s; %s;,\n" % ((face.v[3].co[0] + x), face.v[3].co[1] + y, face.v[3].co[2] + z))
                        elif len(face.v) == 3:
                              self.file.write("%s; %s; %s;,\n" % ((face.v[0].co[0] + x), face.v[0].co[1] + y, face.v[0].co[2] + z))
                              self.file.write("%s; %s; %s;,\n" % ((face.v[1].co[0] + x), face.v[1].co[1] + y, face.v[1].co[2] + z))       
                              self.file.write("%s; %s; %s;,\n" % ((face.v[2].co[0] + x), face.v[2].co[1] + y, face.v[2].co[2] + z))
                              


            #FACES NUMBER 
            
            self.file.write("%s;\n" % (numfaces))  
            #FACES INDEX
            numface=len(obj.faces)
            coun,counter = 0, 0
            for face in mesh.faces :
                  coun += 1
                  if coun == numface:
                        if len(face.v) == 3:
                              self.file.write("3; %s; %s; %s;;\n" % (counter, counter + 1, counter + 2))
                              counter += 3
                        elif len(face.v) == 4:
                              self.file.write("4; %s; %s; %s; %s;;\n" % (counter, counter + 1, counter + 2, counter + 3))
                              counter += 4
                        elif len(face.v) == 2:
                              print "WARNING:the mesh has faces with less then 3 vertices"
                  else:
                        
                        if len(face.v) == 3:
                              self.file.write("3; %s; %s; %s;,\n" % (counter, counter + 1, counter + 2))
                              counter += 3
                        elif len(face.v) == 4:
                              self.file.write("4; %s; %s; %s; %s;,\n" % (counter, counter + 1, counter + 2, counter + 3))
                              counter += 4
                        elif len(face.v) == 2:
                              print "WARNING:the mesh has faces with less then 3 vertices"
                        
            
            
            
            
      #***********************************************
      #MESH MATERIAL LIST
      #***********************************************
      def writeMeshMaterialList(self, name, obj, tex):
            self.file.write("  MeshMaterialList {\n")
            #HOW MANY MATERIALS ARE USED
            count = 0
            for mat in Material.Get():
                  count+=1
            self.file.write("    %s;\n" % (len(tex) + count))
            #HOW MANY FACES IT HAS
            numfaces=len(obj.faces)
            self.file.write("    %s;\n" % (numfaces))
            ##MATERIALS INDEX FOR EVERY FACE
            counter = 0
            for face in obj.faces :
                  counter += 1
                  mater = face.materialIndex
                  if counter == numfaces:
                        if face.image and face.image.name in tex :
                              self.file.write("    %s;;\n" % (tex.index(face.image.name) + count))
                        else :
                              self.file.write("    %s;;\n" % (mater))
                  else :
                        if face.image and face.image.name in tex :
                              self.file.write("    %s,\n" % (tex.index(face.image.name) + count))
                        else :
                              self.file.write("    %s,\n" % (mater))
                  
            ##MATERIAL NAME
            for mat in Material.Get():
                  self.file.write("  Material")
                  for a in range(0,len(mat.name)):
                        if mat.name[a] == ".":
                              print "WARNING:the material " + mat.name + " contains '.' within.Many viewers may refuse to read the exported file"
                  self.file.write(" %s "% (mat.name))
                  self.file.write("{\n")
                  self.file.write("    %s; %s; %s;" % (mat.R, mat.G, mat.B))
                  self.file.write("%s;;\n" % (mat.alpha))
                  self.file.write("    %s;\n" % (mat.spec))
                  self.file.write("    %s; %s; %s;;\n" % (mat.specR, mat.specG, mat.specB))
                  self.file.write("    0.0; 0.0; 0.0;;\n")
                  self.file.write("  }\n") 
            
            for mat in tex:
                  self.file.write("  Material Mat")
                  self.file.write("%s "% (len(tex)))
                  self.file.write("{\n")
                  self.file.write("    1.0; 1.0; 1.0; 1.0;;\n")
                  self.file.write("    1.0;\n")
                  self.file.write("    1.0; 1.0; 1.0;;\n")
                  self.file.write("    0.0; 0.0; 0.0;;\n")
                  self.file.write("  TextureFilename {\n")
                  self.file.write('    "%s" ;'% (face.image.name))
                  self.file.write("  }\n")
                  self.file.write("  }\n") 
            self.file.write("    }\n")
      #***********************************************
      #MESH NORMALS
      #***********************************************
      def writeMeshNormals(self,name,obj):
            self.file.write(" MeshNormals {\n")
            #VERTICES NUMBER
            numvert=len(obj.verts)
            self.file.write("%s;\n" % (numvert))
            #VERTICES NORMAL
            counter = 0
            for vert in obj.verts:
                  counter += 1  
                  if counter == numvert:
                        self.file.write("%s; %s; %s;;\n" % (vert.no[0], vert.no[1], vert.no[2]))
                  else :
                        self.file.write("%s; %s; %s;,\n" % (vert.no[0], vert.no[1], vert.no[2]))
            #FACES NUMBER 
            numfaces=len(obj.faces)
            self.file.write("%s;\n" % (numfaces))  
            #FACES INDEX
            counter = 0
            for face in obj.faces :
                  counter += 1
                  if counter == numfaces:
                        if len(face.v) == 3:
                              self.file.write("3; %s; %s; %s;;\n" % (face[0].index, face[1].index, face[2].index))
                        elif len(face.v) == 4:
                              self.file.write("4; %s; %s; %s; %s;;\n" % (face[0].index, face[1].index, face[2].index, face[3].index))
                  else:
                        if len(face.v) == 3:
                              self.file.write("3; %s; %s; %s;,\n" % (face[0].index, face[1].index, face[2].index))
                        elif len(face.v) == 4 :
                              self.file.write("4; %s; %s; %s; %s;,\n" % (face[0].index, face[1].index, face[2].index, face[3].index))
            self.file.write("}\n")
      #***********************************************
      #MESH TEXTURE COORDS
      #***********************************************
      def writeMeshTextureCoords(self, name, obj):
                  if obj.hasFaceUV():
                        self.file.write("MeshTextureCoords {\n")
                        #VERTICES NUMBER
                        mesh = name.data
                        numvert = 0
                        for face in mesh.faces:
                              numvert = numvert + len(face.v)
                        self.file.write("%s;\n" % (numvert))
                        #UV COORDS
                        counter = -1
                        for face in mesh.faces:
                              counter += 1
                              if len(face.v) == 4:
                                    self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[0][0], -mesh.faces[counter].uv[0][1]))
                                    self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[1][0], -mesh.faces[counter].uv[1][1]))
                                    self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[2][0], -mesh.faces[counter].uv[2][1]))
                                    self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[3][0], -mesh.faces[counter].uv[3][1]))
                              elif len(face.v) == 3:
                                    self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[0][0], -mesh.faces[counter].uv[0][1]))
                                    self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[1][0], -mesh.faces[counter].uv[1][1]))
                                    self.file.write("%s;%s;,\n" % (mesh.faces[counter].uv[2][0], -mesh.faces[counter].uv[2][1]))

                        self.file.write("}\n")

      #***********************************************
      #FRAMES
      #***********************************************
      def writeFrames(self, name, obj):
            matx = name.getMatrix()
            self.file.write("Frame Fr_")  
            self.file.write("%s {\n" % (obj.name))
            self.file.write(" FrameTransformMatrix {\n")
            self.file.write(" %s,%s,%s,%s,\n" %
                                          (round(matx[0][0],6),round(matx[0][1],6),round(matx[0][2],6),round(matx[0][3],6)))
            self.file.write(" %s,%s,%s,%s,\n" %
                                          (round(matx[1][0],6),round(matx[1][1],6),round(matx[1][2],6),round(matx[1][3],6)))
            self.file.write(" %s,%s,%s,%s,\n" %
                                          (round(matx[2][0],6),round(matx[2][1],6),round(matx[2][2],6),round(matx[2][3],6)))
            self.file.write(" %s,%s,%s,%s;;\n" %
                                          (round(matx[3][0],6),round(matx[3][1],6),round(matx[3][2],6),round(matx[3][3],6)))
            self.file.write(" }\n")
      #***********************************************
      #WRITE ANIMATION KEYS
      #***********************************************
      def writeAnimation(self, name, obj):
            startFr = Blender.Get('staframe')
            endFr = Blender.Get('endframe')
            self.file.write("AnimationSet animset_")
            self.file.write("%s {\n" % (obj.name))
            self.file.write(" Animation anim_")
            self.file.write("%s { \n" % (obj.name))
            self.file.write("  {Fr_")
            self.file.write("%s }\n" % (obj.name))
            self.file.write("   AnimationKey { \n")
            self.file.write("   0;\n")
            self.file.write("   %s; \n" % (endFr))
            for fr in range(startFr,endFr + 1) :
                  self.file.write("   %s; " % (fr))
                  self.file.write("4; ")
                  Blender.Set('curframe',fr)
                  rot = name.rot
                  rot_x = rot[0]
                  rot_y = rot[1]
                  rot_z = rot[2]
                  quat = self.euler2quat(rot_x,rot_y,rot_z)
                  self.file.write("%s, %s, %s,%s;;" % 
                                          (quat[0],quat[1],quat[2],quat[3]))
                  if fr == endFr:
                        self.file.write(";\n")
                  else:
                        self.file.write(",\n")
            self.file.write("   }\n")
            self.file.write("   AnimationKey { \n")
            self.file.write("   2;\n")
            self.file.write("   %s; \n" % (endFr))
            for fr in range(startFr,endFr + 1) :
                  self.file.write("   %s; " % (fr))
                  self.file.write("3; ")
                  Blender.Set('curframe',fr)
                  loc = name.loc
                  self.file.write("%s, %s, %s;;" %
                                          (loc[0],loc[1],loc[2]))
                  if fr == endFr:
                        self.file.write(";\n")
                  else:
                        self.file.write(",\n")
            self.file.write("   }\n")
            self.file.write("   AnimationKey { \n")
            self.file.write("   1;\n")
            self.file.write("   %s; \n" % (endFr))
            for fr in range(startFr,endFr + 1) :
                  self.file.write("   %s; " % (fr))
                  self.file.write("3; ")
                  Blender.Set('curframe',fr)
                  size = name.size
                  self.file.write("%s, %s, %s;;" %
                                          (size[0],size[1],size[2]))
                  if fr == endFr:
                        self.file.write(";\n")
                  else:
                        self.file.write(",\n")
            self.file.write("   }\n")
            self.file.write("  }\n")
            self.file.write(" }\n")

      def euler2quat(self,rot_x,rot_y,rot_z):
            c_x = cos(rot_x / 2)
            c_y = cos(rot_y / 2)
            c_z = cos(rot_z / 2)

            s_x = sin(rot_x / 2)
            s_y = sin(rot_y / 2)
            s_z = sin(rot_z / 2)

            cy_cz = c_y * c_z
            sy_sz = s_y * s_z
 
            quat_w = c_x * cy_cz - s_x * sy_sz
            quat_x = s_x * cy_cz + c_x * sy_sz
            quat_y = c_x * s_y * c_z - s_x * c_y * s_z
            quat_z = c_x * c_y * s_z + s_x * s_y * c_z

            return(quat_w,quat_x,quat_y,quat_z)

#***********************************************
# MAIN
#***********************************************

      
def my_callback(filename):
      if filename.find('.x', -2) <= 0: filename += '.x' # add '.x' if the user didn't
      xexport = xExport(filename)
      arg = __script__['arg']
      if arg == 'anim':
            xexport.exportAnim()
      else:
            xexport.exportTex()

fname = Blender.sys.makename(ext = ".x")
Blender.Window.FileSelector(my_callback, "Export DirectX",fname)

Generated by  Doxygen 1.6.0   Back to index