[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [1227] trunk/py/scripts/addons:

John Brown jcb at special-p.co.uk
Sat Dec 4 11:38:27 CET 2010


Revision: 1227
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-extensions&revision=1227
Author:   jcbdigger
Date:     2010-12-04 11:38:27 +0100 (Sat, 04 Dec 2010)

Log Message:
-----------


Added Paths:
-----------
    trunk/py/scripts/addons/io_export_anim_mesh_xna/
    trunk/py/scripts/addons/io_export_anim_mesh_xna/__init__.py
    trunk/py/scripts/addons/io_export_anim_mesh_xna/export_xna.py

Added: trunk/py/scripts/addons/io_export_anim_mesh_xna/__init__.py
===================================================================
--- trunk/py/scripts/addons/io_export_anim_mesh_xna/__init__.py	                        (rev 0)
+++ trunk/py/scripts/addons/io_export_anim_mesh_xna/__init__.py	2010-12-04 10:38:27 UTC (rev 1227)
@@ -0,0 +1,85 @@
+bl_addon_info = {
+    "name": "Blender to XNA",
+    "author": "John C Brown, JCBDigger (@MistyManor)",
+    "version": (1,1),
+    "blender": (2, 5, 5),
+    "api": 32738,
+    "location": "File > Export > XNA FBX Animated Model",
+    "description": "Export the model and animations for use in XNA",
+    "warning": "",
+    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/File_I-O/Blender-toXNA",
+    "tracker_url": "https://projects.blender.org/tracker/index.php?func=detail&aid=25013&group_id=153&atid=469",
+    "category": "Import/Export"}
+
+# ***** 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 on the GNU web site for full
+# details: http://www.gnu.org/licenses/gpl.html
+#
+# ***** END GPL LICENCE BLOCK *****
+
+# This script uses spaces for indents NOT tabs.
+"""
+Blender to XNA
+
+http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/File_I-O/Blender-toXNA
+"""
+
+# To support reload properly, try to access a package var, if it's there, reload everything
+if "bpy" in locals():
+    import sys
+    reload(sys.modules.get("io_export_anim_mesh_xna.export_xna", sys))
+
+import bpy
+
+# Add each additional script in a simlar block to this
+def menu_export_fbx_model(self, context):
+    from io_export_anim_mesh_xna import export_xna
+    import os
+    default_path = os.path.splitext(bpy.data.filepath)[0] + ".fbx"
+    self.layout.operator(export_xna.ExportFBXmodel.bl_idname, text="XNA FBX Model only (.fbx)").filepath = default_path
+
+def menu_export_fbx_takes(self, context):
+    from io_export_anim_mesh_xna import export_xna
+    import os
+    # get the current action name
+    currentAction = ""
+    for arm_obj in bpy.context.scene.objects:
+        if arm_obj.type == 'ARMATURE':
+            if arm_obj.animation_data:
+                if currentAction == "":
+                    currentAction = arm_obj.animation_data.action.name
+    
+    default_path = os.path.splitext(bpy.data.filepath)[0] + "-" + currentAction + ".fbx"
+    self.layout.operator(export_xna.ExportFBXtakes.bl_idname, text="XNA FBX Animations only (.fbx)").filepath = default_path
+    
+def menu_export_fbx_animated(self, context):
+    from io_export_anim_mesh_xna import export_xna
+    import os
+    default_path = os.path.splitext(bpy.data.filepath)[0] + ".fbx"
+    self.layout.operator(export_xna.ExportFBXanimated.bl_idname, text="XNA FBX Animated Model (.fbx)").filepath = default_path
+
+
+# Add references to all scripts invoked by this class
+def register():
+    bpy.types.INFO_MT_file_export.append(menu_export_fbx_animated)
+    bpy.types.INFO_MT_file_export.append(menu_export_fbx_model)
+    bpy.types.INFO_MT_file_export.append(menu_export_fbx_takes)
+
+# Add references to all scripts invoked by this class
+def unregister():
+    bpy.types.INFO_MT_file_export.remove(menu_export_fbx_animated)
+    bpy.types.INFO_MT_file_export.remove(menu_export_fbx_model)
+    bpy.types.INFO_MT_file_export.remove(menu_export_fbx_takes)
+
+if __name__ == "__main__":
+    register()

Added: trunk/py/scripts/addons/io_export_anim_mesh_xna/export_xna.py
===================================================================
--- trunk/py/scripts/addons/io_export_anim_mesh_xna/export_xna.py	                        (rev 0)
+++ trunk/py/scripts/addons/io_export_anim_mesh_xna/export_xna.py	2010-12-04 10:38:27 UTC (rev 1227)
@@ -0,0 +1,3017 @@
+# ***** 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 on the GNU web site for full
+# details: http://www.gnu.org/licenses/gpl.html
+#
+# ***** END GPL LICENCE BLOCK *****
+
+# This script uses spaces for indents NOT tabs.
+# Developer comments at the end of the file
+
+"""
+Blender to XNA
+
+This script is an exporter to the Autodesk FBX file format suitable for use with Microsoft XNA.
+
+http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/File_I-O/Blender-toXNA
+"""
+
+import os
+import time
+import math # math.pi
+import shutil # for file copying
+
+import bpy
+from mathutils import Vector, Euler, Matrix
+
+# I guess FBX uses degrees instead of radians (Arystan).
+# Call this function just before writing to FBX.
+def eulerRadToDeg(eul):
+    ret = Euler()
+
+    ret.x = 180 / math.pi * eul[0]
+    ret.y = 180 / math.pi * eul[1]
+    ret.z = 180 / math.pi * eul[2]
+
+    return ret
+
+# Used to add the scene name into the filepath without using odd chars
+sane_name_mapping_ob = {}
+sane_name_mapping_mat = {}
+sane_name_mapping_tex = {}
+sane_name_mapping_take = {}
+sane_name_mapping_group = {}
+
+# Make sure reserved names are not used
+sane_name_mapping_ob['Scene'] = 'Scene_'
+sane_name_mapping_ob['blend_root'] = 'blend_root_'
+
+def increment_string(t):
+    name = t
+    num = ''
+    while name and name[-1].isdigit():
+        num = name[-1] + num
+        name = name[:-1]
+    if num:	return '%s%d' % (name, int(num)+1)
+    else:	return name + '_0'
+
+
+
+# TODO - Disallow the name 'Scene' - it will bugger things up.
+#        'Blend_Root' is no longer used so it does not matter (JCB)
+def sane_name(data, dct):
+    #if not data: return None
+
+    if type(data)==tuple: # materials are paired up with images
+        data, other = data
+        use_other = True
+    else:
+        other = None
+        use_other = False
+
+    if data:	name = data.name
+    else:		name = None
+    orig_name = name
+
+    if other:
+        orig_name_other = other.name
+        name = '%s #%s' % (name, orig_name_other)
+    else:
+        orig_name_other = None
+
+
+    if not name:
+        name = 'unnamed' # blank string, ASKING FOR TROUBLE!
+    else:
+
+        name = bpy.path.clean_name(name) # use our own
+
+    while name in iter(dct.values()):	name = increment_string(name)
+
+    if use_other: # even if other is None - orig_name_other will be a string or None
+        dct[orig_name, orig_name_other] = name
+    else:
+        dct[orig_name] = name
+
+    return name
+
+def sane_obname(data):		return sane_name(data, sane_name_mapping_ob)
+def sane_matname(data):		return sane_name(data, sane_name_mapping_mat)
+def sane_texname(data):		return sane_name(data, sane_name_mapping_tex)
+def sane_takename(data):	return sane_name(data, sane_name_mapping_take)
+def sane_groupname(data):	return sane_name(data, sane_name_mapping_group)
+
+
+def mat4x4str(mat):
+    return '%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f,%.15f' % tuple([ f for v in mat for f in v ])
+
+
+# ob must be OB_MESH
+def BPyMesh_meshWeight2List(ob, me):
+    ''' Takes a mesh and return its group names and a list of lists, one list per vertex.
+    aligning the each vert list with the group names, each list contains float value for the weight.
+    These 2 lists can be modified and then used with list2MeshWeight to apply the changes.
+    '''
+
+    # Clear the vert group.
+    groupNames= [g.name for g in ob.vertex_groups]
+    len_groupNames= len(groupNames)
+
+    if not len_groupNames:
+        # no verts? return a vert aligned empty list
+        return [[] for i in range(len(me.vertices))], []
+    else:
+        vWeightList= [[0.0]*len_groupNames for i in range(len(me.vertices))]
+
+    for i, v in enumerate(me.vertices):
+        for g in v.groups:
+            vWeightList[i][g.group] = g.weight
+
+    return groupNames, vWeightList
+
+def meshNormalizedWeights(ob, me):
+    try: # account for old bad BPyMesh
+        groupNames, vWeightList = BPyMesh_meshWeight2List(ob, me)
+    except:
+        return [],[]
+
+    if not groupNames:
+        return [],[]
+
+    for i, vWeights in enumerate(vWeightList):
+        tot = 0.0
+        for w in vWeights:
+            tot+=w
+
+        if tot:
+            for j, w in enumerate(vWeights):
+                vWeights[j] = w/tot
+
+    return groupNames, vWeightList
+
+header_comment = \
+'''; FBX 6.1.0 project file
+; Created by Blender XNA FBX Exporter(s)
+; Project home: http://code.google.com/p/blender-to-xna/
+; ------------------------------------------------------
+
+'''
+
+# Start here
+# Called from the user interface
+# This func can be called with just the filepath
+def export_fbx(operator, context, filepath="",
+        EXP_OBS_SELECTED = True,
+        Exp_Model_Only = False,
+        Exp_Takes_Only = False,
+        ANIM_ENABLE = True,
+        ANIM_ACTION_ALL = False,
+        EXP_MESH_APPLY_MOD = True,
+        EXP_IMAGE_COPY = False,
+        Include_Smoothing = False,
+        Include_Edges = False,
+    ):
+    
+    # If we only export the model and we enable animations then the rest pose will 
+    # be included as a take. (JCB)
+    # The armature is always included (JCB)
+
+    # Remove these eventually as they are not applicable to XNA (JCB)
+    EXP_LAMP = False
+    EXP_CAMERA = False
+    ANIM_OPTIMIZE = False
+    ANIM_OPTIMIZE_PRECISSION = 6
+    # We only need the armature for animations (JCB)
+    EXP_MESH = True    # This option does not do what it claims!
+    EXP_ARMATURE = True
+    EXP_EMPTY = True
+    
+    # Check if we have an armature and skip stuff if we do not (JCB)
+    # If we do not have any armatures we cannot have any animations either
+    if len(bpy.data.armatures) < 1:
+        EXP_ARMATURE = False
+        ANIM_ENABLE = False

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list