diff --git a/release/scripts/DirectX8Exporter.py b/release/scripts/DirectX8Exporter.py index b051d7f5713..df2c564a10f 100644 --- a/release/scripts/DirectX8Exporter.py +++ b/release/scripts/DirectX8Exporter.py @@ -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) diff --git a/release/scripts/DirectXExporter.py b/release/scripts/DirectXExporter.py index f6f2bbd8bf6..4fa0d1c83f6 100644 --- a/release/scripts/DirectXExporter.py +++ b/release/scripts/DirectXExporter.py @@ -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) diff --git a/release/scripts/disp_paint233f.py b/release/scripts/disp_paint233f.py index e3e6636f63f..ed2db043fb2 100644 --- a/release/scripts/disp_paint233f.py +++ b/release/scripts/disp_paint233f.py @@ -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.' """ diff --git a/release/scripts/knife.py b/release/scripts/knife.py index d1df1007f1d..dfe3135dd68 100644 --- a/release/scripts/knife.py +++ b/release/scripts/knife.py @@ -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' """ diff --git a/release/scripts/obj_export.py b/release/scripts/obj_export.py index 333f54fe59f..8d52a06d6d9 100644 --- a/release/scripts/obj_export.py +++ b/release/scripts/obj_export.py @@ -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')) diff --git a/release/scripts/obj_import.py b/release/scripts/obj_import.py index 7eeca8176e4..90f287559b1 100644 --- a/release/scripts/obj_import.py +++ b/release/scripts/obj_import.py @@ -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') \ No newline at end of file diff --git a/release/scripts/unweld044.py b/release/scripts/unweld044.py index 469200ad142..d6fa71090a1 100644 --- a/release/scripts/unweld044.py +++ b/release/scripts/unweld044.py @@ -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' """ diff --git a/source/blender/python/BPY_menus.c b/source/blender/python/BPY_menus.c index 401e15e177d..a54062165ee 100644 --- a/source/blender/python/BPY_menus.c +++ b/source/blender/python/BPY_menus.c @@ -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"; diff --git a/source/blender/python/BPY_menus.h b/source/blender/python/BPY_menus.h index 0c1c20161b4..bafeb59dc8c 100644 --- a/source/blender/python/BPY_menus.h +++ b/source/blender/python/BPY_menus.h @@ -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; diff --git a/source/blender/python/api2_2x/Sys.c b/source/blender/python/api2_2x/Sys.c index a7356d39639..9bf6dec7283 100644 --- a/source/blender/python/api2_2x/Sys.c +++ b/source/blender/python/api2_2x/Sys.c @@ -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'; } }