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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2010-01-19 14:31:49 +0300
committerJoshua Leung <aligorith@gmail.com>2010-01-19 14:31:49 +0300
commit7759fc2983422ef234b1d9a2bcdbc4c7e6265071 (patch)
tree4b4fbac13821dc33cef421623db2ef45287f08af /source/blender
parented578c27c821a146ca684137d5eb1ac986858599 (diff)
Motion Paths - (Part 3) Operators, Drawing, and Fixes
This commit makes the new-style Motion Paths work for Objects and Bones. Motion Paths can either be added for Objects (Object buttons) or for Selected Bones in PoseMode (Armature Buttons), and/or removed from these panels too. Changes: * Changed the way the baking code worked, since it was better to be able to bake a bunch of objects at once, instead of doing it per object * Fixed a variety of bugs regarding initialising defaults and reading old files * Added operators for Objects (like for bones), and replaced the existing code for bones. * Fixed bug with baking code that was causing it to bake the wrong ranges Todos: * Frame number drawing is currently messed up, since the "cached" text drawing takes into account the object transforms. * The new MotionPath panels currently appear as the first panels in the respective contexts, probably due to the order in which the files are included. This needs some fixing, though not sure what the best way is yet.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_anim.h4
-rw-r--r--source/blender/blenkernel/intern/anim.c62
-rw-r--r--source/blender/blenkernel/intern/armature.c8
-rw-r--r--source/blender/blenloader/intern/readfile.c17
-rw-r--r--source/blender/editors/armature/poseobject.c230
-rw-r--r--source/blender/editors/include/ED_object.h4
-rw-r--r--source/blender/editors/object/object_edit.c112
-rw-r--r--source/blender/editors/object/object_intern.h2
-rw-r--r--source/blender/editors/object/object_ops.c2
-rw-r--r--source/blender/editors/space_view3d/drawanimviz.c3
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c195
-rw-r--r--source/blender/editors/space_view3d/drawobject.c16
12 files changed, 228 insertions, 427 deletions
diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h
index 4862f4e5c46..c664469527e 100644
--- a/source/blender/blenkernel/BKE_anim.h
+++ b/source/blender/blenkernel/BKE_anim.h
@@ -53,7 +53,9 @@ void animviz_free_motionpath_cache(struct bMotionPath *mpath);
void animviz_free_motionpath(struct bMotionPath *mpath);
struct bMotionPath *animviz_verify_motionpaths(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan);
-void animviz_calc_motionpaths(struct Scene *scene, struct Object *ob);
+
+void animviz_get_object_motionpaths(Object *ob, ListBase *targets);
+void animviz_calc_motionpaths(struct Scene *scene, ListBase *targets);
/* ---------------------------------------------------- */
/* Curve Paths */
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 507fc520a85..6d95df3ca84 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -154,7 +154,7 @@ void animviz_free_motionpath(bMotionPath *mpath)
/* ------------------- */
-/* Setup motion paths for the given data
+/* Setup motion paths for the given data
* - scene: current scene (for frame ranges, etc.)
* - ob: object to add paths for (must be provided)
* - pchan: posechannel to add paths for (optional; if not provided, object-paths are assumed)
@@ -226,8 +226,10 @@ typedef struct MPathTarget {
/* ........ */
-/* get list of motion paths to be baked (assumes the list is ready to be used) */
-static void motionpaths_get_bake_targets(Object *ob, ListBase *targets)
+/* get list of motion paths to be baked for the given object
+ * - assumes the given list is ready to be used
+ */
+void animviz_get_object_motionpaths(Object *ob, ListBase *targets)
{
MPathTarget *mpt;
@@ -260,6 +262,8 @@ static void motionpaths_get_bake_targets(Object *ob, ListBase *targets)
}
}
+/* ........ */
+
/* perform baking for the targets on the current frame */
static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets)
{
@@ -270,8 +274,10 @@ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets)
bMotionPath *mpath= mpt->mpath;
bMotionPathVert *mpv;
- /* current frame must be within the range the cache works for */
- if (IN_RANGE(CFRA, mpath->start_frame, mpath->end_frame) == 0)
+ /* current frame must be within the range the cache works for
+ * - is inclusive of the first frame, but not the last otherwise we get buffer overruns
+ */
+ if ((CFRA < mpath->start_frame) || (CFRA >= mpath->end_frame))
continue;
/* get the relevant cache vert to write to */
@@ -297,36 +303,30 @@ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets)
}
}
-/* ........ */
-
/* Perform baking of the given object's and/or its bones' transforms to motion paths
* - scene: current scene
* - ob: object whose flagged motionpaths should get calculated
* - recalc: whether we need to
*/
// TODO: include reports pointer?
-void animviz_calc_motionpaths(Scene *scene, Object *ob)
+void animviz_calc_motionpaths(Scene *scene, ListBase *targets)
{
- ListBase targets = {NULL, NULL};
MPathTarget *mpt;
int sfra, efra;
int cfra;
- /* sanity checks */
- if (ob == NULL)
- return;
-
- /* get motion paths to affect */
- motionpaths_get_bake_targets(ob, &targets);
-
- if (targets.first == NULL)
+ /* sanity check */
+ if (ELEM(NULL, targets, targets->first))
return;
/* set frame values */
cfra = CFRA;
sfra = efra = cfra;
- for (mpt= targets.first; mpt; mpt= mpt->next) {
+ // TODO: this method could be improved...
+ // 1) max range for standard baking
+ // 2) minimum range for recalc baking (i.e. between keyfames, but how?)
+ for (mpt= targets->first; mpt; mpt= mpt->next) {
/* try to increase area to do (only as much as needed) */
sfra= MIN2(sfra, mpt->mpath->start_frame);
efra= MAX2(efra, mpt->mpath->end_frame);
@@ -340,23 +340,29 @@ void animviz_calc_motionpaths(Scene *scene, Object *ob)
* that doesn't force complete update, but for now, this is the
* most accurate way!
*/
- scene_update_for_newframe(scene, ob->lay); // XXX is the layer flag too restrictive?
+ scene_update_for_newframe(scene, scene->lay); // XXX this is the best way we can get anything moving
/* perform baking for targets */
- motionpaths_calc_bake_targets(scene, &targets);
+ motionpaths_calc_bake_targets(scene, targets);
}
/* reset original environment */
CFRA= cfra;
- scene_update_for_newframe(scene, ob->lay); // XXX is the layer flag too restrictive?
-
- // TODO: make an API call for this too?
- ob->avs.recalc &= ~ANIMVIZ_RECALC_PATHS;
- if (ob->pose)
- ob->pose->avs.recalc &= ~ANIMVIZ_RECALC_PATHS;
+ scene_update_for_newframe(scene, scene->lay); // XXX this is the best way we can get anything moving
- /* free temp data */
- BLI_freelistN(&targets);
+ /* clear recalc flags from targets */
+ for (mpt= targets->first; mpt; mpt= mpt->next) {
+ bAnimVizSettings *avs;
+
+ /* get pointer to animviz settings for each target */
+ if (mpt->pchan)
+ avs= &mpt->ob->pose->avs;
+ else
+ avs= &mpt->ob->avs;
+
+ /* clear the flag requesting recalculation of targets */
+ avs->recalc &= ~ANIMVIZ_RECALC_PATHS;
+ }
}
/* ******************************************************************** */
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index e4079eac31b..3a7d79b8e00 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1602,7 +1602,13 @@ void armature_rebuild_pose(Object *ob, bArmature *arm)
int counter=0;
/* only done here */
- if(ob->pose==NULL) ob->pose= MEM_callocN(sizeof(bPose), "new pose");
+ if(ob->pose==NULL) {
+ /* create new pose */
+ ob->pose= MEM_callocN(sizeof(bPose), "new pose");
+
+ /* set default settings for animviz */
+ animviz_settings_init(&ob->pose->avs);
+ }
pose= ob->pose;
/* clear */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 8975dcd4c67..96b2b793267 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -10381,9 +10381,16 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
avs->ghost_sf= arm->ghostsf;
avs->ghost_ef= arm->ghostef;
+ if ((avs->ghost_sf == avs->ghost_ef) && (avs->ghost_sf == 0)) {
+ avs->ghost_sf= 1;
+ avs->ghost_ef= 100;
+ }
/* type */
- avs->ghost_type= arm->ghosttype;
+ if (arm->ghostep == 0)
+ avs->ghost_type= GHOST_TYPE_NONE;
+ else
+ avs->ghost_type= arm->ghosttype + 1;
/* stepsize */
avs->ghost_step= arm->ghostsize;
@@ -10394,9 +10401,15 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
/* ranges */
avs->path_bc= arm->pathbc;
avs->path_ac= arm->pathac;
+ if ((avs->path_bc == avs->path_ac) && (avs->path_bc == 0))
+ avs->path_bc= avs->path_ac= 10;
avs->path_sf= arm->pathsf;
avs->path_ef= arm->pathef;
+ if ((avs->path_sf == avs->path_ef) && (avs->path_sf == 0)) {
+ avs->path_sf= 1;
+ avs->path_ef= 250;
+ }
/* flags */
if (arm->pathflag & ARM_PATH_FNUMS)
@@ -10419,6 +10432,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
if (avs->path_step == 0)
avs->path_step= 1;
}
+ else
+ animviz_settings_init(&ob->pose->avs);
}
}
diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c
index d26238150ca..ee6e87292fa 100644
--- a/source/blender/editors/armature/poseobject.c
+++ b/source/blender/editors/armature/poseobject.c
@@ -51,6 +51,7 @@
#include "DNA_view3d_types.h"
#include "DNA_userdef_types.h"
+#include "BKE_anim.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
#include "BKE_armature.h"
@@ -200,6 +201,7 @@ int ED_pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan)
}
/* ********************************************** */
+/* Motion Paths */
/* For the object with pose/action: update paths for those that have got them
* This should selectively update paths that exist...
@@ -208,120 +210,25 @@ int ED_pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan)
*/
void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob)
{
- bArmature *arm;
- bPoseChannel *pchan;
- Base *base;
- float *fp;
- int cfra;
- int sfra, efra;
-
- /* sanity checks */
- if ELEM(NULL, ob, ob->pose)
- return;
- arm= ob->data;
-
- /* set frame values */
- cfra = CFRA;
- sfra = efra = cfra;
- for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
- if (pchan->path) {
- /* if the pathsf and pathef aren't initialised, abort! */
- // XXX can now have negative frames, so this check needs improvement
- if (ELEM(0, pchan->pathsf, pchan->pathef))
- return;
-
- /* try to increase area to do (only as much as needed) */
- sfra= MIN2(sfra, pchan->pathsf);
- efra= MAX2(efra, pchan->pathef);
- }
- }
- }
- if (efra <= sfra) return;
-
- /* hack: for unsaved files, set OB_RECALC so that paths can get calculated */
- if ((ob->recalc & OB_RECALC)==0) {
- ob->recalc |= OB_RECALC;
- DAG_id_update_flags(&ob->id);
- }
- else
- DAG_id_update_flags(&ob->id);
-
- /* calculate path over requested range */
- for (CFRA=sfra; CFRA<=efra; CFRA++) {
- /* do all updates */
- for (base= FIRSTBASE; base; base= base->next) {
- if (base->object->recalc) {
- int temp= base->object->recalc;
-
- if (base->object->adt)
- BKE_animsys_evaluate_animdata(&base->object->id, base->object->adt, (float)CFRA, ADT_RECALC_ALL);
-
- /* update object */
- object_handle_update(scene, base->object);
- base->object->recalc= temp;
- }
- }
-
- for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
- if (pchan->path) {
- /* only update if:
- * - in range of this pchan's existing path
- * - ... insert evil filtering/optimising conditions here...
- */
- if (IN_RANGE(CFRA, pchan->pathsf, pchan->pathef)) {
- fp= pchan->path+3*(CFRA-sfra);
-
- if (arm->pathflag & ARM_PATH_HEADS) {
- VECCOPY(fp, pchan->pose_head);
- }
- else {
- VECCOPY(fp, pchan->pose_tail);
- }
-
- mul_m4_v3(ob->obmat, fp);
- }
- }
- }
- }
- }
+ ListBase targets = {NULL, NULL};
- /* reset flags */
- CFRA= cfra;
- ob->pose->flag &= ~POSE_RECALCPATHS;
+ /* set flag to force recalc, then grab the relevant bones to target */
+ ob->pose->avs.recalc |= ANIMVIZ_RECALC_PATHS;
+ animviz_get_object_motionpaths(ob, &targets);
- /* flush one final time - to restore to the original state */
- for (base= FIRSTBASE; base; base= base->next) {
- if (base->object->recalc) {
- int temp= base->object->recalc;
-
- if (base->object->adt)
- BKE_animsys_evaluate_animdata(&base->object->id, base->object->adt, (float)CFRA, ADT_RECALC_ALL);
-
- object_handle_update(scene, base->object);
- base->object->recalc= temp;
- }
- }
+ /* recalculate paths, then free */
+ animviz_calc_motionpaths(scene, &targets);
+ BLI_freelistN(&targets);
}
-/* --------- */
-
/* For the object with pose/action: create path curves for selected bones
* This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range
*/
static int pose_calculate_paths_exec (bContext *C, wmOperator *op)
{
- wmWindow *win= CTX_wm_window(C);
ScrArea *sa= CTX_wm_area(C);
Scene *scene= CTX_data_scene(C);
Object *ob;
- bArmature *arm;
- bPoseChannel *pchan;
- Base *base;
- float *fp;
- int cfra;
- int sfra, efra;
/* since this call may also be used from the buttons window, we need to check for where to get the object */
if (sa->spacetype == SPACE_BUTS)
@@ -329,109 +236,20 @@ static int pose_calculate_paths_exec (bContext *C, wmOperator *op)
else
ob= CTX_data_active_object(C);
- /* only continue if there's an object */
- if ELEM(NULL, ob, ob->pose)
- return OPERATOR_CANCELLED;
- arm= ob->data;
-
- /* version patch for older files here (do_versions patch too complicated) */
- if ((arm->pathsf == 0) || (arm->pathef == 0)) {
- arm->pathsf = SFRA;
- arm->pathef = EFRA;
- }
- if (arm->pathsize == 0) {
- arm->pathsize = 1;
- }
-
- /* get frame values to use */
- cfra= CFRA;
- sfra = arm->pathsf;
- efra = arm->pathef;
-
- if (efra <= sfra) {
- BKE_report(op->reports, RPT_ERROR, "Can't calculate paths when pathlen <= 0");
+ if (ELEM(NULL, ob, ob->pose))
return OPERATOR_CANCELLED;
- }
- /* hack: for unsaved files, set OB_RECALC so that paths can get calculated */
- if ((ob->recalc & OB_RECALC)==0) {
- ob->recalc |= OB_RECALC;
- DAG_id_update_flags(&ob->id);
- }
- else
- DAG_id_update_flags(&ob->id);
-
- /* alloc the path cache arrays */
- for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
- if (arm->layer & pchan->bone->layer) {
- pchan->pathlen= efra-sfra+1;
- pchan->pathsf= sfra;
- pchan->pathef= efra+1;
- if (pchan->path)
- MEM_freeN(pchan->path);
- pchan->path= MEM_callocN(3*pchan->pathlen*sizeof(float), "pchan path");
- }
- }
- }
-
- /* step through frame range sampling the values */
- for (CFRA=sfra; CFRA<=efra; CFRA++) {
- /* for each frame we calculate, update time-cursor... (may be too slow) */
- WM_timecursor(win, CFRA);
-
- /* do all updates */
- for (base= FIRSTBASE; base; base= base->next) {
- if (base->object->recalc) {
- int temp= base->object->recalc;
-
- if (base->object->adt)
- BKE_animsys_evaluate_animdata(&base->object->id, base->object->adt, (float)CFRA, ADT_RECALC_ALL);
-
- object_handle_update(scene, base->object);
- base->object->recalc= temp;
- }
- }
-
- for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
- if (arm->layer & pchan->bone->layer) {
- if (pchan->path) {
- fp= pchan->path+3*(CFRA-sfra);
-
- if (arm->pathflag & ARM_PATH_HEADS) {
- VECCOPY(fp, pchan->pose_head);
- }
- else {
- VECCOPY(fp, pchan->pose_tail);
- }
-
- mul_m4_v3(ob->obmat, fp);
- }
- }
- }
- }
+ /* set up path data for bones being calculated */
+ CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones)
+ {
+ /* verify makes sure that the selected bone has a bone with the appropriate settings */
+ animviz_verify_motionpaths(scene, ob, pchan);
}
+ CTX_DATA_END;
- /* restore original cursor */
- WM_cursor_restore(win);
-
- /* reset current frame, and clear flags */
- CFRA= cfra;
- ob->pose->flag &= ~POSE_RECALCPATHS;
-
- /* flush one final time - to restore to the original state */
- for (base= FIRSTBASE; base; base= base->next) {
- if (base->object->recalc) {
- int temp= base->object->recalc;
-
- if (base->object->adt)
- BKE_animsys_evaluate_animdata(&base->object->id, base->object->adt, (float)CFRA, ADT_RECALC_ALL);
-
- object_handle_update(scene, base->object);
- base->object->recalc= temp;
- }
- }
+ /* calculate the bones that now have motionpaths... */
+ // TODO: only make for the selected bones?
+ ED_pose_recalculate_paths(C, scene, ob);
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
@@ -464,12 +282,12 @@ void ED_pose_clear_paths(Object *ob)
if ELEM(NULL, ob, ob->pose)
return;
- /* free the path blocks */
+ /* free the motionpath blocks */
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
- if (pchan->path) {
- MEM_freeN(pchan->path);
- pchan->path= NULL;
+ if (pchan->mpath) {
+ animviz_free_motionpath(pchan->mpath);
+ pchan->mpath= NULL;
}
}
}
@@ -491,7 +309,7 @@ static int pose_clear_paths_exec (bContext *C, wmOperator *op)
if ELEM(NULL, ob, ob->pose)
return OPERATOR_CANCELLED;
- /* for now, just call the API function for this (which is shared with backend functions) */
+ /* use the backend function for this */
ED_pose_clear_paths(ob);
/* notifiers for updates */
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 91b297b7581..aa6914ab0ad 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -95,6 +95,10 @@ void ED_object_single_users(struct Scene *scene, int full);
int object_is_libdata(struct Object *ob);
int object_data_is_libdata(struct Object *ob);
+/* object motion paths */
+void ED_objects_clear_paths(struct bContext *C, struct Scene *scene);
+void ED_objects_recalculate_paths(struct bContext *C, struct Scene *scene);
+
/* constraints */
struct ListBase *get_active_constraints(struct Object *ob);
struct ListBase *get_constraint_lb(struct Object *ob, struct bConstraint *con, struct bPoseChannel **pchan_r);
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 54fa3f51eb6..e2d714fac0d 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -1610,6 +1610,118 @@ void copy_attr_menu(Scene *scene, View3D *v3d)
copy_attr(scene, v3d, event);
}
+/* ********************************************** */
+/* Motion Paths */
+
+/* For the object with pose/action: update paths for those that have got them
+ * This should selectively update paths that exist...
+ *
+ * To be called from various tools that do incremental updates
+ */
+void ED_objects_recalculate_paths(bContext *C, Scene *scene)
+{
+ ListBase targets = {NULL, NULL};
+
+ /* loop over objects in scene */
+ CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects)
+ {
+ /* set flag to force recalc, then grab the relevant bones to target */
+ ob->avs.recalc |= ANIMVIZ_RECALC_PATHS;
+ animviz_get_object_motionpaths(ob, &targets);
+ }
+ CTX_DATA_END;
+
+ /* recalculate paths, then free */
+ animviz_calc_motionpaths(scene, &targets);
+ BLI_freelistN(&targets);
+}
+
+/* For the object with pose/action: create path curves for selected bones
+ * This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range
+ */
+static int object_calculate_paths_exec (bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+
+ /* set up path data for bones being calculated */
+ CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects)
+ {
+ /* verify makes sure that the selected bone has a bone with the appropriate settings */
+ animviz_verify_motionpaths(scene, ob, NULL);
+ }
+ CTX_DATA_END;
+
+ /* calculate the bones that now have motionpaths... */
+ // TODO: only make for the selected bones?
+ ED_objects_recalculate_paths(C, scene);
+
+ /* notifiers for updates */
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_paths_calculate (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Calculate Object Paths";
+ ot->idname= "OBJECT_OT_paths_calculate";
+ ot->description= "Calculate paths for the selected bones.";
+
+ /* api callbacks */
+ ot->exec= object_calculate_paths_exec;
+ ot->poll= ED_operator_object_active_editable;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/* --------- */
+
+/* for the object with pose/action: clear path curves for selected bones only */
+void ED_objects_clear_paths(bContext *C, Scene *scene)
+{
+ /* loop over objects in scene */
+ CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects)
+ {
+ if (ob->mpath) {
+ animviz_free_motionpath(ob->mpath);
+ ob->mpath= NULL;
+ }
+ }
+ CTX_DATA_END;
+}
+
+/* operator callback for this */
+static int object_clear_paths_exec (bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+
+ /* use the backend function for this */
+ ED_objects_clear_paths(C, scene);
+
+ /* notifiers for updates */
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_paths_clear (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Clear Object Paths";
+ ot->idname= "OBJECT_OT_paths_clear";
+ ot->description= "Clear path caches for selected bones.";
+
+ /* api callbacks */
+ ot->exec= object_clear_paths_exec;
+ ot->poll= ED_operator_object_active_editable;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+
/********************** Smooth/Flat *********************/
static int shade_smooth_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index cfb4cda2460..a11ead1fe9d 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -79,6 +79,8 @@ void OBJECT_OT_restrictview_clear(struct wmOperatorType *ot);
void OBJECT_OT_proxy_make(struct wmOperatorType *ot);
void OBJECT_OT_shade_smooth(struct wmOperatorType *ot);
void OBJECT_OT_shade_flat(struct wmOperatorType *ot);
+void OBJECT_OT_paths_calculate(struct wmOperatorType *ot);
+void OBJECT_OT_paths_clear(struct wmOperatorType *ot);
/* object_select.c */
void OBJECT_OT_select_all(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 8b29e2ca2ae..80992887e97 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -81,6 +81,8 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_restrictview_set);
WM_operatortype_append(OBJECT_OT_shade_smooth);
WM_operatortype_append(OBJECT_OT_shade_flat);
+ WM_operatortype_append(OBJECT_OT_paths_calculate);
+ WM_operatortype_append(OBJECT_OT_paths_clear);
WM_operatortype_append(OBJECT_OT_parent_set);
WM_operatortype_append(OBJECT_OT_parent_no_inverse_set);
diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c
index b8184a60cee..c57fad96a94 100644
--- a/source/blender/editors/space_view3d/drawanimviz.c
+++ b/source/blender/editors/space_view3d/drawanimviz.c
@@ -104,6 +104,7 @@ void draw_motion_paths_init(Scene *scene, View3D *v3d, ARegion *ar)
* - assumes that the viewport has already been initialised properly
* i.e. draw_motion_paths_init() has been called
*/
+// FIXME: the text is still drawn in the wrong space - it includes the current transforms of the object still...
void draw_motion_path_instance(Scene *scene, View3D *v3d, ARegion *ar,
Object *ob, bPoseChannel *pchan, bAnimVizSettings *avs, bMotionPath *mpath)
{
@@ -273,7 +274,7 @@ void draw_motion_path_instance(Scene *scene, View3D *v3d, ARegion *ar,
glPointSize(1.0f);
/* Draw frame numbers of keyframes */
- if (avs->path_viewflag & (MOTIONPATH_VIEW_FNUMS|MOTIONPATH_VIEW_KFNOS)) {
+ if (avs->path_viewflag & MOTIONPATH_VIEW_FNUMS) {
for (i=0, mpv=mpv_start; i < len; i++, mpv++) {
float mframe= (float)(sfra + i);
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index c59c5cddb3f..bfdeaef1834 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -2118,200 +2118,21 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt)
*/
static void draw_pose_paths(Scene *scene, View3D *v3d, ARegion *ar, Object *ob)
{
- RegionView3D *rv3d= ar->regiondata;
- AnimData *adt= BKE_animdata_from_id(&ob->id);
+ bAnimVizSettings *avs= &ob->pose->avs;
bArmature *arm= ob->data;
bPoseChannel *pchan;
- ActKeyColumn *ak;
- DLRBT_Tree keys;
- float *fp, *fp_start;
- int a, stepsize;
- int sfra, efra, len;
- if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
-
- glPushMatrix();
- glLoadMatrixf(rv3d->viewmat);
-
- /* version patch here - cannot access frame info from file reading */
- if (arm->pathsize == 0) arm->pathsize= 1;
- stepsize = arm->pathsize;
+ /* setup drawing environment for paths */
+ draw_motion_paths_init(scene, v3d, ar);
+ /* draw paths where they exist and they releated bone is visible */
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if (pchan->bone->layer & arm->layer) {
- if (pchan->path) {
- /* version patch here - cannot access frame info from file reading */
- if ((pchan->pathsf == 0) || (pchan->pathef == 0)) {
- pchan->pathsf= SFRA;
- pchan->pathef= EFRA;
- }
-
- /* get frame ranges */
- if (arm->pathflag & ARM_PATH_ACFRA) {
- int sind;
-
- /* With "Around Current", we only choose frames from around
- * the current frame to draw. However, this range is still
- * restricted by the limits of the original path.
- */
- sfra= CFRA - arm->pathbc;
- efra= CFRA + arm->pathac;
- if (sfra < pchan->pathsf) sfra= pchan->pathsf;
- if (efra > pchan->pathef) efra= pchan->pathef;
-
- len= efra - sfra;
-
- sind= sfra - pchan->pathsf;
- fp_start= (pchan->path + (3*sind));
- }
- else {
- sfra= pchan->pathsf;
- efra = sfra + pchan->pathlen;
- len = pchan->pathlen;
- fp_start = pchan->path;
- }
-
- /* draw curve-line of path */
- glShadeModel(GL_SMOOTH);
-
- glBegin(GL_LINE_STRIP);
- for (a=0, fp=fp_start; a<len; a++, fp+=3) {
- float intensity; /* how faint */
-
- /* set color
- * - more intense for active/selected bones, less intense for unselected bones
- * - black for before current frame, green for current frame, blue for after current frame
- * - intensity decreases as distance from current frame increases
- */
- #define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max-min)) + min)
- if ((a+sfra) < CFRA) {
- /* black - before cfra */
- if (pchan->bone->flag & BONE_SELECTED) {
- // intensity= 0.5f;
- intensity = SET_INTENSITY(sfra, a, CFRA, 0.25f, 0.75f);
- }
- else {
- //intensity= 0.8f;
- intensity = SET_INTENSITY(sfra, a, CFRA, 0.68f, 0.92f);
- }
- UI_ThemeColorBlend(TH_WIRE, TH_BACK, intensity);
- }
- else if ((a+sfra) > CFRA) {
- /* blue - after cfra */
- if (pchan->bone->flag & BONE_SELECTED) {
- //intensity = 0.5f;
- intensity = SET_INTENSITY(CFRA, a, efra, 0.25f, 0.75f);
- }
- else {
- //intensity = 0.8f;
- intensity = SET_INTENSITY(CFRA, a, efra, 0.68f, 0.92f);
- }
- UI_ThemeColorBlend(TH_BONE_POSE, TH_BACK, intensity);
- }
- else {
- /* green - on cfra */
- if (pchan->bone->flag & BONE_SELECTED) {
- intensity= 0.5f;
- }
- else {
- intensity= 0.99f;
- }
- UI_ThemeColorBlendShade(TH_CFRAME, TH_BACK, intensity, 10);
- }
-
- /* draw a vertex with this color */
- glVertex3fv(fp);
- }
-
- glEnd();
- glShadeModel(GL_FLAT);
-
- glPointSize(1.0);
-
- /* draw little black point at each frame
- * NOTE: this is not really visible/noticable
- */
- glBegin(GL_POINTS);
- for (a=0, fp=fp_start; a<len; a++, fp+=3)
- glVertex3fv(fp);
- glEnd();
-
- /* Draw little white dots at each framestep value */
- UI_ThemeColor(TH_TEXT_HI);
- glBegin(GL_POINTS);
- for (a=0, fp=fp_start; a<len; a+=stepsize, fp+=(stepsize*3))
- glVertex3fv(fp);
- glEnd();
-
- /* Draw frame numbers at each framestep value */
- if (arm->pathflag & ARM_PATH_FNUMS) {
- for (a=0, fp=fp_start; a<len; a+=stepsize, fp+=(stepsize*3)) {
- char str[32];
-
- /* only draw framenum if several consecutive highlighted points don't occur on same point */
- if (a == 0) {
- sprintf(str, "%d", (a+sfra));
- view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0);
- }
- else if ((a > stepsize) && (a < len-stepsize)) {
- if ((equals_v3v3(fp, fp-(stepsize*3))==0) || (equals_v3v3(fp, fp+(stepsize*3))==0)) {
- sprintf(str, "%d", (a+sfra));
- view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0);
- }
- }
- }
- }
-
- /* Keyframes - dots and numbers */
- if (arm->pathflag & ARM_PATH_KFRAS) {
- /* build list of all keyframes in active action for pchan */
- BLI_dlrbTree_init(&keys);
-
- if (adt) {
- bActionGroup *agrp= action_groups_find_named(adt->action, pchan->name);
- if (agrp) {
- agroup_to_keylist(adt, agrp, &keys, NULL);
- BLI_dlrbTree_linkedlist_sync(&keys);
- }
- }
-
- /* Draw slightly-larger yellow dots at each keyframe */
- UI_ThemeColor(TH_VERTEX_SELECT);
- glPointSize(5.0f);
-
- glBegin(GL_POINTS);
- for (a=0, fp=fp_start; a<len; a++, fp+=3) {
- for (ak= keys.first; ak; ak= ak->next) {
- if (ak->cfra == (a+sfra))
- glVertex3fv(fp);
- }
- }
- glEnd();
-
- glPointSize(1.0f);
-
- /* Draw frame numbers of keyframes */
- if ((arm->pathflag & ARM_PATH_FNUMS) || (arm->pathflag & ARM_PATH_KFNOS)) {
- for(a=0, fp=fp_start; a<len; a++, fp+=3) {
- for (ak= keys.first; ak; ak= ak->next) {
- if (ak->cfra == (a+sfra)) {
- char str[32];
-
- sprintf(str, "%d", (a+sfra));
- view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0);
- }
- }
- }
- }
-
- BLI_dlrbTree_free(&keys);
- }
- }
- }
+ if ((pchan->bone->layer & arm->layer) && (pchan->mpath))
+ draw_motion_path_instance(scene, v3d, ar, ob, pchan, avs, pchan->mpath);
}
- if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
- glPopMatrix();
+ /* cleanup after drawing */
+ draw_motion_paths_cleanup(scene, v3d, ar);
}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index c3e248c9d7c..b10b74ff160 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -5180,6 +5180,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
/* no return after this point, otherwise leaks */
view3d_cached_text_draw_begin();
+
/* draw keys? */
#if 0 // XXX old animation system
@@ -5260,8 +5261,19 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
/* patch? children objects with a timeoffs change the parents. How to solve! */
/* if( ((int)ob->ctime) != F_(scene->r.cfra)) where_is_object(scene, ob); */
- /* draw paths... */
- // TODO...
+ /* draw motion paths (in view space) */
+ if (ob->mpath) {
+ bAnimVizSettings *avs= &ob->avs;
+
+ /* setup drawing environment for paths */
+ draw_motion_paths_init(scene, v3d, ar);
+
+ /* draw motion path for object */
+ draw_motion_path_instance(scene, v3d, ar, ob, NULL, avs, ob->mpath);
+
+ /* cleanup after drawing */
+ draw_motion_paths_cleanup(scene, v3d, ar);
+ }
/* multiply view with object matrix.
* local viewmat and persmat, to calculate projections */