From 092e9dcdc342aa173e24a5ab286b1faee4fe8a53 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 1 Dec 2007 11:57:16 +0000 Subject: [PATCH] == Bone Paths - More Tweaks (Cessen requests) == * "Around Current Frame" option now works differently. When this option is activated, the path range calculated remains the same (PSta -> PEnd), but only PPre and PPost amount of path-points on either side of the current frame get shown. This is less clumsy to use, and looks quite neat! * "Clear Paths" now only clears the paths of the selected bones, not all bones. The old behaviour can still be obtained by selecting all bones, but previously there was no way to only clear paths of selected bones. * Own fix: path colours are now drawn less saturated, as they were showing up TOO strongly. TODO: * Fix up interface for "Around current..." option. It's quite confusing atm. * Selective recalculation of path on certain operations could also be investigated further... --- source/blender/src/buttons_editing.c | 4 +- source/blender/src/drawarmature.c | 56 +++++++++++++++------- source/blender/src/poseobject.c | 24 ++++------ source/blender/src/transform_conversions.c | 2 +- 4 files changed, 51 insertions(+), 35 deletions(-) diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index e2debea0750..110603c720f 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -4014,7 +4014,7 @@ static void editing_panel_armature_visuals(Object *ob, bArmature *arm) uiBlockEndAlign(block); uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, ARM_PATH_ACFRA, REDRAWVIEW3D, "Around Current Frame", 170, 105, 160, 20, &arm->pathflag, 0, 0, 0, 0, "Calculate Bone Path around the current frame"); + uiDefButBitS(block, TOG, ARM_PATH_ACFRA, REDRAWVIEW3D, "Around Current Frame", 170, 105, 160, 20, &arm->pathflag, 0, 0, 0, 0, "Only show Bone Path around the current frame"); if (arm->pathflag & ARM_PATH_ACFRA) { uiDefButI(block, NUM,REDRAWVIEW3D,"PPre:",170,85,80,20, &arm->pathbc, 1.0, MAXFRAMEF/2, 0, 0, "The number of frames before current frame for Bone Path display range"); uiDefButI(block, NUM,REDRAWVIEW3D,"PPost:",250,85,80,20, &arm->pathac, 1.0, MAXFRAMEF/2, 0, 0, "The number of frames after current frame for Bone Path display range"); @@ -4028,7 +4028,7 @@ static void editing_panel_armature_visuals(Object *ob, bArmature *arm) uiBlockBeginAlign(block); uiDefBut(block, BUT, B_ARM_CALCPATHS, "Calculate Paths", 170,30,160,20, 0, 0, 0, 0, 0, "(Re)calculates the paths of the selected bones"); - uiDefBut(block, BUT, B_ARM_CLEARPATHS, "Clear All Paths", 170,10,160,20, 0, 0, 0, 0, 0, "Clears all bone paths"); + uiDefBut(block, BUT, B_ARM_CLEARPATHS, "Clear All Paths", 170,10,160,20, 0, 0, 0, 0, 0, "Clears bone paths of the selected bones"); uiBlockEndAlign(block); } diff --git a/source/blender/src/drawarmature.c b/source/blender/src/drawarmature.c index c907bab5a23..b19d5104924 100644 --- a/source/blender/src/drawarmature.c +++ b/source/blender/src/drawarmature.c @@ -1736,9 +1736,9 @@ static void draw_pose_paths(Object *ob) bActionChannel *achan; CfraElem *ce; ListBase ak; - float *fp; + float *fp, *fp_start; int a, stepsize; - int sfra, efra; + int sfra, efra, len; if(G.vd->zbuf) glDisable(GL_DEPTH_TEST); @@ -1758,9 +1758,33 @@ static void draw_pose_paths(Object *ob) pchan->pathef= EFRA; } - /* get frame ranges */ - sfra= pchan->pathsf; - efra = sfra + pchan->pathlen; + /* get frame ranges + * - sfra,efra are the start and end frame numbers (respectively) + * - sind is the starting array index, nind is the number of array items (location array) + */ + 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 */ if ((CFRA > sfra) && (CFRA < efra)) { @@ -1770,16 +1794,16 @@ static void draw_pose_paths(Object *ob) */ /* before cfra (darker) */ - BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.2); + BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.5); glBegin(GL_LINE_STRIP); - for (a=0, fp=pchan->path; (sfra+a)<=CFRA; a++, fp+=3) + for (a=0, fp=fp_start; (sfra+a)<=CFRA; a++, fp+=3) glVertex3fv(fp); glEnd(); /* after cfra (lighter) - backtrack a bit so that we don't have gaps */ - BIF_ThemeColorBlend(TH_WIRE, TH_BONE_POSE, 0.7); + BIF_ThemeColorBlend(TH_BONE_POSE, TH_BACK, 0.5); glBegin(GL_LINE_STRIP); - for (--a, fp-=3; apathlen; a++, fp+=3) + for (--a, fp-=3; apath; apathlen; a++, fp+=3) + for (a=0, fp=fp_start; apath; apathlen; a++, fp+=3) + for (a=0, fp=fp_start; apath; apathlen; a+=stepsize, fp+=(stepsize*3)) + for (a=0, fp=fp_start; apathflag & ARM_PATH_FNUMS) { - for(a=0, fp= pchan->path; apathlen; a+=stepsize, fp+=(stepsize*3)) { + for (a=0, fp=fp_start; a stepsize) && (a < pchan->pathlen-stepsize)) { + else if ((a > stepsize) && (a < len-stepsize)) { if ((VecEqual(fp, fp-(stepsize*3))==0) || (VecEqual(fp, fp+(stepsize*3))==0)) { glRasterPos3fv(fp); sprintf(str, " %d\n", (a+sfra)); @@ -1844,7 +1868,7 @@ static void draw_pose_paths(Object *ob) /* Draw little yellow dots at each keyframe */ BIF_ThemeColor(TH_VERTEX_SELECT); glBegin(GL_POINTS); - for(a=0, fp= pchan->path; apathlen; a++, fp+=3) { + for(a=0, fp=fp_start; anext) { if (ce->cfra == (a+sfra)) glVertex3fv(fp); @@ -1854,7 +1878,7 @@ static void draw_pose_paths(Object *ob) /* Draw frame numbers of keyframes */ if (arm->pathflag & ARM_PATH_FNUMS) { - for(a=0, fp= pchan->path; apathlen; a++, fp+=3) { + for(a=0, fp=fp_start; anext) { if (ce->cfra == (a+sfra)) { char str[32]; diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c index 68af3d7c64c..fe7dd0109e1 100644 --- a/source/blender/src/poseobject.c +++ b/source/blender/src/poseobject.c @@ -219,7 +219,9 @@ int pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan) /* ********************************************** */ -/* for the object with pose/action: create path curves for selected bones */ +/* 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 + */ void pose_calculate_path(Object *ob) { bArmature *arm; @@ -238,24 +240,14 @@ void pose_calculate_path(Object *ob) arm->pathsf = SFRA; arm->pathef = EFRA; } - if ((arm->pathbc == 0) || (arm->pathac == 0)) { - arm->pathbc = 15; - arm->pathac = 15; - } if (arm->pathsize == 0) { arm->pathsize = 1; } /* set frame values */ cfra= CFRA; - if (arm->pathflag & ARM_PATH_ACFRA) { - sfra = cfra - arm->pathbc; - efra = cfra + arm->pathac; - } - else { - sfra = arm->pathsf; - efra = arm->pathef; - } + sfra = arm->pathsf; + efra = arm->pathef; if (efra<=sfra) return; DAG_object_update_flags(G.scene, ob, screen_view3d_layers()); @@ -310,7 +302,7 @@ void pose_calculate_path(Object *ob) } -/* for the object with pose/action: clear all path curves */ +/* for the object with pose/action: clear path curves for selected bones only */ void pose_clear_paths(Object *ob) { bPoseChannel *pchan; @@ -319,8 +311,8 @@ void pose_clear_paths(Object *ob) return; /* free the path blocks */ - for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if(pchan->path) { + for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if (pchan->path) { MEM_freeN(pchan->path); pchan->path= NULL; } diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 78284e11e74..f280e4afdcd 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -3064,7 +3064,7 @@ void autokeyframe_pose_cb_func(Object *ob, int tmode, short targetless_ik) /* do the bone paths */ if (arm->pathflag & ARM_PATH_ACFRA) { - pose_clear_paths(ob); + //pose_clear_paths(ob); pose_calculate_path(ob); }