[Bf-extensions-cvs] [2187f6e] master: Initial Collada exporter from Juan Linietsky (T41071)

Campbell Barton noreply at git.blender.org
Thu Dec 25 18:56:48 CET 2014


Commit: 2187f6e51e0aa5cc562074af68dfa29bc3dcc000
Author: Campbell Barton
Date:   Tue Jul 15 19:03:14 2014 +1000
Branches: master
https://developer.blender.org/rBAC2187f6e51e0aa5cc562074af68dfa29bc3dcc000

Initial Collada exporter from Juan Linietsky (T41071)

===================================================================

A	io_scene_dae/__init__.py
A	io_scene_dae/export_dae.py

===================================================================

diff --git a/io_scene_dae/__init__.py b/io_scene_dae/__init__.py
new file mode 100644
index 0000000..c823a72
--- /dev/null
+++ b/io_scene_dae/__init__.py
@@ -0,0 +1,178 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8-80 compliant>
+
+bl_info = {
+    "name": "Khronos Collada format",
+    "author": "Juan Linietsky",
+    "blender": (2, 7, 1),
+    "location": "File > Import-Export",
+    "description": "Export DAE Scenes",
+    "warning": "",
+    "wiki_url": "",
+    "tracker_url": "",
+    "support": 'OFFICIAL',
+    "category": "Import-Export",
+}
+
+
+if "bpy" in locals():
+    import imp
+    if "export_dae" in locals():
+        imp.reload(export_dae)
+
+
+import bpy
+from bpy.props import StringProperty, BoolProperty, FloatProperty, EnumProperty
+
+from bpy_extras.io_utils import ExportHelper
+
+
+class ExportDAE(bpy.types.Operator, ExportHelper):
+    '''Selection to DAE'''
+    bl_idname = "export_scene.dae"
+    bl_label = "Export DAE"
+    bl_options = {'PRESET'}
+
+    filename_ext = ".dae"
+    filter_glob = StringProperty(default="*.dae", options={'HIDDEN'})
+
+    # List of operator properties, the attributes will be assigned
+    # to the class instance from the operator settings before calling.
+
+    object_types = EnumProperty(
+            name="Object Types",
+            options={'ENUM_FLAG'},
+            items=(('EMPTY', "Empty", ""),
+                   ('CAMERA', "Camera", ""),
+                   ('LAMP', "Lamp", ""),
+                   ('ARMATURE', "Armature", ""),
+                   ('MESH', "Mesh", ""),
+                   ('CURVE', "Curve", ""),
+                   ),
+            default={'EMPTY', 'CAMERA', 'LAMP', 'ARMATURE', 'MESH', 'CURVE'},
+            )
+
+    use_export_selected = BoolProperty(
+            name="Selected Objects",
+            description="Export only selected objects "
+                        "(and visible in active layers if that applies)",
+            default=False,
+            )
+    use_mesh_modifiers = BoolProperty(
+            name="Apply Modifiers",
+            description="Apply modifiers to mesh objects (on a copy!)",
+            default=True,
+            )
+    use_copy_images = BoolProperty(
+            name="Copy Images",
+            description="Copy Images (create images/ subfolder)",
+            default=False,
+            )
+    use_active_layers = BoolProperty(
+            name="Active Layers",
+            description="Export only objects on the active layers",
+            default=True,
+            )
+    use_exclude_ctrl_bones = BoolProperty(
+            name="Exclude Control Bones",
+            description="Exclude skeleton bones with names that begin with 'ctrl'",
+            default=True,
+            )
+    use_anim = BoolProperty(
+            name="Export Animation",
+            description="Export keyframe animation",
+            default=False,
+            )
+    use_anim_action_all = BoolProperty(
+            name="All Actions",
+            description="Export all actions for the first armature found in separate DAE files",
+            default=False,
+            )
+    use_anim_optimize = BoolProperty(
+            name="Optimize Keyframes",
+            description="Remove double keyframes",
+            default=True,
+            )
+    anim_optimize_precision = FloatProperty(
+            name="Precision",
+            description="Tolerence for comparing double keyframes "
+                        "(higher for greater accuracy)",
+            min=1, max=16,
+            soft_min=1, soft_max=16,
+            default=6.0,
+            )
+    use_metadata = BoolProperty(
+            name="Use Metadata",
+            default=True,
+            options={'HIDDEN'},
+            )
+
+    @property
+    def check_extension(self):
+        # return self.batch_mode == 'OFF'
+        return True
+
+    def check(self, context):
+        return True
+        """
+        isretur_def_change = super().check(context)
+        return (is_xna_change or is_def_change)
+        """
+
+    def execute(self, context):
+        if not self.filepath:
+            raise Exception("filepath not set")
+
+        """        global_matrix = Matrix()
+
+                global_matrix[0][0] = \
+                global_matrix[1][1] = \
+                global_matrix[2][2] = self.global_scale
+        """
+
+        keywords = self.as_keywords(ignore=("axis_forward",
+                                            "axis_up",
+                                            "global_scale",
+                                            "check_existing",
+                                            "filter_glob",
+                                            "xna_validate",
+                                            ))
+
+        from . import export_dae
+        return export_dae.save(self, context, **keywords)
+
+
+def menu_func(self, context):
+    self.layout.operator(ExportDAE.bl_idname, text="Khronos Collada (.dae)")
+
+
+def register():
+    bpy.utils.register_module(__name__)
+
+    bpy.types.INFO_MT_file_export.append(menu_func)
+
+
+def unregister():
+    bpy.utils.unregister_module(__name__)
+
+    bpy.types.INFO_MT_file_export.remove(menu_func)
+
+if __name__ == "__main__":
+    register()
diff --git a/io_scene_dae/export_dae.py b/io_scene_dae/export_dae.py
new file mode 100644
index 0000000..1847d6f
--- /dev/null
+++ b/io_scene_dae/export_dae.py
@@ -0,0 +1,1214 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+# Script copyright (C) Juan Linietsky
+# Contact Info: juan at codenix.com
+
+"""
+This script is an exporter to the Khronos Collada file format.
+
+http://www.khronos.org/collada/
+"""
+
+# TODO:
+# Materials & Textures
+# Optionally export Vertex Colors
+# Morph Targets
+# Control bone removal
+# Copy textures
+# Export Keyframe Optimization
+# --
+# Morph Targets
+# Blender native material? (?)
+
+import os
+import time
+import math  # math.pi
+import shutil
+import bpy
+from mathutils import Vector, Matrix
+
+#according to collada spec, order matters
+S_ASSET=0
+S_IMGS=1
+S_FX=2
+S_MATS=3
+S_GEOM=4
+S_CONT=5
+S_CAMS=6
+S_LAMPS=7
+S_ANIM_CLIPS=8
+S_NODES=9
+S_ANIM=10
+
+CMP_EPSILON=0.0001
+
+def snap_tup(tup):
+    ret=()
+    for x in tup:
+        ret+=( x-math.fmod(x,0.0001), )
+
+    return tup
+
+
+def strmtx(mtx):
+    s=" "
+    for x in range(4):
+        for y in range(4):
+            s+=str(mtx[x][y])
+            s+=" "
+    s+=" "
+    return s
+
+def numarr(a,mult=1.0):
+    s=" "
+    for x in a:
+        s+=" "+str(x*mult)
+    s+=" "
+    return s
+
+def strarr(arr):
+    s=" "
+    for x in arr:
+        s+=" "+str(x)
+    s+=" "
+    return s
+
+
+
+class DaeExporter:
+
+    def validate_id(self,d):
+        if (d.find("id-")==0):
+            return "z"+d
+        return d
+
+
+    def new_id(self,t):
+        self.last_id+=1
+        return "id-"+t+"-"+str(self.last_id)
+
+    class Vertex:
+
+        def close_to(v):
+            if ( (self.vertex-v.vertex).length() > CMP_EPSILON ):
+                return False
+            if ( (self.normal-v.normal).length() > CMP_EPSILON ):
+                return False
+            if ( (self.uv-v.uv).length() > CMP_EPSILON ):
+                return False
+            if ( (self.uv2-v.uv2).length() > CMP_EPSILON ):
+                return False
+
+            return True
+
+        def get_tup(self):
+            tup = (self.vertex.x,self.vertex.y,self.vertex.z,self.normal.x,self.normal.y,self.normal.z)
+            for t in self.uv:
+                tup = tup + (t.x,t.y)
+            return tup
+
+        def __init__(self):
+            self.vertex = Vector( (0.0,0.0,0.0) )
+            self.normal = Vector( (0.0,0.0,0.0) )
+            self.color = Vector( (0.0,0.0,0.0) )
+            self.uv = []
+            self.uv2 = Vector( (0.0,0.0) )
+            self.bones=[]
+            self.weights=[]
+
+
+    def writel(self,section,indent,text):
+        if (not (section in self.sections)):
+            self.sections[section]=[]
+        line=""
+        for x in range(indent):
+            line+="\t"
+        line+=text
+        self.sections[section].append(line)
+
+
+    def export_image(self,image):
+
+        if (image in self.image_cache):
+            return self.image_cache[image]
+
+        imgpath = image.filepath
+        if (imgpath.find("//")==0 or imgpath.find("\\\\")==0):
+            #if relative, convert to absolute
+            imgpath = bpy.path.abspath(imgpath)
+
+        #path is absolute, now do something!
+
+        if (self.config["use_copy_images"]):
+            #copy image
+            basedir = os.path.dirname(self.path)+"/images"
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list