== Armature Visualisation - A few additions ==
authorJoshua Leung <aligorith@gmail.com>
Sun, 9 Dec 2007 08:46:23 +0000 (08:46 +0000)
committerJoshua Leung <aligorith@gmail.com>
Sun, 9 Dec 2007 08:46:23 +0000 (08:46 +0000)
* Added an option to make frame numbers of keyframes draw on bone-paths even when frame numbers for other points are not shown.

* Added a new ghosting method, which only shows the keyframes within a range.

source/blender/makesdna/DNA_armature_types.h
source/blender/src/buttons_editing.c
source/blender/src/drawarmature.c

index f5eacede809d7e7efa198f540afd4e2943c945a8..b5c6134fe3f8785728d1c8fea8997662e11cc378 100644 (file)
@@ -68,7 +68,7 @@ typedef struct Bone {
        float                   size[3];                /*  patch for upward compat, UNUSED! */
        short                   layer;
        short                   segments;               /*  for B-bones */
-}Bone;
+} Bone;
 
 typedef struct bArmature {
        ID                      id;
@@ -84,76 +84,76 @@ typedef struct bArmature {
        int                     ghostsf, ghostef;               /* start and end frames of ghost-drawing range */
        int             pathsf, pathef;                 /* start and end frames of path-calculation range for all bones */
        int                     pathbc, pathac;                 /* number of frames before/after current frame of path-calculation for all bones  */
-}bArmature;
+} bArmature;
 
 /* armature->flag */
 /* dont use bit 7, was saved in files to disable stuff */
-
-/* armature->flag */
-#define                ARM_RESTPOS             0x001
-                       /* XRAY is here only for backwards converting */
-#define                ARM_DRAWXRAY    0x002
-#define                ARM_DRAWAXES    0x004
-#define                ARM_DRAWNAMES   0x008
-#define                ARM_POSEMODE    0x010
-#define                ARM_EDITMODE    0x020
-#define                ARM_DELAYDEFORM 0x040
-#define                ARM_DONT_USE    0x080
-#define                ARM_MIRROR_EDIT 0x100
-#define                ARM_AUTO_IK             0x200
-                       /* made option negative, for backwards compat */
-#define                ARM_NO_CUSTOM   0x400
-#define                ARM_COL_CUSTOM  0x800
+typedef enum eArmature_Flag {
+       ARM_RESTPOS             = (1<<0),
+       ARM_DRAWXRAY    = (1<<1),       /* XRAY is here only for backwards converting */
+       ARM_DRAWAXES    = (1<<2),
+       ARM_DRAWNAMES   = (1<<3), 
+       ARM_POSEMODE    = (1<<4), 
+       ARM_EDITMODE    = (1<<5), 
+       ARM_DELAYDEFORM = (1<<6), 
+       ARM_DONT_USE    = (1<<7),
+       ARM_MIRROR_EDIT = (1<<8),
+       ARM_AUTO_IK             = (1<<9),
+       ARM_NO_CUSTOM   = (1<<10),      /* made option negative, for backwards compat */
+       ARM_COL_CUSTOM  = (1<<11)
+} eArmature_Flag;
 
 /* armature->drawtype */
-#define                ARM_OCTA                0
-#define                ARM_LINE                1
-#define                ARM_B_BONE              2
-#define                ARM_ENVELOPE    3
+typedef enum eArmature_Drawtype {
+       ARM_OCTA = 0,
+       ARM_LINE,
+       ARM_B_BONE,
+       ARM_ENVELOPE
+} eArmature_Drawtype;
 
 /* armature->deformflag */
-#define                ARM_DEF_VGROUP                  1
-#define                ARM_DEF_ENVELOPE                2
-#define                ARM_DEF_QUATERNION              4
-#define                ARM_DEF_B_BONE_REST             8
-#define                ARM_DEF_INVERT_VGROUP   16
+typedef enum eArmature_DeformFlag {
+       ARM_DEF_VGROUP                  = (1<<0),
+       ARM_DEF_ENVELOPE                = (1<<1),
+       ARM_DEF_QUATERNION              = (1<<2),
+       ARM_DEF_B_BONE_REST             = (1<<3),
+       ARM_DEF_INVERT_VGROUP   = (1<<4)
+} eArmature_DeformFlag;
 
 /* armature->pathflag */
