ccbed6feae3f411262e664c9bfb039cc6a264c27
[blender.git] / release / scripts / obj_export.py
1 #!BPY 
2
3 """ 
4 Name: 'Wavefront (*.obj)' 
5 Blender: 232 
6 Group: 'Export'
7 Tooltip: 'Save a Wavefront OBJ File' 
8 """ 
9
10 # $Id$
11 #
12 # -------------------------------------------------------------------------- 
13 # OBJ Export v0.9 by Campbell Barton (AKA Ideasman) 
14 # -------------------------------------------------------------------------- 
15 # ***** BEGIN GPL LICENSE BLOCK ***** 
16
17 # This program is free software; you can redistribute it and/or 
18 # modify it under the terms of the GNU General Public License 
19 # as published by the Free Software Foundation; either version 2 
20 # of the License, or (at your option) any later version. 
21
22 # This program is distributed in the hope that it will be useful, 
23 # but WITHOUT ANY WARRANTY; without even the implied warranty of 
24 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
25 # GNU General Public License for more details. 
26
27 # You should have received a copy of the GNU General Public License 
28 # along with this program; if not, write to the Free Software Foundation, 
29 # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
30
31 # ***** END GPL LICENCE BLOCK ***** 
32 # -------------------------------------------------------------------------- 
33
34 #================================================# 
35 # Gets the world matrix of an object             # 
36 # by multiplying by parents mat's recursively    # 
37 # This only works in some simple situations,     # 
38 # needs work....                                 # 
39 #================================================# 
40 def getWorldMat(ob): 
41    mat = ob.getMatrix() 
42    p = ob.getParent() 
43    if p != None: 
44       mat = mat + getWorldMat(p) 
45    return mat 
46     
47 #==================# 
48 # Apply Transform  # 
49 #==================# 
50 def apply_transform(verts, matrix):
51         verts.resize4D()
52         return Mathutils.VecMultMat(verts, matrix)
53
54 #====================================================# 
55 # Return a 6 deciaml point floating point value      # 
56 # as a string that dosent have any python chars      # 
57 #====================================================#  
58 def saneFloat(float): 
59   #return '%(float)b' % vars()  # 6 fp as house.hqx 
60   return str('%f' % float) + ' ' 
61
62
63 from Blender import * 
64
65 NULL_MAT = '(null)' 
66
67 def save_obj(filename): 
68
69    if filename.find('.obj', -4) <= 0: filename += '.obj' # for safety
70
71    file = open(filename, "w") 
72     
73    # Write Header 
74    file.write('# Blender OBJ File: ' + Get('filename') + ' \n') 
75    file.write('# www.blender.org\n') 
76     
77    # Get all meshs 
78    for ob in Object.Get(): 
79       if ob.getType() == 'Mesh': 
80          m = ob.getData() 
81          if len(m.verts) > 0: # Make sure there is somthing to write. 
82              
83             # Set the default mat 
84             currentMatName = '' 
85              
86             file.write('o ' + ob.getName() + '_' + m.name + '\n') # Write Object name 
87              
88             # Dosent work properly, 
89             matrix = getWorldMat(ob) 
90              
91             # Vert 
92             for v in m.verts: 
93                # Transform the vert 
94                vTx = apply_transform(v.co, matrix) 
95                 
96                file.write('v ') 
97                file.write(saneFloat(vTx[0])) 
98                file.write(saneFloat(vTx[1])) 
99                file.write(saneFloat(vTx[2]) + '\n') 
100              
101             # UV 
102             for f in m.faces: 
103                for uvIdx in range(len(f.v)): 
104                   file.write('vt ') 
105                   if f.uv: 
106                      file.write(saneFloat(f.uv[uvIdx][0])) 
107                      file.write(saneFloat(f.uv[uvIdx][1])) 
108                   else: 
109                      file.write('0.0 ') 
110                      file.write('0.0 ') 
111                       
112                   file.write('0.0' + '\n') 
113              
114             # NORMAL 
115             for f in m.faces: 
116                for v in f.v: 
117                   # Transform the normal 
118                   noTx = apply_transform(v.no, matrix) 
119                   noTx.normalize()
120                   file.write('vn ') 
121                   file.write(saneFloat(noTx[0])) 
122                   file.write(saneFloat(noTx[1])) 
123                   file.write(saneFloat(noTx[2]) + '\n') 
124                                
125             uvIdx = 0 
126             for f in m.faces: 
127                # Check material and change if needed. 
128                if len(m.materials) > f.mat: 
129                   if currentMatName != m.materials[f.mat].getName(): 
130                      currentMatName = m.materials[f.mat].getName() 
131                      file.write('usemtl ' + currentMatName + '\n') 
132                    
133                elif currentMatName != NULL_MAT: 
134                   currentMatName = NULL_MAT 
135                   file.write('usemtl ' + currentMatName + '\n') 
136                 
137                file.write('f ') 
138                for v in f.v: 
139                   file.write( str(m.verts.index(v) +1) + '/') # Vert IDX 
140                   file.write( str(uvIdx +1) + '/') # UV IDX 
141                   file.write( str(uvIdx +1) + ' ') # NORMAL IDX 
142                   uvIdx+=1 
143                file.write('\n') 
144                 
145    file.close() 
146
147 Window.FileSelector(save_obj, 'SELECT OBJ FILE')