[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [2573] contrib/py/scripts/addons: Added the first public version of the CMU Mocap Browser addon.

Daniel M. Basso danielmbasso at gmail.com
Thu Nov 3 01:22:19 CET 2011


Revision: 2573
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=2573
Author:   dmbasso
Date:     2011-11-03 00:22:18 +0000 (Thu, 03 Nov 2011)
Log Message:
-----------
Added the first public version of the CMU Mocap Browser addon.

Added Paths:
-----------
    contrib/py/scripts/addons/cmu_mocap_browser/
    contrib/py/scripts/addons/cmu_mocap_browser/__init__.py
    contrib/py/scripts/addons/cmu_mocap_browser/library.py

Added: contrib/py/scripts/addons/cmu_mocap_browser/__init__.py
===================================================================
--- contrib/py/scripts/addons/cmu_mocap_browser/__init__.py	                        (rev 0)
+++ contrib/py/scripts/addons/cmu_mocap_browser/__init__.py	2011-11-03 00:22:18 UTC (rev 2573)
@@ -0,0 +1,372 @@
+# ##### 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 3
+#  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>
+
+# This script was developed with financial support from the Foundation for
+# Science and Technology of Portugal, under the grant SFRH/BD/66452/2009.
+
+
+bl_info = {
+    'name': "Carnegie Mellon University Mocap Library Browser",
+    'author': "Daniel Monteiro Basso <daniel at basso.inf.br>",
+    'version': (2011, 10, 30, 1),
+    'blender': (2, 6, 0),
+    'api': 41226,
+    'location': "View3D > Tools",
+    'description': "Assistant for using CMU Motion Capture data",
+    'warning': '',
+    'wiki_url': "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
+                "Scripts/3D_interaction/CMU_Mocap_Library_Browser",
+    'tracker_url': "http://projects.blender.org/tracker/index.php?"\
+                   "func=detail&aid=29086&group_id=153&atid=467",
+    'category': '3D View'}
+
+
+import os
+import bpy
+import bgl
+import blf
+import math
+from . import library
+
+
+def initialize_subjects():
+    """
+        Initializes the main object and the subjects (actors) list
+    """
+    while bpy.data.scenes[0].cmu_mocap_lib.subject_list:
+        bpy.data.scenes[0].cmu_mocap_lib.subject_list.remove(0)
+    for k, v in library.subjects.items():
+        n = bpy.data.scenes[0].cmu_mocap_lib.subject_list.add()
+        n.name = "{:d} - {}".format(k, v['desc'])
+        n.idx = k
+
+
+def update_motions(self, context):
+    """
+        Updates the motions list after a subject is selected
+    """
+    sidx = -1
+    if self.subject_active != -1:
+        sidx = self.subject_list[self.subject_active].idx
+    while self.motion_list:
+        self.motion_list.remove(0)
+    if sidx != -1:
+        for k, v in library.subjects[sidx]["motions"].items():
+            n = self.motion_list.add()
+            n.name = "{:d} - {}".format(k, v["desc"])
+            n.idx = k
+        self.motion_active = -1
+
+
+class ListItem(bpy.types.PropertyGroup):
+    name = bpy.props.StringProperty()
+    idx = bpy.props.IntProperty()
+
+
+class CMUMocapLib(bpy.types.PropertyGroup):
+    local_storage = bpy.props.StringProperty(
+        name="Local Storage",
+        subtype='DIR_PATH',
+        description="Location to store downloaded resources",
+        default="~/cmu_mocap_lib")
+    follow_structure = bpy.props.BoolProperty(
+        name="Follow Library Folder Structure",
+        description="Store resources in subfolders of the local storage",
+        default=True)
+    automatically_import = bpy.props.BoolProperty(
+        name="Automatically Import after Download",
+        description="Import the resource after the download is finished",
+        default=True)
+    subject_list = bpy.props.CollectionProperty(
+        name="subjects", type=ListItem)
+    subject_active = bpy.props.IntProperty(
+        name="subject_idx", default=-1, update=update_motions)
+    subject_import_name = bpy.props.StringProperty(
+        name="Armature Name",
+        description="Identifier of the imported subject's armature",
+        default="Skeleton")
+    motion_list = bpy.props.CollectionProperty(name="motions", type=ListItem)
+    motion_active = bpy.props.IntProperty(name="motion_idx", default=-1)
+    frame_skip = bpy.props.IntProperty(name="Fps Divisor", default=4,
+    # usually the sample rate is 120, so the default 4 gives you 30fps
+                          description="Frame supersampling factor", min=1)
+    cloud_scale = bpy.props.FloatProperty(name="Marker Cloud Scale",
+                          description="Scale the marker cloud by this value",
+                          default=1., min=0.0001, max=1000000.0,
+                          soft_min=0.001, soft_max=100.0)
+
+
+def draw_callback(self, context):
+    mid = int(360 * self.recv / self.fsize)
+    cx = 200
+    cy = 30
+    blf.position(0, 230, 23, 0)
+    blf.size(0, 20, 72)
+    blf.draw(0, "{0:2d}% of {1}".format(
+        100 * self.recv // self.fsize, self.hfsize))
+
+    bgl.glEnable(bgl.GL_BLEND)
+    bgl.glColor4f(.7, .7, .7, 0.8)
+    bgl.glBegin(bgl.GL_TRIANGLE_FAN)
+    bgl.glVertex2i(cx, cy)
+    for i in range(mid):
+        x = cx + 20 * math.sin(math.radians(float(i)))
+        y = cy + 20 * math.cos(math.radians(float(i)))
+        bgl.glVertex2f(x, y)
+    bgl.glEnd()
+
+    bgl.glColor4f(.0, .0, .0, 0.6)
+    bgl.glBegin(bgl.GL_TRIANGLE_FAN)
+    bgl.glVertex2i(cx, cy)
+    for i in range(mid, 360):
+        x = cx + 20 * math.sin(math.radians(float(i)))
+        y = cy + 20 * math.cos(math.radians(float(i)))
+        bgl.glVertex2f(x, y)
+    bgl.glEnd()
+
+    bgl.glDisable(bgl.GL_BLEND)
+    bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
+
+
+class CMUMocapDownloadImport(bpy.types.Operator):
+    bl_idname = "mocap.download_import"
+    bl_label = "Download and Import a file"
+
+    remote_file = bpy.props.StringProperty(
+        name="Remote File",
+        description="Location from where to download the file data")
+    local_file = bpy.props.StringProperty(
+        name="Local File",
+        description="Destination where to save the file data")
+    do_import = bpy.props.BoolProperty(
+        name="Manual Import",
+        description="Import the resource non-automatically",
+        default=False)
+
+    timer = None
+    fout = None
+    src = None
+    fsize = 0
+    recv = 0
+    cloud_scale = 1
+
+    def modal(self, context, event):
+        context.area.tag_redraw()
+        if event.type == 'ESC':
+            self.fout.close()
+            os.unlink(self.local_file)
+            return self.cancel(context)
+        if event.type == 'TIMER':
+            to_read = min(self.fsize - self.recv, 100 * 2 ** 10)
+            data = self.src.read(to_read)
+            self.fout.write(data)
+            self.recv += to_read
+            if self.fsize == self.recv:
+                self.fout.close()
+                return self.cancel(context)
+        return {'PASS_THROUGH'}
+
+    def cancel(self, context):
+        context.window_manager.event_timer_remove(self.timer)
+        context.region.callback_remove(self.handle)
+        if os.path.exists(self.local_file):
+            self.import_or_open()
+        return {'CANCELLED'}
+
+    def execute(self, context):
+        cml = bpy.data.scenes[0].cmu_mocap_lib
+        if not os.path.exists(self.local_file):
+            try:
+                os.makedirs(os.path.split(self.local_file)[0])
+            except:
+                pass
+            from urllib.request import urlopen
+            self.src = urlopen(self.remote_file)
+            info = self.src.info()
+            self.fsize = int(info["Content-Length"])
+            m = int(math.log10(self.fsize) // 3)
+            self.hfsize = "{:.1f}{}".format(
+                self.fsize * math.pow(10, -m * 3),
+                ['b', 'Kb', 'Mb', 'Gb', 'Tb', 'Eb', 'Pb'][m])  # :-p
+            self.fout = open(self.local_file, 'wb')
+            self.recv = 0
+            context.window_manager.modal_handler_add(self)
+            self.handle = context.region.\
+                callback_add(draw_callback, (self, context), 'POST_PIXEL')
+            self.timer = context.window_manager.\
+                event_timer_add(0.001, context.window)
+            return {'RUNNING_MODAL'}
+        else:
+            self.import_or_open()
+        return {"FINISHED"}
+
+    def import_or_open(self):
+        cml = bpy.data.scenes[0].cmu_mocap_lib
+        if cml.automatically_import or self.do_import:
+            if self.local_file.endswith("mpg"):
+                bpy.ops.wm.path_open(filepath=self.local_file)
+            elif self.local_file.endswith("asf"):
+                bpy.ops.import_anim.asf(
+                    filepath=self.local_file,
+                    from_inches=True,
+                    rotX=True, rotZ=True,
+                    armature_name=cml.subject_import_name)
+            elif self.local_file.endswith("amc"):
+                ob = bpy.context.active_object
+                if not ob or ob.type != 'ARMATURE' or \
+                    'source_file_path' not in ob:
+                    self.report({'ERROR'}, "Please select a CMU Armature.")
+                    return
+                bpy.ops.import_anim.amc(
+                    filepath=self.local_file,
+                    frame_skip=cml.frame_skip)
+            elif self.local_file.endswith("c3d"):
+                bpy.ops.import_anim.c3d(
+                    filepath=self.local_file,
+                    from_inches=False,
+                    auto_scale=True,
+                    scale=cml.cloud_scale,
+                    show_names=False,
+                    frame_skip=cml.frame_skip)
+
+
+class CMUMocapConfig(bpy.types.Panel):
+    bl_idname = "object.cmu_mocap_config"
+    bl_label = "CMU Mocap Browser Configuration"
+    bl_space_type = 'VIEW_3D'
+    bl_region_type = 'TOOLS'
+
+    def draw(self, context):
+        if not bpy:
+            return
+        cml = bpy.data.scenes[0].cmu_mocap_lib
+        layout = self.layout
+        layout.operator("wm.url_open",
+            text="Carnegie Mellon University Mocap Library",
+            icon='URL').url = 'http://mocap.cs.cmu.edu/'
+        layout.prop(cml, "local_storage")
+        layout.prop(cml, "follow_structure")
+        layout.prop(cml, "automatically_import")
+
+
+class CMUMocapSubjectBrowser(bpy.types.Panel):

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-extensions-cvs mailing list