-#define                ARM_PATH_FNUMS          (1<<0)
-#define                ARM_PATH_KFRAS          (1<<1)
-#define                ARM_PATH_HEADS          (1<<2)
-#define        ARM_PATH_ACFRA          (1<<3)
+typedef enum eArmature_PathFlag {
+       ARM_PATH_FNUMS          = (1<<0),
+       ARM_PATH_KFRAS          = (1<<1),
+       ARM_PATH_HEADS          = (1<<2),
+       ARM_PATH_ACFRA          = (1<<3),
+       ARM_PATH_KFNOS          = (1<<4)
+} eArmature_PathFlag;
 
 /* armature->ghosttype */
-#define        ARM_GHOST_CUR   0
-#define                ARM_GHOST_RANGE 1
+typedef enum eArmature_GhostType {
+       ARM_GHOST_CUR = 0,
+       ARM_GHOST_RANGE,
+       ARM_GHOST_KEYS
+} eArmature_GhostType;
 
 /* bone->flag */
-#define                BONE_SELECTED   1
-#define                BONE_ROOTSEL    2
-#define                BONE_TIPSEL             4
-                       /* Used instead of BONE_SELECTED during transform */
-#define                BONE_TRANSFORM  8
-#define                BONE_CONNECTED 16
-                       /* 32 used to be quatrot, was always set in files, do not reuse unless you clear it always */
-                       /* hidden Bones when drawing Posechannels */
-#define                BONE_HIDDEN_P           64
-                       /* For detecting cyclic dependancies */
-#define                BONE_DONE               128
-                       /* active is on mouse clicks only */
-#define                BONE_ACTIVE             256
-                       /* No parent rotation or scale */
-#define                BONE_HINGE              512
-                       /* hidden Bones when drawing Armature Editmode */
-#define                BONE_HIDDEN_A           1024
-                       /* multiplies vgroup with envelope */
-#define                BONE_MULT_VG_ENV        2048
-#define                BONE_NO_DEFORM          4096
-                       /* set to prevent destruction of its unkeyframed pose (after transform) */
-#define        BONE_UNKEYED            8192
-                       /* set to prevent hinge child bones from influencing the transform center */
-#define        BONE_HINGE_CHILD_TRANSFORM 16384
-                       /* No parent scale */
-#define                BONE_NO_SCALE           (1<<15)
+typedef enum eBone_Flag {
+       BONE_SELECTED                           = (1<<0),
+       BONE_ROOTSEL                            = (1<<1),
+       BONE_TIPSEL                                     = (1<<2),
+       BONE_TRANSFORM                          = (1<<3),       /* Used instead of BONE_SELECTED during transform */
+       BONE_CONNECTED                          = (1<<4),
+       /* 32 used to be quatrot, was always set in files, do not reuse unless you clear it always */   
+       BONE_HIDDEN_P                           = (1<<6),       /* hidden Bones when drawing Posechannels */    
+       BONE_DONE                                       = (1<<7),       /* For detecting cyclic dependancies */
+       BONE_ACTIVE                                     = (1<<8),       /* active is on mouse clicks only */
+       BONE_HINGE                                      = (1<<9),       /* No parent rotation or scale */
+       BONE_HIDDEN_A                           = (1<<10),      /* hidden Bones when drawing Armature Editmode */
+       BONE_MULT_VG_ENV                        = (1<<11),      /* multiplies vgroup with envelope */
+       BONE_NO_DEFORM                          = (1<<12),
+       BONE_UNKEYED                            = (1<<13),      /* set to prevent destruction of its unkeyframed pose (after transform) */              
+       BONE_HINGE_CHILD_TRANSFORM      = (1<<14),      /* set to prevent hinge child bones from influencing the transform center */
+       BONE_NO_SCALE                           = (1<<15)       /* No parent scale */
+} eBone_Flag;
 
 #endif
index 6c033c02db285983dea916eb6ae8dc3f7e2cb2e8..059c705eab1a59fbb1162f019535a0296fe09948 100644 (file)
@@ -3986,10 +3986,13 @@ static void editing_panel_armature_visuals(Object *ob, bArmature *arm)
        uiDefBut(block, LABEL, 0, "Ghost Options", 10,180,150,20, 0, 0, 0, 0, 0, "");
 
        uiBlockBeginAlign(block);
