- Scripts:

Campbell Barton updated his Wavefront OBJ scripts and Ben Omari updated his DirectX 7 and 8 ones (thanks both).  The other listed scripts had minor updates to accomodate the menu changes.
- Scripts in menus:
  renamed Tools to Object, Generators to Add, and Modifiers to Mesh (Metaball, Curve, Surface can be added later), to integrate better in the interface.
- Fixed a bug in Blender.sys.makename: last letter of file extension was being cut out.
This commit is contained in:
Willian Padovani Germano 2004-06-21 12:01:23 +00:00
parent 625e7fb12c
commit a41759cb8b
10 changed files with 426 additions and 262 deletions

@ -1,14 +1,18 @@
#!BPY
""" Registration info for Blender menus:
Name: 'DirectX'
Blender: 233
Name: 'DirectX8'
Blender: 234
Group: 'Export'
Submenu: 'Mesh,armatures,animations' mesh
Submenu: 'Export to DX8 file format' export
Submenu: 'How to use this exporter?' help
Tip: 'Export to DirectX8 text file format format.'
"""
# DirectX.py version 2.0
# Copyright (C) 2003 Arben OMARI -- aromari@tin.it
# $Id$
#
# DirectX8Exporter.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
@ -34,6 +38,48 @@ bon_list = []
new_bon = {}
mat_flip = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1])
def draw():
# clearing screen
Blender.BGL.glClearColor(0.5, 0.5, 0.5, 1)
Blender.BGL.glColor3f(1.,1.,1.)
Blender.BGL.glClear(Blender.BGL.GL_COLOR_BUFFER_BIT)
# Buttons
Blender.Draw.Button("Exit", 1, 10, 40, 100, 25)
#Text
Blender.BGL.glColor3f(1, 1, 1)
Blender.BGL.glRasterPos2d(10, 310)
Blender.Draw.Text("1.Only one mesh and one armature in the scene")
Blender.BGL.glRasterPos2d(10, 290)
Blender.Draw.Text("2.Before parenting set:")
Blender.BGL.glRasterPos2d(10, 270)
Blender.Draw.Text(" a)Armature and mesh must have the same origin location")
Blender.BGL.glRasterPos2d(10, 255)
Blender.Draw.Text(" (press N for both and set the same LocX,LocY and LocZ)")
Blender.BGL.glRasterPos2d(10, 230)
Blender.Draw.Text(" b)Armature and mesh must have the same to rotation")
Blender.BGL.glRasterPos2d(10, 215)
Blender.Draw.Text(" (select them and press Ctrl + A)")
Blender.BGL.glRasterPos2d(10, 195)
Blender.Draw.Text("3.Flip Normals ")
Blender.BGL.glRasterPos2d(10, 175)
Blender.Draw.Text("4.Set the number of the animation frames to export ")
Blender.BGL.glRasterPos2d(10, 155)
Blender.Draw.Text("5.Read warnings in console(if any)")
def event(evt, val):
if evt == Blender.Draw.ESCKEY and not val: Blender.Draw.Exit()
def bevent(evt):
if evt == 1: Blender.Draw.Exit()
#***********************************************
#***********************************************
@ -80,7 +126,12 @@ class xExport:
Blender.Set('curframe',1)
am_ob = Object.Get(name.name)
mat_ob = mat_flip * am_ob.getMatrix()
self.writeArmFrames(mat_ob, "RootFrame", 0)
mat_o = Matrix([mat_ob[0][0],mat_ob[0][1],mat_ob[0][2],mat_ob[0][3]],
[mat_ob[1][0],mat_ob[1][1],mat_ob[1][2],mat_ob[1][3]],
[mat_ob[2][0],mat_ob[2][1],mat_ob[2][2],mat_ob[2][3]],
[0, 0, 0, 1])
self.writeArmFrames(mat_o, "RootFrame", 0)
root_bon = arm.getBones()
bon_list.append(root_bon[0])
mat_r = self.writeCombineMatrix(root_bon[0])
@ -348,6 +399,7 @@ template SkinWeights {\n\
mat_ob = name.getMatrix()
mat_ar = armat.getInverseMatrix()
mat_f = mat_ob * mat_ar
self.writeArmFrames(mat_f, "body", 1)
self.file.write(" Mesh object {\n")
@ -432,9 +484,6 @@ template SkinWeights {\n\
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(" TextureFilename {\n")
self.file.write(' "none" ;')
self.file.write(" }\n")
self.file.write(" }\n")
for mat in tex:
@ -485,6 +534,7 @@ template SkinWeights {\n\
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
#***********************************************
@ -565,15 +615,22 @@ template SkinWeights {\n\
self.file.write("}\n")
#***********************************************#***********************************************#***********************************************
#***********************************************
# MAIN
#***********************************************
def my_callback(filename):
if filename.find('.x', -2) <= 0: filename += '.x' # add '.x' if the user didn't
if filename.find('.x', -2) <= 0: filename += '.x'
xexport = xExport(filename)
xexport.writeRootBone()
Blender.Window.FileSelector(my_callback, "Export DirectX8")
arg = __script__['arg']
if arg == 'help':
Blender.Draw.Register(draw,event,bevent)
else:
fname = Blender.sys.makename(ext = ".x")
Blender.Window.FileSelector(my_callback, "Export DirectX8", fname)

@ -1,17 +1,18 @@
#!BPY
""" Registration info for Blender menus:
Name: 'DirectX (.X)...'
Blender: 232
Name: 'DirectX'
Blender: 234
Group: 'Export'
Submenu: 'Only Mesh Data...' mesh
Submenu: 'Animation (not armature yet)...' anim
Submenu: 'Only mesh data...' mesh
Submenu: 'Animation(not armature yet)...' anim
Tip: 'Export to DirectX text file format format.'
"""
# $Id$
#
# DirectX.py version 1.0
# Copyright (C) 2003 Arben OMARI -- aromari@tin.it
# 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
@ -30,6 +31,7 @@ Tip: 'Export to DirectX text file format format.'
import Blender
from Blender import Types, Object, NMesh, Material
#import string
from math import *
@ -55,7 +57,7 @@ class xExport:
for name in Object.Get():
obj = name.getData()
if type(obj) == Types.NMeshType :
self.writeMaterials(name,tex)
self.writeFrames(name, obj)
self.writeMeshcoord(name, obj )
self.writeMeshMaterialList(name, obj, tex)
@ -76,8 +78,7 @@ class xExport:
self.writeHeader()
for name in Object.Get():
obj = name.getData()
if type(obj) == Types.NMeshType :
self.writeMaterials(name,tex)
if type(obj) == Types.NMeshType :
self.writeMeshcoord(name, obj )
self.writeMeshMaterialList(name, obj, tex)
self.writeMeshNormals(name, obj)
@ -102,21 +103,7 @@ class xExport:
def writeEnd(self):
self.file.close()
print "... finished"
#***********************************************
#EXPORT MATERIALS
#***********************************************
def writeMaterials(self,name,tex):
for mat in Material.Get():
self.file.write("Material")
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")
self.writeTextures(name, tex)
#***********************************************
@ -127,18 +114,7 @@ class xExport:
for face in mesh.faces:
if face.image and face.image.name not in tex:
tex.append(face.image.name)
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")
#***********************************************
#EXPORT MESH DATA
@ -196,21 +172,24 @@ class xExport:
coun += 1
if coun == numface:
if len(face.v) == 3:
self.file.write("3; %s, %s, %s;;\n" % (counter, counter + 1, counter + 2))
self.file.write("3; %s; %s; %s;;\n" % (counter, counter + 1, counter + 2))
counter += 3
else :
self.file.write("4; %s, %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))
self.file.write("3; %s; %s; %s;,\n" % (counter, counter + 1, counter + 2))
counter += 3
else :
self.file.write("4; %s, %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"
@ -219,16 +198,15 @@ class xExport:
#MESH MATERIAL LIST
#***********************************************
def writeMeshMaterialList(self, name, obj, tex):
self.file.write("//LET'S BEGIN WITH OPTIONAL DATA\n")
self.file.write(" MeshMaterialList {\n")
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))
self.file.write(" %s;\n" % (len(tex) + count))
#HOW MANY FACES IT HAS
numfaces=len(obj.faces)
self.file.write("%s;\n" % (numfaces))
self.file.write(" %s;\n" % (numfaces))
##MATERIALS INDEX FOR EVERY FACE
counter = 0
for face in obj.faces :
@ -236,23 +214,43 @@ class xExport:
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))
self.file.write(" %s;;\n" % (tex.index(face.image.name) + count))
else :
self.file.write("%s;;\n" % (mater))
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))
self.file.write(" %s,\n" % (tex.index(face.image.name) + count))
else :
self.file.write("%s,\n" % (mater))
self.file.write(" %s,\n" % (mater))
##MATERIAL NAME
for mat in Material.Get():
self.file.write("{%s}\n"% (mat.name))
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("{Mat")
self.file.write("%s}\n"% (tex.index(mat) + 1))
self.file.write("}\n")
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
#***********************************************
@ -278,14 +276,14 @@ class xExport:
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))
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("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))
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("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
@ -296,7 +294,6 @@ class xExport:
#VERTICES NUMBER
mesh = name.data
numvert = 0
numfaces=len(obj.faces)
for face in mesh.faces:
numvert = numvert + len(face.v)
self.file.write("%s;\n" % (numvert))
@ -304,26 +301,15 @@ class xExport:
counter = -1
for face in mesh.faces:
counter += 1
if counter == numfaces - 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]))
else :
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]))
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")
@ -441,4 +427,5 @@ def my_callback(filename):
else:
xexport.exportTex()
Blender.Window.FileSelector(my_callback, "Export DirectX")
fname = Blender.sys.makename(ext = ".x")
Blender.Window.FileSelector(my_callback, "Export DirectX",fname)

