利用者:Koilz/2.56 code review draw armature
just explaining how it works, as good as i can.
source\blender\editors\space_view3d\drawarmature.c
int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag) { Object *ob= base->object; bArmature *arm= ob->data; int retval= 0; /* dont know what this is, guess something todo with if program is rendering */ if(v3d->flag2 & V3D_RENDER_OVERRIDE) return 1; if(dt>OB_WIRE && arm->drawtype!=ARM_LINE) { glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); glEnable(GL_COLOR_MATERIAL); glColor3ub(255,0,255); glDisable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); } if(arm->edbo) { arm->flag |= ARM_EDITMODE; draw_ebones(v3d, ar, ob, dt); arm->flag &= ~ARM_EDITMODE; } else{ /* dont know why OB_FROMDUPLI, dont know what G_PICKSEL, dont know what DRAW_SCENESET, + few other things */ if(ob->pose && ob->pose->chanbase.first) { if(!(base->flag & OB_FROMDUPLI)) { if(G.f & G_PICKSEL) { if(OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)){ if(ob==modifiers_isDeformedByArmature(OBACT)) arm->flag |= ARM_POSEMODE; } else if(ob->mode & OB_MODE_POSE) arm->flag |= ARM_POSEMODE; } else if(ob->mode & OB_MODE_POSE) { if (arm->ghosttype == ARM_GHOST_RANGE) { draw_ghost_poses_range(scene, v3d, ar, base); } else if (arm->ghosttype == ARM_GHOST_KEYS) { draw_ghost_poses_keys(scene, v3d, ar, base); } else if (arm->ghosttype == ARM_GHOST_CUR) { if (arm->ghostep) draw_ghost_poses(scene, v3d, ar, base); } if ((flag & DRAW_SCENESET)==0) { if(ob==OBACT) arm->flag |= ARM_POSEMODE; else if(OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) { if(ob==modifiers_isDeformedByArmature(OBACT)) arm->flag |= ARM_POSEMODE; } draw_pose_paths(scene, v3d, ar, ob); } } } draw_pose_bones(scene, v3d, ar, base, dt, FALSE); arm->flag &= ~ARM_POSEMODE; if(ob->mode & OB_MODE_POSE) UI_ThemeColor(TH_WIRE); } else retval= 1; } glFrontFace(GL_CCW); return retval; }
This function draws the armatures in the view 3d window. There is a function that loops through all objects then executed the right functions for the right objects. In this step, the programs looping through the armatures, and theve all got different settings.
This function divides the main problem, which mode should the armature be drawn in, pose, edit, object. It also executes the extra draw functions, ghosting and pose paths.
if(arm->edbo) {
This part, its using the arm->edbo listbase, if there are any editable bones in the armatures list base edbo, it knows its in edit mode so, thats one way of checking.
if(arm->edbo) { arm->flag |= ARM_EDITMODE; draw_ebones(v3d, ar, ob, dt); arm->flag &= ~ARM_EDITMODE; }
11010001 11010101 OR 00000100 = 11010101 11010101 AND 11111011 = 11010001
The arm->flag sets the mode you want draw the armature in, here its OR'ing the arm->flag with ARM_EDITMODE, so if any previous flags, they wont be removed. Then it executes draw_ebones(), then AND's the arm->flag with ~ARM_EDITMODE which restors it to its previous state.
else{
This part draws the armature in object or pose mode. draw_pose_bones() draws both types, object mode bones and pose mode bones (custom bones too, i assume). To draw them differently the arm->flag is used.
Some current blender logic.
An armature can only be in edit mode if it is the active object (selected one).
An armature can only be in pose mode if it is the active object, or if it being used as an armature modifier by another active object.
In any other cases, i think the armature gets drawn in object mode.
if(!(base->flag & OB_FROMDUPLI)) {
Code after this part does checks on parts of the program and sets the arm->flag draw mode to match the blender logic. It also draws the the ghosting an pose paths in the checks.
draw_pose_bones(scene, v3d, ar, base, dt, FALSE);