-               uiDefButS(block, MENU, REDRAWVIEW3D, "Ghosts %t|Around Current Frame %x0|In Range %x1", 
+               uiDefButS(block, MENU, REDRAWVIEW3D, "Ghosts %t|Around Current Frame %x0|In Range %x1|On Keyframes %x2", 
                                                                                                        10, 160, 150, 20, &arm->ghosttype, 0, 0, 0, 0, "Choose range of Ghosts to draw for current Action");    
                
-               uiDefButS(block, NUM, REDRAWVIEW3D, "GStep: ", 10,140,150,20, &arm->ghostsize, 1.0f, 20.0f, 0, 0, "How many frames between Ghost instances");
+               if (arm->ghosttype != ARM_GHOST_KEYS)
+                       uiDefButS(block, NUM, REDRAWVIEW3D, "GStep: ", 10,140,150,20, &arm->ghostsize, 1.0f, 20.0f, 0, 0, "How many frames between Ghost instances");
+               else
+                       uiDefBut(block, LABEL, REDRAWVIEW3D, "GStep: N/A", 10,140,150,20, NULL, 0.0f, 0.0f, 0, 0, "How many frames between Ghost instances");
        uiBlockEndAlign(block);
        
        uiBlockBeginAlign(block);
@@ -3997,7 +4000,7 @@ static void editing_panel_armature_visuals(Object *ob, bArmature *arm)
                /* range is around current frame */
                uiDefButS(block, NUM, REDRAWVIEW3D, "Ghost: ", 10,110,150,20, &arm->ghostep, 0.0f, 30.0f, 0, 0, "Draw Ghosts around current frame, for current Action");
        }
-       else if (arm->ghosttype == ARM_GHOST_RANGE) {
+       else if (ELEM(arm->ghosttype, ARM_GHOST_RANGE, ARM_GHOST_KEYS)) {
                /* range is defined by start+end frame below */
                uiDefButI(block, NUM,REDRAWVIEW3D,"GSta:",10,110,150,20, &arm->ghostsf,1.0,MAXFRAMEF, 0, 0, "The start frame for Ghost display range");
                uiDefButI(block, NUM,REDRAWVIEW3D,"GEnd:",10,90,150,20, &arm->ghostef,arm->ghostsf,MAXFRAMEF, 0, 0, "The end frame for Ghost display range");   
@@ -4008,9 +4011,11 @@ static void editing_panel_armature_visuals(Object *ob, bArmature *arm)
        uiDefBut(block, LABEL, 0, "Bone Paths Drawing:", 165,180,170,20, 0, 0, 0, 0, 0, "");
        
        uiBlockBeginAlign(block);
-       uiDefButBitS(block, TOG, ARM_PATH_FNUMS, REDRAWVIEW3D, "Frame Nums", 170, 160, 80, 20, &arm->pathflag, 0, 0, 0, 0, "Show frame numbers on path");
-               uiDefButS(block, NUM, REDRAWVIEW3D, "PStep:",250,160,80,20, &arm->pathsize,1,100, 10, 50, "Frames between highlighted points on bone path");
-               uiDefButBitS(block, TOG, ARM_PATH_KFRAS, REDRAWVIEW3D, "Show Keys", 170, 140, 160, 20, &arm->pathflag, 0, 0, 0, 0, "Show key frames on path");
+               uiDefButS(block, NUM, REDRAWVIEW3D, "PStep:",170,160,80,20, &arm->pathsize,1,100, 10, 50, "Frames between highlighted points on bone path");
+               uiDefButBitS(block, TOG, ARM_PATH_FNUMS, REDRAWVIEW3D, "Frame Nums", 250, 160, 80, 20, &arm->pathflag, 0, 0, 0, 0, "Show frame numbers on path");
+               
+               uiDefButBitS(block, TOG, ARM_PATH_KFRAS, REDRAWVIEW3D, "Show Keys", 170, 140, 80, 20, &arm->pathflag, 0, 0, 0, 0, "Show key frames on path");
+               uiDefButBitS(block, TOG, ARM_PATH_KFNOS, REDRAWVIEW3D, "Keyframe Nums", 250, 140, 80, 20, &arm->pathflag, 0, 0, 0, 0, "Show frame numbers of key frames on path");
        uiBlockEndAlign(block);
        
        uiBlockBeginAlign(block);
index 96038324a4b9aafc9162c5db178a566b4f2c7ec3..9fb0e497159f6dd9bf3c175d2ea61654d65acbc1 100644 (file)
@@ -1903,7 +1903,7 @@ static void draw_pose_paths(Object *ob)
                                        glPointSize(1.0);
                                        
                                        /* Draw frame numbers of keyframes  */
-                                       if (arm->pathflag & ARM_PATH_FNUMS) {
+                                       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)) {
@@ -1939,7 +1939,7 @@ static void draw_ghost_poses_range(Base *base)
        
        start = arm->ghostsf;
        end = arm->ghostef;
-       if (end<=start)
+       if (end <= start)
                return;
        
        stepsize= (float)(arm->ghostsize);
@@ -1960,10 +1960,10 @@ static void draw_ghost_poses_range(Base *base)
        armature_rebuild_pose(ob, ob->data);    /* child pointers for IK */
        
        glEnable(GL_BLEND);
-       if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
+       if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
        
        /* draw from first frame of range to last */
-       for(CFRA= start; CFRA<end; CFRA+=stepsize) {
+       for (CFRA= start; CFRA<end; CFRA+=stepsize) {
                colfac = (end-CFRA)/range;
                BIF_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0f*sqrt(colfac)));
                
@@ -1972,7 +1972,7 @@ static void draw_ghost_poses_range(Base *base)
                draw_pose_channels(base, OB_WIRE);
        }
        glDisable(GL_BLEND);
-       if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+       if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
 
        free_pose_channels(posen);
        MEM_freeN(posen);
@@ -1984,7 +1984,79 @@ static void draw_ghost_poses_range(Base *base)
        armature_rebuild_pose(ob, ob->data);
        ob->flag |= OB_POSEMODE;
        ob->ipoflag= ipoflago; 
+}
 
