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

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2011-01-15 22:34:59 +0300
committerCampbell Barton <ideasman42@gmail.com>2011-01-15 22:34:59 +0300
commitfa68b830205780cb7fb6a4994195bce61323ae50 (patch)
tree49577c62266c2cb1ba37081b1d98e0da8c719e38 /io_shape_mdd
parentb89e757cfd55caf4f32f6041bfbf5aed4f362c43 (diff)
move MDD io from svn into extensions.
Diffstat (limited to 'io_shape_mdd')
-rw-r--r--io_shape_mdd/__init__.py132
-rw-r--r--io_shape_mdd/export_mdd.py130
-rw-r--r--io_shape_mdd/import_mdd.py102
3 files changed, 364 insertions, 0 deletions
diff --git a/io_shape_mdd/__init__.py b/io_shape_mdd/__init__.py
new file mode 100644
index 00000000..4dcb97e9
--- /dev/null
+++ b/io_shape_mdd/__init__.py
@@ -0,0 +1,132 @@
+# ##### 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>
+
+bl_info = {
+ "name": "NewTek MDD format",
+ "author": "Bill L.Nieuwendorp",
+ "location": "File > Import-Export",
+ "description": "Import-Export MDD as mesh shape keys",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
+ "Scripts/Import-Export/NewTek_OBJ",
+ "tracker_url": "",
+ "support": 'OFFICIAL',
+ "category": "Import-Export"}
+
+# To support reload properly, try to access a package var, if it's there, reload everything
+if "bpy" in locals():
+ import imp
+ if "import_mdd" in locals():
+ imp.reload(import_mdd)
+ if "export_mdd" in locals():
+ imp.reload(export_mdd)
+
+
+import bpy
+from bpy.props import *
+from io_utils import ExportHelper, ImportHelper
+
+
+class ImportMDD(bpy.types.Operator, ImportHelper):
+ '''Import MDD vertex keyframe file to shape keys'''
+ bl_idname = "import_shape.mdd"
+ bl_label = "Import MDD"
+
+ filename_ext = ".mdd"
+ filter_glob = StringProperty(default="*.mdd", options={'HIDDEN'})
+
+ frame_start = IntProperty(name="Start Frame", description="Start frame for inserting animation", min=-300000, max=300000, default=0)
+ frame_step = IntProperty(name="Step", min=1, max=1000, default=1)
+
+ @classmethod
+ def poll(cls, context):
+ ob = context.active_object
+ return (ob and ob.type == 'MESH')
+
+ def execute(self, context):
+
+ # initialize from scene if unset
+ scene = context.scene
+ if not self.frame_start:
+ self.frame_start = scene.frame_current
+
+ from . import import_mdd
+ return import_mdd.load(self, context, **self.as_keywords(ignore=("filter_glob",)))
+
+
+class ExportMDD(bpy.types.Operator, ExportHelper):
+ '''Animated mesh to MDD vertex keyframe file'''
+ bl_idname = "export_shape.mdd"
+ bl_label = "Export MDD"
+
+ filename_ext = ".mdd"
+ filter_glob = StringProperty(default="*.mdd", options={'HIDDEN'})
+
+ # get first scene to get min and max properties for frames, fps
+
+ minframe = 1
+ maxframe = 300000
+ minfps = 1
+ maxfps = 120
+
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+ fps = IntProperty(name="Frames Per Second", description="Number of frames/second", min=minfps, max=maxfps, default=25)
+ frame_start = IntProperty(name="Start Frame", description="Start frame for baking", min=minframe, max=maxframe, default=1)
+ frame_end = IntProperty(name="End Frame", description="End frame for baking", min=minframe, max=maxframe, default=250)
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.active_object
+ return (obj and obj.type == 'MESH')
+
+ def execute(self, context):
+ # initialize from scene if unset
+ scene = context.scene
+ if not self.frame_start:
+ self.frame_start = scene.frame_start
+ if not self.frame_end:
+ self.frame_end = scene.frame_end
+ if not self.fps:
+ self.fps = scene.render.fps
+
+ from . import export_mdd
+ return export_mdd.save(self, context, **self.as_keywords(ignore=("check_existing", "filter_glob")))
+
+
+def menu_func_import(self, context):
+ self.layout.operator(ImportMDD.bl_idname, text="Lightwave Point Cache (.mdd)")
+
+
+def menu_func_export(self, context):
+ self.layout.operator(ExportMDD.bl_idname, text="Lightwave Point Cache (.mdd)")
+
+
+def register():
+ bpy.types.INFO_MT_file_import.append(menu_func_import)
+ bpy.types.INFO_MT_file_export.append(menu_func_export)
+
+
+def unregister():
+ bpy.types.INFO_MT_file_import.remove(menu_func_import)
+ bpy.types.INFO_MT_file_export.remove(menu_func_export)
+
+if __name__ == "__main__":
+ register()
diff --git a/io_shape_mdd/export_mdd.py b/io_shape_mdd/export_mdd.py
new file mode 100644
index 00000000..42795d45
--- /dev/null
+++ b/io_shape_mdd/export_mdd.py
@@ -0,0 +1,130 @@
+# ##### 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>
+
+# Contributors: Bill L.Nieuwendorp
+
+"""
+This script Exports Lightwaves MotionDesigner format.
+
+The .mdd format has become quite a popular Pipeline format<br>
+for moving animations from package to package.
+
+Be sure not to use modifiers that change the number or order of verts in the mesh
+"""
+
+import bpy
+import mathutils
+from struct import pack
+
+
+def zero_file(filepath):
+ '''
+ If a file fails, this replaces it with 1 char, better not remove it?
+ '''
+ file = open(filepath, 'w')
+ file.write('\n') # apparently macosx needs some data in a blank file?
+ file.close()
+
+
+def check_vertcount(mesh, vertcount):
+ '''
+ check and make sure the vertcount is consistent throughout the frame range
+ '''
+ if len(mesh.vertices) != vertcount:
+ raise Exception('Error, number of verts has changed during animation, cannot export')
+ f.close()
+ zero_file(filepath)
+ return
+
+
+def save(operator, context, filepath="", frame_start=1, frame_end=300, fps=25):
+ """
+ Blender.Window.WaitCursor(1)
+
+ mesh_orig = Mesh.New()
+ mesh_orig.getFromObject(obj.name)
+ """
+
+ scene = context.scene
+ obj = context.object
+
+ if bpy.ops.object.mode_set.poll():
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ orig_frame = scene.frame_current
+ scene.frame_set(frame_start)
+ me = obj.create_mesh(scene, True, 'PREVIEW')
+
+ #Flip y and z
+ mat_flip = mathutils.Matrix(((1.0, 0.0, 0.0, 0.0), \
+ (0.0, 0.0, 1.0, 0.0), \
+ (0.0, 1.0, 0.0, 0.0), \
+ (0.0, 0.0, 0.0, 1.0), \
+ ))
+
+ numverts = len(me.vertices)
+
+ numframes = frame_end - frame_start + 1
+ fps = float(fps)
+ f = open(filepath, 'wb') # no Errors yet:Safe to create file
+
+ # Write the header
+ f.write(pack(">2i", numframes, numverts))
+
+ # Write the frame times (should we use the time IPO??)
+ f.write(pack(">%df" % (numframes), *[frame / fps for frame in range(numframes)])) # seconds
+
+ #rest frame needed to keep frames in sync
+ """
+ Blender.Set('curframe', frame_start)
+ me_tmp.getFromObject(obj.name)
+ """
+
+ check_vertcount(me, numverts)
+ me.transform(mat_flip * obj.matrix_world)
+ f.write(pack(">%df" % (numverts * 3), *[axis for v in me.vertices for axis in v.co]))
+
+ for frame in range(frame_start, frame_end + 1): # in order to start at desired frame
+ """
+ Blender.Set('curframe', frame)
+ me_tmp.getFromObject(obj.name)
+ """
+
+ scene.frame_set(frame)
+ me = obj.create_mesh(scene, True, 'PREVIEW')
+ check_vertcount(me, numverts)
+ me.transform(mat_flip * obj.matrix_world)
+
+ # Write the vertex data
+ f.write(pack(">%df" % (numverts * 3), *[axis for v in me.vertices for axis in v.co]))
+
+ """
+ me_tmp.vertices= None
+ """
+ f.close()
+
+ print('MDD Exported: %r frames:%d\n' % (filepath, numframes - 1))
+ """
+ Blender.Window.WaitCursor(0)
+ Blender.Set('curframe', orig_frame)
+ """
+ scene.frame_set(orig_frame)
+
+ return {'FINISHED'}
diff --git a/io_shape_mdd/import_mdd.py b/io_shape_mdd/import_mdd.py
new file mode 100644
index 00000000..02be14e9
--- /dev/null
+++ b/io_shape_mdd/import_mdd.py
@@ -0,0 +1,102 @@
+# ##### 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>
+
+# mdd importer by Bill L.Nieuwendorp
+# conversion to blender 2.5: Ivo Grigull (loolarge)
+#
+# Warning if the vertex order or vertex count differs from the
+# origonal model the mdd was Baked out from their will be Strange
+# behavior
+#
+# vertex animation to ShapeKeys with ipo and gives the frame a value of 1.0
+# A modifier to read mdd files would be Ideal but thats for another day :)
+#
+# Please send any fixes,updates,bugs to Slow67_at_Gmail.com
+# Bill Niewuendorp
+
+import bpy
+from struct import unpack
+
+
+def load(operator, context, filepath, frame_start=0, frame_step=1):
+
+ scene = context.scene
+ obj = context.object
+
+ print('\n\nimporting mdd %r' % filepath)
+
+ if bpy.ops.object.mode_set.poll():
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ file = open(filepath, 'rb')
+ frames, points = unpack(">2i", file.read(8))
+ time = unpack((">%df" % frames), file.read(frames * 4))
+
+ print('\tpoints:%d frames:%d' % (points, frames))
+
+ # If target object doesn't have Basis shape key, create it.
+ try:
+ num_keys = len(obj.data.shape_keys.keys)
+ except:
+ basis = obj.shape_key_add()
+ basis.name = "Basis"
+ obj.data.update()
+
+ scene.frame_current = frame_start
+
+ def UpdateMesh(ob, fr):
+
+ # Insert new shape key
+ new_shapekey = obj.shape_key_add()
+ new_shapekey.name = ("frame_%.4d" % fr)
+ new_shapekey_name = new_shapekey.name
+
+ obj.active_shape_key_index = len(obj.data.shape_keys.keys) - 1
+ index = len(obj.data.shape_keys.keys) - 1
+ obj.show_only_shape_key = True
+
+ verts = obj.data.shape_keys.keys[len(obj.data.shape_keys.keys) - 1].data
+
+ for v in verts: # 12 is the size of 3 floats
+ v.co[:] = unpack('>3f', file.read(12))
+ #me.update()
+ obj.show_only_shape_key = False
+
+ # insert keyframes
+ shape_keys = obj.data.shape_keys
+
+ scene.frame_current -= 1
+ obj.data.shape_keys.keys[index].value = 0.0
+ shape_keys.keys[len(obj.data.shape_keys.keys) - 1].keyframe_insert("value")
+
+ scene.frame_current += 1
+ obj.data.shape_keys.keys[index].value = 1.0
+ shape_keys.keys[len(obj.data.shape_keys.keys) - 1].keyframe_insert("value")
+
+ scene.frame_current += 1
+ obj.data.shape_keys.keys[index].value = 0.0
+ shape_keys.keys[len(obj.data.shape_keys.keys) - 1].keyframe_insert("value")
+
+ obj.data.update()
+
+ for i in range(frames):
+ UpdateMesh(obj, i)
+
+ return {'FINISHED'}