From ec584662cbe0d0b4acf31fe3ff3a7186b2709fe6 Mon Sep 17 00:00:00 2001 From: John Connors Date: Mon, 11 Aug 2008 00:06:43 +0100 Subject: [PATCH] Adding blender exporter --- sexpr_exporter.py | 1099 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1099 insertions(+) create mode 100644 sexpr_exporter.py diff --git a/sexpr_exporter.py b/sexpr_exporter.py new file mode 100644 index 0000000..1b552f5 --- /dev/null +++ b/sexpr_exporter.py @@ -0,0 +1,1099 @@ +#!BPY + +""" +# Name: 'sexpr (.sexpr)...' +# Blender: 246 +# Group: 'Export' +# Tooltip: 'Export to S-Expressions for reading by Scheme/Lisp Faimily.' +""" +__author__ = "William Robinson and John Connors" +__url__ = ("blender", "blenderartists.org", "http://badbyteblues.blogspot.com/") +__version__ = "1.0" + +__bpydoc__ = """\ +This script exports a Blender mesh with armature as an s-expression in a lispy +format. +""" +# sexpr_exporter.py version 1.0 +# Copyright (C) 2007,2008 William Robinson and John Connors +# +# 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. + + +import Blender +from Blender import Types, Object, NMesh, Material,Armature,Mesh +from Blender.Mathutils import * +from Blender import Draw, BGL +from Blender.BGL import * +import math + +global mat_flip,index_list,space,bone_list,mat_dict +global anim,flip_norm,swap_zy,flip_z,speed,ticks,no_light,recalc_norm,Bl_norm +bone_list =[] +index_list = [] +mat_dict = {} +space = 0;flip_z = 1;anim=0;swap_yz=0;flip_norm=0;speed=0;ticks= 25 +Bl_norm = 1;recalc_norm = 0;no_light = 0 + +toggle_val = 0 +toggle1_val = 0 +toggle2_val = 0 +toggle3_val = 1 +toggle4_val = 0 +toggle5_val = 1 +toggle6_val = 0 +toggle7_val = 0 +anim_tick = Draw.Create(25) + +#*********************************************** +# Only allow letters, digits, and # underscore in Names. +#*********************************************** +def make_legal_name(starting_name): + new_name = starting_name.replace('.','_') + new_name = new_name.replace(' ','_') + if new_name[0].isdigit(): + new_name = '_' + new_name + new_name = '"' + new_name + '"' + return new_name + +#*********************************************** +# MAIN +#*********************************************** + +def my_callback(filename): + if filename.find('.sexpr', -6) <= 0: filename += '.sexpr' + xexport = xExport(filename) + xexport.SelectObjs() + +def my_callback_sel(filename): + if filename.find('.sexpr', -6) <= 0: filename += '.sexpr' + xexport = xExport(filename) + xexport.exportSelMesh() +def event(evt, val): + if evt == Draw.ESCKEY: + Draw.Exit() + return + +def button_event(evt): + global toggle_val,toggle1_val,toggle2_val,toggle3_val,toggle4_val,toggle5_val,toggle6_val,toggle7_val + global flip_z,swap_yz,flip_norm,anim,ticks,speed,no_light,Bl_norm,recalc_norm + arg = __script__['arg'] + if evt == 1: + toggle_val = 1 - toggle_val + anim = toggle_val + Draw.Redraw(1) + if evt == 2: + toggle1_val = 1 - toggle1_val + flip_norm = toggle1_val + Draw.Redraw(1) + if evt == 3: + toggle2_val = 1 - toggle2_val + swap_yz = toggle2_val + Draw.Redraw(1) + if evt == 4: + toggle3_val = 1 - toggle3_val + flip_z = toggle3_val + Draw.Redraw(1) + if evt == 5: + toggle4_val = 1 - toggle4_val + speed = toggle4_val + Draw.Redraw(1) + if evt == 10: + toggle5_val = 1 - toggle5_val + if toggle5_val==1: + toggle6_val = 0 + toggle7_val = 0 + else : + toggle6_val = 1 + toggle7_val = 1 + no_light = toggle7_val + recalc_norm = toggle6_val + Bl_norm = toggle5_val + Draw.Redraw(1) + if evt == 11: + toggle6_val = 1 - toggle6_val + if toggle6_val==1: + toggle5_val = 0 + toggle7_val = 0 + else : + toggle5_val = 1 + toggle7_val = 1 + no_light = toggle7_val + recalc_norm = toggle6_val + Bl_norm = toggle5_val + Draw.Redraw(1) + if evt == 12: + toggle7_val = 1 - toggle7_val + if toggle7_val==1: + toggle6_val = 0 + toggle5_val = 0 + else : + toggle6_val = 1 + toggle5_val = 1 + no_light = toggle7_val + recalc_norm = toggle6_val + Bl_norm = toggle5_val + Draw.Redraw(1) + if evt == 6: + ticks = anim_tick.val + if evt == 7: + fname = Blender.sys.makename(ext = ".sexpr") + Blender.Window.FileSelector(my_callback, "Export Sexpr", fname) + if evt == 8: + fname = Blender.sys.makename(ext = ".sexpr") + Blender.Window.FileSelector(my_callback_sel, "Export Sexpr", fname) + if evt == 9: + Draw.Exit() + + +def draw(): + global animsg,flipmsg,swapmsg,anim_tick + global flip_z,swap_yz,flip_norm,anim,ticks,speed,recalc_norm,Bl_norm,no_light + glClearColor(0.55,0.6,0.6,1) + glClear(BGL.GL_COLOR_BUFFER_BIT) + #external box + glColor3f(0.2,0.3,0.3) + rect(10,402,300,382) + #-- + #glColor3f(0.3,0.4,0.4) + #rect(11,399,298,398) + #-- + glColor3f(0.5,0.75,0.65) + rect(14,398,292,30) + #-- + glColor3f(0.5,0.75,0.65) + rect(14,366,292,160) + #-- + glColor3f(0.5,0.75,0.65) + rect(14,202,292,60) + #-- + glColor3f(0.5,0.75,0.65) + rect(14,138,292,40) + #-- + glColor3f(0.5,0.75,0.65) + rect(14,94,292,70) + + glColor3f(0.8,.8,0.6) + glRasterPos2i(20, 380) + Draw.Text("Sexpr Exporter ",'large') + Draw.Text("(for Blender 2.41)", 'small') + #-------Aniamtion toggle--------------------------------------------- + Draw.Toggle("Anim", 1, 20, 330, 55, 20, toggle_val,"export animations") + if toggle_val : + anim = 1 + animsg = "animation will be exported" + else: + anim = 0 + animsg = "animation will be not exported" + glRasterPos2i(100,335) + Draw.Text(animsg) + #---Flip normals toggle----------------------------------------------- + Draw.Toggle("Flip norm", 2, 20, 300, 55, 20, toggle1_val,"invert normals") + if toggle1_val : + flip_norm = 1 + flipmsg = "flipped normals" + else: + flip_norm = 0 + flipmsg = "not flipped normals" + glRasterPos2i(100,305) + Draw.Text(flipmsg) + #------Swap yz toggle---------------------------------------------------------------- + Draw.Toggle("Swap zy", 3, 20, 270, 55, 20, toggle2_val,"swap z,y axis(y up)") + if toggle2_val : + swap_yz = 1 + swapmsg = "Y-axis up" + else: + swap_yz = 0 + swapmsg = "Z-axis up" + glRasterPos2i(100,275) + Draw.Text(swapmsg) + #------Flip z toggle---------------------------------------------------------------- + Draw.Toggle("Flip z", 4, 20, 240, 55, 20, toggle3_val,"flip z axis") + if toggle3_val : + flip_z = 1 + zmsg = "left handed system" + else: + flip_z = 0 + zmsg = "right handed system" + glRasterPos2i(100,245) + Draw.Text(zmsg) + #------Speed toggle---------------------------------------------------------------- + Draw.Toggle("Speed", 5, 20, 210, 55, 20, toggle4_val,"Animation speed") + if toggle4_val : + speed = 1 + spedmsg = "set speed" + anim_tick = Draw.Number("", 6,200, 210, 85, 20, anim_tick.val,1,100000,"ticks per second") + else: + speed = 0 + spedmsg = "" + glRasterPos2i(100,215) + Draw.Text(spedmsg) + #------Blender Normals toggle---------------------------------------------------------------- + Draw.Toggle("Bl.normals", 10, 20, 105, 75, 25, toggle5_val,"export normals as in Blender") + if toggle5_val : + Bl_norm = 1 + #------Recalculute Normals toggle---------------------------------------------------------------- + Draw.Toggle("recalc.no", 11, 120, 105, 75, 25, toggle6_val,"export recalculated normals") + if toggle6_val : + recalc_norm = 1 + #------Recalculute Normals toggle---------------------------------------------------------------- + Draw.Toggle("no smooth", 12, 220, 105, 75, 25, toggle7_val,"every vertex has the face normal,no smoothing") + if toggle7_val : + no_light = 1 + #------Draw Button export---------------------------------------------------------------- + exp_butt = Draw.Button("Export All",7,20, 155, 75, 30, "export all the scene objects") + sel_butt = Draw.Button("Export Sel",8,120, 155, 75, 30, "export the selected object") + exit_butt = Draw.Button("Exit",9,220, 155, 75, 30, "exit") + glRasterPos2i(20,75) + Draw.Text("(C) 2008 John Connors ") + glRasterPos2i(20,55) + Draw.Text("http://badbyteblues.blogspot.com") + glRasterPos2i(20,35) + Draw.Text("johnc@yagc.ndo.co.uk") + +def rect(x,y,width,height): + glBegin(GL_LINE_LOOP) + glVertex2i(x,y) + glVertex2i(x+width,y) + glVertex2i(x+width,y-height) + glVertex2i(x,y-height) + glEnd() + +def rectFill(x,y,width,height): + glBegin(GL_POLYGON) + glVertex2i(x,y) + glVertex2i(x+width,y) + glVertex2i(x+width,y-height) + glVertex2i(x,y-height) + glEnd() + + + +Draw.Register(draw, event, button_event) + + +#*********************************************** +#*********************************************** +# EXPORTER +#*********************************************** +#*********************************************** + +class xExport: + def __init__(self, filename): + self.file = open(filename, "w") + +#********************************************************************************************************************************************* + #*********************************************** + #Select Scene objects + #*********************************************** + def analyzeScene(self): + parent_list = [] + for obj in Blender.Scene.GetCurrent().objects: + if obj.type in ('Mesh', 'Armature', 'Empty'): + if obj.parent == None : + parent_list.append(obj) + + return parent_list + + def getChildren(self,obj): + obs = Blender.Scene.GetCurrent().objects + return [ ob for ob in obs if ob.parent == obj ] + + def getArmChildren(self,obj): + for ob in Blender.Scene.GetCurrent().objects: #Object.Get(): + if ob.parent == obj : + return ob + + def getLocMat(self, obj): + pare = obj.parent + mat = obj.matrixWorld + mat_id = Matrix([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]) + if pare: + mat_p = pare.matrixWorld + mat_c = Matrix(mat_p) + mat_c.invert() + mat_f = mat * mat_c + else : + mat_id.invert() + mat_f = mat * mat_id + return mat_f + + def writeObjFrames(self,obj): + global space,chld_obj,ch_list + mesh = obj.getData() + if obj.type == "Empty" : + mat = self.getLocMat(obj) + mat_c = Matrix(mat) + self.writeArmFrames(mat_c, make_legal_name(obj.name)) + if type(mesh) == Types.ArmatureType : + Child_obj = self.getArmChildren(obj) + chld_obj = obj + ch_list.append(Child_obj) + self.writeRootBone(obj, Child_obj) + if obj.type == 'Mesh' and obj not in ch_list: + self.exportMesh(obj) + + + def writeChildObj(self,obj): + global space,ch_list + space += 1 + if obj : + for ob in obj: + if ob not in ch_list: + self.writeObjFrames(ob) + ch_list.append(ob) + ch_ob = self.getChildren(ob) + self.writeChildObj(ch_ob) + self.closeBrackets() + self.file.write(" ; End of the Object %s \n" % (ob.name)) + + + def writeRootFrame(self): + global flip_z,swap_yz,speed + if speed: + self.writeAnimTicks() + if flip_z: + mat_flip = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]) + else : + mat_flip = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]) + if swap_yz : + mat_rot = RotationMatrix(-90, 4, 'x') + mat_flip = mat_rot * mat_flip + self.writeArmFrames(mat_flip, ":RootFrame") + + ################################################################## + def SelectObjs(self): + global space,chld_obj,ch_list,flip_z,swap_yz,speed + print "exporting..." + self.writeHeader() + self.writeRootFrame() + obj_list = self.analyzeScene() + space += 1 + ch_list = [] + for obj in obj_list: + self.writeObjFrames(obj) + ch_l = self.getChildren(obj) + for ch in ch_l: + + + if ch and ch.type == "Armature": + ch_list.append(ch) + self.writeObjFrames(ch) + else : + self.writeChildObj(ch_l) + if obj.type != "Armature": + self.file.write(" ) ; SI End of the Object %s \n" % (obj.name)) + + + + self.file.write(") ; End of the Root Frame\n") + if anim : + self.file.write("(:AnimationSet :AnimationSet0 \n") + for obj in Blender.Scene.GetCurrent().objects: + if obj.type in ('Mesh', 'Empty'): + ip_list = obj.ipo + if ip_list != None : + self.writeAnimationObj(obj) + elif obj.type == 'Armature': + act_list = obj.getAction() + if act_list != None : + self.writeAnimation(obj) + #ip_list = obj.ipo + #if ip_list != None : + # self.writeAnimationObj(obj) + + self.file.write(") ; End of Animation Set\n") + self.writeEnd() + ####################################################### + + + def writeAnimTicks(self): + global ticks + self.file.write("(:AnimTicksPerSecond \n") + self.file.write("%d \n" % (ticks)) + self.file.write(")\n") + + #*********************************************** + #Export Mesh without Armature + #*********************************************** + def exportMesh(self, obj): + tex = [] + mesh = obj.getData() + self.writeTextures(obj, tex) + self.writeMeshcoordArm(obj, arm_ob = None) + self.writeMeshMaterialList(obj, mesh, tex) + self.writeMeshNormals(obj, mesh) + self.writeMeshTextureCoords(obj, mesh) + self.file.write(") ; End of the Mesh %s \n" % (obj.name)) + + + #*********************************************** + #Export the Selected Mesh + #*********************************************** + def exportSelMesh(self): + print "exporting ..." + self.writeHeader() + self.writeRootFrame() + tex = [] + objs = Object.GetSelected() + for obj in objs: + if obj.type == 'Mesh': + mesh = obj.data + self.writeTextures(obj, tex) + self.writeMeshcoordArm(obj, arm_ob = None) + self.writeMeshMaterialList(obj, mesh, tex) + self.writeMeshNormals(obj, mesh) + self.writeMeshTextureCoords(obj, mesh) + self.file.write(")\n") + self.file.write(")\n") + ind = objs.index(obj) + if ind == len(objs)-1: + self.file.write(")\n") + ip_list = obj.ipo + if ip_list != None : + self.file.write("(:AnimationSet :AnimationSet0 \n") + self.writeAnimationObj(obj) + self.file.write(")\n") + else : + print "The selected object is not a mesh" + print "...finished" + #*********************************************** + #Export Mesh with Armature + #*********************************************** + def exportMeshArm(self,arm,arm_ob,ch_obj): + tex = [] + mesh = ch_obj.getData() + self.writeTextures(ch_obj, tex) + self.writeMeshcoordArm(ch_obj ,arm_ob) + self.writeMeshMaterialList(ch_obj, mesh, tex) + self.writeMeshNormals(ch_obj, mesh) + self.writeMeshTextureCoords(ch_obj, mesh) + self.writeSkinWeights(arm,mesh) + #self.file.write(" ) ; End of the Frame %s \n" % (ch_obj.name)) + self.file.write(") ; End of the Object %s \n" % (ch_obj.name)) + + #*********************************************** + #Export Root Bone + #*********************************************** + def writeRootBone(self, chld_obj, child_obj): + global space,root_bon + arms = chld_obj.getData() + mat_arm = self.getLocMat(chld_obj) + for bon in arms.bones.values(): + if bon.hasParent(): + pass + else: + root_bon = bon + space += 1 + mat_r = self.writeAnimCombineMatrix(root_bon,1) + self.writeArmFrames(mat_r, make_legal_name(root_bon.name)) + + bon_c = root_bon.children + self.writeChildren(bon_c) + self.file.write(") ; End of the Bone %s \n" % (root_bon.name)) + self.exportMeshArm(arms, chld_obj ,child_obj) + + #*********************************************** + #Create Children structure + #*********************************************** + def writeBon(self,bon): + global space + mat_r = self.writeAnimCombineMatrix(bon,1) + self.writeArmFrames(mat_r, make_legal_name(bon.name)) + + + def writeChildren(self,bon_c): + global space,bone_list + space += 1 + if bon_c: + for bo in bon_c: + if bo.name not in bone_list: + self.writeBon(bo) + bone_list.append(bo.name) + bo_c = bo.children + self.writeChildren(bo_c) + self.closeBrackets() + + + + def closeBrackets(self): + global space + space = space-1 + tab = " " + self.file.write(")\n") + + + + #*********************************************** + #Offset Matrix + #*********************************************** + def writeMatrixOffset(self,bon): + global chld_obj + Blender.Set('curframe', 1) + pose = chld_obj.getPose() + pos_b = pose.bones[bon.name] + mat_b = pos_b.poseMatrix + mat_c = Matrix(mat_b) + mat_c.invert() + return mat_c + + + #*********************************************** + #Combine Matrix + #*********************************************** + def writeCombineMatrix(self,bon): + global chld_obj + + Blender.Set('curframe', 1) + pose = chld_obj.getPose() + pos_b = pose.bones[bon.name] + mat_b = pos_b.poseMatrix + if bon.hasParent(): + pare = bon.parent + pos_p = pose.bones[pare.name] + mat_p = pos_p.poseMatrix + else: + mat_p = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]) + mat_c = Matrix(mat_p) + mat_c.invert() + mat_f = mat_b * mat_c + + return mat_f + #*********************************************** + #Combine Matrix + #*********************************************** + def writeAnimCombineMatrix(self,bon,fre): + global chld_obj + Blender.Set('curframe', fre) + pose = chld_obj.getPose() + pos_b = pose.bones[bon.name] + mat_b = pos_b.poseMatrix + if bon.hasParent(): + pare = bon.parent + pos_p = pose.bones[pare.name] + mat_p = pos_p.poseMatrix + + else: + mat_p = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]) + mat_c = Matrix(mat_p) + mat_c.invert() + mat_f = mat_b * mat_c + + return mat_f + + +#********************************************************************************************************************************************* + #*********************************************** + #Write SkinWeights + #*********************************************** + def writeSkinWeights(self, arm, mesh): + global index_list + v_dict = {} + Blender.Set('curframe',1) + self.file.write("(:XSkinMeshHeader \n") + max_infl = 0 + for bo in arm.bones.values() : + name = bo.name + try : + vertx_list = mesh.getVertsFromGroup(name,1) + for inde in vertx_list : + vert_infl = mesh.getVertexInfluences(inde[0]) + ln_infl = len(vert_infl) + if ln_infl > max_infl : + max_infl = ln_infl + + except: + pass + + self.file.write("%d \n" % (max_infl)) + self.file.write("%d \n" % (max_infl * 3)) + self.file.write("%d \n" % (len(arm.bones.values()))) + self.file.write(")\n") + + for bo in arm.bones.values() : + bo_list = [] + weight_list = [] + name = bo.name + f_name = make_legal_name(name) + try : + vert_list = mesh.getVertsFromGroup(name,1) + le = 0 + for indx in vert_list: + ver_infl = mesh.getVertexInfluences(indx[0]) + infl = 0.0 + if len(ver_infl) != 0: + sum = 0.0 + for bone_n, weight in ver_infl: + if bone_n == name: + infl = weight + sum += weight + infl /= sum + + i = -1 + for el in index_list : + i += 1 + if el == indx[0] : + le +=1 + bo_list.append(i) + weight_list.append(infl) + + + self.file.write("(:SkinWeights \n") + self.file.write('"%s"\n' % (f_name)) + self.file.write('%d\n' % (le)) + count = 0 + for ind in bo_list : + count += 1 + if count == len(bo_list): + self.file.write("%d\n" % (ind)) + else : + self.file.write("%d\n" % (ind)) + cou = 0 + for wegh in weight_list : + cou += 1 + + if cou == len(weight_list): + self.file.write("%f\n" % (round(wegh,6))) + else : + self.file.write("%f\n" % (round(wegh,6))) + + + matx = self.writeMatrixOffset(bo) + self.writeOffsFrames(matx, name) + except : + pass + self.file.write(") ; End of XSkinMeshHeader\n") + + + #*********************************************** + # Write Matrices + #*********************************************** + def writeArmFrames(self, matx, name): + self.file.write("(:Frame ") + self.file.write("%s \n\n" % (name)) + self.file.write("(:FrameTransformMatrix \n\n") + self.writeFrame(matx) + + #*********************************************** + # Write Frames + #*********************************************** + def writeOffsFrames(self, matx, name): + space = 1 + self.writeFrame(matx) + + #*********************************************** + # Write Frames + #*********************************************** + def writeFrame(self, matx): + self.file.write("%f %f %f %f \n" % + (round(matx[0][0],4),round(matx[0][1],4),round(matx[0][2],4),round(matx[0][3],4))) + self.file.write("%f %f %f %f\n" % + (round(matx[1][0],4),round(matx[1][1],4),round(matx[1][2],4),round(matx[1][3],4))) + self.file.write("%f %f %f %f \n" % + (round(matx[2][0],4),round(matx[2][1],4),round(matx[2][2],4),round(matx[2][3],4))) + self.file.write("%f %f %f %f\n" % + (round(matx[3][0],4),round(matx[3][1],4),round(matx[3][2],4),round(matx[3][3],4))) + self.file.write(")\n") +#********************************************************************************************************************************************* + + #*********************************************** + #HEADER + #*********************************************** + def writeHeader(self): + pass + + #*********************************************** + #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 with Armature + #*********************************************** + def writeMeshcoordArm(self, obj ,arm_ob): + global index_list,flip_z + #TransformMatrix + mat = self.getLocMat(obj) + self.writeArmFrames(mat, make_legal_name(obj.name)) + mesh = NMesh.GetRawFromObject(obj.name) + self.file.write("(:Mesh \n") + numface=len(mesh.faces) + #VERTICES NUMBER + numvert = 0 + for face in mesh.faces: + numvert = numvert + len(face.v) + self.file.write("%d ;; nvertices\n" % (numvert)) + if numvert == 0: + print "Mesh named",mesh.name,"has no vertices.Problems may occur using the .sexpr file" + #VERTICES COORDINATES + counter = 0 + for face in mesh.faces: + counter += 1 + for n in range(len(face.v)): + index_list.append(face.v[n].index) + vec_vert = Vector([(face.v[n].co[0]), face.v[n].co[1], face.v[n].co[2], 1]) + if arm_ob : + f_vec_vert = vec_vert * mat + else : + f_vec_vert = vec_vert + self.file.write("%f %f %f" % (round(f_vec_vert[0],4), round(f_vec_vert[1],4), round(f_vec_vert[2],4))) + if counter == numface : + if n == len(face.v)-1 : + self.file.write("\n") + else : + self.file.write("\n") + else : + self.file.write("\n") + if flip_z: + a3 = 0;b3 = 2;c3 = 1 + a4 = 0;b4 = 3;c4 = 2;d4 = 1 + else: + a3 = 0;b3 = 1;c3 = 2 + a4 = 0;b4 = 1;c4 = 2;d4 = 3 + + #FACES NUMBER + self.file.write("%s ;; numfaces\n" % (numface)) + coun,counter = 0, 0 + for face in mesh.faces : + coun += 1 + separator = ',' + if coun == numface: + separator = ';' + if len(face.v) == 3: + self.file.write("3 %d %d %d\n" % (counter + a3, counter + b3, counter + c3)) + counter += 3 + elif len(face.v) == 4: + self.file.write("4 %d %d %d %d\n" % (counter + a4, counter + b4, counter + c4, counter + d4)) + counter += 4 + elif len(face.v) < 3: + print "WARNING:the mesh has faces with less then 3 vertices" + print " It my be not exported correctly." + + + #*********************************************** + #MESH MATERIAL LIST + #*********************************************** + def writeMeshMaterialList(self, obj, mesh, tex): + self.file.write("(:MeshMaterialList \n") + #HOW MANY MATERIALS ARE USED + count = 0 + for mat in mesh.getMaterials(): + count+=1 + self.file.write("%d ; nMaterials\n" % (len(tex) + count)) + #HOW MANY FACES IT HAS + numfaces=len(mesh.faces) + self.file.write("%d ;; nFaces\n" % (numfaces)) + ##MATERIALS INDEX FOR EVERY FACE + counter = 0 + for face in mesh.faces : + counter += 1 + mater = face.materialIndex + if counter == numfaces: + if face.image and face.image.name in tex : + self.file.write(" %d\n" % (tex.index(face.image.name) + count)) + else : + self.file.write(" %d\n" % (mater)) + else : + if face.image and face.image.name in tex : + self.file.write(" %d\n" % (tex.index(face.image.name) + count)) + else : + self.file.write(" %d\n" % (mater)) + + ##MATERIAL NAME + for mat in mesh.getMaterials(): + self.file.write("(:Material") + self.file.write(" %s \n"% (make_legal_name(mat.name))) + self.file.write(" %f %f %f " % (mat.R, mat.G, mat.B)) + self.file.write("%s \n" % (mat.alpha)) + self.file.write(" %f \n" % (mat.spec)) + self.file.write(" %f %f %f \n" % (mat.specR, mat.specG, mat.specB)) + self.file.write(" 0.0 0.0 0.0 \n") + self.file.write(") ;End of Material\n") + + for mat in tex: + self.file.write("(:Material Mat") + self.file.write("%s \n"% (len(tex))) + 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 ") + self.file.write(' "%s" '% (mat)) + self.file.write(")\n") + self.file.write(") ; End of Material\n") + self.file.write(") ;End of MeshMaterialList\n") + + #*********************************************** + #MESH NORMALS + #*********************************************** + def writeMeshNormals(self,name,mesh): + global flip_norm,flip_z,no_light,recalc_norm,Bl_norm + + self.file.write("(:MeshNormals \n") + #VERTICES NUMBER + numvert = 0 + for face in mesh.faces: + numvert = numvert + len(face.v) + self.file.write("%d ;; nNormals\n" % (numvert)) + numfaces=len(mesh.faces) + if flip_norm : + fl = -1 + else : + fl = 1 + #VERTICES NORMAL + if Bl_norm: + self.writeBlenderNormals(mesh,fl) + if recalc_norm: + self.writeRecalcNormals(mesh,fl) + if no_light: + self.writeNoSmothing(mesh,fl) + + + + if flip_z: + a3 = 0;b3 = 2;c3 = 1 + a4 = 0;b4 = 3;c4 = 2;d4 = 1 + else: + a3 = 0;b3 = 1;c3 = 2 + a4 = 0;b4 = 1;c4 = 2;d4 = 3 + + #FACES NUMBER + self.file.write("%s \n" % (numfaces)) + coun,counter = 0, 0 + for face in mesh.faces : + coun += 1 + if coun == numfaces: + if len(face.v) == 3: + self.file.write("3 %d %d %d\n" % (counter + a3, counter + b3, counter + c3)) + counter += 3 + else : + self.file.write("4 %d %d %d %d\n" % (counter + a4, counter + b4, counter + c4, counter + d4)) + counter += 4 + else: + + if len(face.v) == 3: + self.file.write("3 %d %d %d\n" % (counter + a3, counter + b3, counter + c3)) + counter += 3 + else : + self.file.write("4 %d %d %d %d\n" % (counter + a4, counter + b4, counter + c4, counter + d4)) + counter += 4 + self.file.write(") ; End of MeshNormals\n") + + def writeBlenderNormals(self,mesh,fl): + numfaces=len(mesh.faces) + #VERTICES NORMAL + counter = 0 + for face in mesh.faces: + counter += 1 + for n in range(len(face.v)): + self.file.write(" %f %f %f" % ( + (round(face.v[n].no[0],6)*fl),(round(face.v[n].no[1],6)*fl),(round(face.v[n].no[2],6)*fl))) + if counter == numfaces : + if n == len(face.v)-1 : + self.file.write("\n") + else : + self.file.write("\n") + else : + self.file.write("\n") + + + def writeRecalcNormals(self,mesh,fl): + numfaces=len(mesh.faces) + normal_list = {} + idx = 0 + for vertex in mesh.verts: + v_norm = Vector([0, 0, 0]) + normal_list[idx] = v_norm + idx += 1 + for face in mesh.faces: + for verts in face.v: + if verts.index == vertex.index : + v_norm[0] += face.no[0] + v_norm[1] += face.no[1] + v_norm[2] += face.no[2] + v_norm.normalize() + counter = 0 + for face in mesh.faces: + counter += 1 + n = 0 + for vert in face.v: + n += 1 + norm = normal_list[vert.index] + self.file.write("%f %f %f" % ((round(norm[0],6)*fl),(round(norm[1],6)*fl),(round(norm[2],6)*fl))) + self.file.write("\n") + + def writeNoSmothing(self,mesh,fl): + numfaces=len(mesh.faces) + counter = 0 + for face in mesh.faces: + counter += 1 + n = 0 + for n in range(len(face.v)): + self.file.write(" %f %f %f" % ((round(face.no[0],6)*fl),(round(face.no[1],6)*fl),(round(face.no[2],6)*fl))) + self.file.write("\n") + + #*********************************************** + #MESH TEXTURE COORDS + #*********************************************** + def writeMeshTextureCoords(self, name, mesh): + if mesh.hasFaceUV(): + self.file.write("(:MeshTextureCoords \n") + #VERTICES NUMBER + numvert = 0 + for face in mesh.faces: + numvert += len(face.v) + self.file.write("%d\n ;; nUVS" % (numvert)) + #UV COORDS + numfaces = len(mesh.faces) + counter = -1 + co = 0 + for face in mesh.faces: + counter += 1 + co += 1 + for n in range(len(face.v)): + self.file.write("%f %f" % (mesh.faces[counter].uv[n][0], -mesh.faces[counter].uv[n][1])) + if co == numfaces : + if n == len(face.v) - 1 : + self.file.write("\n") + else : + self.file.write("\n") + else : + self.file.write("\n") + self.file.write(") ; End of MeshTextureCoords\n") + +#***********************************************#***********************************************#*********************************************** + #*********************************************** + #FRAMES + #*********************************************** + def writeFrames(self, matx): + + self.file.write("%f %f %f %f " % + (round(matx[0][0],4),round(matx[0][1],4),round(matx[0][2],4),round(matx[0][3],4))) + self.file.write("%f %f %f %f " % + (round(matx[1][0],4),round(matx[1][1],4),round(matx[1][2],4),round(matx[1][3],4))) + self.file.write("%f %f %f %f " % + (round(matx[2][0],4),round(matx[2][1],4),round(matx[2][2],4),round(matx[2][3],4))) + self.file.write("%f %f %f %f " % + (round(matx[3][0],4),round(matx[3][1],4),round(matx[3][2],4),round(matx[3][3],4))) + + + + + + #*********************************************** + #WRITE ANIMATION KEYS + #*********************************************** + def writeAnimation(self,arm_ob): + global mat_dict, root_bon + arm = arm_ob.getData() + act_list = arm_ob.getAction() + ip = act_list.getAllChannelIpos() + for bon in arm.bones.values() : + point_list = [] + name = bon.name + name_f = make_legal_name(name) + try : + ip_bon_channel = ip[bon.name] + ip_bon_name = ip_bon_channel.getName() + + ip_bon = Blender.Ipo.Get(ip_bon_name) + poi = ip_bon.getCurves() + + for po in poi[3].getPoints(): + a = po.getPoints() + point_list.append(int(a[0])) + #point_list.pop(0) + + self.file.write("(:Animation \n") + self.file.write("( %s )\n" %(name_f)) + self.file.write("(:AnimationKey \n") + self.file.write("4 ") + self.file.write("%d\n" % (len(point_list))) + + for fr in point_list: + + if name == root_bon.name : + + + mat_b = self.writeAnimCombineMatrix(bon,fr) + mat_arm = self.getLocMat(arm_ob) + mat = mat_b * mat_arm + else: + mat = self.writeAnimCombineMatrix(bon,fr) + + self.file.write("%d " % (fr)) + self.file.write("16 ") + + self.writeFrames(mat) + + if fr == point_list[len(point_list)-1]: + self.file.write("\n") + else: + self.file.write("\n") + self.file.write(")\n") + self.file.write(")\n") + except: + pass + + + + #*********************************************** + #WRITE ANIMATION KEYS + #*********************************************** + def writeAnimationObj(self, obj): + point_list = [] + ip = obj.ipo + poi = ip.getCurves() + for po in poi[0].getPoints(): + a = po.getPoints() + point_list.append(int(a[0])) + + self.file.write("(:Animation \n") + self.file.write("( ") + self.file.write("%s )\n" % (make_legal_name(obj.name))) + self.file.write("(:AnimationKey \n") + self.file.write("4 ") + self.file.write("%d \n" % (len(point_list))) + for fr in point_list: + self.file.write(" %d " % (fr)) + self.file.write(" 16 ") + Blender.Set('curframe',fr) + + #mat_new = self.getLocMat(obj) + mat_new = obj.matrixLocal + self.writeFrames(mat_new) + self.file.write("\n") + + self.file.write(")\n") + self.file.write(")\n") + + + +#***********************************************#***********************************************#*********************************************** + + + + + -- 2.11.4.GIT