forked from bartvdbraak/blender
- Scripts:
Campbell Barton updated his Wavefront OBJ scripts and Ben Omari updated his DirectX 7 and 8 ones (thanks both). The other listed scripts had minor updates to accomodate the menu changes. - Scripts in menus: renamed Tools to Object, Generators to Add, and Modifiers to Mesh (Metaball, Curve, Surface can be added later), to integrate better in the interface. - Fixed a bug in Blender.sys.makename: last letter of file extension was being cut out.
This commit is contained in:
parent
625e7fb12c
commit
a41759cb8b
@ -1,14 +1,18 @@
|
||||
#!BPY
|
||||
|
||||
""" Registration info for Blender menus:
|
||||
Name: 'DirectX'
|
||||
Blender: 233
|
||||
Name: 'DirectX8'
|
||||
Blender: 234
|
||||
Group: 'Export'
|
||||
Submenu: 'Mesh,armatures,animations' mesh
|
||||
Submenu: 'Export to DX8 file format' export
|
||||
Submenu: 'How to use this exporter?' help
|
||||
Tip: 'Export to DirectX8 text file format format.'
|
||||
"""
|
||||
# DirectX.py version 2.0
|
||||
# Copyright (C) 2003 Arben OMARI -- aromari@tin.it
|
||||
|
||||
# $Id$
|
||||
#
|
||||
# DirectX8Exporter.py version 1.0
|
||||
# Copyright (C) 2003 Arben OMARI -- omariarben@everyday.com
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -34,6 +38,48 @@ bon_list = []
|
||||
new_bon = {}
|
||||
mat_flip = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1])
|
||||
|
||||
def draw():
|
||||
|
||||
# clearing screen
|
||||
Blender.BGL.glClearColor(0.5, 0.5, 0.5, 1)
|
||||
Blender.BGL.glColor3f(1.,1.,1.)
|
||||
Blender.BGL.glClear(Blender.BGL.GL_COLOR_BUFFER_BIT)
|
||||
|
||||
# Buttons
|
||||
Blender.Draw.Button("Exit", 1, 10, 40, 100, 25)
|
||||
|
||||
#Text
|
||||
Blender.BGL.glColor3f(1, 1, 1)
|
||||
Blender.BGL.glRasterPos2d(10, 310)
|
||||
Blender.Draw.Text("1.Only one mesh and one armature in the scene")
|
||||
Blender.BGL.glRasterPos2d(10, 290)
|
||||
Blender.Draw.Text("2.Before parenting set:")
|
||||
|
||||
|
||||
|
||||
Blender.BGL.glRasterPos2d(10, 270)
|
||||
Blender.Draw.Text(" a)Armature and mesh must have the same origin location")
|
||||
Blender.BGL.glRasterPos2d(10, 255)
|
||||
Blender.Draw.Text(" (press N for both and set the same LocX,LocY and LocZ)")
|
||||
Blender.BGL.glRasterPos2d(10, 230)
|
||||
Blender.Draw.Text(" b)Armature and mesh must have the same to rotation")
|
||||
Blender.BGL.glRasterPos2d(10, 215)
|
||||
Blender.Draw.Text(" (select them and press Ctrl + A)")
|
||||
Blender.BGL.glRasterPos2d(10, 195)
|
||||
Blender.Draw.Text("3.Flip Normals ")
|
||||
Blender.BGL.glRasterPos2d(10, 175)
|
||||
Blender.Draw.Text("4.Set the number of the animation frames to export ")
|
||||
Blender.BGL.glRasterPos2d(10, 155)
|
||||
Blender.Draw.Text("5.Read warnings in console(if any)")
|
||||
|
||||
def event(evt, val):
|
||||
if evt == Blender.Draw.ESCKEY and not val: Blender.Draw.Exit()
|
||||
|
||||
def bevent(evt):
|
||||
|
||||
if evt == 1: Blender.Draw.Exit()
|
||||
|
||||
|
||||
|
||||
#***********************************************
|
||||
#***********************************************
|
||||
@ -80,7 +126,12 @@ class xExport:
|
||||
Blender.Set('curframe',1)
|
||||
am_ob = Object.Get(name.name)
|
||||
mat_ob = mat_flip * am_ob.getMatrix()
|
||||
self.writeArmFrames(mat_ob, "RootFrame", 0)
|
||||
mat_o = Matrix([mat_ob[0][0],mat_ob[0][1],mat_ob[0][2],mat_ob[0][3]],
|
||||
[mat_ob[1][0],mat_ob[1][1],mat_ob[1][2],mat_ob[1][3]],
|
||||
[mat_ob[2][0],mat_ob[2][1],mat_ob[2][2],mat_ob[2][3]],
|
||||
[0, 0, 0, 1])
|
||||
|
||||
self.writeArmFrames(mat_o, "RootFrame", 0)
|
||||
root_bon = arm.getBones()
|
||||
bon_list.append(root_bon[0])
|
||||
mat_r = self.writeCombineMatrix(root_bon[0])
|
||||
@ -348,6 +399,7 @@ template SkinWeights {\n\
|
||||
mat_ob = name.getMatrix()
|
||||
mat_ar = armat.getInverseMatrix()
|
||||
mat_f = mat_ob * mat_ar
|
||||
|
||||
self.writeArmFrames(mat_f, "body", 1)
|
||||
|
||||
self.file.write(" Mesh object {\n")
|
||||
@ -432,9 +484,6 @@ template SkinWeights {\n\
|
||||
self.file.write(" %s;\n" % (mat.spec))
|
||||
self.file.write(" %s; %s; %s;;\n" % (mat.specR, mat.specG, mat.specB))
|
||||
self.file.write(" 0.0; 0.0; 0.0;;\n")
|
||||
self.file.write(" TextureFilename {\n")
|
||||
self.file.write(' "none" ;')
|
||||
self.file.write(" }\n")
|
||||
self.file.write(" }\n")
|
||||
|
||||
for mat in tex:
|
||||
@ -485,6 +534,7 @@ template SkinWeights {\n\
|
||||
elif len(face.v) == 4 :
|
||||
self.file.write(" 4; %s, %s, %s, %s;,\n" % (face[0].index, face[1].index, face[2].index, face[3].index))
|
||||
self.file.write("}\n")
|
||||
|
||||
#***********************************************
|
||||
#MESH TEXTURE COORDS
|
||||
#***********************************************
|
||||
@ -565,15 +615,22 @@ template SkinWeights {\n\
|
||||
self.file.write("}\n")
|
||||
|
||||
#***********************************************#***********************************************#***********************************************
|
||||
|
||||
|
||||
|
||||
#***********************************************
|
||||
# MAIN
|
||||
#***********************************************
|
||||
|
||||
|
||||
def my_callback(filename):
|
||||
if filename.find('.x', -2) <= 0: filename += '.x' # add '.x' if the user didn't
|
||||
if filename.find('.x', -2) <= 0: filename += '.x'
|
||||
xexport = xExport(filename)
|
||||
xexport.writeRootBone()
|
||||
|
||||
|
||||
Blender.Window.FileSelector(my_callback, "Export DirectX8")
|
||||
arg = __script__['arg']
|
||||
if arg == 'help':
|
||||
Blender.Draw.Register(draw,event,bevent)
|
||||
else:
|
||||
fname = Blender.sys.makename(ext = ".x")
|
||||
Blender.Window.FileSelector(my_callback, "Export DirectX8", fname)
|
||||
|
@ -1,17 +1,18 @@
|
||||
#!BPY
|
||||
|
||||
""" Registration info for Blender menus:
|
||||
Name: 'DirectX (.X)...'
|
||||
Blender: 232
|
||||
Name: 'DirectX'
|
||||
Blender: 234
|
||||
Group: 'Export'
|
||||
Submenu: 'Only Mesh Data...' mesh
|
||||
Submenu: '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)
|
||||
@ -77,7 +79,6 @@ class xExport:
|
||||
for name in Object.Get():
|
||||
obj = name.getData()
|
||||
if type(obj) == Types.NMeshType :
|
||||
self.writeMaterials(name,tex)
|
||||
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,17 +114,6 @@ 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")
|
||||
|
||||
|
||||
#***********************************************
|
||||
@ -196,20 +172,23 @@ 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,7 +198,6 @@ 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")
|
||||
#HOW MANY MATERIALS ARE USED
|
||||
count = 0
|
||||
@ -247,11 +225,31 @@ class xExport:
|
||||
|
||||
##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(" 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,17 +301,6 @@ 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]))
|
||||
@ -441,4 +427,5 @@ def my_callback(filename):
|
||||
else:
|
||||
xexport.exportTex()
|
||||
|
||||
Blender.Window.FileSelector(my_callback, "Export DirectX")
|
||||
fname = Blender.sys.makename(ext = ".x")
|
||||
Blender.Window.FileSelector(my_callback, "Export DirectX",fname)
|
||||
|
@ -3,7 +3,7 @@
|
||||
""" Registration info for Blender menus: <- these words are ignored
|
||||
Name: 'Dispaint'
|
||||
Blender: 233
|
||||
Group: 'Modifiers'
|
||||
Group: 'Mesh'
|
||||
Tip: 'use vertex paint color value to modify shape displacing vertices along normal.'
|
||||
"""
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
"""
|
||||
Name: 'Blender Knife Tool'
|
||||
Blender: 232
|
||||
Group: 'Modifiers'
|
||||
Group: 'Mesh'
|
||||
Tooltip: 'Cut a mesh along a plane w/o creating doubles'
|
||||
"""
|
||||
|
||||
|
@ -31,6 +31,24 @@ Tooltip: 'Save a Wavefront OBJ File'
|
||||
# ***** END GPL LICENCE BLOCK *****
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
#==================================================#
|
||||
# New name based on old with a different extension #
|
||||
#==================================================#
|
||||
def newFName(ext):
|
||||
return Get('filename')[: -len(Get('filename').split('.', -1)[-1]) ] + ext
|
||||
|
||||
|
||||
#===============================================#
|
||||
# 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
|
||||
|
||||
|
||||
#================================================#
|
||||
# Gets the world matrix of an object #
|
||||
# by multiplying by parents mat's recursively #
|
||||
@ -47,9 +65,10 @@ def getWorldMat(ob):
|
||||
#==================#
|
||||
# Apply Transform #
|
||||
#==================#
|
||||
def apply_transform(verts, matrix):
|
||||
verts.resize4D()
|
||||
return Mathutils.VecMultMat(verts, matrix)
|
||||
def apply_transform(vert, matrix):
|
||||
vertCopy = Mathutils.CopyVec(vert)
|
||||
vertCopy.resize4D()
|
||||
return Mathutils.VecMultMat(vertCopy, matrix)
|
||||
|
||||
#====================================================#
|
||||
# Return a 6 deciaml point floating point value #
|
||||
@ -63,17 +82,60 @@ def saneFloat(float):
|
||||
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):
|
||||
|
||||
if filename.find('.obj', -4) <= 0: filename += '.obj' # for safety
|
||||
# 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':
|
||||
@ -81,7 +143,8 @@ def save_obj(filename):
|
||||
if len(m.verts) > 0: # Make sure there is somthing to write.
|
||||
|
||||
# Set the default mat
|
||||
currentMatName = ''
|
||||
currentMatName = NULL_MAT
|
||||
currentImgName = NULL_IMG
|
||||
|
||||
file.write('o ' + ob.getName() + '_' + m.name + '\n') # Write Object name
|
||||
|
||||
@ -100,6 +163,7 @@ def save_obj(filename):
|
||||
|
||||
# UV
|
||||
for f in m.faces:
|
||||
if len(f.v) > 2:
|
||||
for uvIdx in range(len(f.v)):
|
||||
file.write('vt ')
|
||||
if f.uv:
|
||||
@ -112,8 +176,9 @@ def save_obj(filename):
|
||||
file.write('0.0' + '\n')
|
||||
|
||||
# NORMAL
|
||||
for f in m.faces:
|
||||
for v in f.v:
|
||||
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()
|
||||
@ -124,6 +189,7 @@ def save_obj(filename):
|
||||
|
||||
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():
|
||||
@ -134,6 +200,17 @@ def save_obj(filename):
|
||||
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
|
||||
|
||||
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
|
||||
@ -144,4 +221,4 @@ def save_obj(filename):
|
||||
|
||||
file.close()
|
||||
|
||||
Window.FileSelector(save_obj, 'Export OBJ')
|
||||
Window.FileSelector(save_obj, 'Export OBJ', newFName('obj'))
|
||||
|
@ -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,8 +113,13 @@ def load_image(mat, img_fileName, type, mesh):
|
||||
texture.image = image
|
||||
|
||||
# adds textures to faces (Textured/Alt-Z mode)
|
||||
# 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)
|
||||
@ -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,6 +215,7 @@ 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
|
||||
@ -256,7 +281,11 @@ 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):
|
||||
@ -275,10 +304,18 @@ def load_obj(file):
|
||||
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)
|
||||
@ -297,6 +334,13 @@ def load_obj(file):
|
||||
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]
|
||||
|
||||
@ -312,4 +356,3 @@ def load_obj(file):
|
||||
NMesh.PutRaw(mesh, fileName + '_' + objectName)
|
||||
|
||||
Window.FileSelector(load_obj, 'Import OBJ')
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
""" Registration info for Blender menus: <- these words are ignored
|
||||
Name: 'UnWeld'
|
||||
Blender: 232
|
||||
Group: 'Modifiers'
|
||||
Group: 'Mesh'
|
||||
Tip: 'unweld all faces from one selected and commun vertex. Made vertex bevelling'
|
||||
"""
|
||||
|
||||
|
@ -78,13 +78,13 @@ static int bpymenu_group_atoi (char *str)
|
||||
if (!strcmp(str, "Import")) return PYMENU_IMPORT;
|
||||
else if (!strcmp(str, "Export")) return PYMENU_EXPORT;
|
||||
else if (!strcmp(str, "Help")) return PYMENU_HELP;
|
||||
else if (!strcmp(str, "Generators")) return PYMENU_GENERATORS;
|
||||
else if (!strcmp(str, "Modifiers")) return PYMENU_MODIFIERS;
|
||||
else if (!strcmp(str, "Add")) return PYMENU_ADD;
|
||||
else if (!strcmp(str, "Mesh")) return PYMENU_MESH;
|
||||
else if (!strcmp(str, "Wizards")) return PYMENU_WIZARDS;
|
||||
else if (!strcmp(str, "Animation")) return PYMENU_ANIMATION;
|
||||
else if (!strcmp(str, "Materials")) return PYMENU_MATERIALS;
|
||||
else if (!strcmp(str, "UV")) return PYMENU_UV;
|
||||
else if (!strcmp(str, "Tools")) return PYMENU_TOOLS;
|
||||
else if (!strcmp(str, "Object")) return PYMENU_OBJECT;
|
||||
/* "Misc" or an inexistent group name: use misc */
|
||||
else return PYMENU_MISC;
|
||||
}
|
||||
@ -98,14 +98,14 @@ char *BPyMenu_group_itoa (short menugroup)
|
||||
case PYMENU_EXPORT:
|
||||
return "Export";
|
||||
break;
|
||||
case PYMENU_GENERATORS:
|
||||
return "Generators";
|
||||
case PYMENU_ADD:
|
||||
return "Add";
|
||||
break;
|
||||
case PYMENU_HELP:
|
||||
return "Help";
|
||||
break;
|
||||
case PYMENU_MODIFIERS:
|
||||
return "Modifiers";
|
||||
case PYMENU_MESH:
|
||||
return "Mesh";
|
||||
break;
|
||||
case PYMENU_WIZARDS:
|
||||
return "Wizards";
|
||||
@ -119,8 +119,8 @@ char *BPyMenu_group_itoa (short menugroup)
|
||||
case PYMENU_UV:
|
||||
return "UV";
|
||||
break;
|
||||
case PYMENU_TOOLS:
|
||||
return "Tools";
|
||||
case PYMENU_OBJECT:
|
||||
return "Object";
|
||||
break;
|
||||
case PYMENU_MISC:
|
||||
return "Misc";
|
||||
|
@ -70,7 +70,7 @@ typedef struct BPyMenu {
|
||||
/* Scripts can be added to only a few pre-defined places in menus, like
|
||||
* File->Import, File->Export, etc. (for speed and better control).
|
||||
* To make a new menu 'slot' available for scripts:
|
||||
* - add an entry to the enum below, right before PYMENU_TOTAL, of course;
|
||||
* - add an entry to the enum below, before PYMENU_TOTAL, of course;
|
||||
* - update the bpymenu_group_atoi() and BPyMenu_group_itoa() functions in
|
||||
* BPY_menus.c;
|
||||
* - add the necessary code to the header_***.c file in
|
||||
@ -79,15 +79,15 @@ typedef struct BPyMenu {
|
||||
typedef enum {
|
||||
PYMENU_WIZARDS, /* complex 'app' scripts */
|
||||
PYMENU_UV, /* UV editing tools, to go in UV/Image editor space, 'UV' menu */
|
||||
PYMENU_TOOLS,
|
||||
PYMENU_MODIFIERS, /* modifies existing obj *data* */
|
||||
PYMENU_OBJECT,
|
||||
PYMENU_MISC,
|
||||
PYMENU_MESH,
|
||||
PYMENU_MATERIALS,
|
||||
PYMENU_HELP, /* inserted in the info header 'Help' menu */
|
||||
PYMENU_GENERATORS, /* creates new objects */
|
||||
PYMENU_IMPORT,
|
||||
PYMENU_EXPORT,
|
||||
PYMENU_ANIMATION,
|
||||
PYMENU_ADD, /* creates new objects */
|
||||
PYMENU_TOTAL
|
||||
} PYMENUHOOKS;
|
||||
|
||||
|
@ -291,7 +291,7 @@ static PyObject *M_sys_makename(PyObject *self, PyObject *args, PyObject *kw)
|
||||
if (dot) n = dot - basename;
|
||||
else n = strlen(basename);
|
||||
|
||||
BLI_strncpy(basename + n, ext, lenext);
|
||||
BLI_strncpy(basename + n, ext, lenext + 1);
|
||||
basename[n+lenext] = '\0';
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user