Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release/scripts/io/export_fbx.py')
-rw-r--r--release/scripts/io/export_fbx.py154
1 files changed, 76 insertions, 78 deletions
diff --git a/release/scripts/io/export_fbx.py b/release/scripts/io/export_fbx.py
index 4505b56b41c..60e9e90e11b 100644
--- a/release/scripts/io/export_fbx.py
+++ b/release/scripts/io/export_fbx.py
@@ -55,7 +55,7 @@ import math # math.pi
import shutil # for file copying
import bpy
-from mathutils import Vector, Euler, Matrix, RotationMatrix
+from mathutils import Vector, Euler, Matrix
def copy_file(source, dest):
# XXX - remove, can use shutil
@@ -75,7 +75,7 @@ def copy_images(dest_dir, textures):
image_paths = set()
for tex in textures:
- image_paths.add(bpy.utils.expandpath(tex.filepath))
+ image_paths.add(bpy.path.abspath(tex.filepath))
# Now copy images
copyCount = 0
@@ -83,7 +83,7 @@ def copy_images(dest_dir, textures):
if Blender.sys.exists(image_path):
# Make a name for the target path.
dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1]
- if not Blender.sys.exists(dest_image_path): # Image isnt alredy there
+ if not Blender.sys.exists(dest_image_path): # Image isnt already there
print('\tCopying "%s" > "%s"' % (image_path, dest_image_path))
try:
copy_file(image_path, dest_image_path)
@@ -107,19 +107,19 @@ def eulerRadToDeg(eul):
mtx4_identity = Matrix()
# testing
-mtx_x90 = RotationMatrix( math.pi/2, 3, 'X') # used
-#mtx_x90n = RotationMatrix(-90, 3, 'x')
-#mtx_y90 = RotationMatrix( 90, 3, 'y')
-#mtx_y90n = RotationMatrix(-90, 3, 'y')
-#mtx_z90 = RotationMatrix( 90, 3, 'z')
-#mtx_z90n = RotationMatrix(-90, 3, 'z')
-
-#mtx4_x90 = RotationMatrix( 90, 4, 'x')
-mtx4_x90n = RotationMatrix(-math.pi/2, 4, 'X') # used
-#mtx4_y90 = RotationMatrix( 90, 4, 'y')
-mtx4_y90n = RotationMatrix(-math.pi/2, 4, 'Y') # used
-mtx4_z90 = RotationMatrix( math.pi/2, 4, 'Z') # used
-mtx4_z90n = RotationMatrix(-math.pi/2, 4, 'Z') # used
+mtx_x90 = Matrix.Rotation( math.pi/2, 3, 'X') # used
+#mtx_x90n = Matrix.Rotation(-90, 3, 'x')
+#mtx_y90 = Matrix.Rotation( 90, 3, 'y')
+#mtx_y90n = Matrix.Rotation(-90, 3, 'y')
+#mtx_z90 = Matrix.Rotation( 90, 3, 'z')
+#mtx_z90n = Matrix.Rotation(-90, 3, 'z')
+
+#mtx4_x90 = Matrix.Rotation( 90, 4, 'x')
+mtx4_x90n = Matrix.Rotation(-math.pi/2, 4, 'X') # used
+#mtx4_y90 = Matrix.Rotation( 90, 4, 'y')
+mtx4_y90n = Matrix.Rotation(-math.pi/2, 4, 'Y') # used
+mtx4_z90 = Matrix.Rotation( math.pi/2, 4, 'Z') # used
+mtx4_z90n = Matrix.Rotation(-math.pi/2, 4, 'Z') # used
# def strip_path(p):
# return p.split('\\')[-1].split('/')[-1]
@@ -176,7 +176,7 @@ def sane_name(data, dct):
name = 'unnamed' # blank string, ASKING FOR TROUBLE!
else:
- name = bpy.utils.clean_name(name) # use our own
+ name = bpy.path.clean_name(name) # use our own
while name in iter(dct.values()): name = increment_string(name)
@@ -200,14 +200,14 @@ def sane_groupname(data): return sane_name(data, sane_name_mapping_group)
# FORCE_CWD - dont use the basepath, just add a ./ to the filename.
# use when we know the file will be in the basepath.
# '''
-# fname = bpy.utils.expandpath(fname_orig)
+# fname = bpy.path.abspath(fname_orig)
# # fname = Blender.sys.expandpath(fname_orig)
# fname_strip = os.path.basename(fname)
# # fname_strip = strip_path(fname)
# if FORCE_CWD:
# fname_rel = '.' + os.sep + fname_strip
# else:
-# fname_rel = bpy.utils.relpath(fname, basepath)
+# fname_rel = bpy.path.relpath(fname, basepath)
# # fname_rel = Blender.sys.relpath(fname, basepath)
# if fname_rel.startswith('//'): fname_rel = '.' + os.sep + fname_rel[2:]
# return fname, fname_strip, fname_rel
@@ -221,7 +221,7 @@ def mat4x4str(mat):
def getVertsFromGroup(me, group_index):
ret = []
- for i, v in enumerate(me.verts):
+ for i, v in enumerate(me.vertices):
for g in v.groups:
if g.group == group_index:
ret.append((i, g.weight))
@@ -243,11 +243,11 @@ def BPyMesh_meshWeight2List(ob):
if not len_groupNames:
# no verts? return a vert aligned empty list
- return [[] for i in range(len(me.verts))], []
+ return [[] for i in range(len(me.vertices))], []
else:
- vWeightList= [[0.0]*len_groupNames for i in range(len(me.verts))]
+ vWeightList= [[0.0]*len_groupNames for i in range(len(me.vertices))]
- for i, v in enumerate(me.verts):
+ for i, v in enumerate(me.vertices):
for g in v.groups:
vWeightList[i][g.group] = g.weight
@@ -305,7 +305,8 @@ def write(filename, batch_objects = None, \
BATCH_OWN_DIR = False
):
- bpy.ops.object.mode_set(mode='OBJECT')
+ if bpy.context.object:
+ bpy.ops.object.mode_set(mode='OBJECT')
# ----------------- Batch support!
if BATCH_ENABLE:
@@ -353,13 +354,13 @@ def write(filename, batch_objects = None, \
new_fbxpath = fbxpath # own dir option modifies, we need to keep an original
for data in data_seq: # scene or group
- newname = BATCH_FILE_PREFIX + bpy.utils.clean_name(data.name)
-# newname = BATCH_FILE_PREFIX + BPySys.bpy.utils.clean_name(data.name)
+ newname = BATCH_FILE_PREFIX + bpy.path.clean_name(data.name)
+# newname = BATCH_FILE_PREFIX + BPySys.bpy.path.clean_name(data.name)
if BATCH_OWN_DIR:
new_fbxpath = fbxpath + newname + os.sep
- # path may alredy exist
+ # path may already exist
# TODO - might exist but be a file. unlikely but should probably account for it.
if bpy.utils.exists(new_fbxpath) == 0:
@@ -391,7 +392,7 @@ def write(filename, batch_objects = None, \
# Call self with modified args
- # Dont pass batch options since we alredy usedt them
+ # Dont pass batch options since we already usedt them
write(filename, data.objects,
context,
False,
@@ -561,7 +562,7 @@ def write(filename, batch_objects = None, \
elif type =='CAMERA':
# elif ob and type =='Camera':
y = matrix_rot * Vector((0.0, 1.0, 0.0))
- matrix_rot = RotationMatrix(math.pi/2, 3, y) * matrix_rot
+ matrix_rot = Matrix.Rotation(math.pi/2, 3, y) * matrix_rot
return matrix_rot
@@ -663,7 +664,7 @@ def write(filename, batch_objects = None, \
rot = tuple(matrix_rot.to_euler())
elif ob and ob.type =='Camera':
y = matrix_rot * Vector((0.0, 1.0, 0.0))
- matrix_rot = RotationMatrix(math.pi/2, 3, y) * matrix_rot
+ matrix_rot = Matrix.Rotation(math.pi/2, 3, y) * matrix_rot
rot = tuple(matrix_rot.to_euler())
else:
rot = tuple(matrix_rot.to_euler())
@@ -947,10 +948,7 @@ def write(filename, batch_objects = None, \
render = scene.render
width = render.resolution_x
height = render.resolution_y
-# render = scene.render
-# width = render.sizeX
-# height = render.sizeY
- aspect = float(width)/height
+ aspect = width / height
data = my_cam.blenObject.data
@@ -962,11 +960,9 @@ def write(filename, batch_objects = None, \
file.write('\n\t\t\tProperty: "FieldOfView", "FieldOfView", "A+",%.6f' % math.degrees(data.angle))
file.write('\n\t\t\tProperty: "FieldOfViewX", "FieldOfView", "A+",1')
file.write('\n\t\t\tProperty: "FieldOfViewY", "FieldOfView", "A+",1')
- file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",14.0323972702026')
+ # file.write('\n\t\t\tProperty: "FocalLength", "Real", "A+",14.0323972702026')
file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",%.6f' % data.shift_x) # not sure if this is in the correct units?
-# file.write('\n\t\t\tProperty: "OpticalCenterX", "Real", "A+",%.6f' % data.shiftX) # not sure if this is in the correct units?
file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",%.6f' % data.shift_y) # ditto
-# file.write('\n\t\t\tProperty: "OpticalCenterY", "Real", "A+",%.6f' % data.shiftY) # ditto
file.write('\n\t\t\tProperty: "BackgroundColor", "Color", "A+",0,0,0')
file.write('\n\t\t\tProperty: "TurnTable", "Real", "A+",0')
file.write('\n\t\t\tProperty: "DisplayTurnTableIcon", "bool", "",1')
@@ -975,7 +971,7 @@ def write(filename, batch_objects = None, \
file.write('\n\t\t\tProperty: "UseRealTimeMotionBlur", "bool", "",1')
file.write('\n\t\t\tProperty: "ResolutionMode", "enum", "",0')
file.write('\n\t\t\tProperty: "ApertureMode", "enum", "",2')
- file.write('\n\t\t\tProperty: "GateFit", "enum", "",0')
+ file.write('\n\t\t\tProperty: "GateFit", "enum", "",2')
file.write('\n\t\t\tProperty: "CameraFormat", "enum", "",0')
file.write('\n\t\t\tProperty: "AspectW", "double", "",%i' % width)
file.write('\n\t\t\tProperty: "AspectH", "double", "",%i' % height)
@@ -1086,7 +1082,7 @@ def write(filename, batch_objects = None, \
else:
do_shadow = 0
- if light.only_shadow or (not light.diffuse and not light.specular):
+ if light.use_only_shadow or (not light.diffuse and not light.specular):
# if mode & Blender.Lamp.Modes.OnlyShadow or (mode & Blender.Lamp.Modes.NoDiffuse and mode & Blender.Lamp.Modes.NoSpecular):
do_light = 0
else:
@@ -1194,7 +1190,7 @@ def write(filename, batch_objects = None, \
# mat_spec = mat.spec/2.0
mat_alpha = mat.alpha
mat_emit = mat.emit
- mat_shadeless = mat.shadeless
+ mat_shadeless = mat.use_shadeless
# mat_shadeless = mat.mode & Blender.Material.Modes.SHADELESS
if mat_shadeless:
mat_shader = 'Lambert'
@@ -1254,7 +1250,7 @@ def write(filename, batch_objects = None, \
file.write('\n\t}')
def copy_image(image):
- fn = bpy.utils.expandpath(image.filepath)
+ fn = bpy.path.abspath(image.filepath)
fn_strip = os.path.basename(fn)
if EXP_IMAGE_COPY:
@@ -1331,9 +1327,9 @@ def write(filename, batch_objects = None, \
Property: "CurrentMappingType", "enum", "",0
Property: "UVSwap", "bool", "",0''')
- file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.clamp_x)
+ file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.use_clamp_x)
# file.write('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.clampX)
- file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.clamp_y)
+ file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.use_clamp_y)
# file.write('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.clampY)
file.write('''
@@ -1402,7 +1398,7 @@ def write(filename, batch_objects = None, \
# TODO - this is a bit lazy, we could have a simple write loop
# for this case because all weights are 1.0 but for now this is ok
# Parent Bones arent used all that much anyway.
- vgroup_data = [(j, 1.0) for j in range(len(my_mesh.blenData.verts))]
+ vgroup_data = [(j, 1.0) for j in range(len(my_mesh.blenData.vertices))]
else:
# This bone is not a parent of this mesh object, no weights
vgroup_data = []
@@ -1491,7 +1487,7 @@ def write(filename, batch_objects = None, \
file.write('\n\t\tVertices: ')
i=-1
- for v in me.verts:
+ for v in me.vertices:
if i==-1:
file.write('%.6f,%.6f,%.6f' % tuple(v.co)); i=0
else:
@@ -1503,7 +1499,7 @@ def write(filename, batch_objects = None, \
file.write('\n\t\tPolygonVertexIndex: ')
i=-1
for f in me.faces:
- fi = f.verts[:]
+ fi = f.vertices[:]
# last index XORd w. -1 indicates end of face
fi[-1] = fi[-1] ^ -1
@@ -1523,8 +1519,8 @@ def write(filename, batch_objects = None, \
# write loose edges as faces.
for ed in me.edges:
- if ed.loose:
- ed_val = ed.verts[:]
+ if ed.is_loose:
+ ed_val = ed.vertices[:]
ed_val = ed_val[0], ed_val[-1] ^ -1
if i==-1:
@@ -1542,14 +1538,14 @@ def write(filename, batch_objects = None, \
i=-1
for ed in me.edges:
if i==-1:
- file.write('%i,%i' % (ed.verts[0], ed.verts[1]))
+ file.write('%i,%i' % (ed.vertices[0], ed.vertices[1]))
# file.write('%i,%i' % (ed.v1.index, ed.v2.index))
i=0
else:
if i==13:
file.write('\n\t\t')
i=0
- file.write(',%i,%i' % (ed.verts[0], ed.verts[1]))
+ file.write(',%i,%i' % (ed.vertices[0], ed.vertices[1]))
# file.write(',%i,%i' % (ed.v1.index, ed.v2.index))
i+=1
@@ -1564,7 +1560,7 @@ def write(filename, batch_objects = None, \
Normals: ''')
i=-1
- for v in me.verts:
+ for v in me.vertices:
if i==-1:
file.write('%.15f,%.15f,%.15f' % tuple(v.normal)); i=0
# file.write('%.15f,%.15f,%.15f' % tuple(v.no)); i=0
@@ -1588,11 +1584,11 @@ def write(filename, batch_objects = None, \
i=-1
for f in me.faces:
if i==-1:
- file.write('%i' % f.smooth); i=0
+ file.write('%i' % f.use_smooth); i=0
else:
if i==54:
file.write('\n '); i=0
- file.write(',%i' % f.smooth)
+ file.write(',%i' % f.use_smooth)
i+=1
file.write('\n\t\t}')
@@ -1606,27 +1602,23 @@ def write(filename, batch_objects = None, \
ReferenceInformationType: "Direct"
Smoothing: ''')
-# SHARP = Blender.Mesh.EdgeFlags.SHARP
i=-1
for ed in me.edges:
if i==-1:
- file.write('%i' % (ed.sharp)); i=0
-# file.write('%i' % ((ed.flag&SHARP)!=0)); i=0
+ file.write('%i' % (ed.use_edge_sharp)); i=0
else:
if i==54:
file.write('\n '); i=0
- file.write(',%i' % (ed.sharp))
-# file.write(',%i' % ((ed.flag&SHARP)!=0))
+ file.write(',%i' % (ed.use_edge_sharp))
i+=1
file.write('\n\t\t}')
-# del SHARP
# small utility function
# returns a slice of data depending on number of face verts
# data is either a MeshTextureFace or MeshColor
def face_data(data, face):
- totvert = len(f.verts)
+ totvert = len(f.vertices)
return data[:totvert]
@@ -2076,7 +2068,7 @@ def write(filename, batch_objects = None, \
# ob.copy().link(me)
# # If new mesh has no vgroups we can try add if verts are teh same
# if not me.getVertGroupNames(): # vgroups were not kept by the modifier
-# if len(me.verts) == len(orig_mesh.verts):
+# if len(me.vertices) == len(orig_mesh.vertices):
# groupNames, vWeightDict = BPyMesh.meshWeight2Dict(orig_mesh)
# BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict)
@@ -2763,7 +2755,7 @@ Takes: {''')
act_end = end
else:
# use existing name
- if blenAction == blenActionDefault: # have we alredy got the name
+ if blenAction == blenActionDefault: # have we already got the name
file.write('\n\tTake: "%s" {' % sane_name_mapping_take[blenAction.name])
else:
file.write('\n\tTake: "%s" {' % sane_takename(blenAction))
@@ -2782,7 +2774,7 @@ Takes: {''')
# Set the action active
for my_bone in ob_arms:
- if blenAction in my_bone.blenActionList:
+ if ob.animation_data and blenAction in my_bone.blenActionList:
ob.animation_data.action = blenAction
# print '\t\tSetting Action!', blenAction
# scene.update(1)
@@ -2918,7 +2910,7 @@ Takes: {''')
for val, frame in context_bone_anim_keys:
if frame != context_bone_anim_keys[0][1]: # not the first
file.write(',')
- # frame is alredy one less then blenders frame
+ # frame is already one less then blenders frame
file.write('\n\t\t\t\t\t\t\t%i,%.15f,L' % (fbx_time(frame), val ))
if i==0: file.write('\n\t\t\t\t\t\tColor: 1,0,0')
@@ -2940,7 +2932,8 @@ Takes: {''')
# end action loop. set original actions
# do this after every loop incase actions effect eachother.
for my_bone in ob_arms:
- my_bone.blenObject.animation_data.action = my_bone.blenAction
+ if my_bone.blenObject.animation_data:
+ my_bone.blenObject.animation_data.action = my_bone.blenAction
file.write('\n}')
@@ -2964,7 +2957,7 @@ Takes: {''')
# Clear mesh data Only when writing with modifiers applied
for me in meshes_to_clear:
bpy.data.meshes.remove(me)
-# me.verts = None
+# me.vertices = None
# --------------------------- Footer
if world:
@@ -3037,7 +3030,7 @@ Takes: {''')
# --------------------------------------------
# UI Function - not a part of the exporter.
-# this is to seperate the user interface from the rest of the exporter.
+# this is to separate the user interface from the rest of the exporter.
# from Blender import Draw, Window
EVENT_NONE = 0
EVENT_EXIT = 1
@@ -3364,20 +3357,24 @@ class ExportFBX(bpy.types.Operator):
BATCH_FILE_PREFIX = StringProperty(name="Prefix", description="Prefix each file with this name", maxlen=1024, default="")
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return context.active_object
def execute(self, context):
if not self.properties.filepath:
raise Exception("filepath not set")
+ filepath = self.properties.filepath
+ filepath = bpy.path.ensure_ext(filepath, ".fbx")
+
GLOBAL_MATRIX = mtx4_identity
GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = self.properties.TX_SCALE
if self.properties.TX_XROT90: GLOBAL_MATRIX = mtx4_x90n * GLOBAL_MATRIX
if self.properties.TX_YROT90: GLOBAL_MATRIX = mtx4_y90n * GLOBAL_MATRIX
if self.properties.TX_ZROT90: GLOBAL_MATRIX = mtx4_z90n * GLOBAL_MATRIX
- write(self.properties.filepath,
+ write(filepath,
None, # XXX
context,
self.properties.EXP_OBS_SELECTED,
@@ -3397,13 +3394,17 @@ class ExportFBX(bpy.types.Operator):
self.properties.BATCH_ENABLE,
self.properties.BATCH_GROUP,
self.properties.BATCH_FILE_PREFIX,
- self.properties.BATCH_OWN_DIR)
+ self.properties.BATCH_OWN_DIR,
+ )
return {'FINISHED'}
def invoke(self, context, event):
- wm = context.manager
- wm.add_fileselect(self)
+ import os
+ if not self.properties.is_property_set("filepath"):
+ self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".fbx"
+
+ context.manager.add_fileselect(self)
return {'RUNNING_MODAL'}
@@ -3415,7 +3416,7 @@ class ExportFBX(bpy.types.Operator):
# NOTES (all line numbers correspond to original export_fbx.py (under release/scripts)
# - Draw.PupMenu alternative in 2.5?, temporarily replaced PupMenu with print
-# - get rid of bpy.utils.clean_name somehow
+# - get rid of bpy.path.clean_name somehow
# + fixed: isinstance(inst, bpy.types.*) doesn't work on RNA objects: line 565
# + get rid of BPyObject_getObjectArmature, move it in RNA?
# - BATCH_ENABLE and BATCH_GROUP options: line 327
@@ -3430,24 +3431,21 @@ class ExportFBX(bpy.types.Operator):
# - bpy.data.remove_scene: line 366
# - bpy.sys.time move to bpy.sys.util?
# - new scene creation, activation: lines 327-342, 368
-# - uses bpy.utils.expandpath, *.relpath - replace at least relpath
+# - uses bpy.path.abspath, *.relpath - replace at least relpath
# SMALL or COSMETICAL
# - find a way to get blender version, and put it in bpy.util?, old was Blender.Get('version')
def menu_func(self, context):
- default_path = os.path.splitext(bpy.data.filepath)[0] + ".fbx"
- self.layout.operator(ExportFBX.bl_idname, text="Autodesk FBX (.fbx)").filepath = default_path
+ self.layout.operator(ExportFBX.bl_idname, text="Autodesk FBX (.fbx)")
def register():
- bpy.types.register(ExportFBX)
bpy.types.INFO_MT_file_export.append(menu_func)
def unregister():
- bpy.types.unregister(ExportFBX)
bpy.types.INFO_MT_file_export.remove(menu_func)
if __name__ == "__main__":