[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [39005] branches/soc-2011-pepper/release/ scripts: Initial coding of path editing operator.

Benjy Cook benjycook at hotmail.com
Thu Aug 4 00:26:59 CEST 2011


Revision: 39005
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=39005
Author:   benjycook
Date:     2011-08-03 22:26:59 +0000 (Wed, 03 Aug 2011)
Log Message:
-----------
Initial coding of path editing operator. Still needs some work, but all the basic functionality is there. Select a path and the stride bone (as active) and it will reparameterize the path to propel the armature forward in the same magnitude of the original

Modified Paths:
--------------
    branches/soc-2011-pepper/release/scripts/modules/mocap_tools.py
    branches/soc-2011-pepper/release/scripts/startup/ui_mocap.py

Modified: branches/soc-2011-pepper/release/scripts/modules/mocap_tools.py
===================================================================
--- branches/soc-2011-pepper/release/scripts/modules/mocap_tools.py	2011-08-03 19:12:18 UTC (rev 39004)
+++ branches/soc-2011-pepper/release/scripts/modules/mocap_tools.py	2011-08-03 22:26:59 UTC (rev 39005)
@@ -81,6 +81,9 @@
     def y(self):
         return self.vec[1]
 
+    def resize_2d(self):
+        return Vector((self.x, self.y))
+
     length = property(vecLength)
     lengthSq = property(vecLengthSq)
     x = property(x)
@@ -322,7 +325,10 @@
             return 0, None
         for pt in data_pts[s:e + 1]:
             bezVal = bezierEval(bez, pt.u)
-            tmpError = (pt.co - bezVal).length / pt.co.length
+            normalize_error = pt.co.length
+            if normalize_error == 0:
+                normalize_error = 1
+            tmpError = (pt.co - bezVal).length / normalize_error
             if tmpError >= maxError:
                 maxError = tmpError
                 maxErrorPt = pt.index
@@ -471,10 +477,8 @@
 #(e.g. a bone's x,y,z rotation)
 
 
-def fcurves_simplify(sel_opt="all", error=0.002, group_mode=True):
+def fcurves_simplify(context, obj, sel_opt="all", error=0.002, group_mode=True):
     # main vars
-    context = bpy.context
-    obj = context.active_object
     fcurves = obj.animation_data.action.fcurves
 
     if sel_opt == "sel":
@@ -706,3 +710,52 @@
         existingConstraint = [constraint for constraint in bone.constraints if constraint.name == "DOF Limitation"]
         if existingConstraint:
             bone.constraints.remove(existingConstraint[0])
+
+
+def path_editing(context, stride_obj, path):
+    y_fcurve = [fcurve for fcurve in stride_obj.animation_data.action.fcurves if fcurve.data_path == "location"][1]
+    s, e = context.scene.frame_start, context.scene.frame_end  # y_fcurve.range()
+    s = int(s)
+    e = int(e)
+    y_s = y_fcurve.evaluate(s)
+    y_e = y_fcurve.evaluate(e)
+    direction = (y_e - y_s) / abs(y_e - y_s)
+    existing_cons = [constraint for constraint in stride_obj.constraints if constraint.type == "FOLLOW_PATH"]
+    for cons in existing_cons:
+        stride_obj.constraints.remove(cons)
+    path_cons = stride_obj.constraints.new("FOLLOW_PATH")
+    if direction < 0:
+        path_cons.forward_axis = "TRACK_NEGATIVE_Y"
+    else:
+        path_cons.forward_axis = "FORWARD_Y"
+    path_cons.target = path
+    path_cons.use_curve_follow = True
+    path.data.path_duration = e - s
+    try:
+        path.data.animation_data.action.fcurves
+    except AttributeError:
+        path.data.keyframe_insert("eval_time", frame=0)
+    eval_time_fcurve = [fcurve for fcurve in path.data.animation_data.action.fcurves if fcurve.data_path == "eval_time"]
+    eval_time_fcurve = eval_time_fcurve[0]
+    totalLength = 0
+    parameterization = {}
+    print("evaluating curve")
+    for t in range(s, e - 1):
+        if s == t:
+            chordLength = 0
+        else:
+            chordLength = (y_fcurve.evaluate(t) - y_fcurve.evaluate(t + 1))
+        totalLength += chordLength
+        parameterization[t] = totalLength
+    for t in range(s + 1, e - 1):
+        if totalLength == 0:
+            print("no forward motion")
+        parameterization[t] /= totalLength
+        parameterization[t] *= e - s
+    parameterization[e] = e - s
+    for t in parameterization.keys():
+        eval_time_fcurve.keyframe_points.insert(frame=t, value=parameterization[t])
+    error = 0.01
+    reparaError = error * 32
+    maxIterations = 16
+    print("finished path editing")

Modified: branches/soc-2011-pepper/release/scripts/startup/ui_mocap.py
===================================================================
--- branches/soc-2011-pepper/release/scripts/startup/ui_mocap.py	2011-08-03 19:12:18 UTC (rev 39004)
+++ branches/soc-2011-pepper/release/scripts/startup/ui_mocap.py	2011-08-03 22:26:59 UTC (rev 39005)
@@ -304,6 +304,18 @@
                             layout.separator()
 
 
+class ExtraToolsPanel(bpy.types.Panel):
+    # Motion capture retargeting panel
+    bl_label = "Extra Mocap Tools"
+    bl_space_type = "PROPERTIES"
+    bl_region_type = "WINDOW"
+    bl_context = "object"
+
+    def draw(self, context):
+        layout = self.layout
+        layout.operator('mocap.pathediting', text="Follow Path")
+
+
 class OBJECT_OT_RetargetButton(bpy.types.Operator):
     '''Retarget animation from selected armature to active armature '''
     bl_idname = "mocap.retarget"
@@ -383,7 +395,7 @@
     bl_label = "Converts samples / simplifies keyframes to beziers"
 
     def execute(self, context):
-        mocap_tools.fcurves_simplify()
+        mocap_tools.fcurves_simplify(context, context.active_object)
         return {"FINISHED"}
 
     @classmethod
@@ -598,6 +610,25 @@
             return False
 
 
+class OBJECT_OT_PathEditing(bpy.types.Operator):
+    '''Sets active object (stride object) to follow the selected curve'''
+    bl_idname = "mocap.pathediting"
+    bl_label = "Sets active object (stride object) to follow the selected curve"
+
+    def execute(self, context):
+        path = [obj for obj in context.selected_objects if obj != context.active_object][0]
+        mocap_tools.path_editing(context, context.active_object, path)
+        return {"FINISHED"}
+
+    @classmethod
+    def poll(cls, context):
+        if context.active_object:
+            selected_objs = [obj for obj in context.selected_objects if obj != context.active_object]
+            return selected_objs
+        else:
+            return False
+
+
 def register():
     bpy.utils.register_module(__name__)
 




More information about the Bf-blender-cvs mailing list