|
From: <tre...@us...> - 2007-09-24 21:26:50
|
Revision: 438
http://ogoglio.svn.sourceforge.net/ogoglio/?rev=438&view=rev
Author: trevorolio
Date: 2007-09-24 14:26:54 -0700 (Mon, 24 Sep 2007)
Log Message:
-----------
Added the blender scripts we use for avatar munging
Modified Paths:
--------------
maven/trunk/ogoglio/src/main/resources/scripts/testApplet.sh
Added Paths:
-----------
maven/trunk/ogoglio/src/main/resources/blender/
maven/trunk/ogoglio/src/main/resources/blender/IKBaker.py
maven/trunk/ogoglio/src/main/resources/blender/ObjExporter.py
maven/trunk/ogoglio/src/main/resources/blender/ogoglio_avatar.py
Added: maven/trunk/ogoglio/src/main/resources/blender/IKBaker.py
===================================================================
--- maven/trunk/ogoglio/src/main/resources/blender/IKBaker.py (rev 0)
+++ maven/trunk/ogoglio/src/main/resources/blender/IKBaker.py 2007-09-24 21:26:54 UTC (rev 438)
@@ -0,0 +1,206 @@
+#!BPY
+
+"""
+Name: 'IK Capture (.bvh)...'
+Blender: 237
+Group: 'Export'
+Tip: 'Export a (.bvh) IK capture file'
+"""
+
+__author__ = "Jean-Baptiste PERIN"
+__url__ = ("blender", "elysiun")
+__version__ = "0.4 05/12/01"
+__email__= ["M. PERIN Jean-Baptiste, jb_...@ya...", "scripts"]
+__bpydoc__ = """\
+This script exports Empty animation to bvh file format.
+
+Supported: Poser 3.01<br>
+
+Missing:<br>
+
+Known issues:<br>
+
+Notes:<br>
+
+"""
+
+#----------------------------------------------
+# (c) Jean-Baptiste PERIN december 2005, released under Blender Artistic Licence
+#----------------------------------------------
+
+import Blender
+import math
+empty_rest_ori = {}
+
+
+def getRootBone(armature):
+ rootBone = None
+ for bone in armature.bones.values():
+ if bone.parent == None :
+ if rootBone == None:
+ rootBone = bone
+ else:
+ print"Multiple root armature not handled"
+ return rootBone
+
+def getBoneCurPos(armature, bone):
+ lempty = Blender.Object.Get(bone.name)
+ return (lempty.getLocation())
+
+def getBoneCurRot(armature, bone):
+ lempty = Blender.Object.Get(bone.name)
+ return (lempty.getMatrix('worldspace'))
+
+def getBoneRestPos(armature, bone):
+ return (bone.head)
+
+def getBoneRestRot(armature, bone):
+ lempty = Blender.Object.Get(bone.name)
+ return (bone.matrix)
+
+def indentString(i):
+ string = ""
+ for v in range(0,i):
+ string += "\t"
+ return string
+
+def printBoneHierarchie (armature, bone, level):
+ str = "%sJOINT %s\n"%(indentString(level), bone.name)
+ str += "%s{\n"%indentString(level)
+ restPos = getBoneRestPos(armature, bone);
+ parentRestPos = getBoneRestPos(armature, bone.parent);
+ str += "%s\tOFFSET %f %f %f\n"%(indentString(level),
+ restPos['ARMATURESPACE'][0] - parentRestPos['ARMATURESPACE'][0],
+ restPos['ARMATURESPACE'][1] - parentRestPos['ARMATURESPACE'][1],
+ restPos['ARMATURESPACE'][2] - parentRestPos['ARMATURESPACE'][2])
+ empty_rest_ori [bone.name] = getBoneRestRot(armature, bone)['ARMATURESPACE']
+ print empty_rest_ori [bone.name]
+ str += "%s\tCHANNELS 3 Zrotation Xrotation Yrotation\n"%indentString(level)
+ if bone.children != None:
+ for b in bone.children:
+ if bone.name == b.parent.name:
+ str += printBoneHierarchie (armature,b, level+1)
+ else:
+ str += "%s\tEnd Site\n"%indentString(level)
+ str += "%s\t{\n"%indentString(level)
+ str += "%s\t\tOFFSET %f %f %f\n"%(indentString(level),
+ bone.tail['ARMATURESPACE'][0]-bone.head['ARMATURESPACE'][0],
+ bone.tail['ARMATURESPACE'][1]-bone.head['ARMATURESPACE'][1],
+ bone.tail['ARMATURESPACE'][2]-bone.head['ARMATURESPACE'][2])
+ str += "%s\t}\n"%indentString(level)
+
+ str += "%s}\n"%indentString(level)
+ return (str)
+
+def printArmatureHierarchie(armature):
+ rootBone = getRootBone(armature)
+ str = "ROOT %s\n{\n"%rootBone.name
+ str += "\tOFFSET %f %f %f\n"%(getBoneRestPos(armature, rootBone)['ARMATURESPACE'][0],
+ getBoneRestPos(armature, rootBone)['ARMATURESPACE'][1],
+ getBoneRestPos(armature, rootBone)['ARMATURESPACE'][2])
+ str += "\tCHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation\n"
+ empty_rest_ori [rootBone.name] = getBoneRestRot(armature, rootBone)['ARMATURESPACE']
+ for b in rootBone.children:
+ if rootBone.name == b.parent.name:
+ str += printBoneHierarchie (armature,b,1)
+ str += "}\n"
+ return (str)
+
+
+def printBoneFrame (armature, bone, level):
+ result = Blender.Mathutils.Matrix(empty_rest_ori [bone.name][0], empty_rest_ori [bone.name][1], empty_rest_ori [bone.name][2], empty_rest_ori [bone.name][3])
+ result.invert()
+ boneRot = getBoneCurRot(armature, bone);
+ rot = Blender.Mathutils.Matrix(boneRot[0], boneRot[1], boneRot[2], boneRot[3])
+ result = result * rot
+
+ ancestor = bone.parent
+ while ancestor:
+ pos = Blender.Mathutils.Matrix(empty_rest_ori [ancestor.name][0], empty_rest_ori [ancestor.name][1], empty_rest_ori [ancestor.name][2], empty_rest_ori [ancestor.name][3])
+ boneRot = getBoneCurRot(armature, ancestor);
+ rotInv = Blender.Mathutils.Matrix(boneRot[0], boneRot[1], boneRot[2], boneRot[3])
+ rotInv.invert()
+ result = rotInv * pos * result
+ ancestor = ancestor.parent
+
+ eul = result.rotationPart().toEuler()
+
+ str = "%f %f %f "%(
+ eul[2],
+ eul[0],
+ eul[1])
+ if bone.children != None:
+ for b in bone.children:
+ if bone.name == b.parent.name:
+ str += printBoneFrame (armature, b, level+1)
+ return (str)
+
+def printArmatureFrame (armature):
+ rootBone = getRootBone(armature)
+ bonePos = getBoneCurPos(armature, rootBone)
+ boneRot = getBoneCurRot(armature, rootBone)
+
+ str = "%f %f %f %f %f %f "%(
+ bonePos[0],
+ bonePos[1],
+ bonePos[2],
+ boneRot.rotationPart().toEuler()[2],
+ boneRot.rotationPart().toEuler()[0],
+ boneRot.rotationPart().toEuler()[1]
+ )
+ for b in rootBone.children:
+ if rootBone.name == b.parent.name:
+ str += printBoneFrame (armature,b,1)
+ str += "\n"
+ return (str)
+
+def exportBVH(filename):
+ global armaturename
+ print "Exporting armature %s to file %s "%( armaturename, filename)
+ startFrame = Blender.Get('staframe')
+ endFrame = Blender.Get('endframe')
+
+ outputfile = file(filename,'w')
+
+ outputfile.write("HIERARCHY\n")
+
+ armData = Blender.Object.Get(armaturename).getData()
+
+ str_res = printArmatureHierarchie (armData)
+ outputfile.write(str_res)
+ outputfile.write("MOTION\n")
+ outputfile.write("Frames: %d\n"%(endFrame-startFrame))
+ outputfile.write("Frame Time: %f\n"%(1.0/Blender.Scene.getCurrent().getRenderingContext().framesPerSec()))
+
+ ctx = Blender.Scene.getCurrent().getRenderingContext()
+ Blender.Set('curframe', startFrame)
+ while Blender.Get('curframe') < endFrame:
+ print "frame : %d"%(Blender.Get('curframe'))
+ str_res = printArmatureFrame(armData)
+ outputfile.write(str_res)
+ Blender.Set('curframe',Blender.Get('curframe')+1)
+
+ outputfile.close()
+
+ Blender.Set('curframe', startFrame)
+
+ Blender.Redraw()
+
+print "**** START ****"
+
+bfilename = Blender.Get('filename')
+armaturename = ""
+nfilename = bfilename.replace('.blend', '.bvh')
+print nfilename
+obj_sel = Blender.Object.GetSelected()
+if (obj_sel != None) and (len (obj_sel) == 1) and (type(obj_sel[0].getData()) == Blender.Types.ArmatureType):
+ print obj_sel[0].getName()
+ print type(obj_sel[0].getData())
+ armaturename = obj_sel[0].getName()
+ Blender.Window.FileSelector(exportBVH, 'Export BVH',nfilename)
+else:
+ error_txt = "Error%t|Select one and only one armature before running this script"
+ Blender.Draw.PupMenu(error_txt)
+ print error_txt
+
+print "**** END ****"
\ No newline at end of file
Added: maven/trunk/ogoglio/src/main/resources/blender/ObjExporter.py
===================================================================
--- maven/trunk/ogoglio/src/main/resources/blender/ObjExporter.py (rev 0)
+++ maven/trunk/ogoglio/src/main/resources/blender/ObjExporter.py 2007-09-24 21:26:54 UTC (rev 438)
@@ -0,0 +1,1269 @@
+#!BPY
+"""Registration info for Blender menus:
+Name: 'OBJ...'
+Blender: 232
+Group: 'Import'
+Tip: 'Import Wavefront File Format (*.obj)'
+"""
+
+#=========================================================================
+# Wavefront OBJ Importer/Exporter v1.2
+# This is a complete OBJ importer and exporter script
+# All Rights Reserved
+# ch...@ar...
+#=========================================================================
+
+#=========================================================================
+# mise a jour pour Blender 228 et suivant jm soler
+# mise a jour pour importer zbrush obj avec uvmapping jm soler
+# mise a jour pour utiliser le selecteur de fichier jm soler
+# mise a jour pour importer les fichiers obj de forester/arboretum jm soler
+#=========================================================================
+
+#=========================================================================
+# DESCRIPTION: This script allows for full importing and exporting of
+# .obj files. uv texture coordinates and normals can be exported and
+# imported. .obj groups and materials can also be converted to and
+# from material indexes in Blender.
+#
+# INSTALLATION:
+# You need the FULL python installation to run this script. You can
+# down load the latest version of PYTHON from http://www.python.org.
+#
+# INSTRUCTIONS (You definitely want to read this!):
+# Once the script is loaded in Blender, hit alt-p. This will bring up
+# the main interface panel. You will have a choise of exporting or
+# importing an .obj module. If you are exporting you must have at least
+# one mesh selected in Blender, or you will get an error.
+# You can change the export filename by entering the path and filename
+# in the dialog. If you do not enter a path, the path will default to
+# your blender directory. You can change the default path in the script <==== NOTE
+# itself by modifying the variable 'Filename' at the top of the script.
+#
+# EXPORTING:
+# There are 4 different export options: Default, Groups, Material Layers,
+# and Standard. "Default" will export your mesh using Material Layers if
+# the mesh has material indexes. "Groups" and "Material Layers" are
+# logically equivalent, but are a different .obj format. If you are
+# exporting a Poser morph target, you must select "Material Layers". <===== NOTE
+# "Standard" will ignore grouping information, even if your mesh has
+# material indexes.
+#
+# There is also a choice between export using "mesh coordinates" or
+# "object coordinates". "Object coordinates" are any location, rotation,
+# or scaling values created outside of mesh edit. They belong to the object
+# rather than the mesh. If you export using mesh coordinates (the default)
+# the center of the object will always be at 0, 0, 0. Export using "mesh
+# coordinates is definintely what you want to use if you are working with
+# a Poser morph target. If you are exporting a group of objects, you will
+# automatically be placed in "object coordinate" mode.
+#
+# IMPORTING:
+# If your OBJ model has uv mapping coordinates, and you want to use them <===== NOTE
+# in Blender, you can access them in two ways. The best way is through Blender's
+# realtime UV coordinates which you enable simply by selecting the UV option in
+# the material edit window. This gives you an exact version of the uv coordinates.
+# An older method is to select the "stick" option in the material edit window. I
+# really don't know why anyone would want to use this option since it cannot handle
+# seams and texture overlap, but I left it in just in case someone could use it for
+# something.
+#
+# If your OBJ contains groups, once it has been imported, it may still appear
+# to lack any material indexes. If this happens, it can be remedied <=== NOTE
+# by going to the mesh editor window, clicking on the mesh selection button, and
+# reselecting the mesh you have just imported. You will now have as many
+# materials attached to your object as there are groups. You can then select
+# different groups by doing a material select when you are in edit mode.
+#
+# Finally, you might have problems with certain parts of the object not displaying
+# after you go in and out of edit mode the first time. To fix this, simply go into
+# edit mode again, and select the "remove doubles" option.
+#
+#
+# HISTORY:
+# Nov 13, 2001: Initial Release
+# Nov 16, 2001: Version 1.1 - no longer need to pre-define dummy materials
+# Dec 13, 2001: Version 1.2 - now imports into realtime UV (the UV button in the material edit window), and
+# exports realtime UV. This format is more compatible with the native .OBJ uv format. Should eliminate
+# texture misalignments and seams. Simply press the UV button in the material edit window after importing.
+#
+# GetRaw
+#================================
+
+
+# ===============================
+# Setup our runtime constants
+# ===============================
+
+DEBUG=1 #Set this to "1" to see extra messages
+MESHVERSION=3 # If the export file doesn't work,
+FILEVERSION=3 # try changing these to "2"
+
+EVENT_PATHCHANGE= 1
+EVENT_IMPORT= 2
+EVENT_IMPORT_CONT= 3
+EVENT_OPTIONS= 4
+EVENT_EXPORT= 7
+EVENT_EXPORT_CHK= 5
+EVENT_EXPORT_CANCEL= 6
+EVENT_QUIT= 8
+EVENT_EXPORT_ERR= 9
+EVENT_TYPE= 10
+EVENT_DONE= 11
+EVENT_IMPORT_SELECT= 12
+
+# ===============================
+# Import our libraries
+# ===============================
+
+#import string
+#import os
+#import struct
+
+try:
+ import nt
+ os=nt
+ os.sep='\\'
+except:
+ import posix
+ os=posix
+ os.sep='/'
+
+def isdir(path):
+ try:
+ st = os.stat(path)
+ return 1
+ except:
+ return 0
+
+def split(pathname):
+ PATHNAME=pathname
+ PATHNAME=PATHNAME.replace('\\','/')
+ k0=PATHNAME.split('/')
+ directory=pathname.replace(k0[len(k0)-1],'')
+ Name=k0[len(k0)-1]
+ return directory, Name
+
+def join(l0,l1):
+ return l0+os.sep+l1
+
+os.isdir=isdir
+os.split=split
+os.join=join
+
+import math
+import Blender
+#import Blender210
+from Blender import *
+from Blender import NMesh
+from Blender.Draw import *
+from Blender.BGL import *
+from Blender import Material
+from Blender import Window
+
+
+
+# ===============================
+# Input Variables
+# ===============================
+
+Filename = "/Users/trevor/Desktop/something.obj"
+
+gFilename=Create(Filename)
+gAlert = 0
+type = 1
+exporttype = 1
+returncode = 0
+operation = "Export"
+center = [0,0,0]
+rotation = [0,0,0]
+Transform = []
+multiflag = 0
+
+#================================
+# def Fileselect function:
+#================================
+def ImportFunctionselet(filename):
+ global gFilename
+ global ExportOptions
+ global ExportType
+ global type
+ global exporttype
+ global operation
+ global gAlert
+ gFilename.val=filename
+ ImportFunction(filename, type)
+ operation = "Import"
+
+#================================
+def ExitGUI ():
+#================================
+ Exit()
+
+#================================
+def EventGUI (event):
+#================================
+ global gFilename
+ global ExportOptions
+ global ExportType
+ global type
+ global exporttype
+ global operation
+ global gAlert
+
+ if (event==EVENT_IMPORT):
+ ImportFunction(gFilename.val, type)
+ operation = "Import"
+
+ if (event==EVENT_IMPORT_SELECT):
+ Window.FileSelector (ImportFunctionselet, 'IMPORT FILE')
+
+
+ if (event==EVENT_IMPORT_CONT):
+ gAlert = 0
+ operation = "Import"
+ Draw ()
+
+ if (event==EVENT_EXPORT):
+ ExportFunction(gFilename.val, type)
+ operation = "Export"
+
+ if (event==EVENT_EXPORT_CHK):
+ ExportFunctionOK(gFilename.val, type)
+ Draw ()
+ if (event==EVENT_EXPORT_CANCEL):
+ gAlert = 0
+ Draw ()
+ if (event==EVENT_OPTIONS):
+ type = ExportOptions.val
+ Draw ()
+ if (event==EVENT_TYPE):
+ exporttype = ExportType.val
+ Draw ()
+ if (event==EVENT_EXPORT_ERR):
+ gAlert = 0
+ Draw ()
+ if (event==EVENT_DONE):
+ gAlert = 0
+ Draw ()
+ if (event==EVENT_QUIT):
+ ExitGUI()
+
+#================================
+def DrawGUI():
+#================================
+ global type
+ global exporttype
+ global operation
+
+ glClearColor (0.6,0.6,0.6,0)
+ glClear (GL_COLOR_BUFFER_BIT)
+
+ global gFilename
+ global gAlert
+ global ExportOptions
+ global ExportType
+
+ if (gAlert==0):
+ # Add in the copyright notice and title
+ glRasterPos2d(32, 380)
+ Text("Wavefront OBJ Importer/Exporter")
+ glRasterPos2d(32, 350)
+ Text("Copyright (C) Chris Lynch 2001")
+
+ gFilename=String ("Filename: ",EVENT_PATHCHANGE,32,250,320,32,gFilename.val,255,"Full pathname and filename")
+ Button ("Export",EVENT_EXPORT,32,200,100,32)
+ Button ("Import",EVENT_IMPORT,252,200,100,32)
+ Button ("Select Import",EVENT_IMPORT_SELECT,355,200,100,32)
+ glRasterPos2d(32, 165)
+ Text("Select Export Options:")
+ options = "Export Options %t| Default %x1| Material Layers %x2| Obj Groups %x3| Standard %x4"
+ ExportOptions = Menu (options,EVENT_OPTIONS,200,150,150,32, type)
+ Button ("Done",EVENT_QUIT,142,50,100,32)
+ glRasterPos2d(32, 115)
+ Text("Export using ")
+ options = "Export Type %t| Mesh Coordinates %x1| Object Coordinates %x2"
+ ExportType = Menu (options,EVENT_TYPE,170,100,180,32, exporttype)
+ Button ("Done",EVENT_QUIT,142,50,100,32)
+
+ elif (gAlert==1):
+ glRasterPos2i (32,250)
+ Text (gFilename.val+ " already exists. Save anyway?")
+ Button ("Save",EVENT_EXPORT_CHK,150,200,50,32)
+ Button ("Cancel",EVENT_EXPORT_CANCEL,250,200,50,32)
+ gAlert = 0
+ elif (gAlert==2):
+ glRasterPos2i (32,250)
+ Text (gFilename.val+ " cannot be found. Check directory and filename.")
+ Button ("Continue",EVENT_IMPORT_CONT,32,190,70,32)
+ gAlert = 0
+ elif gAlert == 3:
+ glRasterPos2i (32,250)
+ Text ("No objects selected to export. You must select one or more objects.")
+ Button ("Continue",EVENT_EXPORT_ERR,192,200,70,32)
+ gAlert = 0
+ elif gAlert == 5:
+ glRasterPos2i (32,250)
+ Text ("Invalid directory path.")
+ Button ("Continue",EVENT_EXPORT_ERR,192,200,70,32)
+ gAlert = 0
+ else:
+ glRasterPos2i (32,250)
+ Text (str(operation)+ " of " +str(gFilename.val)+ " done.")
+ Button ("Continue",EVENT_DONE,192,200,70,32)
+
+#================================
+def RegisterGUI ():
+#================================
+ Register (DrawGUI,None,EventGUI)
+
+#================================
+# MAIN SCRIPT
+#================================
+# Opens a file, writes data in it
+# and closes it up.
+#================================
+RegisterGUI()
+
+#================================
+def ImportFunction (importName, type):
+#================================
+ global gFilename
+ global gAlert
+
+ try:
+ FILE=open (importName,"r")
+ directory, Name = os.split(gFilename.val)
+ print directory, Name
+ words = Name.split(".")
+ Name = words[0]
+ ObjImport(FILE, Name, gFilename.val)
+ FILE.close()
+ gAlert = 4
+ Draw ()
+ except IOError:
+ gAlert=2
+ Draw ()
+
+#================================
+def ExportFunction (exportName, type):
+#================================
+ global gFilename
+ global gAlert
+
+ try:
+ FILE=open (exportName,"r")
+ FILE.close()
+ gAlert = 1
+ Draw ()
+ except IOError:
+
+ directory, Name = os.split(gFilename.val)
+
+
+ if os.isdir(directory):
+ ExportFunctionOK(exportName, type)
+ Draw ()
+ else:
+ gAlert = 5
+ Draw ()
+
+#================================
+def ExportFunctionOK (exportName, type):
+#================================
+ global gFilename
+ global gAlert
+ global returncode
+
+ FILE=open (exportName,"w")
+
+ directory, Name = os.split(gFilename.val)
+
+ words = Name.split(".")
+ Name = words[0]
+ ObjExport(FILE, Name, type)
+ if returncode > 0:
+ gAlert = 3
+ else:
+ gAlert = 4
+ FILE.flush()
+ FILE.close()
+
+#=========================
+def ObjImport(file, Name, filename):
+#=========================
+ vcount = 0
+ vncount = 0
+ vtcount = 0
+ fcount = 0
+ gcount = 0
+ setcount = 0
+ groupflag = 0
+ objectflag = 0
+ mtlflag = 0
+ baseindex = 0
+ basevtcount = 0
+ basevncount = 0
+ matindex = 0
+
+ pointList = []
+ uvList = []
+ normalList = []
+ faceList = []
+ materialList = []
+ imagelist = []
+
+ uv = []
+ lines = file.readlines()
+ linenumber = 1
+
+ for line in lines:
+ words = line.split()
+ if words and words[0] == "#":
+ pass # ignore comments
+ elif words and words[0] == "v":
+ vcount = vcount + 1
+
+ for n_ in [1,2,3]:
+ if words[n_].find(',')!=-1:
+ words[n_]=words[n_].replace(',','.')
+
+ x = float(words[1])
+ y = float(words[2])
+ z = float(words[3])
+
+ pointList.append([x, y, z])
+
+ elif words and words[0] == "vt":
+ vtcount = vtcount + 1
+ for n_ in [1,2]:
+ if words[n_].find(',')!=-1:
+ words[n_]=words[n_].replace(',','.')
+
+ u = float(words[1])
+ v = float(words[2])
+ uvList.append([u, v])
+
+ elif words and words[0] == "vn":
+ vncount = vncount + 1
+
+ for n_ in [1,2,3]:
+ if words[n_].find(',')!=-1:
+ words[n_]=words[n_].replace(',','.')
+
+ i = float(words[1])
+ j = float(words[2])
+ k = float(words[3])
+ normalList.append([i, j, k])
+
+ elif words and words[0] == "f":
+ fcount = fcount + 1
+ vi = [] # vertex indices
+ ti = [] # texture indices
+ ni = [] # normal indices
+ words = words[1:]
+ lcount = len(words)
+ for index in (xrange(lcount)):
+ if words[index].find( "/") == -1:
+ vindex = int(words[index])
+ if vindex < 0: vindex = baseindex + vindex + 1
+ vi.append(vindex)
+ else:
+ vtn = words[index].split( "/")
+ vindex = int(vtn[0])
+ if vindex < 0: vindex = baseindex + vindex + 1
+ vi.append(vindex)
+
+ if len(vtn) > 1 and vtn[1]:
+ tindex = int(vtn[1])
+ if tindex < 0: tindex = basevtcount +tindex + 1
+ ti.append(tindex)
+
+ if len(vtn) > 2 and vtn[2]:
+ nindex = int(vtn[2])
+ if nindex < 0: nindex = basevncount +nindex + 1
+ ni.append(nindex)
+ faceList.append([vi, ti, ni, matindex])
+
+ elif words and words[0] == "o":
+ ObjectName = words[1]
+ objectflag = 1
+ #print "Name is %s" % ObjectName
+
+ elif words and words[0] == "g":
+ groupflag = 1
+ index = len(words)
+ if objectflag == 0:
+ objectflag = 1
+ if index > 1:
+ ObjectName = words[1].join("_")
+ GroupName = words[1].join("_")
+ else:
+ ObjectName = "Default"
+ GroupName = "Default"
+ #print "Object name is %s" % ObjectName
+ #print "Group name is %s" % GroupName
+ else:
+ if index > 1:
+ GroupName = join(words[1],"_")
+ else:
+ GroupName = "Default"
+ #print "Group name is %s" % GroupName
+
+ if mtlflag == 0:
+ matindex = AddMeshMaterial(GroupName,materialList, matindex)
+ gcount = gcount + 1
+
+ if fcount > 0:
+ baseindex = vcount
+ basevncount = vncount
+ basevtcount = vtcount
+
+ elif words and words[0] == "mtllib":
+ # try to export materials
+ directory, dummy = os.split(filename)
+ filename = os.join(directory, words[1])
+ print "try to import : ",filename
+
+ try:
+ file = open(filename, "r")
+ except:
+ print "no material file %s" % filename
+ else:
+ mtlflag = 0
+ #file = open(filename, "r")
+ line = file.readline()
+ mtlflag = 1
+ while line:
+ words = line.split()
+ if words and words[0] == "newmtl":
+ name = words[1]
+ line = file.readline() # Ns ?
+ words = line.split()
+ while words[0] not in ["Ka","Kd","Ks","map_Kd"]:
+ line = file.readline()
+ words = line.split()
+
+ if words[0] == "Ka":
+ Ka = [float(words[1]),
+ float(words[2]),
+ float(words[3])]
+ line = file.readline() # Kd
+ words = line.split()
+
+ if words[0] == "Kd":
+ Kd = [float(words[1]),
+ float(words[2]),
+ float(words[3])]
+ line = file.readline() # Ks
+ words = line.split()
+
+ if words[0] == "Ks":
+ Ks = [float(words[1]),
+ float(words[2]),
+ float(words[3])]
+ line = file.readline() # Ks
+ words = line.split()
+
+ if words[0] == "map_Kd":
+ Kmap= words[1]
+ img=os.join(directory, Kmap)
+ im=Blender.Image.Load(img)
+ line = file.readline() # Ks
+ words = line.split()
+
+ matindex = AddGlobalMaterial(name, matindex)
+ matlist = Material.Get()
+
+ if len(matlist) > 0:
+ if name!='defaultMat':
+ material = matlist[matindex]
+ material.R = Kd[0]
+ material.G = Kd[1]
+ material.B = Kd[2]
+ try:
+ material.specCol[0] = Ks[0]
+ material.specCol[1] = Ks[1]
+ material.specCol[2] = Ks[2]
+ except:
+ pass
+ try:
+ alpha = 1 - ((Ka[0]+Ka[1]+Ka[2])/3)
+ except:
+ pass
+ try:
+ material.alpha = alpha
+ except:
+ pass
+
+ try:
+
+ img=os.join(directory, Kmap)
+ im=Blender.Image.Load(img)
+ imagelist.append(im)
+
+ t=Blender.Texture.New(Kmap)
+ t.setType('Image')
+ t.setImage(im)
+
+ material.setTexture(0,t)
+ material.getTextures()[0].texco=16
+ except:
+ pass
+
+ else:
+ material = matlist[matindex]
+
+ material.R = 0.8
+ material.G = 0.8
+ material.B = 0.8
+ material.specCol[0] = 0.5
+ material.specCol[1] = 0.5
+ material.specCol[2] = 0.5
+
+ img=os.join(directory, Kmap)
+ im=Blender.Image.Load(img)
+ imagelist.append(im)
+
+ t=Blender.Texture.New(Kmap)
+ t.setType('Image')
+ t.setImage(im)
+
+ material.setTexture(0,t)
+ material.getTextures()[0].texco=16
+
+ else:
+ mtlflag = 0
+
+ line = file.readline()
+
+
+ file.close()
+
+ elif words and words[0] == "usemtl":
+ if mtlflag == 1:
+ name = words[1]
+ matindex = AddMeshMaterial(name, materialList, matindex)
+ elif words:
+ print "%s: %s" % (linenumber, words)
+ linenumber = linenumber + 1
+ file.close()
+
+ # import in Blender
+
+ print "import into Blender ..."
+ mesh = NMesh.GetRaw ()
+
+ i = 0
+ while i < vcount:
+ x, y, z = pointList[i]
+ vert=NMesh.Vert(x, y, z)
+ mesh.verts.append(vert)
+ i=i+1
+
+ if vtcount > 0:
+ #mesh.hasFaceUV() = 1
+ print ("Object has uv coordinates")
+
+ if len(materialList) > 0:
+ for m in materialList:
+ try:
+ M=Material.Get(m)
+ mesh.materials.append(M)
+ except:
+ pass
+
+ total = len(faceList)
+ i = 0
+
+ for f in faceList:
+ if i%1000 == 0:
+ print ("Progress = "+ str(i)+"/"+ str(total))
+
+ i = i + 1
+ vi, ti, ni, matindex = f
+ face=NMesh.Face()
+ if len(materialList) > 0:
+ face.mat = matindex
+
+ limit = len(vi)
+ setcount = setcount + len(vi)
+ c = 0
+
+ while c < limit:
+ m = vi[c]-1
+ if vtcount > 0 and len(ti) > c:
+ n = ti[c]-1
+ if vncount > 0 and len(ni) > c:
+ p = ni[c]-1
+
+ if vtcount > 0:
+ try:
+ u, v = uvList[n]
+ except:
+ pass
+
+ """
+ # multiply uv coordinates by 2 and add 1. Apparently blender uses uv range of 1 to 3 (not 0 to 1).
+ mesh.verts[m].uvco[0] = (u*2)+1
+ mesh.verts[m].uvco[1] = (v*2)+1
+ """
+
+ if vncount > 0:
+ if p > len(normalList):
+ print("normal len = " +str(len(normalList))+ " vector len = " +str(len(pointList)))
+ print("p = " +str(p))
+ x, y, z = normalList[p]
+ mesh.verts[m].no[0] = x
+ mesh.verts[m].no[1] = y
+ mesh.verts[m].no[2] = z
+ c = c+1
+
+ if len(vi) < 5:
+ for index in vi:
+ face.v.append (mesh.verts[index-1])
+
+ if vtcount > 0:
+ for index in ti:
+ u, v = uvList[index-1]
+ face.uv.append((u,v))
+
+ if len(imagelist)>0:
+ face.image=imagelist[0]
+ #print
+
+ if vcount>0:
+ face.smooth=1
+
+ mesh.faces.append(face)
+
+ print "all other (general) polygons ..."
+ for f in faceList:
+ vi, ti, ni, matindex = f
+ if len(vi) > 4:
+ # export the polygon as edges
+ print ("Odd face, vertices = "+ str(len(vi)))
+ for i in range(len(vi)-2):
+ face = NMesh.Face()
+ if len(materialList) > 0:
+ face.mat = matindex
+ face.v.append(mesh.verts[vi[0]-1])
+ face.v.append(mesh.verts[vi[i+1]-1])
+ face.v.append(mesh.verts[vi[i+2]-1])
+
+ if vtcount > 0:
+ if len(ti) > i+2:
+ u, v = uvList[ti[0]-1]
+ face.uv.append((u,v))
+ u, v = uvList[ti[i+1]-1]
+ face.uv.append((u,v))
+ u, v = uvList[ti[i+2]-1]
+ face.uv.append((u,v))
+
+ mesh.faces.append(face)
+
+ NMesh.PutRaw(mesh, Name,1)
+
+ print ("Total number of vertices is "+ str(vcount))
+ print ("Total number of faces is "+ str(len(faceList)))
+ print ("Total number of sets is "+ str(setcount))
+
+
+ print("Finished importing " +str(Name)+ ".obj")
+
+#=========================================
+def AddMeshMaterial(name, materialList, matindex):
+#=========================================
+
+ index = 0
+ found = 0
+ limit = len(materialList)
+
+ while index < limit:
+ if materialList[index] == name:
+ matindex = index
+ found = 1
+ index = limit
+ index = index + 1
+
+ if found == 0:
+ materialList.append(name)
+ matindex = len(materialList)-1
+
+ return matindex
+
+#=========================================
+def AddGlobalMaterial (name, matindex):
+#=========================================
+
+ index = 0
+ found = 0
+ matindex = 0
+ MatList = Material.Get()
+ limit = len(MatList)
+
+ while index < limit:
+ if MatList[index].name == name:
+ matindex = index
+ found = 1
+ index = limit
+ index = index + 1
+
+ if found == 0:
+ material = Material.New(name)
+ matindex = index
+
+ return matindex
+
+#================================
+def ObjExport(FILE, Name, type):
+#================================
+ global returncode
+ global vertexcount
+ global uvcount
+ global Transform
+ global multiflag
+ global exporttype
+
+ vertexcount = 0
+ uvcount = 0
+ returncode = 0
+ print("Writing %s..." % Name)
+ FILE.write("# Wavefront OBJ (1.0) exported by lynx's OBJ import/export script\n\n")
+
+ Objects = Object.GetSelected()
+ if Objects == []:
+ print("You have not selected an object!")
+ returncode = 4
+ else:
+ for object in Objects:
+ MtlList = []
+ if len(Objects) > 1 or exporttype > 1:
+ Transform = CreateMatrix(object, Transform)
+ multiflag = 1
+
+ mesh = NMesh.GetRawFromObject(object.name)
+ ObjName = mesh.name
+ has_uvco = mesh.hasVertexUV()
+
+ FILE.write("# Meshname:\t%s\n" % ObjName)
+
+ faces = mesh.faces
+ materials = mesh.materials
+ Vertices = mesh.verts
+ GlobalMaterials = Material.Get()
+
+ if len(materials) >= 1 and len(GlobalMaterials) > 0 and type < 4:
+ CreateMtlFile(Name, materials, MtlList)
+
+ # Total Vertices and faces; comment if not useful
+ FILE.write("# Total number of Faces:\t%s\n" % len(faces))
+ FILE.write("# Total number of Vertices:\t%s\n" % len(Vertices))
+
+ FILE.write("\n")
+
+ # print first image map for uvcoords to use
+ # to be updated when we get access to other textures
+ if mesh.hasFaceUV(): FILE.write("# UV Texture:\t%s\n\n" % mesh.hasFaceUV())
+
+ if len(materials) >= 1 and len(GlobalMaterials) > 0 and type < 3:
+ UseLayers(faces, Vertices, MtlList, has_uvco, FILE, ObjName, Name)
+ elif len(materials) >= 1 and len(GlobalMaterials) > 0 and type == 3:
+ UseMtl(faces, Vertices, MtlList, has_uvco, FILE, ObjName, Name)
+ else:
+ Standard(faces, Vertices, has_uvco, FILE, ObjName)
+
+#================================================
+def CreateMtlFile (name, MeshMaterials, MtlList):
+#================================================
+ global gFilename
+
+ # try to export materials
+ directory, mtlname = os.split(gFilename.val)
+ mtlname = name + ".mtl"
+ filename = os.join(directory, mtlname)
+ file = open(filename, "w")
+
+ file.write("# Materials for %s.\n" % (name + ".obj"))
+ file.write("# Created by Blender.\n")
+ file.write("# These files must be in the same directory for the materials to be read correctly.\n\n")
+
+ MatList = Material.Get()
+ print str(MeshMaterials)
+
+ MtlNList=[]
+ for m in MatList:
+ MtlNList.append(m.name)
+
+ counter = 1
+ found = 0
+
+ for material in MeshMaterials:
+ for mtl in MtlList:
+ if material == mtl:
+ found = 1
+
+ MtlList.append(material)
+
+ if found == 0:
+ file.write("newmtl %s \n" % material.name)
+ index = 0
+ print material, MatList
+ while index < len(MatList):
+ if material.name == MatList[index].name:
+ mtl = MatList[index]
+ index = len(MatList)
+ found = 1
+ index = index + 1
+
+ if found == 1:
+ alpha = mtl.getAlpha()
+ file.write(" Ka %s %s %s \n" % (round(1-alpha,5), round(1-alpha,5), round(1-alpha,5)))
+ file.write(" Kd %s %s %s \n" % (round(mtl.R,5), round(mtl.G,5), round(mtl.B,5)))
+ file.write(" Ks %s %s %s \n" % (round(mtl.specCol[0],5), round(mtl.specCol[1],5), round(mtl.specCol[2],5)))
+ mtextures = mtl.getTextures() # get a list of the MTex objects
+ #try:
+ #for mtex in mtextures:
+ # if mtex.tex.type == Texture.Types.IMAGE and (mtex.texco & Texture.TexCo.UV):
+ # file.write(" map_Kd %s \n" % Blender.sys.basename(mtex[0].tex.image.filename))
+ # break
+ #except:
+ # if mtextures[0].tex.type == Texture.Types.IMAGE and (mtextures[0].texco & Texture.TexCo.UV):
+ # file.write(" map_Kd %s \n" % Blender.sys.basename(mtextures[0].tex.image.filename))
+
+
+ file.write(" illum 1\n")
+
+ else:
+ file.write(" Ka %s %s %s \n" % (0, 0, 0))
+ file.write(" Kd %s %s %s \n" % (1, 1, 1))
+ file.write(" Ks %s %s %s \n" % (1, 1, 1))
+ file.write(" illum 1\n")
+
+ found = 0
+
+ file.flush()
+ file.close()
+
+#===========================================================
+def Standard(faces, Vertices, has_uvco, FILE, ObjName):
+#===========================================================
+ global vertexcount
+ global uvcount
+ global multiflag
+
+ uvPtrs = []
+ uvList = []
+
+ FILE.write("o %s\n\n" % (ObjName))
+ FILE.write("g %s\n\n" % (ObjName))
+
+ for v in Vertices:
+ vert = v.co
+ if multiflag == 1:
+ vert = Alter(vert, Transform)
+ x, y, z = vert
+
+ FILE.write("v %s %s %s\n" % (x, y, z))
+
+ uv_flag = 0
+ for face in faces:
+ for uv in face.uv:
+ found = 0
+ index = len(uvList)
+ limit = 0
+ if len(uvList)-200 > 0:
+ limit = len(uvList)-200
+ while index > limit and found == 0:
+ uv_value = uvList[index-1]
+ if uv[0] == uv_value[0] and uv[1] == uv_value[1]:
+ uvPtrs.append(index+uvcount)
+ found = 1
+ index = index - 1
+ if found == 0:
+ uvList.append(uv)
+ index = len(uvList)
+ uvPtrs.append(index+uvcount)
+ u, v = uv
+ FILE.write("vt %s %s\n" % (u, v))
+ uv_flag = 1
+
+ if has_uvco and uv_flag == 0:
+ for v in Vertices:
+ u, v, z = v.uvco
+ u = (u-1)/2
+ v = (v-1)/2
+ FILE.write("vt %s %s\n" % (u, v))
+
+ for v in Vertices:
+ x, y, z = v.no
+ FILE.write("vn %s %s %s\n" % (x, y, z))
+
+ p = 0
+ uvindex = 0
+ total = len(faces)
+
+ for face in faces:
+ p = p+1
+ if (p%1000) == 0:
+ print ("Progress = "+ str(p)+ " of "+ str(total) +" faces")
+
+ FILE.write("f ")
+ for index in range(len(face.v)):
+ v = face.v[index].index + vertexcount
+ if len(face.uv) > 0:
+ FILE.write("%s/%s/%s " % (v+1, uvPtrs[uvindex], v+1))
+ uvindex = uvindex+1
+ elif has_uvco:
+ FILE.write("%s/%s/%s " % (v+1, v+1, v+1))
+ else:
+ FILE.write("%s//%s " % (v+1, v+1))
+ FILE.write("\n")
+
+ vertexcount = vertexcount + len(Vertices)
+ uvcount = uvcount + len(uvList)
+
+ print("Export of " +str(ObjName)+ ".obj finished.\n")
+
+#=====================================================================
+def UseLayers(faces, Vertices, MtlList, has_uvco, FILE, ObjName, Name):
+#=====================================================================
+ global vertexcount
+ global uvcount
+ global multiflag
+
+ uvPtrs = []
+ uvList = []
+
+ FILE.write("mtllib %s\n\n" % (Name + ".mtl"))
+ FILE.write("g %s\n\n" % (ObjName))
+
+ for v in Vertices:
+ vert = v.co
+ if multiflag == 1:
+ vert = Alter(vert, Transform)
+ x, y, z = vert
+ FILE.write("v %s %s %s\n" % (x, y, z))
+
+ uv_flag = 0
+ for m in range(len(MtlList)):
+ for face in faces:
+ if face.mat == m:
+ for uv in face.uv:
+ found = 0
+ index = len(uvList)
+ limit = 0
+ if len(uvList)-200 > 0:
+ limit = len(uvList)-200
+ while index > limit and found == 0:
+ uv_value = uvList[index-1]
+ if uv[0] == uv_value[0] and uv[1] == uv_value[1]:
+ uvPtrs.append(index+uvcount)
+ found = 1
+ index = index - 1
+ if found == 0:
+ uvList.append(uv)
+ index = len(uvList)
+ uvPtrs.append(index+uvcount)
+ u, v = uv
+ FILE.write("vt %s %s\n" % (u, v))
+ uv_flag = 1
+
+ if has_uvco and uv_flag == 0:
+ for v in Vertices:
+ u, v, z = v.uvco
+ u = (u-1)/2
+ v = (v-1)/2
+ FILE.write("vt %s %s\n" % (u, v))
+
+ for v in Vertices:
+ x, y, z = v.no
+ FILE.write("vn %s %s %s\n" % (x, y, z))
+
+ total = len(faces)
+ p = 0
+ uvindex = 0
+ for m in range(len(MtlList)):
+ FILE.write("usemtl %s\n" % (MtlList[m].name))
+ for face in faces:
+ if face.mat == m:
+ p = p+1
+ if (p%1000) == 0:
+ print ("Progress = "+ str(p)+ " of "+ str(total) +" faces")
+
+ FILE.write("f ")
+ for index in range(len(face.v)):
+ v = face.v[index].index + vertexcount
+ if len(face.uv) > 0:
+ FILE.write("%s/%s/%s " % (v+1, uvPtrs[uvindex], v+1))
+ uvindex = uvindex+1
+ elif has_uvco:
+ FILE.write("%s/%s/%s " % (v+1, v+1, v+1))
+ else:
+ FILE.write("%s//%s " % (v+1, v+1))
+ FILE.write("\n")
+
+ vertexcount = vertexcount + len(Vertices)
+ print("Export of " +str(ObjName)+ ".obj using material layers finished.\n")
+
+#==================================================================
+def UseMtl(faces, Vertices, MtlList, has_uvco, FILE, ObjName, Name):
+#==================================================================
+ global vertexcount
+ global multiflag
+
+ FILE.write("mtllib %s\n\n" % (Name + ".mtl"))
+ FILE.write("o %s\n\n" % (ObjName))
+
+ index = 0
+ VertexList = []
+ for vertex in Vertices:
+ VertexList.append(-1)
+ index = index + 1
+ print("number of vertices is " +str(len(VertexList)))
+
+ Totalindex = 0
+ ix = 0
+ NewVertexList = []
+ NewVertexCo = []
+ for m in range(len(MtlList)):
+ # Group name is the name of the mesh
+ if MtlList[m]:
+ FILE.write("g %s\n" % (MtlList[m].name+str(m+1)))
+ else:
+ FILE.write("g %s\n" % ("Null"+str(m+1)))
+ FILE.write("s off\n\n")
+
+ FILE.write("usemtl %s\n\n" % (MtlList[m].name))
+
+ for face in faces:
+ if face.mat == m:
+ for vertex in face.v:
+ v = vertex.index
+ if VertexList[v] < 0:
+ VertexList[v] = Totalindex
+ NewVertexList.append(v)
+ Totalindex = Totalindex + 1
+
+ for v_old in NewVertexList:
+ vert = Vertices[v_old].co
+ if multiflag == 1:
+ vert = Alter(vert, Transform)
+ x, y, z = vert
+ FILE.write("v %s %s %s\n" % (x, y, z))
+ NewVertexCo.append([x,y,z])
+
+ if has_uvco:
+ for v_old in NewVertexList:
+ u, v, z = Vertices[v_old].uvco
+ u = (u-1)/2
+ v = (v-1)/2
+ FILE.write("vt %s %s\n" % (u, v))
+
+ for v_old in NewVertexList:
+ x, y, z = Vertices[v_old].no
+ FILE.write("vn %s %s %s\n" % (x, y, z))
+
+ for face in faces:
+ if face.mat == m:
+ FILE.write("f ")
+ for index in range(len(face.v)):
+ v = face.v[index].index
+ v_new = VertexList[v]
+ if has_uvco:
+ FILE.write("%s/%s/%s " % (v_new+1, v_new+1, v_new+1))
+ else:
+ FILE.write("%s//%s " % (v_new+1, v_new+1))
+ FILE.write("\n")
+
+ FILE.write("\n")
+
+ NewVertexList = []
+ print("Group " +str(m+1)+ " of " +str(len(MtlList))+ " finished.")
+
+ print("Export of " +str(ObjName)+ ".obj using groups finished.\n")
+
+#========================================
+def CreateMatrix(object, Transform):
+#========================================
+ Mx = []
+ My = []
+ Mz = []
+ T1 = []
+ Transform = []
+
+ angle = object.RotX
+ Mx.append([1, 0, 0])
+ y = math.cos(angle)
+ z = -math.sin(angle)
+ Mx.append([0, y, z])
+ y = math.sin(angle)
+ z = math.cos(angle)
+ Mx.append([0, y, z])
+
+ angle = object.RotY
+ x = math.cos(angle)
+ z = math.sin(angle)
+ My.append([x, 0, z])
+ My.append([0, 1, 0])
+ x = -math.sin(angle)
+ z = math.cos(angle)
+ My.append([x, 0, z])
+
+ angle = object.RotZ
+ x = math.cos(angle)
+ y = -math.sin(angle)
+ Mz.append([x, y, 0])
+ x = math.sin(angle)
+ y = math.cos(angle)
+ Mz.append([x, y, 0])
+ Mz.append([0, 0, 1])
+
+ m0 = Mx[0]
+ m1 = Mx[1]
+ m2 = Mx[2]
+ for row in My:
+ x, y, z = row
+ nx = x*m0[0] + y*m1[0] + z*m2[0]
+ ny = x*m0[1] + y*m1[1] + z*m2[1]
+ nz = x*m0[2] + y*m1[2] + z*m2[2]
+ T1.append([nx, ny, nz])
+
+ m0 = T1[0]
+ m1 = T1[1]
+ m2 = T1[2]
+ for row in Mz:
+ x, y, z = row
+ nx = x*m0[0] + y*m1[0] + z*m2[0]
+ ny = x*m0[1] + y*m1[1] + z*m2[1]
+ nz = x*m0[2] + y*m1[2] + z*m2[2]
+ Transform.append([nx, ny, nz])
+
+ Transform.append([object.SizeX, object.SizeY, object.SizeZ])
+ Transform.append([object.LocX, object.LocY, object.LocZ])
+
+ return Transform
+
+#======================================
+def Alter(vect, Transform):
+#======================================
+ v2 = []
+ nv = []
+
+ x, y, z = vect
+ sx, sy, sz = Transform[3]
+ lx, ly, lz = Transform[4]
+
+ v2.append(x*sx)
+ v2.append(y*sy)
+ v2.append(z*sz)
+
+ for index in range(len(vect)):
+ t = Transform[index]
+ nv.append(v2[0]*t[0] + v2[1]*t[1] +v2[2]*t[2])
+
+ nv[0] = nv[0]+lx
+ nv[1] = nv[1]+ly
+ nv[2] = nv[2]+lz
+
+ return nv
\ No newline at end of file
Added: maven/trunk/ogoglio/src/main/resources/blender/ogoglio_avatar.py
===================================================================
--- maven/trunk/ogoglio/src/main/resources/blender/ogoglio_avatar.py (rev 0)
+++ maven/trunk/ogoglio/src/main/resources/blender/ogoglio_avatar.py 2007-09-24 21:26:54 UTC (rev 438)
@@ -0,0 +1,691 @@
+#!BPY
+
+"""
+Name: 'Ogoglio Avatar (.obj, .mlt, .smap)...'
+Blender: 243
+Group: 'Export'
+Tooltip: 'Save As Ogoglio Avatar files'
+"""
+
+__author__ = "Campbell Barton, Jiri Hnidek (modded by Trevor F. Smith)"
+__url__ = ['www.blender.org', 'blenderartists.org', 'ogoglio.com']
+__version__ = "1.0"
+
+__bpydoc__ = """\
+This script is an avatar exporter to OBJ and SMAP file formats.
+
+Usage:
+
+Select the objects you wish to export and run this script from "File->Export" menu.
+Selecting the default options from the popup box will be good in most cases.
+All objects that can be represented as a mesh (mesh, curve, metaball, surface, text3d)
+will be exported as mesh data.
+"""
+
+
+# --------------------------------------------------------------------------
+# OBJ Export v1.1 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 *****
+# --------------------------------------------------------------------------
+
+
+import Blender
+from Blender import Mesh, Scene, Window, sys, Image, Draw
+import BPyMesh
+import BPyObject
+
+import BPyMessages
+
+# Returns a tuple - path,extension.
+# 'hello.obj' > ('hello', '.obj')
+def splitExt(path):
+ dotidx = path.rfind('.')
+ if dotidx == -1:
+ return path, ''
+ else:
+ return path[:dotidx], path[dotidx:]
+
+def fixName(name):
+ if name == None:
+ return 'None'
+ else:
+ return name.replace(' ', '_')
+
+# Used to add the scene name into the filename without using odd chars
+def saneFilechars(name):
+ for ch in ' /\\~!@#$%^&*()+=[];\':",./<>?\t\r\n':
+ name = name.replace(ch, '_')
+ return name
+
+global MTL_DICT
+
+# A Dict of Materials
+# (material.name, image.name):matname_imagename # matname_imagename has gaps removed.
+MTL_DICT = {}
+
+def write_mtl(filename):
+ global MTL_DICT
+
+ world = Blender.World.GetCurrent()
+ if world:
+ worldAmb = world.getAmb()
+ else:
+ worldAmb = (0,0,0) # Default value
+
+ file = open(filename, "w")
+ file.write('# Blender3D MTL File: %s\n' % Blender.Get('filename').split('\\')[-1].split('/')[-1])
+ file.write('# Material Count: %i\n' % len(MTL_DICT))
+ # Write material/image combinations we have used.
+ for key, mtl_mat_name in MTL_DICT.iteritems():
+
+ # Get the Blender data for the material and the image.
+ # Having an image named None will make a bug, dont do it :)
+
+ file.write('newmtl %s\n' % mtl_mat_name) # Define a new material: matname_imgname
+
+ if key[0] == None:
+ #write a dummy material here?
+ file.write('Ns 0\n')
+ file.write('Ka %.6f %.6f %.6f\n' % tuple([c for c in worldAmb]) ) # Ambient, uses mirror colour,
+ file.write('Kd 0.8 0.8 0.8\n')
+ file.write('Ks 0.8 0.8 0.8\n')
+ file.write('d 1\n') # No alpha
+ file.write('illum 2\n') # light normaly
+ else:
+ mat = Blender.Material.Get(key[0])
+ file.write('Ns %.6f\n' % ((mat.getHardness()-1) * 1.9607843137254901) ) # Hardness, convert blenders 1-511 to MTL's
+ file.write('Ka %.6f %.6f %.6f\n' % tuple([c*mat.amb for c in worldAmb]) ) # Ambient, uses mirror colour,
+ file.write('Kd %.6f %.6f %.6f\n' % tuple([c*mat.ref for c in mat.rgbCol]) ) # Diffuse
+ file.write('Ks %.6f %.6f %.6f\n' % tuple([c*mat.spec for c in mat.specCol]) ) # Specular
+ file.write('Ni %.6f\n' % mat.IOR) # Refraction index
+ file.write('d %.6f\n' % mat.alpha) # Alpha (obj uses 'd' for dissolve)
+
+ # 0 to disable lighting, 1 for ambient & diffuse only (specular color set to black), 2 for full lighting.
+ if mat.getMode() & Blender.Material.Modes['SHADELESS']:
+ file.write('illum 0\n') # ignore lighting
+ elif mat.getSpec() == 0:
+ file.write('illum 1\n') # no specular.
+ else:
+ file.write('illum 2\n') # light normaly
+
+
+ # Write images!
+ if key[1] != None: # We have an image on the face!
+ img = Image.Get(key[1])
+ file.write('map_Kd %s\n' % img.filename.split('\\')[-1].split('/')[-1]) # Diffuse mapping image
+
+ elif key[0] != None: # No face image. if we havea material search for MTex image.
+ for mtex in mat.getTextures():
+ if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE:
+ try:
+ filename = mtex.tex.image.filename.split('\\')[-1].split('/')[-1]
+ file.write('map_Kd %s\n' % filename) # Diffuse mapping image
+ break
+ except:
+ # Texture has no image though its an image type, best ignore.
+ pass
+
+ file.write('\n\n')
+
+ file.close()
+
+def copy_file(source, dest):
+ file = open(source, 'rb')
+ data = file.read()
+ file.close()
+
+ file = open(dest, 'wb')
+ file.write(data)
+ file.close()
+
+
+def copy_images(dest_dir):
+ if dest_dir[-1] != sys.sep:
+ dest_dir += sys.sep
+
+ # Get unique image names
+ uniqueImages = {}
+ for matname, imagename in MTL_DICT.iterkeys(): # Only use image name
+ # Get Texface images
+ if imagename != None:
+ uniqueImages[imagename] = None # Should use sets here. wait until Python 2.4 is default.
+
+ # Get MTex images
+ if matname != None:
+ mat= Material.Get(matname)
+ for mtex in mat.getTextures():
+ if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE:
+ try:
+ uniqueImages[mtex.tex.image.name] = None
+ except:
+ pass
+
+ # Now copy images
+ copyCount = 0
+
+ for imageName in uniqueImages.iterkeys():
+ bImage = Image.Get(imageName)
+ image_path = sys.expandpath(bImage.filename)
+ if sys.exists(image_path):
+ # Make a name for the target path.
+ dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1]
+ if not sys.exists(dest_image_path): # Image isnt alredy there
+ print '\tCopying "%s" > "%s"' % (image_path, dest_image_path)
+ copy_file(image_path, dest_image_path)
+ copyCount+=1
+ print '\tCopied %d images' % copyCount
+
+def veckey3d(v):
+ return round(v.x, 6), round(v.y, 6), round(v.z, 6)
+
+def veckey2d(v):
+ return round(v.x, 6), round(v.y, 6)
+
+def write(filename, objects,\
+EXPORT_TRI=False, EXPORT_EDGES=False, EXPORT_NORMALS=False, EXPORT_NORMALS_HQ=False,\
+EXPORT_UV=True, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False,\
+EXPORT_APPLY_MODIFIERS=True, EXPORT_ROTX90=True, EXPORT_BLEN_OBS=True,\
+EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_MORPH_TARGET=False):
+ '''
+ Basic write function. The context and options must be alredy set
+ This can be accessed externaly
+ eg.
+ write( 'c:\\test\\foobar.obj', Blender.Object.GetSelected() ) # Using default options.
+ '''
+ print 'OBJ Export path: "%s"' % filename
+ global MTL_DICT
+ temp_mesh_name = '~tmp-mesh'
+
+ time1 = sys.time()
+ scn = Scene.GetCurrent()
+
+ file = open(filename, "w")
+
+ # Write Header
+ file.write('# Blender3D v%s OBJ File: %s\n' % (Blender.Get('version'), Blender.Get('filename').split('/')[-1].split('\\')[-1] ))
+ file.write('# www.blender3d.org\n')
+
+ # Tell the obj file what material file to use.
+ if EXPORT_MTL:
+ mtlfilename = '%s.mtl' % '.'.join(filename.split('.')[:-1])
+ file.write('mtllib %s\n' % ( mtlfilename.split('\\')[-1].split('/')[-1] ))
+
+ # Get the container mesh. - used for applying modifiers and non mesh objects.
+ containerMesh = meshName = tempMesh = None
+
+ for meshName in Blender.NMesh.GetNames():
+ if meshName.startswith(temp_mesh_name):
+ tempMesh = Mesh.Get(meshName)
+ if not tempMesh.users:
+ containerMesh = tempMesh
+ if not containerMesh:
+ containerMesh = Mesh.New(temp_mesh_name)
+
+ if EXPORT_ROTX90:
+ mat_xrot90= Blender.Mathutils.RotationMatrix(-90, 4, 'x')
+
+ del meshName
+ del tempMesh
+
+ # Initialize totals, these are updated each object
+ totverts = totuvco = totno = 1
+
+ face_vert_index = 1 # used for uvs now
+
+ globalNormals = {}
+
+ # Get all meshs
+ for ob_main in objects:
+ for ob, ob_mat in BPyObject.getDerivedObjects(ob_main):
+ # Will work for non meshes now! :)
+ # getMeshFromObject(ob, container_mesh=None, apply_modifiers=True, vgroups=True, scn=None)
+ me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, True, scn)
+ if not me:
+ continue
+
+ faceuv= me.faceUV
+
+ # We have a valid mesh
+ if EXPORT_TRI and me.faces:
+ # Add a dummy object to it.
+ has_quads = False
+ for f in me.faces:
+ if len(f) == 4:
+ has_quads = True
+ break
+
+ if has_quads:
+ oldmode = Mesh.Mode()
+ Mesh.Mode(Mesh.SelectModes['FACE'])
+
+ me.sel = True
+ tempob = scn.objects.new(me)
+ me.quadToTriangle(0) #...
[truncated message content] |