@ -3,7 +3,7 @@
""" Registration info for Blender menus: <- these words are ignored
Name: 'Dispaint'
Blender: 233
Group: 'Modifiers'
Group: 'Mesh'
Tip: 'use vertex paint color value to modify shape displacing vertices along normal.'
"""

@ -3,7 +3,7 @@
"""
Name: 'Blender Knife Tool'
Blender: 232
Group: 'Modifiers'
Group: 'Mesh'
Tooltip: 'Cut a mesh along a plane w/o creating doubles'
"""

@ -1,147 +1,224 @@
#!BPY
#!BPY
"""
Name: 'Wavefront (.obj)...'
Blender: 232
"""
Name: 'Wavefront (.obj)...'
Blender: 232
Group: 'Export'
Tooltip: 'Save a Wavefront OBJ File'
"""
Tooltip: 'Save a Wavefront OBJ File'
"""
# $Id$
#
# --------------------------------------------------------------------------
# OBJ Export v0.9 by Campbell Barton (AKA Ideasman)
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
# --------------------------------------------------------------------------
# OBJ Export v0.9 by Campbell Barton (AKA Ideasman)
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
#================================================#
# Gets the world matrix of an object #
# by multiplying by parents mat's recursively #
# This only works in some simple situations, #
# needs work.... #
#================================================#
def getWorldMat(ob):
mat = ob.getMatrix()
p = ob.getParent()
if p != None:
mat = mat + getWorldMat(p)
return mat
#==================#
# Apply Transform #
#==================#
def apply_transform(verts, matrix):
verts.resize4D()
return Mathutils.VecMultMat(verts, matrix)
#====================================================#
# Return a 6 deciaml point floating point value #
# as a string that dosent have any python chars #
#====================================================#
def saneFloat(float):
#return '%(float)b' % vars() # 6 fp as house.hqx
return str('%f' % float) + ' '
#==================================================#
# New name based on old with a different extension #
#==================================================#
def newFName(ext):
return Get('filename')[: -len(Get('filename').split('.', -1)[-1]) ] + ext
from Blender import *
#===============================================#
# Strips the slashes from the front of a string #
#===============================================#
def stripPath(path):
for CH in range(len(path), 0, -1):
if path[CH-1] == "/" or path[CH-1] == "\\":
path = path[CH:]
break
return path
NULL_MAT = '(null)'
def save_obj(filename):
#================================================#
# Gets the world matrix of an object #
# by multiplying by parents mat's recursively #
# This only works in some simple situations, #
# needs work.... #
#================================================#
def getWorldMat(ob):
mat = ob.getMatrix()
p = ob.getParent()
if p != None:
mat = mat + getWorldMat(p)
return mat
#==================#
# Apply Transform #
#==================#
def apply_transform(vert, matrix):
vertCopy = Mathutils.CopyVec(vert)
vertCopy.resize4D()
return Mathutils.VecMultMat(vertCopy, matrix)
if filename.find('.obj', -4) <= 0: filename += '.obj' # for safety
#====================================================#
# Return a 6 deciaml point floating point value #
# as a string that dosent have any python chars #
#====================================================#
def saneFloat(float):
#return '%(float)b' % vars() # 6 fp as house.hqx
return str('%f' % float) + ' '
file = open(filename, "w")
# Write Header
file.write('# Blender OBJ File: ' + Get('filename') + ' \n')
file.write('# www.blender.org\n')
# Get all meshs
for ob in Object.Get():
if ob.getType() == 'Mesh':
m = ob.getData()
if len(m.verts) > 0: # Make sure there is somthing to write.
# Set the default mat
currentMatName = ''
file.write('o ' + ob.getName() + '_' + m.name + '\n') # Write Object name
# Dosent work properly,
matrix = getWorldMat(ob)
# Vert
for v in m.verts:
# Transform the vert
vTx = apply_transform(v.co, matrix)
file.write('v ')
file.write(saneFloat(vTx[0]))
file.write(saneFloat(vTx[1]))
file.write(saneFloat(vTx[2]) + '\n')
# UV
for f in m.faces:
for uvIdx in range(len(f.v)):
file.write('vt ')
if f.uv:
file.write(saneFloat(f.uv[uvIdx][0]))
file.write(saneFloat(f.uv[uvIdx][1]))
else:
file.write('0.0 ')
file.write('0.0 ')
from Blender import *
NULL_MAT = '(null)'
NULL_IMG = '(null)'
def save_mtl(filename):
file = open(filename, "w")
for mat in Material.Get():
file.write('newmtl ' + mat.getName() + '\n') # Define a new material
file.write('Ns ' + saneFloat((mat.getHardness()-1) * 1.9607843137254901 ) + '\n') # Hardness, convert blenders 1-511 to MTL's
col = mat.getRGBCol()
file.write('Kd ' + saneFloat(col[0]) + saneFloat(col[1]) + saneFloat(col[2]) +'\n') # Diffuse
col = mat.getMirCol()
file.write('Ka ' + saneFloat(col[0]) + saneFloat(col[1]) + saneFloat(col[2]) + '\n') # Ambient, uses mirror colour,
col = mat.getSpecCol()
file.write('Ks ' + saneFloat(col[0]) + saneFloat(col[1]) + saneFloat(col[2]) +'\n') # Specular
file.write('d ' + saneFloat(mat.getAlpha()) +'\n') # Alpha (dissolve)
# illum, 0 to disable lightng, 2 is normal.
file.write('illum ')
if mat.getMode() & Material.Modes['SHADELESS']:
file.write('0\n') # ignore lighting
else:
file.write('2\n') # light normaly
# End OF Mat
file.write('\n') # new line
file.close()
def save_obj(filename):
# First output all material
mtlfilename = filename[:-4] + '.mtl'
save_mtl(mtlfilename)
file = open(filename, "w")
# Write Header
file.write('# Blender OBJ File: ' + Get('filename') + ' \n')
file.write('# www.blender.org\n')
# Tell the obj file what file to use.
file.write('mtllib ' + stripPath(mtlfilename) + ' \n')
# Get all meshs
for ob in Object.Get():
if ob.getType() == 'Mesh':
m = ob.getData()
if len(m.verts) > 0: # Make sure there is somthing to write.
# Set the default mat
currentMatName = NULL_MAT
currentImgName = NULL_IMG
file.write('o ' + ob.getName() + '_' + m.name + '\n') # Write Object name
# Dosent work properly,
matrix = getWorldMat(ob)
# Vert
for v in m.verts:
# Transform the vert
vTx = apply_transform(v.co, matrix)
file.write('v ')
file.write(saneFloat(vTx[0]))
file.write(saneFloat(vTx[1]))
file.write(saneFloat(vTx[2]) + '\n')
# UV
for f in m.faces:
if len(f.v) > 2:
for uvIdx in range(len(f.v)):
file.write('vt ')
if f.uv:
file.write(saneFloat(f.uv[uvIdx][0]))
file.write(saneFloat(f.uv[uvIdx][1]))
else:
file.write('0.0 ')
file.write('0.0 ')
file.write('0.0' + '\n')
# NORMAL
for f1 in m.faces:
if len(f1.v) > 2:
for v in f1.v:
# Transform the normal
noTx = apply_transform(v.no, matrix)
noTx.normalize()
file.write('vn ')
file.write(saneFloat(noTx[0]))
file.write(saneFloat(noTx[1]))
file.write(saneFloat(noTx[2]) + '\n')
uvIdx = 0
for f in m.faces:
if len(f.v) > 2:
# Check material and change if needed.
if len(m.materials) > f.mat:
if currentMatName != m.materials[f.mat].getName():
currentMatName = m.materials[f.mat].getName()
file.write('usemtl ' + currentMatName + '\n')
elif currentMatName != NULL_MAT:
currentMatName = NULL_MAT
file.write('usemtl ' + currentMatName + '\n')
# UV IMAGE
# If the face uses a different image from the one last set then add a usemap line.
if f.image:
if f.image.filename != currentImgName:
currentImgName = f.image.filename
file.write( 'usemat ' + stripPath(currentImgName) +'\n') # Set a new image for all following faces
file.write('0.0' + '\n')
# NORMAL
for f in m.faces:
for v in f.v:
# Transform the normal
noTx = apply_transform(v.no, matrix)
noTx.normalize()
file.write('vn ')
file.write(saneFloat(noTx[0]))
file.write(saneFloat(noTx[1]))
file.write(saneFloat(noTx[2]) + '\n')
uvIdx = 0
for f in m.faces:
# Check material and change if needed.
if len(m.materials) > f.mat:
if currentMatName != m.materials[f.mat].getName():
currentMatName = m.materials[f.mat].getName()
file.write('usemtl ' + currentMatName + '\n')
elif currentMatName != NULL_MAT:
currentMatName = NULL_MAT
file.write('usemtl ' + currentMatName + '\n')
file.write('f ')
for v in f.v:
file.write( str(m.verts.index(v) +1) + '/') # Vert IDX
file.write( str(uvIdx +1) + '/') # UV IDX
file.write( str(uvIdx +1) + ' ') # NORMAL IDX
uvIdx+=1
file.write('\n')
file.close()
elif currentImgName != NULL_IMG: # Not using an image so set to NULL_IMG
currentImgName = NULL_IMG
file.write( 'usemat ' + stripPath(currentImgName) +'\n') # Set a new image for all following faces
file.write('f ')
for v in f.v:
file.write( str(m.verts.index(v) +1) + '/') # Vert IDX
file.write( str(uvIdx +1) + '/') # UV IDX
file.write( str(uvIdx +1) + ' ') # NORMAL IDX
uvIdx+=1
file.write('\n')
file.close()
Window.FileSelector(save_obj, 'Export OBJ')
Window.FileSelector(save_obj, 'Export OBJ', newFName('obj'))