+static void draw_ghost_poses_keys(Base *base)
+{
+       Object *ob= base->object;
+       bAction *act= ob_get_action(ob);
+       bArmature *arm= ob->data;
+       bPose *posen, *poseo;
+       ListBase keys= {NULL, NULL};
+       ActKeyColumn *ak, *akn;
+       float start, end, range, colfac, i;
+       int cfrao, flago, ipoflago;
+       
+       start = arm->ghostsf;
+       end = arm->ghostef;
+       if (end <= start)
+               return;
+       
+       /* get keyframes - then clip to only within range */
+       action_to_keylist(act, &keys, NULL);
+       range= 0;
+       for (ak= keys.first; ak; ak= akn) {
+               akn= ak->next;
+               
+               if ((ak->cfra < start) || (ak->cfra > end))
+                       BLI_freelinkN(&keys, ak);
+               else
+                       range++;
+       }
+       if (range == 0) return;
+       
+       /* store values */
+       ob->flag &= ~OB_POSEMODE;
+       cfrao= CFRA;
+       flago= arm->flag;
+       arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES);
+       ipoflago= ob->ipoflag; 
+       ob->ipoflag |= OB_DISABLE_PATH;
+       
+       /* copy the pose */
+       poseo= ob->pose;
+       copy_pose(&posen, ob->pose, 1);
+       ob->pose= posen;
+       armature_rebuild_pose(ob, ob->data);    /* child pointers for IK */
+       
+       glEnable(GL_BLEND);
+       if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
+       
+       /* draw from first frame of range to last */
+       for (ak=keys.first, i=0; ak; ak=ak->next, i++) {
+               colfac = i/range;
+               BIF_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0f*sqrt(colfac)));
+               
+               CFRA= (int)ak->cfra;
+               
+               do_all_pose_actions(ob);
+               where_is_pose(ob);
+               draw_pose_channels(base, OB_WIRE);
+       }
+       glDisable(GL_BLEND);
+       if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+
+       free_pose_channels(posen);
+       BLI_freelistN(&keys);
+       MEM_freeN(posen);
+       
+       /* restore */
+       CFRA= cfrao;
+       ob->pose= poseo;
+       arm->flag= flago;
+       armature_rebuild_pose(ob, ob->data);
+       ob->flag |= OB_POSEMODE;
+       ob->ipoflag= ipoflago; 
 }
 
 /* object is supposed to be armature in posemode */
@@ -2122,10 +2194,13 @@ int draw_armature(Base *base, int dt)
                                                arm->flag |= ARM_POSEMODE;
                                }
                                else if(ob->flag & OB_POSEMODE) {
-                                       if (arm->ghosttype == ARM_GHOST_RANGE){
+                                       if (arm->ghosttype == ARM_GHOST_RANGE) {
                                                draw_ghost_poses_range(base);
                                        }
-                                       else {
+                                       else if (arm->ghosttype == ARM_GHOST_KEYS) {
+                                               draw_ghost_poses_keys(base);
+                                       }
+                                       else if (arm->ghosttype == ARM_GHOST_CUR) {
                                                if (arm->ghostep)
                                                        draw_ghost_poses(base);
                                        }