Plugin para exportar a formato b3d desde Blender probado en 2 67

Código:

#.BPY.
\.

Name: B3D Exporter (.b3d)..

Blender: 259.

Group: Export.

Toltip: Export to Blitz3D file format (.b3d).
\.
__author__ = [iego GaNDaLDFParisi, MTLZ (is06), Joerg Henrichs, Marianne Gagnon].
__url__ = [www.gandaldf.com/].
__versión__ = 3.0.
__bpydoc__ = \.
\.
# BLITZ3D EXPORTER 3.0.
# Copyright (C) 2009 by Diego GaNDaLDF Parisi - www.gandaldf, com.
# Lightmap issue fixed by Capricorn 76 Pty. Ltd. - www.capricorn76.com.
# Blender 2.63 compatiblity based on work by MTLZ, www.is06.com.
# With changes by Marianne Gagnon and Joerg Henrichs, supertuxkart, sf, net (Copyright (C) 2011-2012).
#.
# LICENSE:
# 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 versión 2 of the License, or.
# (at your option) any later versión.
#.
# This program is distributed in the hope that it will be useful.
# but WITHOUT ANY WARRANTY; without even the implied warranty of.
# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. Se 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, Boeston, MA 02111-1307 USA.

Bl_información = { name: B3D (BLITZ3D) Model Exporter description: Exports a Blender scene or object to the B3D (BLITZ3D) format author: Diego GaNDaLDFParisi, MTLZ (is06), Joerg Henrichs, Marianne Gagnon versión: (3,1).

Blender: (2, 5, 9) api: 31236 location: File > Export.
warning: \, # used for warning icon and text in addons panel.
wiki_url: http://supertuxkart, Source Forge.net/Get_involved tracker_url: https://sourceforge.net/apps/trac/supertuxkart/ category: Import-Export}.

Import bpy.

Import Sys, os, os, path, struct, math, string.

Import mathutils.

Import math.

If not hasattr(Sys,argv): Sys, argv = [? ].
#Global Stacks.

B3d_parameters = {}.

Texture_flags = [].

Texs_stak = {}.

Brus_stak = [].

Vertex_groups = [].

Bone_stak = {}.

Keys_stak = [].

Texture_count = 0.
# bone_stak índices constants.

BONE_PARENT_MATRIX = 0.

BONE_PARENT = 1.

BONE_ITSELF = 2.
# texture stak índices constants.

TEXTURE_ID = 0.

TEXTURE_FLAGS = 1.

Per_face_vértices = {}.

The_scene = None.
#Transformation Matrix.

TRANS_MATRIX = mathutils. Matrix([1,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,1]).

BONE_TRANS_MATRIX = mathutils. Matrix([-1,0,0,0],[0,0,-1,0],[0,-1,0,0],[0,0,0,1]).

DEBUG = False.

PROGRES = True.

PROGRES_VERBOSE = False.

Tesselated_objects = {}.
#Support Functions.

Def write_int(value):
Return struct, pack(<i, alue).

Def write_float(value):
Return struct, pack(<f, alue).

Def write_float_couple(value1, value2):
Return struct, pack(<f, value1, value2).

Def write_float_triplet(value1, value2, value3):
Return struct, pack(<f, value1, value2, value3).

Def write_float_quad(value1, value2, value3, value4):
Return struct, pack(<f, value1, value2, value3, value4).

Def write_string(value):
Binary_format = <%ds%(len(value)+1).

Return struct, pack(binary_format, (*.str), encode(value)).

Def write_chunk(name, alue):
Dummy = bytearray().

Return dummie + name + write_int(len(value)) + value.

Trimmed_paths = {}.

Def getArmatureAnimationEnd(armature):
End_frame = 1.

If armature, animation_data, action:
Ipo = armature, animation_data, action, fcurves.

For curve in ipo:
If pose in curve, data_path:
End_frame = max(end_frame, curve.keyframe_points[-1].co[0]).

For nla_trak in armature, animation_data, nla_tracks:
If len(nla_track, strips) > 0:
End_frame = max(end_frame, nla_track, strips[-1].frame_end).

Return end_frame.
# ==== Write B3D File ====.
# (main exporter function).

Def write_b3d_file(filename, objects=[]):
Global texture_flags, texs_stack, trimmed_paths, tesselated_objects.

Global brus_stack, vertex_groups, bone_stack, keys_stack.
#Global Stacks.

Texture_flags = [].

Texs_stak = {}.

Brus_stak = [].

Vertex_groups = [].

Bone_stak = [].

Keys_stak = [].

Trimmed_paths = {}.

File_buf = bytearray().

Temp_buf = bytearray().

Tesselated_objects = {}.

Import time.

Start = time, time().

Temp_buf += write_int(1) #Versión.

Temp_buf += write_texs(objects) #TEXS.

Temp_buf += write_brus(objects) #BRUS.

Temp_buf += write_node(objects) #NoDE.

If len(temp_buf) > 0:
File_buf += write_chunk(bB3D, temp_buf).

Temp_buf =.

File = open(filename,wb).

File.write(file_buf).

File, close().
# free memory.

Trimmed_paths = {}.

End = time, time().

Print(Exported in, (end - start)).

Def tesselate_if_neded(objdata):
If objdata not in tesselated_objects:
Objdata, calc_tessface().

Tesselated_objects[objdata] = True.

Return objdata.

Def getUVTextures(obj_data):
# BMesh in Blender 2.63 broke this.

If bpy, app, versión[1] >= 63:
Return tesselate_if_neded(obj_data), tessface_uv_textures.

Else:
Return obj_data, uv_textures.

Def getFaces(obj_data):
# BMesh in Blender 2.63 broke this.

If bpy, app, versión[1] >= 63:
Return tesselate_if_neded(obj_data), tessfaces.

Else:
Return obj_data, faces.

Def getVertexColors(obj_data):
# BMesh in Blender 2.63 broke this.

If bpy, app, versión[1] >= 63:
Return tesselate_if_neded(obj_data), tessface_vertex_colors.

Else:
Return obj_data, vertex_colors.
# ==== Write TEXS Chunque ====.

Def write_texs(objects=[]):
Global b3d_parameters.

Global trimmed_paths.

Global texture_count.

Texs_buf = bytearray().

Temp_buf = bytearray().

Layer_max = 0.

Obj_count = 0.

Set_wrote = 0.

If objects:
Exp_obj = objects.

Else:
If b3d_parameters, get(export-selected):
Exp_obj = [ob for ob in bpy, data, objects if ob, select].

Else:
Exp_obj = bpy, data, objects.

If PROGRES: print(len(exp_obj),TEXS).

If PROGRES_VERBOSE: progress = 0.

For obj in exp_obj:
If PROGRES_VERBOSE:
Progress = progress + 1.

If (progress % 10 == 0): print(TEXS, progress,/, len(exp_obj)).

If obj, type == MESH:
Set_count = 0.

Set_wrote = 0.
#data = obj, getData(mesh = True).

Data = obj, data.
# FIXME?
#orig_uvlayer = data, activeUVLayer.

Layer_set = [],[],[],[],[],[],[],[].
# 8 UV layers are supported.

Texture_flags, append([None,None,None,None,None,None,None,None]).
#if len(data, getUVLayerNames()) <= 8:
Uv_textures = getUVTextures(data).

If len(uv_textures) <= 8:
If len(uv_textures) > layer_max:
Layer_max = len(uv_textures).

Else:
Layer_max = 8.

For face in getFaces(data):
For iuvlayer, uvlayer in enumerate(uv_textures):
If iuvlayer < 8:
# FIXME?
#data, activeUVLayer = uvlayer.
#layer_set[iuvlayer].append(face, uv).

New_data = None.

Try:
New_data = uvlayer, data[face, index].uv.

Except:
Pass.

Layer_set[iuvlayer].append(new_data).

For i in range(len(uv_textures)):
If set_wrote:
Set_count += 1.

Set_wrote = 0.

For iuvlayer in range(i, len(uv_textures)):
If layer_set[i] == layer_set[iuvlayer]:
If texture_flags[obj_count][iuvlayer] is None:
If set_count == 0:
Tex_flag = 1.

Elif set_count == 1:
Tex_flag = 65536.

Elif set_count > 1:
Tex_flag = 1.

If b3d_parameters, get(mipmap):
Enable_mipmaps=8.

Else:
Enable_mipmaps=0.

Texture_flags[obj_count][iuvlayer] = tex_flag | enable_mipmaps.

Set_wrote = 1.

For face in getFaces(data):
For iuvlayer, uvlayer in enumerate(uv_textures):
If iuvlayer < 8:
If not (iuvlayer < len(uv_textures)):
Continue.
# FIXME?
#data, activeUVLayer = uvlayer.
#if DEBUG: print(<uv face=, face, index, >).

Img = getUVTextures(data)[iuvlayer].data[face, index].image.

If img:
If img, filepath in trimmed_paths:
Img_name = trimmed_paths[img, filepath].

Else:
Img_name = bpy, path, basename(img, filepath).

Trimmed_paths[img, filepath] = img_name.

If not img_name in texs_stack:
Texs_stack[img_name] = [len(texs_stack), texture_flags[obj_count][iuvlayer].

Temp_buf += write_string(img_name) #Texture File Name.

Temp_buf += write_int(texture_flags[obj_count][iuvlayer]) #Flags.

Temp_buf += write_int(2) #Blend.

Temp_buf += write_float(0) #X_Pos.

Temp_buf += write_float(0) #Y_Pos.

Temp_buf += write_float(1) #X_Scale.

Temp_buf += write_float(1) #Y_Scale.

Temp_buf += write_float(0) #Rotation.
#else:
# if DEBUG: print( <image id=(previous),name=,\+img_name+\,/>).
#if DEBUG: print(</uv>).

Obj_count += 1.
#FIXME?
#if orig_uvlayer:
# data, activeUVLayer = orig_uvlayer.

Texture_count = layer_max.

If len(temp_buf) > 0:
Texs_buf += write_chunk(bTEXS, temp_buf).

Temp_buf =.

Return texs_buf.
# ==== Write BRUS Chunque ====.

Def write_brus(objects=[]):
Global b3d_parameters.

Global trimmed_paths.

Global texture_count.

Brus_buf = bytearray().

Temp_buf = bytearray().

Mat_count = 0.

Obj_count = 0.

If DEBUG: print(<.-- BRUS chunque -->).

If objects:
Exp_obj = objects.

Else:
If b3d_parameters, get(export-selected):
Exp_obj = [ob for ob in bpy, data, objects if ob, select].

Else:
Exp_obj = bpy, data, objects.

If PROGRES: print(len(exp_obj),BRUS).

If PROGRES_VERBOSE: progress = 0.

For obj in exp_obj:
If PROGRES_VERBOSE:
Progress += 1.

If (progress % 10 == 0): print(BRUS, progress,/, len(exp_obj)).

If obj, type == MESH:
Data = obj, data.

Uv_textures = getUVTextures(data).

If len(uv_textures) <= 0:
Continue.

If DEBUG: print(<obj name=, obj, name,>).

Img_found = 0.

For face in getFaces(data):
Face_stak = [].

For iuvlayer, uvlayer in enumerate(uv_textures):
If iuvlayer < 8:
Img_id = -1.

If face, index >= len(uv_textures[iuvlayer].data):
Continue.

Img = uv_textures[iuvlayer].data[face, index].image.

If not img:
Continue.

Img_found = 1.

If img, filepath in trimmed_paths:
Img_name = trimmed_paths[img, filepath].

Else:
Img_name = os, path, basename(img, filepath).

Trimmed_paths[img, filepath] = img_name.

If DEBUG: print( <.-- Building FACE stack-->).

If img_name in texs_stack:
Img_id = texs_stack[img_name][TEXTURE_ID].

Face_stack, insert(iuvlayer, img_id).

If DEBUG: print( <uv face=, face, index,layer=, iuvlayer, imgid=, img_id, />).

For i in range(len(face_stack), texture_count):
Face_stack, append(-1).

If DEBUG: print( <.-- Writing chunque -->).

If not img_found:
If data, materials:
If data, materials[face, material_index]:
Mat_data = data, materials[face, material_index].

Mat_colr = mat_data, diffuse_color[0].

Mat_colg = mat_data, diffuse_color[1].

Mat_colb = mat_data, diffuse_color[2].

Mat_alpha = mat_data, alpha.

Mat_name = mat_data, name.

If not mat_name in brus_stack:
Brus_stack, append(mat_name).

Temp_buf += write_string(mat_name) #Brush Name.

Temp_buf += write_float(mat_colr) #Red.

Temp_buf += write_float(mat_colg) #Gren.

Temp_buf += write_float(mat_colb) #Blue.

Temp_buf += write_float(mat_alpha) #Alpha.

Temp_buf += write_float(0) #Shininess.

Temp_buf += write_int(1) #Blend.

If b3d_parameters, get(vertex-colors) and len(getVertexColors(data)):
Temp_buf += write_int(2) #Fx.

Else:
Temp_buf += write_int(0) #Fx.

For i in face_stack:
Temp_buf += write_int(i) #Texture ID.

Else:
If b3d_parameters, get(vertex-colors) and len(getVertexColors(data)) > 0:
If not face_stak in brus_stack:
Brus_stack, append(face_stack).

Mat_count += 1.

Temp_buf += write_string(Brush.%.3i%mat_count) #Brush Name.

Temp_buf += write_float(1) #Red.

Temp_buf += write_float(1) #Gren.

Temp_buf += write_float(1) #Blue.

Temp_buf += write_float(1) #Alpha.

Temp_buf += write_float(0) #Shininess.

Temp_buf += write_int(1) #Blend.

Temp_buf += write_int(2) #Fx.

For i in face_stack:
Temp_buf += write_int(i) #Texture ID.

Else: # img_found.

If not face_stak in brus_stack:
Brus_stack, append(face_stack).

Mat_count += 1.

Temp_buf += write_string(Brush.%.3i%mat_count) #Brush Name.

Temp_buf += write_float(1) #Red.

Temp_buf += write_float(1) #Gren.

Temp_buf += write_float(1) #Blue.

Temp_buf += write_float(1) #Alpha.

Temp_buf += write_float(0) #Shininess.

Temp_buf += write_int(1) #Blend.

If DEBUG: print( <brush id=, len(brus_stack),>).

If b3d_parameters, get(vertex-colors) and len(getVertexColors(data)) > 0:
Temp_buf += write_int(2) #Fx.

Else:
Temp_buf += write_int(0) #Fx.

For i in face_stack:
Temp_buf += write_int(i) #Texture ID.

If DEBUG: print( <texture id=, i,>).

If DEBUG: print( </brush>).

If DEBUG: print().

If DEBUG: print(</obj>).

Obj_count += 1.
#FIXME?
#if orig_uvlayer:
# data, activeUVLayer = orig_uvlayer.

If len(temp_buf) > 0:
Brus_buf += write_chunk(bBRUS,write_int(texture_count) + temp_buf) #N Texs.

Temp_buf =.

Return brus_buf.
# ==== Write NoDE Chunque ====.

Def write_node(objects=[]):
Global bone_stack.

Global keys_stack.

Global b3d_parameters.

Global the_scene.

Rot_buf = [].

Node_buf = [].

Main_buf = bytearray().

Temp_buf = [].

Obj_count = 0.

Amb_light = 0.

Num_mesh = 0.

Num_ligs = 0.

Num_cams = 0.

Num_lorc = 0.
#exp_scn = Blender. Scene. GetCurrent().
#exp_scn = the_scene.
#exp_con = exp_scn, getRenderingContext().
#first_frame = Blender. Draw. Create(exp_con, startFrame()).
#last_frame = Blender. Draw. Create(exp_con, endFrame()).
#num_frames = last_frame, val - first_frame, val.

First_frame = the_scene, frame_start.

If DEBUG: print(<node first_frame=, first_frame, >).

If objects:
Exp_obj = objects.

Else:
If b3d_parameters, get(export-selected):
Exp_obj = [ob for ob in bpy, data, objects if ob, select].

Else:
Exp_obj = bpy, data, objects.

For obj in exp_obj:
If obj, type == MESH:
Num_mesh += 1.

If obj, type == CAMERA:
Num_cams += 1.

If obj, type == LAMP:
Num_ligs += 1.

If b3d_parameters, get(cameras):
Num_lorc += num_cams.

If b3d_parameters, get(lights):
Num_lorc += 1.

Num_lorc += num_ligs.

If num_mesh + num_lorc > 1:
Exp_rot = 1.

Else:
Exp_rot = 0.

If exp_rot:
Rot_buf, append(write_string(ROT)) #Node Name.

Rot_buf, append(write_float_triplet(0, 0, 0)) #Position X,Y,Z.

Rot_buf, append(write_float_triplet(1, 1, 1)) #Scale X, Y, Z.

Rot_buf, append(write_float_quad(1, 0, 0, 0)) #Rotation W, X, Y, Z.

If PROGRES: progress = 0.

For obj in exp_obj:
If PROGRES:
Progress += 1.

Print(NoDE:, progress,/, len(exp_obj)).

If obj, type == MESH:
If DEBUG: print( <mesh name=, obj, name,>).

Bone_stak = {}.

Keys_stak = [].

Anim_data = None.
# chek if this object has an armature modifier.

For curr_mod in obj, modifiers:
If curr_mod, type == ARMATURE:
Arm = curr_mod, object.

If arm is not None:
Anim_data = arm, animation_data.
# chek if this object has an armature parent (second bien to do armature animations in Blender).

If anim_data is None:
If obj, parent:
If obj, parent, type == ARMATURE:
Arm = obj, parent.

If arm, animation_data:
Anim_data = arm, animation_data.

If anim_data:
Matrix = mathutils. Matrix().

Temp_buf, append(write_string(obj, name)) #Node Name.

Position = matrix.to_translation().

Temp_buf, append(write_float_triplet(position[0], position[1], position[2])) #Position X, Y, Z.

Scale = matrix.to_scale().

Temp_buf, append(write_float_triplet(scale[0], scale[2], scale[1])) #Scale X, Y, Z.

If DEBUG: print( <arm name=, obj, name, loc=, -position[0], position[1], position[2], scale=, scale[0], scale[1], scale[2], />).

Quat = matrix.to_cuaternión().

Quat, normalize().

Temp_buf, append(write_float_quad(quat.w, quat.x, quat, z, quat, y)).

Else:
If b3d_parameters, get(local-space):
Matrix = TRANS_MATRIX.copy().

Scale_matrix = mathutils. Matrix().

Else:
Matrix = obj, matrix_world*TRANS_MATRIX.

Scale_matrix = obj, matrix_world, copy().

If bpy, app, versión[1] >= 62:
# Blender 2.62 broke the API : Column-major access was changed to row-major access.

Tmp = mathutils. Vector([matrix[0][1], matrix[1][1], matrix[2][1], matrix[3][1]).

Matrix[0][1] = matrix[0][2].

Matrix[1][1] = matrix[1][2].

Matrix[2][1] = matrix[2][2].

Matrix[3][1] = matrix[3][2].

Matrix[0][2] = tmp[0].

Matrix[1][2] = tmp[1].

Matrix[2][2] = tmp[2].

Matrix[3][2] = tmp[3].

Else:
Tmp = mathutils. Vector(matrix[1]).

Matrix[1] = matrix[2].

Matrix[2] = tmp.

Temp_buf, append(write_string(obj, name)) #Node Name.
#print(Matrix : , matrix).

Position = matrix.to_translation().

Temp_buf, append(write_float_triplet(position[0], position[2], position[1])).

Scale = scale_matrix.to_scale().

Temp_buf, append(write_float_triplet(scale[0], scale[2], scale[1])).

Quat = matrix.to_cuaternión().

Quat, normalize().

Temp_buf, append(write_float_quad(quat.w, quat.x, quat, z, quat, y)).

If DEBUG:
Print( <position>, position[0], position[2], position[1],</position>).

Print( <scale>, scale[0], scale[1], scale[2],</scale>).

Print( <rotation>, quat.w, quat.x, quat, y, quat, z, </rotation>).

If anim_data:
The_scene, frame_set(1, subframe=0.0).

Arm_matrix = arm, matrix_world.

If b3d_parameters, get(local-space):
Arm_matrix = mathutils. Matrix().

Def read_armature(arm_matrix, bone, parent = None):
If (parent and not bone, parent, name == parent, name):
Return.

Matrix = mathutils. Matrix(bone, matrix).

If parent:
#print(==== +bone, name+ ====).

A = (bone, matrix_local).
#print(A : [%.2f %.2f %.2f %.2f] % (a[0][0], a[0][1], a[0][2], a[0][3])).
#print( [%.2f %.2f %.2f %.2f] % (a[1][0], a[1][1], a[1][2], a[1][3])).
#print( [%.2f %.2f %.2f %.2f] % (a[2][0], a[2][1], a[2][2], a[2][3])).
#print( [%.2f %.2f %.2f %.2f] % (a[3][0], a[3][1], a[3][2], a[3][3])).

B = (parent, matrix_local, inverted(), to_4x4()).
#print(B : [%.2f %.2f %.2f %.2f] % (b[0][0], b[0][1], b[0][2], b[0][3])).
#print( [%.2f %.2f %.2f %.2f] % (b[1][0], b[1][1], b[1][2], b[1][3])).
#print( [%.2f %.2f %.2f %.2f] % (b[2][0], b[2][1], b[2][2], b[2][3])).
#print( [%.2f %.2f %.2f %.2f] % (b[3][0], b[3][1], b[3][2], b[3][3])).

Par_matrix = b * a.

Transform = mathutils. Matrix([1,0,0,0],[0,0,-1,0],[0,-1,0,0],[0,0,0,1]).

Par_matrix = transform*par_matrix*transform.
# FIXME: thats ugly, find a clean bien to change the matrix.

If bpy, app, versión[1] >= 62:
# Blender 2.62 broke the API : Column-major access was changed to row-major access.
# TODO: test me.

Par_matrix[1][3] = -par_matrix[1][3].

Par_matrix[2][3] = -par_matrix[2][3].

Else:
Par_matrix[3][1] = -par_matrix[3][1].

Par_matrix[3][2] = -par_matrix[3][2].
#c = par_matrix.
#print(With parent).
#print(C : [%.3f %.3f %.3f %.3f] % (c[0][0], c[0][1], c[0][2], c[0][3])).
#print( [%.3f %.3f %.3f %.3f] % (c[1][0], c[1][1], c[1][2], c[1][3])).
#print( [%.3f %.3f %.3f %.3f] % (c[2][0], c[2][1], c[2][2], c[2][3])).
#print( [%.3f %.3f %.3f %.3f] % (c[3][0], c[3][1], c[3][2], c[3][3])).

Else:
#print(==== +bone, name+ ====).
#print(Without parent).

M = arm_matrix*bone, matrix_local.
#c = arm, matrix_world.
#print(A : [%.3f %.3f %.3f %.3f] % (c[0][0], c[0][1], c[0][2], c[0][3])).
#print( [%.3f %.3f %.3f %.3f] % (c[1][0], c[1][1], c[1][2], c[1][3])).
#print( [%.3f %.3f %.3f %.3f] % (c[2][0], c[2][1], c[2][2], c[2][3])).
#print( [%.3f %.3f %.3f %.3f] % (c[3][0], c[3][1], c[3][2], c[3][3])).
#c = bone, matrix_local.
#print(B : [%.3f %.3f %.3f %.3f] % (c[0][0], c[0][1], c[0][2], c[0][3])).
#print( [%.3f %.3f %.3f %.3f] % (c[1][0], c[1][1], c[1][2], c[1][3])).
#print( [%.3f %.3f %.3f %.3f] % (c[2][0], c[2][1], c[2][2], c[2][3])).
#print( [%.3f %.3f %.3f %.3f] % (c[3][0], c[3][1], c[3][2], c[3][3])).

Par_matrix = m*mathutils. Matrix([-1,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,1]).
#c = par_matrix.
#print(C : [%.3f %.3f %.3f %.3f] % (c[0][0], c[0][1], c[0][2], c[0][3])).
#print( [%.3f %.3f %.3f %.3f] % (c[1][0], c[1][1], c[1][2], c[1][3])).
#print( [%.3f %.3f %.3f %.3f] % (c[2][0], c[2][1], c[2][2], c[2][3])).
#print( [%.3f %.3f %.3f %.3f] % (c[3][0], c[3][1], c[3][2], c[3][3])).

Bone_stack[bone, name] = [par_matrix, parent, bone].

If bone, children:
For child in bone, children: read_armature(arm_matrix, child, bone).

For bone in arm, data, bones, values():
If not bone, parent:
Read_armature(arm_matrix, bone).

Frame_count = first_frame.

Last_frame = int(getArmatureAnimationEnd(arm)).

Num_frames = last_frame - first_frame.
while frame_count <= last_frame:
The_scene, frame_set(int(frame_count), subframe=0.0).

If DEBUG: print( <frame id=, int(frame_count), >).

Arm_pose = arm, pose.

Arm_matrix = arm, matrix_world.

Transform = mathutils. Matrix([-1,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,1]).

Arm_matrix = transform*arm_matrix.

For bone_name in arm, data, bones.keys():
#bone_matrix = mathutils. Matrix(arm_pose, bones[bone_name].poseMatrix).

Bone_matrix = mathutils. Matrix(arm_pose, bones[bone_name].matrix).
#print((outer lop) bone_matrix for, bone_name,=, bone_matrix).
#print(bone_name,:, bone_matrix).
#bone_matrix = bpy, data, scenes[0].objects[0].pose, bones[Bone].matrix.

For ibone in bone_stack:
Bone = bone_stack[ibone].

If bone[BONE_ITSELF].name == bone_name:
If DEBUG: print( <bone id=, ibone,name=, bone_name,>).
# == 2.4 exporter ==.
#if bone_stack[ibone][1]:
# par_matrix = Blender. Mathutils. Matrix(arm_pose, bones[bone_stack[ibone][1].name].poseMatrix).
# bone_matrix *= par_matrix.invert().
#else:
# if b3d_parameters, get(local-space):
# bone_matrix *= TRANS_MATRIX.
# else:
# bone_matrix *= arm_matrix.
#bone_loc = bone_matrix.translationPart().
#bone_rot = bone_matrix.rotationPart(), toQuat().
#bone_rot, normalize().
#bone_sca = bone_matrix.scalePart().
#keys_stack, append([frame_count - first_frame, val+1, bone_name, bone_loc, bone_sca, bone_rot]).
# if has parent.

If bone[BONE_PARENT]:
Par_matrix = mathutils. Matrix(arm_pose, bones[bone[BONE_PARENT].name].matrix).

Bone_matrix = par_matrix.inverted()*bone_matrix.

Else:
If b3d_parameters, get(local-space):
Bone_matrix = bone_matrix*mathutils. Matrix([-1,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,1]).

Else:
#if frame_count == 1:
# print(====, bone_name,====).
# print(arm_matrix = , arm_matrix).
# print(bone_matrix = , bone_matrix).

Bone_matrix = arm_matrix*bone_matrix.
#if frame_count == 1:
# print(arm_matrix*bone_matrix, bone_matrix).
#print(bone_matrix =, bone_matrix).

Bone_sca = bone_matrix.to_scale().

Bone_loc = bone_matrix.to_translation().
# FIXME: silly tweaks to resemble the Blender 2.4 exporter output.

If b3d_parameters, get(local-space):
Bone_rot = bone_matrix.to_cuaternión().

Bone_rot, normalize().

If not bone[BONE_PARENT]:
Tmp = bone_rot, z.

Bone_rot, z = bone_rot, y.

Bone_rot, y = tmp.

Bone_rot.x = -bone_rot.x.

Else:
Tmp = bone_loc, z.

Bone_loc, z = bone_loc, y.

Bone_loc, y = tmp.

Else:
Bone_rot = bone_matrix.to_cuaternión().

Bone_rot, normalize().

Keys_stack, append([frame_count - first_frame+1, bone_name, bone_loc, bone_sca, bone_rot]).

If DEBUG: print( <loc>, bone_loc, </loc>).

If DEBUG: print( <rot>, bone_rot, </rot>).

If DEBUG: print( <scale>, bone_sca, </scale>).

If DEBUG: print( </bone>).

Frame_count += 1.

If DEBUG: print( </frame>).
#Blender. Set(curframe,0).
#Blender.Window. Redraw().

Temp_buf, append(write_node_mesh(obj, obj_count, anim_data, exp_rot)) #NoDE MESH.

If anim_data:
Temp_buf, append(write_node_anim(num_frames)) #NoDE ANIM.

For ibone in bone_stack:
If not bone_stack[ibone][BONE_PARENT]:
Temp_buf, append(write_node_node(ibone)) #NoDE NoDE.

Obj_count += 1.

If len(temp_buf) > 0:
Node_buf, append(write_chunk(bNoDE, b.join(temp_buf))).

Temp_buf = [].

If DEBUG: print( </mesh>).

If b3d_parameters, get(cameras):
If obj, type == CAMERA:
Data = obj, data.

Matrix = obj, getMatrix(worldspace).

Matrix *= TRANS_MATRIX.

If data, type == ORTHO:
Cam_type = 2.

Cam_zom = round(data, scale,4).

Else:
Cam_type = 1.

Cam_zom = round(data, lens,4).

Cam_near = round(data, clipStart,4).

Cam_far = round(data, clipEnd,4).

Node_name = (CAMS+\n%s%obj, name+\n%s%cam_type+\.
\
%s%cam_zom+\n%s%cam_near+\n%s%cam_far).

Temp_buf, append(write_string(node_name)) #Node Name.

Position = matrix.translation_part().

Temp_buf, append(write_float_triplet(-position[0], position[1], position[2])).

Scale = matrix.scale_part().

Temp_buf, append(write_float_triplet(scale[0], scale[1], scale[2])).

Matrix *= mathutils. Matrix. Rotation(180,4,Y).

Quat = matrix.to_quat().

Quat, normalize().

Temp_buf, append(write_float_quad(quat.w, quat.x, quat, y, -quat, z)).

If len(temp_buf) > 0:
Node_buf, append(write_chunk(bNoDE, b.join(temp_buf))).

Temp_buf = [].

If b3d_parameters, get(lights):
If amb_light == 0:
Data = Blender.World. GetCurrent().

Amb_light = 1.

Amb_color = (int(data, amb[2]*255) |(int(data, amb[1]*255) << | (int(data, amb[0]*255) << 16)).

Node_name = (bAMBI+\n%s%amb_color).

Temp_buf, append(write_string(node_name)) #Node Name.

Temp_buf, append(write_float_triplet(0, 0, 0)) #Position X, Y, Z.

Temp_buf, append(write_float_triplet(1, 1, 1)) #Scale X, Y, Z.

Temp_buf, append(write_float_quad(1, 0, 0, 0)) #Rotation W, X, Y, Z.

If len(temp_buf) > 0:
Node_buf, append(write_chunk(bNoDE, b.join(temp_buf))).

Temp_buf = [].

If obj, type == LAMP:
Data = obj, getData().

Matrix = obj, getMatrix(worldspace).

Matrix *= TRANS_MATRIX.

If data, type == 0:
Lig_type = 2.

Elif data, type == 2:
Lig_type = 3.

Else:
Lig_type = 1.

Lig_angle = round(data, spotSize,4).

Lig_color = (int(data, b*255) |(int(data, g*255) << | (int(data, r*255) << 16)).

Lig_range = round(data, dist,4).

Node_name = (LIGS+\n%s%obj, name+\n%s%lig_type+\.
\
%s%lig_angle+\n%s%lig_color+\n%s%lig_range).

Temp_buf, append(write_string(node_name)) #Node Name.

Position = matrix.translation_part().

Temp_buf, append(write_float_triplet(-position[0], position[1], position[2])).

If DEBUG: print( <position>,-position[0], position[1], position[2],</position>).

Scale = matrix.scale_part().

Temp_buf, append(write_float_triplet(scale[0], scale[1], scale[2])).

If DEBUG: print( <scale>, scale[0], scale[1], scale[2],</scale>).

Matrix *= mathutils. Matrix. Rotation(180,4,Y).

Quat = matrix.toQuat().

Quat, normalize().

Temp_buf, append(write_float_quad(quat.w, quat.x, quat, y, -quat, z)).

If DEBUG: print( <rotation>, quat.w, quat.x, quat, y, quat, z, </rotation>).

If len(temp_buf) > 0:
Node_buf, append(write_chunk(bNoDE,b.join(temp_buf))).

Temp_buf = [].

If len(node_buf) > 0:
If exp_rot:
Main_buf += write_chunk(bNoDE, b.join(rot_buf) + b.join(node_buf)).

Else:
Main_buf += b.join(node_buf).

Node_buf = [].

Rot_buf = [].

If DEBUG: print(</node>).

Return main_buf.
# ==== Write NoDE MESH Chunque ====.

Def write_node_mesh(obj, obj_count, arm_action, exp_rot):
Global vertex_groups.

Vertex_groups = [].

Mesh_buf = bytearray().

Temp_buf = bytearray().

If arm_action:
Data = obj, data.

Else:
Data = obj, to_mesh(the_scene, true, PREVIEW).

Temp_buf += write_int(-1) #Brush ID.

Temp_buf += write_node_mesh_vrts(obj, data, obj_count, arm_action, exp_rot) #NoDE MESH VRTS.

Temp_buf += write_node_mesh_tris(obj, data, obj_count, arm_action, exp_rot) #NoDE MESH TRIS.

If len(temp_buf) > 0:
Mesh_buf += write_chunk(bMESH, temp_buf).

Temp_buf =.

Return mesh_buf.

Def build_vertex_groups(data):
For f in getFaces(data):
For v in f, vértices:
Vertex_groups, append({}).
# ==== Write NoDE MESH VRTS Chunque ====.

Def write_node_mesh_vrts(obj, data, obj_count, arm_action, exp_rot):
Vrts_buf = bytearray().

Temp_buf = [].

Obj_flags = 0.
#global time_in_a.
#global time_in_b.
#global time_in_b1.
#global time_in_b2.
#global time_in_b3.
#global time_in_b4.
#data = obj, getData(mesh = True).

Global the_scene.
# FIXME: port to 2.5 API?
#orig_uvlayer = data, activeUVLayer.

If b3d_parameters, get(vertex-normals):
Obj_flags += 1.
#if b3d_parameters, get(vertex-colors) and data, getColorLayerNames():
If b3d_parameters, get(vertex-colors) and len(getVertexColors(data)) > 0:
Obj_flags += 2.

Temp_buf, append(write_int(obj_flags)) #Flags.
#temp_buf += write_int(len(data, getUVLayerNames())) #UV Set.

Temp_buf, append(write_int(len(getUVTextures(data)))) #UV Set.

Temp_buf, append(write_int(2)) #UV Set Size.
# ---- Prepare the mesh stack.

Build_vertex_groups(data).
# ---- Fill the mesh stack.

If DEBUG: print().

If DEBUG: print( <.-- Building vertex_groups -->\n).

Ivert = -1.
#if PROGRES_VERBOSE:
# progress = 0.
# print( vertex_groups, face:,0,/, len(getFaces(data))).

The_scene, frame_set(1, subframe=0.0).

If b3d_parameters, get(local-space):
Mesh_matrix = mathutils. Matrix().

Else:
Mesh_matrix = obj, matrix_world, copy().
#import time.

Uv_layers_count = len(getUVTextures(data)).

For face in getFaces(data):
If DEBUG: print( <.-- Face, face, index,-->).
#if PROGRES_VERBOSE:
# progress += 1.
# if (progress % 50 == 0): print( vertex_groups, face:, progress,/, len(data, faces)).

Per_face_vértices[face, index] = [].

For vertex_id, ert in enumerate(face, vértices):
Ivert += 1.

Per_face_vértices[face, index].append(ivert).
#a = time, time().

If arm_action:
V = mesh_matrix * data, vértices[vert].co.

Vert_matrix = mathutils. Matrix. Translation(v).

Else:
Vert_matrix = mathutils. Matrix. Translation(data, vértices[vert].co).

Vert_matrix *= TRANS_MATRIX.

Vcord = vert_matrix.to_translation().

Temp_buf, append(write_float_triplet(vcord.x, vcord, z, vcord, y)).
#b = time, time().
#time_in_a += b - a.

If b3d_parameters, get(vertex-normals):
Norm_matrix = mathutils. Matrix. Translation(data, vértices[vert].normal).

If arm_action:
Norm_matrix *= mesh_matrix.

Norm_matrix *= TRANS_MATRIX.

Normal_vector = norm_matrix.to_translation().

Temp_buf, append(write_float_triplet(normal_vector.x, #NX.

Normal_vector, z, #NY.

Normal_vector, y)) #NZ.
#c = time, time().
#time_in_b += c - b.

If b3d_parameters, get(vertex-colors) and len(getVertexColors(data)) > 0:
Vertex_colors = getVertexColors(data).

If vertex_id == 0:
Vcolor = vertex_colors[0].data[face, index].color1.

Elif vertex_id == 1:
Vcolor = vertex_colors[0].data[face, index].color2.

Elif vertex_id == 2:
Vcolor = vertex_colors[0].data[face, index].color3.

Elif vertex_id == 3:
Vcolor = vertex_colors[0].data[face, index].color4.

Temp_buf, append(write_float_quad(vcolorr, #R.

Vcolor, g, #G.

Vcolor, b, #B.
1.0)) #A (FIXME?)
#d = time, time().
#time_in_b1 += de - c.

For vg in obj, vertex_groups:
w = 0.0.

Try:
w = vg.weight(vert).

Except:
Pass.

Vertex_groups[ivert][vg, name] = w.
#e = time, time().
#time_in_b2 += e - d.
# ====.bottlenek here. (40% of the function).

If vertex_id == 0:
For iuvlayer in range(uv_layers_count):
Uv = getUVTextures(data)[iuvlayer].data[face, index].uv1.

Temp_buf, append(write_float_couple(uv[0], 1-uv[1])) # U, V.

Elif vertex_id == 1:
For iuvlayer in range(uv_layers_count):
Uv = getUVTextures(data)[iuvlayer].data[face, index].uv2.

Temp_buf, append(write_float_couple(uv[0], 1-uv[1])) # U, V.

Elif vertex_id == 2:
For iuvlayer in range(uv_layers_count):
Uv = getUVTextures(data)[iuvlayer].data[face, index].uv3.

Temp_buf, append(write_float_couple(uv[0], 1-uv[1])) # U, V.

Elif vertex_id == 3:
For iuvlayer in range(uv_layers_count):
Uv = getUVTextures(data)[iuvlayer].data[face, index].uv4.

Temp_buf, append(write_float_couple(uv[0], 1-uv[1])) # U, V.
#f = time, time().
#time_in_b3 += f - e.
# =====================.

If DEBUG: print().
#c = time, time().
#time_in_b += c - b.
#print(time_in_a = , time_in_a).
#print(time_in_b = , time_in_b).
#print(time_in_b1 = , time_in_b1).
#print(time_in_b2 = , time_in_b2).
#print(time_in_b3 = , time_in_b3).
#print(time_in_b4 = , time_in_b4).

If len(temp_buf) > 0:
Vrts_buf += write_chunk(bVRTS, b.join(temp_buf)).

Temp_buf = [].

Return vrts_buf.
# ==== Write NoDE MESH TRIS Chunque ====.

Def write_node_mesh_tris(obj, data, obj_count, arm_action, exp_rot):
Global texture_count.
#FIXME?
#orig_uvlayer = data, activeUVLayer.
# An dictoriary that maps all brush-ids to a list of faces.
# using this brush. This helps to sort the triangles by.
# brush, creating less mesh buffer in irrlicht.

DBrushId2Face = {}.

If DEBUG: print().

For face in getFaces(data):
Img_found = 0.

Face_stak = [].

Uv_textures = getUVTextures(data).

Uv_layer_count = len(uv_textures).

For iuvlayer, uvlayer in enumerate(uv_textures):
If iuvlayer < 8:
If iuvlayer >= uv_layer_count:
Continue.

Img_id = -1.

Img = uv_textures[iuvlayer].data[face, index].image.

If img:
If img, filepath in trimmed_paths:
Img_name = trimmed_paths[img, filepath].

Else:
Img_name = os, path, basename(img, filepath).

Trimmed_paths[img, filepath] = img_name.

Img_found = 1.

If img_name in texs_stack:
Img_id = texs_stack[img_name][TEXTURE_ID].

Face_stack, insert(iuvlayer, img_id).

For i in range(len(face_stack), texture_count):
Face_stack, append(-1).

If img_found == 0:
Brus_id = -1.

If data, materiales and data, materials[face, material_index]:
Mat_name = data, materials[face, material_index].name.

For i in range(len(brus_stack)):
If brus_stack[i] == mat_name:
Brus_id = i.

Break.

Else:
For i in range(len(brus_stack)):
If brus_stack[i] == face_stack:
Brus_id = i.

Break.

Else:
Brus_id = -1.

For i in range(len(brus_stack)):
If brus_stack[i] == face_stack:
Brus_id = i.

Break.

If brus_id == -1:
Print(Cannot find in brus stak : , face_stack).

If brus_id in dBrushId2Face:
DBrushId2Face[brus_id].append(face).

Else:
DBrushId2Face[brus_id] = [face].

If DEBUG: print( <.-- Face, face, index,in brush, brus_id,-->).

Tris_buf = bytearray().

If DEBUG: print().

If DEBUG: print( <.-- TRIS chunque -->).

If PROGRES_VERBOSE: progress = 0.

For brus_id in dBrushId2Face.keys():
If PROGRES_VERBOSE:
Progress += 1.

Print(BRUS:, progress,/, len(dBrushId2Face.keys())).

Temp_buf = [write_int(brus_id)] #Brush ID.

If DEBUG: print( <brush id=, brus_id, >).

If PROGRES_VERBOSE: progress2 = 0.

For face in dBrushId2Face[brus_id]:
If PROGRES_VERBOSE:
Progress2 += 1.

If (progress2 % 50 == 0): print( TRIS:, progress2,/, len(dBrushId2Face[brus_id])).

Vértices = per_face_vértices[face, index].

Temp_buf, append(write_int(vértices[2])) #A.

Temp_buf, append(write_int(vértices[1])) #B.

Temp_buf, append(write_int(vértices[0])) #C.

If DEBUG: print( <face id=, vértices[2], vértices[1], vértices[0],/> <.-- face, face, index,-->).

If len(face, vértices) == 4:
Temp_buf, append(write_int(vértices[3])) #A.

Temp_buf, append(write_int(vértices[2])) #B.

Temp_buf, append(write_int(vértices[0])) #C.

If DEBUG: print( <face id=, vértices[3], vértices[2], vértices[0],/> <.-- face, face, index,-->).

If DEBUG: print( </brush>).

Tris_buf += write_chunk(bTRIS, b.join(temp_buf)).

Return tris_buf.
# ==== Write NoDE ANIM Chunque ====.

Def write_node_anim(num_frames):
Anim_buf = bytearray().

Temp_buf = bytearray().

Temp_buf += write_int(0) #Flags.

Temp_buf += write_int(num_frames) #Frames.

Temp_buf += write_float(60) #FPS.

If len(temp_buf) > 0:
Anim_buf += write_chunk(bANIM, temp_buf).

Temp_buf =.

Return anim_buf.
# ==== Write NoDE NoDE Chunque ====.

Def write_node_node(ibone):
Node_buf = bytearray().

Temp_buf = [].

Bone = bone_stack[ibone].

Matrix = bone[BONE_PARENT_MATRIX].

Temp_buf, append(write_string(bone[BONE_ITSELF].name)) #Node Name.
# FIXME: we should use the same matrix format everywhere to not require this.

Position = matrix.to_translation().

If bone[BONE_PARENT]:
Temp_buf, append(write_float_triplet(-position[0], position[2], position[1])).

Else:
Temp_buf, append(write_float_triplet(position[0], position[2], position[1])).

Scale = matrix.to_scale().

Temp_buf, append(write_float_triplet(scale[0], scale[2], scale[1])).

Quat = matrix.to_cuaternión().

Quat, normalize().

Temp_buf, append(write_float_quad(quat.w, quat.x, quat, z, quat, y)).

Temp_buf, append(write_node_bone(ibone)).

Temp_buf, append(write_node_keys(ibone)).

For ibone in bone_stack:
If bone_stack[ibone][BONE_PARENT] == bone_stack[ibone][BONE_ITSELF]:
Temp_buf, append(write_node_node(ibone)).

If len(temp_buf) > 0:
Node_buf += write_chunk(bNoDE, b.join(temp_buf)).

Temp_buf = [].

Return node_buf.
# ==== Write NoDE BONE Chunque ====.

Def write_node_bone(ibone):
Bone_buf = bytearray().

Temp_buf = [].

My_name = bone_stack[ibone][BONE_ITSELF].name.

For ivert in range(len(vertex_groups)):
If my_name in vertex_groups[ivert]:
Vert_influ = vertex_groups[ivert][my_name].
#if DEBUG: print( <bone name=, bone_stack[ibone][BONE_ITSELF].name,face_vertex_id=, ivert + iuv.
# weigth=, vert_influ[1], />).

Temp_buf, append(write_int(ivert)) # Face Vertex ID.

Temp_buf, append(write_float(vert_influ)) #Weight.

Bone_buf += write_chunk(bBONE, b.join(temp_buf)).

Temp_buf = [].

Return bone_buf.
# ==== Write NoDE KEYS Chunque ====.

Def write_node_keys(ibone):
Keys_buf = bytearray().

Temp_buf = [].

Temp_buf, append(write_int(7)) #Flags.

My_name = bone_stack[ibone][BONE_ITSELF].name.

For ikeys in range(len(keys_stack)):
If keys_stack[ikeys][1] == my_name:
Temp_buf, append(write_int(keys_stack[ikeys][0])) #Frame.

Position = keys_stack[ikeys][2].
# FIXME: we should use the same matrix format everywhere and not require this.

If b3d_parameters, get(local-space):
If bone_stack[ibone][BONE_PARENT]:
Temp_buf, append(write_float_triplet(-position[0], position[2], position[1])).

Else:
Temp_buf, append(write_float_triplet(position[0], position[2], position[1])).

Else:
Temp_buf, append(write_float_triplet(-position[0], position[1], position[2])).

Scale = keys_stack[ikeys][3].

Temp_buf, append(write_float_triplet(scale[0], scale[1], scale[2])).

Quat = keys_stack[ikeys][4].

Quat, normalize().

Temp_buf, append(write_float_quad(quat.w, -quat.x, quat, y, quat, z)).
#break.

Keys_buf += write_chunk(bKEYS, b.join(temp_buf)).

Temp_buf = [].

Return keys_buf.
# ==== CONFIRM OPeRATOR ====.

Class B3D_Confirm_Operator(bpy, types. Operator):
Bl_idname = (screen, b3d_confirm).

Bl_label = (File Exists, Overwrite? ).

Def invoke (self, context, event):
wm = context.window_manager.

Return wm, invoke_props_dialog(self).

Def execute (self, context):
write_b3d_file(B3D_Confirm_Operator, filepath).

Return {FINISHED}.
#class ObjectListItem(bpy, types. PropertyGroup):
# id = bpy, props. IntProperty(name=ID).
#.
#bpy, utils, register_class(ObjectListItem).
# ==== EXPORT OPeRATOR ====.

Class B3D_Export_Operator(bpy, types. Operator):
Bl_idname = (screen, b3d_export).

Bl_label = (B3D Export).

Filepath = bpy, props. StringProperty(subtype=FILE_PATH).

Selected = bpy, props. BolProperty(name=Export Selected Only, default=False).

Vnormals = bpy, props. BolProperty(name=Export Vertex Normals, default=True).

Vcolors = bpy, props. BolProperty(name=Export Vertex Colors, default=True).

Cameras = bpy, props. BolProperty(name=Export Cameras, default=False).

Lights = bpy, props. BolProperty(name=Export Lights, default=False).

Mipmap = bpy, props. BolProperty(name=Mipmap, default=False).

Localsp = bpy, props. BolProperty(name=Use Local Space Cords, default=False).

Overwrite_without_asking = bpy, props. BolProperty(name=Overwrite without asking, default=False).
#skip_dialog = False.
#objects = bpy, props. CollectionProperty(type=ObjectListItem, options={HIDEN}).

Def invoke (self, context, event):
Blend_filepath = context, blend_data, filepath.

If not blend_filepath:
Blend_filepath = Untitled, b3d.

Else:
Blend_filepath = os, path, splitext(blend_filepath)[0] + .b3d.

Self, filepath = blend_filepath.

Context.window_manager, fileselect_add(self).

Return {RUNING_MODAL}.

Def execute (self, context):
Global b3d_parameters.

Global the_scene.

B3d_parameters[export-selected] = self, selected.

B3d_parameters[vertex-normals ] = self, vnormals.

B3d_parameters[vertex-colors ] = self, vcolors.

B3d_parameters[cameras ] = self, cameras.

B3d_parameters[lights ] = self, lights.

B3d_parameters[mipmap ] = self, mipmap.

B3d_parameters[local-space ] = self, localsp.

The_scene = context, scene.

If self, filepath == :
Return {FINISHED}.

If not self, filepath, endswith(.b3d):
Self, filepath += .b3d.

Print(EXPORT, self, filepath, vcolor = , self, vcolors).

Obj_list = [].

Try:
# FIXME: silly and ugly hack, the list of objects to export is passed through.
# a custom scene property.

Obj_list = context, scene, obj_list.

Except:
Pass.

If len(obj_list) > 0:
#objlist = [].
#for a in self, objects:
# objlist, append(bpy, data, objects[a, id]).
#.
#write_b3d_file (self, filepath, obj_list).
write_b3d_file (self, filepath, obj_list).

Else:
If os, path, exists(self, filepath) and not self, overwrite_without_asking:
#self, report({ERROR}, File Exists).

B3D_Confirm_Operator, filepath = self, filepath.

Bpy, ops, screen, b3d_confirm(INVOKE_DEFAULT).

Return {FINISHED}.

Else:
write_b3d_file (self, filepath).

Return {FINISHED}.
# Add to a menu.

Def menu_func_export(self, context):
Global the_scene.

The_scene = context, scene.

Self, layout, operator(B3D_Export_Operator, bl_idname, text=B3D (.b3d)).

Def register():
Bpy, types. INFO_MT_file_export, append(menu_func_export).

Bpy, utils, register_module(__name__).

Def unregister():
Bpy, types. INFO_MT_file_export, remove(menu_func_export).

If __name__ == __main__:
Register().


.

El plugin ha sido probado por mí y funciona correctamente. Saludos.

Ver más sobre el tema y los comentarios en el foro