[Bf-extensions-cvs] [7ef069a] master: C3D: import markers as armature's bones
Daniel Monteiro Basso
noreply at git.blender.org
Fri Feb 3 23:33:01 CET 2017
Commit: 7ef069a9dff394f0d1ae48950d9a9f08379f6bf8
Author: Daniel Monteiro Basso
Date: Fri Feb 3 22:32:51 2017 +0000
Branches: master
https://developer.blender.org/rBA7ef069a9dff394f0d1ae48950d9a9f08379f6bf8
C3D: import markers as armature's bones
===================================================================
M io_anim_c3d/__init__.py
===================================================================
diff --git a/io_anim_c3d/__init__.py b/io_anim_c3d/__init__.py
index 66d1419..2c9cd0d 100644
--- a/io_anim_c3d/__init__.py
+++ b/io_anim_c3d/__init__.py
@@ -25,8 +25,8 @@
bl_info = {
"name": "C3D Graphics Lab Motion Capture file (.c3d)",
"author": "Daniel Monteiro Basso <daniel at basso.inf.br>",
- "version": (2013, 12, 10, 1),
- "blender": (2, 69, 5),
+ "version": (2015, 5, 5, 1),
+ "blender": (2, 74, 1),
"location": "File > Import",
"description": "Imports C3D Graphics Lab Motion Capture files",
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
@@ -37,14 +37,14 @@ bl_info = {
import bpy
from bpy.props import (
- StringProperty,
- BoolProperty,
- FloatProperty,
- IntProperty,
- )
+ StringProperty,
+ BoolProperty,
+ FloatProperty,
+ IntProperty,
+)
+import os
import math
-import time
from mathutils import Vector
from . import import_c3d
@@ -56,6 +56,7 @@ class C3DAnimateCloud(bpy.types.Operator):
bl_idname = "import_anim.c3danim"
bl_label = "Animate C3D"
+ is_armature = False
markerset = None
uname = None
curframe = 0
@@ -64,25 +65,46 @@ class C3DAnimateCloud(bpy.types.Operator):
timer = None
Y_up = False
+ def update_empty(self, fno, ml, m):
+ name = self.unames[self.prefix + ml]
+ o = bpy.context.scene.objects[name]
+ p = Vector(m.position) * self.scale
+ o.location = Vector((p[0], -p[2], p[1])) if self.Y_up else p
+ o.keyframe_insert('location', frame=fno)
+
+ def update_bone(self, fno, ml, m, bones):
+ name = self.prefix + ml
+ if name not in bones:
+ return
+ b = bones[name]
+ p = Vector(m.position) * self.scale
+ b.matrix.translation = Vector((p[0], -p[2], p[1])) if self.Y_up else p
+ b.keyframe_insert('location', -1, fno, name)
+
+ def update_frame(self):
+ fno = self.curframe
+ if not self.use_frame_no:
+ fno = (self.curframe - self.markerset.startFrame) / self.fskip
+ for i in range(self.fskip):
+ self.markerset.readNextFrameData()
+ if self.is_armature:
+ bones = bpy.context.active_object.pose.bones
+ for ml in self.markerset.markerLabels:
+ m = self.markerset.getMarker(ml, self.curframe)
+ if m.confidence < self.confidence:
+ continue
+ if self.is_armature:
+ self.update_bone(fno, ml, m, bones)
+ else:
+ self.update_empty(fno, ml, m)
+
def modal(self, context, event):
if event.type == 'ESC':
return self.cancel(context)
if event.type == 'TIMER':
if self.curframe > self.markerset.endFrame:
return self.cancel(context)
- fno = self.curframe
- if not self.use_frame_no:
- fno = (self.curframe - self.markerset.startFrame) / self.fskip
- for i in range(self.fskip):
- self.markerset.readNextFrameData()
- for ml in self.markerset.markerLabels:
- name = self.unames[self.prefix + ml]
- o = bpy.context.scene.objects[name]
- m = self.markerset.getMarker(ml, self.curframe)
- p = Vector(m.position) * self.scale
- o.location = Vector((p[0], -p[2], p[1])) if self.Y_up else p
- if m.confidence >= self.confidence:
- o.keyframe_insert('location', frame=fno)
+ self.update_frame()
self.curframe += self.fskip
return {'PASS_THROUGH'}
@@ -106,91 +128,98 @@ class C3DImporter(bpy.types.Operator):
bl_label = "Import C3D"
filepath = StringProperty(
- subtype='FILE_PATH',
- )
+ subtype='FILE_PATH',
+ )
Y_up = BoolProperty(
- name="Up vector is Y axis",
- default=False,
- description="Check when the data uses Y-up, uncheck when it uses Z-up",
- )
+ name="Up vector is Y axis",
+ default=False,
+ description="Check when the data uses Y-up, uncheck when it uses Z-up",
+ )
from_inches = BoolProperty(
- name="Convert from inches to meters",
- default=False,
- description="Scale by 2.54/100",
- )
+ name="Convert from inches to meters",
+ default=False,
+ description="Scale by 2.54/100",
+ )
scale = FloatProperty(
- name="Scale",
- default=1.0,
- description="Scale the positions by this value",
- min=0.0000001, max=1000000.0,
- soft_min=0.001, soft_max=100.0,
- )
+ name="Scale",
+ default=1.0,
+ description="Scale the positions by this value",
+ min=0.0000001, max=1000000.0,
+ soft_min=0.001, soft_max=100.0,
+ )
auto_scale = BoolProperty(
- name="Adjust scale automatically",
- default=False,
- description="Guess correct scale factor",
- )
+ name="Adjust scale automatically",
+ default=False,
+ description="Guess correct scale factor",
+ )
auto_magnitude = BoolProperty(
- name="Adjust scale magnitude",
- default=True,
- description="Automatically adjust scale magnitude",
- )
+ name="Adjust scale magnitude",
+ default=True,
+ description="Automatically adjust scale magnitude",
+ )
+ create_armature = BoolProperty(
+ name="Create an armature",
+ default=True,
+ description="Import the markers as bones instead of empties",
+ )
size = FloatProperty(
- name="Empty Size",
- default=.03,
- description="The size of each empty",
- min=0.0001, max=1000000.0,
- soft_min=0.001, soft_max=100.0,
- )
+ name="Empty or bone size",
+ default=.03,
+ description="The size of each empty or bone",
+ min=0.0001, max=1000000.0,
+ soft_min=0.001, soft_max=100.0,
+ )
x_ray = BoolProperty(
- name="Use X-Ray",
- default=True,
- description="Show the empties over other objects",
- )
+ name="Use X-Ray",
+ default=True,
+ description="Show the empties or armature over other objects",
+ )
frame_skip = 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,
- )
+ name="Fps divisor",
+ default=1,
+ description="Frame supersampling factor",
+ min=1,
+ )
use_frame_no = BoolProperty(
- name="Use frame numbers",
- default=False,
- description="Offset start of animation according to the source",
- )
+ name="Use frame numbers",
+ default=False,
+ description="Offset start of animation according to the source",
+ )
show_names = BoolProperty(
- name="Show Names", default=False,
- description="Show the markers' name",
- )
+ name="Show Names", default=False,
+ description="Show the markers' name",
+ )
prefix = StringProperty(
- name="Name Prefix", maxlen=32,
- description="Prefix object names with this",
- )
+ name="Name Prefix", maxlen=32,
+ description="Prefix object names with this",
+ )
use_existing = BoolProperty(
- name="Use existing empties",
- default=False,
- description="Use previously created homonymous empties",
- )
+ name="Use existing empties or armature",
+ default=False,
+ description="Use previously created homonymous empties or bones",
+ )
confidence = FloatProperty(
- name="Minimum Confidence Level", default=0,
- description="Only consider markers with at least "
- "this confidence level",
- min=-1., max=1000000.0,
- soft_min=-1., soft_max=100.0,
- )
+ name="Minimum Confidence Level", default=0,
+ description="Only consider markers with at least "
+ "this confidence level",
+ min=-1., max=1000000.0,
+ soft_min=-1., soft_max=100.0,
+ )
filter_glob = StringProperty(default="*.c3d;*.csv", options={'HIDDEN'})
def find_height(self, ms):
"""
Heuristic to find the height of the subject in the markerset
- (only works for standing poses)
+ (only works for standing poses and you must have correct data
+ on the first frame)
"""
- zmin = None
+ zmin, zmax = None, None
hidx = 1 if self.properties.Y_up else 2
for ml in ms.markerLabels:
+ # check if LTOE is a substring of this marker label
if 'LTOE' in ml:
+ # substitute the substring to get the head marker
hd = ml.replace('LTOE', 'LFHD')
if hd not in ms.markerLabels:
break
@@ -198,6 +227,7 @@ class C3DImporter(bpy.types.Operator):
pmax_idx = ms.markerLabels.index(hd)
zmin = ms.frames[0][pmin_idx].position[hidx]
zmax = ms.frames[0][pmax_idx].position[hidx]
+ break
if zmin is None: # could not find named markers, get extremes
allz = [m.position[hidx] for m in ms.frames[0]]
zmin, zmax = min(allz), max(allz)
@@ -205,43 +235,32 @@ class C3DImporter(bpy.types.Operator):
def adjust_scale_magnitude(self, height, scale):
mag = math.log10(height * scale)
- #print('mag',mag, 'scale',scale)
return scale * math.pow(10, -int(mag))
def adjust_scale(self, height, scale):
+ """
+ Try to find the correct scale for some common configurations
+ found in CMU's c3d files.
+ """
factor = he
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list