@ -1,5 +1,5 @@
#!BPY
"""
Name: 'Wavefront (.obj)...'
Blender: 232
@ -32,6 +32,7 @@ Tooltip: 'Load a Wavefront OBJ File'
# --------------------------------------------------------------------------
NULL_MAT = '(null)' # Name for mesh's that have no mat set.
NULL_IMG = '(null)' # Name for mesh's that have no mat set.
MATLIMIT = 16 # This isnt about to change but probably should not be hard coded.
@ -79,10 +80,28 @@ def getMat(matName):
except:
return Material.New(matName)
#==================================================================================#
# This function sets textures defined in .mtl file #
#==================================================================================#
def load_image(mat, img_fileName, type, mesh):
def getImg(img_fileName):
for i in Image.Get():
if i.filename == img_fileName:
return i
# if we are this far it means the image hasnt been loaded.
try:
return Image.Load(img_fileName)
except:
print "unable to open", img_fileName
return
#==================================================================================#
# This function sets textures defined in .mtl file #
#==================================================================================#
def load_mat_image(mat, img_fileName, type, mesh):
try:
image = Image.Load(img_fileName)
except:
@ -94,9 +113,14 @@ def load_image(mat, img_fileName, type, mesh):
texture.image = image
# adds textures to faces (Textured/Alt-Z mode)
for f in mesh.faces:
if mesh.materials[f.mat].name == mat.name:
f.image = image
# Only apply the diffuse texture to the face if the image has not been set with the inline usemat func.
if type == 'Kd':
for f in mesh.faces:
if mesh.materials[f.mat].name == mat.name:
# the inline usemat command overides the material Image
if not f.image:
f.image = image
# adds textures for materials (rendering)
if type == 'Ka':
@ -135,20 +159,20 @@ def load_mtl(dir, mtl_file, mesh):
elif l[0] == 'Ks':
currentMat.setSpecCol(eval(l[1]), eval(l[2]), eval(l[3]))
elif l[0] == 'Ns':
currentMat.setEmit(eval(l[1])/100.0)
currentMat.setHardness( int((eval(l[1])*0.51)) )
elif l[0] == 'd':
currentMat.setAlpha(eval(l[1]))
elif l[0] == 'Tr':
currentMat.setAlpha(eval(l[1]))
elif l[0] == 'map_Ka':
img_fileName = dir + l[1]
load_image(currentMat, img_fileName, 'Ka', mesh)
elif l[0] == 'map_Kd':
img_fileName = dir + l[1]
load_image(currentMat, img_fileName, 'Kd', mesh)
load_mat_image(currentMat, img_fileName, 'Ka', mesh)
elif l[0] == 'map_Ks':
img_fileName = dir + l[1]
load_image(currentMat, img_fileName, 'Ks', mesh)
load_mat_image(currentMat, img_fileName, 'Ks', mesh)
elif l[0] == 'map_Kd':
img_fileName = dir + l[1]
load_mat_image(currentMat, img_fileName, 'Kd', mesh)
lIdx+=1
#==================================================================================#
@ -191,7 +215,8 @@ def load_obj(file):
nullMat = getMat(NULL_MAT)
currentMat = nullMat # Use this mat.
currentImg = NULL_IMG # Null image is a string, otherwise this should be set to an image object.
# Main loop
lIdx = 0
while lIdx < len(fileLines):
@ -256,8 +281,12 @@ def load_obj(file):
f.uv.append( uvMapList[ vtIdxLs[2] ] )
if vtIdxLs[3] < len(uvMapList):
f.uv.append( uvMapList[ vtIdxLs[3] ] )
mesh.faces.append(f) # move the face onto the mesh
# Apply the current image to the face
if currentImg != NULL_IMG:
mesh.faces[-1].image = currentImg
elif len(vIdxLs) >= 3: # This handles tri's and fans
for i in range(len(vIdxLs)-2):
f = NMesh.Face()
@ -273,12 +302,20 @@ def load_obj(file):
f.uv.append( uvMapList[ vtIdxLs[i+1] ] )
if vtIdxLs[2] < len(uvMapList):
f.uv.append( uvMapList[ vtIdxLs[i+2] ] )
mesh.faces.append(f) # move the face onto the mesh
# Apply the current image to the face
if currentImg != NULL_IMG:
mesh.faces[-1].image = currentImg
# is o the only vert/face delimeter?
# if not we could be screwed.
elif l[0] == 'o':
# Some material stuff
if mtl_fileName != '':
load_mtl(DIR, mtl_fileName, mesh)
# Make sure the objects is worth puttong
if len(mesh.verts) > 0:
NMesh.PutRaw(mesh, fileName + '_' + objectName)
@ -290,12 +327,19 @@ def load_obj(file):
# New texture list
uvMapList = []
elif l[0] == 'usemtl':
if l[1] == '(null)':
currentMat = getMat(NULL_MAT)
else:
currentMat = getMat(' '.join(l[1:])) # Use join in case of spaces
elif l[0] == 'usemat':
if l[1] == '(null)':
currentImg = NULL_IMG
else:
currentImg = getImg(DIR + ' '.join(l[1:])) # Use join in case of spaces
elif l[0] == 'mtllib':
mtl_fileName = l[1]
@ -311,5 +355,4 @@ def load_obj(file):
if len(mesh.verts) > 0:
NMesh.PutRaw(mesh, fileName + '_' + objectName)
Window.FileSelector(load_obj, 'Import OBJ')
Window.FileSelector(load_obj, 'Import OBJ')

@ -2,7 +2,7 @@
""" Registration info for Blender menus: <- these words are ignored
Name: 'UnWeld'
Blender: 232
Group: 'Modifiers'
Group: 'Mesh'
Tip: 'unweld all faces from one selected and commun vertex. Made vertex bevelling'
"""

@ -78,13 +78,13 @@ static int bpymenu_group_atoi (char *str)
if (!strcmp(str, "Import")) return PYMENU_IMPORT;
else if (!strcmp(str, "Export")) return PYMENU_EXPORT;
else if (!strcmp(str, "Help")) return PYMENU_HELP;
else if (!strcmp(str, "Generators")) return PYMENU_GENERATORS;
else if (!strcmp(str, "Modifiers")) return PYMENU_MODIFIERS;
else if (!strcmp(str, "Add")) return PYMENU_ADD;
else if (!strcmp(str, "Mesh")) return PYMENU_MESH;
else if (!strcmp(str, "Wizards")) return PYMENU_WIZARDS;
else if (!strcmp(str, "Animation")) return PYMENU_ANIMATION;
else if (!strcmp(str, "Materials")) return PYMENU_MATERIALS;
else if (!strcmp(str, "UV")) return PYMENU_UV;
else if (!strcmp(str, "Tools")) return PYMENU_TOOLS;
else if (!strcmp(str, "Object")) return PYMENU_OBJECT;
/* "Misc" or an inexistent group name: use misc */
else return PYMENU_MISC;
}
@ -98,14 +98,14 @@ char *BPyMenu_group_itoa (short menugroup)
case PYMENU_EXPORT:
return "Export";
break;
case PYMENU_GENERATORS:
return "Generators";
case PYMENU_ADD:
return "Add";
break;
case PYMENU_HELP:
return "Help";
break;
case PYMENU_MODIFIERS:
return "Modifiers";
case PYMENU_MESH:
return "Mesh";
break;
case PYMENU_WIZARDS:
return "Wizards";
@ -119,8 +119,8 @@ char *BPyMenu_group_itoa (short menugroup)
case PYMENU_UV:
return "UV";
break;
case PYMENU_TOOLS:
return "Tools";
case PYMENU_OBJECT:
return "Object";
break;
case PYMENU_MISC:
return "Misc";

@ -70,7 +70,7 @@ typedef struct BPyMenu {
/* Scripts can be added to only a few pre-defined places in menus, like
* File->Import, File->Export, etc. (for speed and better control).
* To make a new menu 'slot' available for scripts:
* - add an entry to the enum below, right before PYMENU_TOTAL, of course;
* - add an entry to the enum below, before PYMENU_TOTAL, of course;
* - update the bpymenu_group_atoi() and BPyMenu_group_itoa() functions in
* BPY_menus.c;
* - add the necessary code to the header_***.c file in
@ -79,15 +79,15 @@ typedef struct BPyMenu {
typedef enum {
PYMENU_WIZARDS, /* complex 'app' scripts */
PYMENU_UV, /* UV editing tools, to go in UV/Image editor space, 'UV' menu */
PYMENU_TOOLS,
PYMENU_MODIFIERS, /* modifies existing obj *data* */
PYMENU_OBJECT,
PYMENU_MISC,
PYMENU_MESH,
PYMENU_MATERIALS,
PYMENU_HELP, /* inserted in the info header 'Help' menu */
PYMENU_GENERATORS, /* creates new objects */
PYMENU_IMPORT,
PYMENU_EXPORT,
PYMENU_ANIMATION,
PYMENU_ADD, /* creates new objects */
PYMENU_TOTAL
} PYMENUHOOKS;

@ -291,7 +291,7 @@ static PyObject *M_sys_makename(PyObject *self, PyObject *args, PyObject *kw)
if (dot) n = dot - basename;
else n = strlen(basename);
BLI_strncpy(basename + n, ext, lenext);
BLI_strncpy(basename + n, ext, lenext + 1);
basename[n+lenext] = '\0';
}
}