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:
authorJoseph Eagar <joeedh@gmail.com>2009-07-22 06:57:40 +0400
committerJoseph Eagar <joeedh@gmail.com>2009-07-22 06:57:40 +0400
commit69327f2ebd6dab06b3f75911ef7a28fd562994be (patch)
tree18b8df7d8ac4106f85cb4a907f5edc566f453b7f /source/blender/editors/armature
parenteecc3f51d4632aa028f6a4d550d43b6804db4aaa (diff)
parentd44d7e220dfbf7b0575ec93f1bb18777f4277eef (diff)
merge with trunk at r21785, and also fixed stupid ngon normals bug
Diffstat (limited to 'source/blender/editors/armature')
-rw-r--r--source/blender/editors/armature/armature_intern.h24
-rw-r--r--source/blender/editors/armature/armature_ops.c24
-rw-r--r--source/blender/editors/armature/editarmature.c14
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c8
-rw-r--r--source/blender/editors/armature/editarmature_sketch.c191
-rw-r--r--source/blender/editors/armature/poselib.c7
-rw-r--r--source/blender/editors/armature/poseobject.c650
7 files changed, 552 insertions, 366 deletions
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index d5ad63ca21b..7b3f9a020e3 100644
--- a/source/blender/editors/armature/armature_intern.h
+++ b/source/blender/editors/armature/armature_intern.h
@@ -33,28 +33,40 @@ struct wmOperatorType;
/* editarmature.c operators */
void ARMATURE_OT_bone_primitive_add(struct wmOperatorType *ot);
+
void ARMATURE_OT_bones_align(struct wmOperatorType *ot);
void ARMATURE_OT_calculate_roll(struct wmOperatorType *ot);
void ARMATURE_OT_switch_direction(struct wmOperatorType *ot);
+
void ARMATURE_OT_subdivs(struct wmOperatorType *ot);
void ARMATURE_OT_subdivide_simple(struct wmOperatorType *ot);
void ARMATURE_OT_subdivide_multi(struct wmOperatorType *ot);
+
void ARMATURE_OT_parent_set(struct wmOperatorType *ot);
void ARMATURE_OT_parent_clear(struct wmOperatorType *ot);
+
void ARMATURE_OT_select_all_toggle(struct wmOperatorType *ot);
void ARMATURE_OT_select_inverse(struct wmOperatorType *ot);
void ARMATURE_OT_select_hierarchy(struct wmOperatorType *ot);
void ARMATURE_OT_select_linked(struct wmOperatorType *ot);
+
void ARMATURE_OT_delete(struct wmOperatorType *ot);
void ARMATURE_OT_duplicate_selected(struct wmOperatorType *ot);
void ARMATURE_OT_extrude(struct wmOperatorType *ot);
void ARMATURE_OT_click_extrude(struct wmOperatorType *ot);
+/* ******************************************************* */
+/* Pose-Mode Operators */
void POSE_OT_hide(struct wmOperatorType *ot);
void POSE_OT_reveal(struct wmOperatorType *ot);
+
void POSE_OT_rot_clear(struct wmOperatorType *ot);
void POSE_OT_loc_clear(struct wmOperatorType *ot);
void POSE_OT_scale_clear(struct wmOperatorType *ot);
+
+void POSE_OT_copy(struct wmOperatorType *ot);
+void POSE_OT_paste(struct wmOperatorType *ot);
+
void POSE_OT_select_all_toggle(struct wmOperatorType *ot);
void POSE_OT_select_inverse(struct wmOperatorType *ot);
void POSE_OT_select_parent(struct wmOperatorType *ot);
@@ -62,6 +74,16 @@ void POSE_OT_select_hierarchy(struct wmOperatorType *ot);
void POSE_OT_select_linked(struct wmOperatorType *ot);
void POSE_OT_select_constraint_target(struct wmOperatorType *ot);
+void POSE_OT_groups_menu(struct wmOperatorType *ot);
+void POSE_OT_group_add(struct wmOperatorType *ot);
+void POSE_OT_group_remove(struct wmOperatorType *ot);
+void POSE_OT_group_remove(struct wmOperatorType *ot);
+void POSE_OT_group_assign(struct wmOperatorType *ot);
+void POSE_OT_group_unassign(struct wmOperatorType *ot);
+
+/* ******************************************************* */
+/* Etch-A-Ton */
+
void SKETCH_OT_gesture(struct wmOperatorType *ot);
void SKETCH_OT_delete(struct wmOperatorType *ot);
void SKETCH_OT_draw_stroke(struct wmOperatorType *ot);
@@ -70,12 +92,14 @@ void SKETCH_OT_finish_stroke(struct wmOperatorType *ot);
void SKETCH_OT_cancel_stroke(struct wmOperatorType *ot);
void SKETCH_OT_select(struct wmOperatorType *ot);
+/* ******************************************************* */
/* PoseLib */
void POSELIB_OT_pose_add(struct wmOperatorType *ot);
void POSELIB_OT_pose_remove(struct wmOperatorType *ot);
void POSELIB_OT_pose_rename(struct wmOperatorType *ot);
void POSELIB_OT_browse_interactive(struct wmOperatorType *ot);
+/* ******************************************************* */
/* editarmature.c */
struct bArmature;
struct EditBone;
diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c
index df32f452a38..bf4ec09f3fb 100644
--- a/source/blender/editors/armature/armature_ops.c
+++ b/source/blender/editors/armature/armature_ops.c
@@ -147,6 +147,9 @@ void ED_operatortypes_armature(void)
WM_operatortype_append(POSE_OT_loc_clear);
WM_operatortype_append(POSE_OT_scale_clear);
+ WM_operatortype_append(POSE_OT_copy);
+ WM_operatortype_append(POSE_OT_paste);
+
WM_operatortype_append(POSE_OT_select_all_toggle);
WM_operatortype_append(POSE_OT_select_inverse);
@@ -155,6 +158,12 @@ void ED_operatortypes_armature(void)
WM_operatortype_append(POSE_OT_select_linked);
WM_operatortype_append(POSE_OT_select_constraint_target);
+ WM_operatortype_append(POSE_OT_groups_menu);
+ WM_operatortype_append(POSE_OT_group_add);
+ WM_operatortype_append(POSE_OT_group_remove);
+ WM_operatortype_append(POSE_OT_group_assign);
+ WM_operatortype_append(POSE_OT_group_unassign);
+
/* POSELIB */
WM_operatortype_append(POSELIB_OT_browse_interactive);
@@ -225,13 +234,19 @@ void ED_keymap_armature(wmWindowManager *wm)
WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, 0, 0);
kmi= WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_boolean_set(kmi->ptr, "unselected", 1);
+ RNA_boolean_set(kmi->ptr, "unselected", 1);
WM_keymap_add_item(keymap, "POSE_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0);
/*clear pose*/
WM_keymap_add_item(keymap, "POSE_OT_rot_clear", RKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "POSE_OT_loc_clear", GKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "POSE_OT_scale_clear", SKEY, KM_PRESS, KM_ALT, 0);
+ // for now, we include hotkeys for copy/paste
+ WM_keymap_add_item(keymap, "POSE_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "POSE_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0);
+ kmi= WM_keymap_add_item(keymap, "POSE_OT_paste", VKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "flipped", 1);
+
WM_keymap_add_item(keymap, "POSE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "POSE_OT_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0);
@@ -251,6 +266,13 @@ void ED_keymap_armature(wmWindowManager *wm)
WM_keymap_add_item(keymap, "POSE_OT_select_linked", LKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "POSE_OT_constraint_add_with_targets", CKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "POSE_OT_constraints_clear", CKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
+ WM_keymap_add_item(keymap, "POSE_OT_ik_add", IKEY, KM_PRESS, /*KM_CTRL|*/KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "POSE_OT_ik_clear", IKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
+
+ WM_keymap_add_item(keymap, "POSE_OT_groups_menu", GKEY, KM_PRESS, KM_CTRL, 0);
+
// XXX this should probably be in screen instead... here for testing purposes in the meantime... - Aligorith
WM_keymap_verify_item(keymap, "ANIM_OT_insert_keyframe_menu", IKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "ANIM_OT_delete_keyframe_old", IKEY, KM_PRESS, KM_ALT, 0);
diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c
index d00f4c770d1..68d8ffbc11d 100644
--- a/source/blender/editors/armature/editarmature.c
+++ b/source/blender/editors/armature/editarmature.c
@@ -1598,10 +1598,8 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *op)
/* cancel if nothing selected */
if (CTX_DATA_COUNT(C, selected_bones) == 0)
- return OPERATOR_CANCELLED;
-
- /* if (okee("Erase selected bone(s)")==0) return; */
-
+ return OPERATOR_CANCELLED;
+
/* Select mirrored bones */
if (arm->flag & ARM_MIRROR_EDIT) {
for (curBone=arm->edbo->first; curBone; curBone=curBone->next) {
@@ -5095,9 +5093,9 @@ static void constraint_bone_name_fix(Object *ob, ListBase *conlist, char *oldnam
/* called by UI for renaming a bone */
/* warning: make sure the original bone was not renamed yet! */
/* seems messy, but thats what you get with not using pointers but channel names :) */
-void armature_bone_rename(Object *ob, char *oldnamep, char *newnamep)
+void ED_armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep)
{
- bArmature *arm= ob->data;
+ Object *ob;
char newname[MAXBONENAME];
char oldname[MAXBONENAME];
@@ -5242,7 +5240,7 @@ void armature_flip_names(Scene *scene)
if (ebone->flag & BONE_SELECTED) {
BLI_strncpy(newname, ebone->name, sizeof(newname));
bone_flip_name(newname, 1); // 1 = do strip off number extensions
- armature_bone_rename(obedit, ebone->name, newname);
+ ED_armature_bone_rename(arm, ebone->name, newname);
}
}
}
@@ -5263,7 +5261,7 @@ void armature_autoside_names(Scene *scene, short axis)
if (ebone->flag & BONE_SELECTED) {
BLI_strncpy(newname, ebone->name, sizeof(newname));
bone_autoside_name(newname, 1, axis, ebone->head[axis], ebone->tail[axis]);
- armature_bone_rename(obedit, ebone->name, newname);
+ ED_armature_bone_rename(arm, ebone->name, newname);
}
}
}
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
index 6f5692dbf4c..a1ce256a1af 100644
--- a/source/blender/editors/armature/editarmature_retarget.c
+++ b/source/blender/editors/armature/editarmature_retarget.c
@@ -2139,15 +2139,15 @@ static MemoNode * solveJoints(MemoNode *table, BArcIterator *iter, float **vec_c
MemoNode *min_node = NULL;
float *vec0 = vec_cache[previous];
float *vec1 = vec_cache[current];
- float min_weight;
- int min_next;
+ float min_weight= 0.0f;
+ int min_next= 0;
int next;
for (next = current + 1; next <= nb_positions - (joints_left - 1); next++)
{
MemoNode *next_node;
float *vec2 = vec_cache[next];
- float weight = 0;
+ float weight = 0.0f;
/* ADD WEIGHT OF PREVIOUS - CURRENT - NEXT triple */
weight = calcCostAngleLengthDistance(iter, vec_cache, edge, vec0, vec1, vec2, current, next, angle_weight, length_weight, distance_weight);
@@ -2824,7 +2824,7 @@ void BIF_retargetArmature(bContext *C)
ReebGraph *reebg;
double start_time, end_time;
double gstart_time, gend_time;
- double reeb_time, rig_time, retarget_time, total_time;
+ double reeb_time, rig_time=0.0, retarget_time=0.0, total_time;
gstart_time = start_time = PIL_check_seconds_timer();
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index af1ed3e2746..974eeb91a68 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -186,7 +186,6 @@ typedef struct SK_GestureAction {
GestureApplyFct apply;
} SK_GestureAction;
-SK_Sketch *GLOBAL_sketch = NULL;
SK_Point boneSnap;
int LAST_SNAP_POINT_VALID = 0;
float LAST_SNAP_POINT[3];
@@ -217,6 +216,8 @@ void sk_applyReverseGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
int sk_detectConvertGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
void sk_applyConvertGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
+SK_Sketch* contextSketch(const bContext *c, int create);
+SK_Sketch* viewcontextSketch(ViewContext *vc, int create);
void sk_resetOverdraw(SK_Sketch *sketch);
int sk_hasOverdraw(SK_Sketch *sketch, SK_Stroke *stk);
@@ -381,7 +382,7 @@ int BIF_nbJointsTemplate(const bContext *C)
char * BIF_nameBoneTemplate(const bContext *C)
{
ToolSettings *ts = CTX_data_tool_settings(C);
- SK_Sketch *stk = GLOBAL_sketch;
+ SK_Sketch *stk = contextSketch(C, 1);
RigGraph *rg;
int index = 0;
@@ -1592,6 +1593,7 @@ int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Strok
float p[3];
float size = 0;
+ BLI_freelistN(&sketch->depth_peels);
sketch->depth_peels.first = sketch->depth_peels.last = NULL;
peelObjectsContext(C, &sketch->depth_peels, dd->mval);
@@ -3023,9 +3025,10 @@ int BDR_drawSketchNames(ViewContext *vc)
{
if (ValidSketchViewContext(vc))
{
- if (GLOBAL_sketch != NULL)
+ SK_Sketch *sketch = viewcontextSketch(vc, 0);
+ if (sketch)
{
- sk_drawSketch(vc->scene, vc->v3d, GLOBAL_sketch, 1);
+ sk_drawSketch(vc->scene, vc->v3d, sketch, 1);
return 1;
}
}
@@ -3037,18 +3040,20 @@ void BDR_drawSketch(const bContext *C)
{
if (ED_operator_sketch_mode(C))
{
- if (GLOBAL_sketch != NULL)
+ SK_Sketch *sketch = contextSketch(C, 0);
+ if (sketch)
{
- sk_drawSketch(CTX_data_scene(C), CTX_wm_view3d(C), GLOBAL_sketch, 0);
+ sk_drawSketch(CTX_data_scene(C), CTX_wm_view3d(C), sketch, 0);
}
}
}
static int sketch_delete(bContext *C, wmOperator *op, wmEvent *event)
{
- if (GLOBAL_sketch != NULL)
+ SK_Sketch *sketch = contextSketch(C, 0);
+ if (sketch)
{
- sk_deleteSelectedStrokes(GLOBAL_sketch);
+ sk_deleteSelectedStrokes(sketch);
// allqueue(REDRAWVIEW3D, 0);
}
return OPERATOR_FINISHED;
@@ -3056,9 +3061,10 @@ static int sketch_delete(bContext *C, wmOperator *op, wmEvent *event)
void BIF_sk_selectStroke(bContext *C, short mval[2], short extend)
{
- if (GLOBAL_sketch != NULL)
+ SK_Sketch *sketch = contextSketch(C, 0);
+ if (sketch)
{
- sk_selectStroke(C, GLOBAL_sketch, mval, extend);
+ sk_selectStroke(C, sketch, mval, extend);
}
}
@@ -3066,9 +3072,10 @@ void BIF_convertSketch(bContext *C)
{
if (ED_operator_sketch_full_mode(C))
{
- if (GLOBAL_sketch != NULL)
+ SK_Sketch *sketch = contextSketch(C, 0);
+ if (sketch)
{
- sk_convert(C, GLOBAL_sketch);
+ sk_convert(C, sketch);
// BIF_undo_push("Convert Sketch");
// allqueue(REDRAWVIEW3D, 0);
// allqueue(REDRAWBUTSEDIT, 0);
@@ -3080,42 +3087,86 @@ void BIF_deleteSketch(bContext *C)
{
if (ED_operator_sketch_full_mode(C))
{
- if (GLOBAL_sketch != NULL)
+ SK_Sketch *sketch = contextSketch(C, 0);
+ if (sketch)
{
- sk_deleteSelectedStrokes(GLOBAL_sketch);
+ sk_deleteSelectedStrokes(sketch);
// BIF_undo_push("Convert Sketch");
// allqueue(REDRAWVIEW3D, 0);
}
}
}
-//void BIF_selectAllSketch(bContext *C, int mode)
-//{
-// if (BIF_validSketchMode(C))
-// {
-// if (GLOBAL_sketch != NULL)
-// {
-// sk_selectAllSketch(GLOBAL_sketch, mode);
-//// XXX
-//// allqueue(REDRAWVIEW3D, 0);
-// }
-// }
-//}
+#if 0
+void BIF_selectAllSketch(bContext *C, int mode)
+{
+ if (BIF_validSketchMode(C))
+ {
+ SK_Sketch *sketch = contextSketch(C, 0);
+ if (sketch)
+ {
+ sk_selectAllSketch(sketch, mode);
+// XXX
+// allqueue(REDRAWVIEW3D, 0);
+ }
+ }
+}
+#endif
-void BIF_freeSketch(bContext *C)
+void ED_freeSketch(SK_Sketch *sketch)
{
- if (GLOBAL_sketch != NULL)
+ sk_freeSketch(sketch);
+}
+
+SK_Sketch* ED_createSketch()
+{
+ return sk_createSketch();
+}
+
+SK_Sketch* contextSketch(const bContext *C, int create)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ SK_Sketch *sketch = NULL;
+
+ if (obedit && obedit->type == OB_ARMATURE)
{
- sk_freeSketch(GLOBAL_sketch);
- GLOBAL_sketch = NULL;
+ bArmature *arm = obedit->data;
+
+ if (arm->sketch == NULL && create)
+ {
+ arm->sketch = sk_createSketch();
+ }
+ sketch = arm->sketch;
}
+
+ return sketch;
+}
+
+SK_Sketch* viewcontextSketch(ViewContext *vc, int create)
+{
+ Object *obedit = vc->obedit;
+ SK_Sketch *sketch = NULL;
+
+ if (obedit && obedit->type == OB_ARMATURE)
+ {
+ bArmature *arm = obedit->data;
+
+ if (arm->sketch == NULL && create)
+ {
+ arm->sketch = sk_createSketch();
+ }
+ sketch = arm->sketch;
+ }
+
+ return sketch;
}
static int sketch_cancel(bContext *C, wmOperator *op, wmEvent *event)
{
- if (GLOBAL_sketch != NULL)
+ SK_Sketch *sketch = contextSketch(C, 0);
+ if (sketch != NULL)
{
- sk_cancelStroke(GLOBAL_sketch);
+ sk_cancelStroke(sketch);
ED_area_tag_redraw(CTX_wm_area(C));
return OPERATOR_FINISHED;
}
@@ -3124,9 +3175,10 @@ static int sketch_cancel(bContext *C, wmOperator *op, wmEvent *event)
static int sketch_finish(bContext *C, wmOperator *op, wmEvent *event)
{
- if (GLOBAL_sketch != NULL)
+ SK_Sketch *sketch = contextSketch(C, 0);
+ if (sketch != NULL)
{
- if (sk_finish_stroke(C, GLOBAL_sketch))
+ if (sk_finish_stroke(C, sketch))
{
ED_area_tag_redraw(CTX_wm_area(C));
return OPERATOR_FINISHED;
@@ -3137,10 +3189,11 @@ static int sketch_finish(bContext *C, wmOperator *op, wmEvent *event)
static int sketch_select(bContext *C, wmOperator *op, wmEvent *event)
{
- if (GLOBAL_sketch != NULL)
+ SK_Sketch *sketch = contextSketch(C, 0);
+ if (sketch)
{
short extend = 0;
- sk_selectStroke(C, GLOBAL_sketch, event->mval, extend);
+ sk_selectStroke(C, sketch, event->mval, extend);
ED_area_tag_redraw(CTX_wm_area(C));
}
@@ -3149,7 +3202,8 @@ static int sketch_select(bContext *C, wmOperator *op, wmEvent *event)
static int sketch_draw_stroke_cancel(bContext *C, wmOperator *op)
{
- sk_cancelStroke(GLOBAL_sketch);
+ SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
+ sk_cancelStroke(sketch);
MEM_freeN(op->customdata);
return OPERATOR_CANCELLED;
}
@@ -3158,18 +3212,14 @@ static int sketch_draw_stroke(bContext *C, wmOperator *op, wmEvent *event)
{
short snap = RNA_boolean_get(op->ptr, "snap");
SK_DrawData *dd;
-
- if (GLOBAL_sketch == NULL)
- {
- GLOBAL_sketch = sk_createSketch();
- }
+ SK_Sketch *sketch = contextSketch(C, 1);
op->customdata = dd = MEM_callocN(sizeof("SK_DrawData"), "SketchDrawData");
sk_initDrawData(dd, event->mval);
- sk_start_draw_stroke(GLOBAL_sketch);
+ sk_start_draw_stroke(sketch);
- sk_draw_stroke(C, GLOBAL_sketch, GLOBAL_sketch->active_stroke, dd, snap);
+ sk_draw_stroke(C, sketch, sketch->active_stroke, dd, snap);
WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
@@ -3178,7 +3228,8 @@ static int sketch_draw_stroke(bContext *C, wmOperator *op, wmEvent *event)
static int sketch_draw_gesture_cancel(bContext *C, wmOperator *op)
{
- sk_cancelStroke(GLOBAL_sketch);
+ SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
+ sk_cancelStroke(sketch);
MEM_freeN(op->customdata);
return OPERATOR_CANCELLED;
}
@@ -3187,17 +3238,14 @@ static int sketch_draw_gesture(bContext *C, wmOperator *op, wmEvent *event)
{
short snap = RNA_boolean_get(op->ptr, "snap");
SK_DrawData *dd;
-
- if (GLOBAL_sketch == NULL)
- {
- GLOBAL_sketch = sk_createSketch();
- }
+ SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
+ sk_cancelStroke(sketch);
op->customdata = dd = MEM_callocN(sizeof("SK_DrawData"), "SketchDrawData");
sk_initDrawData(dd, event->mval);
- sk_start_draw_gesture(GLOBAL_sketch);
- sk_draw_stroke(C, GLOBAL_sketch, GLOBAL_sketch->gesture, dd, snap);
+ sk_start_draw_gesture(sketch);
+ sk_draw_stroke(C, sketch, sketch->gesture, dd, snap);
WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
@@ -3208,6 +3256,7 @@ static int sketch_draw_modal(bContext *C, wmOperator *op, wmEvent *event, short
{
short snap = RNA_boolean_get(op->ptr, "snap");
SK_DrawData *dd = op->customdata;
+ SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
int retval = OPERATOR_RUNNING_MODAL;
switch (event->type)
@@ -3220,7 +3269,7 @@ static int sketch_draw_modal(bContext *C, wmOperator *op, wmEvent *event, short
case MOUSEMOVE:
dd->mval[0] = event->mval[0];
dd->mval[1] = event->mval[1];
- sk_draw_stroke(C, GLOBAL_sketch, stk, dd, snap);
+ sk_draw_stroke(C, sketch, stk, dd, snap);
ED_area_tag_redraw(CTX_wm_area(C));
break;
case ESCKEY:
@@ -3235,7 +3284,7 @@ static int sketch_draw_modal(bContext *C, wmOperator *op, wmEvent *event, short
{
sk_endContinuousStroke(stk);
sk_filterLastContinuousStroke(stk);
- sk_updateNextPoint(GLOBAL_sketch, stk);
+ sk_updateNextPoint(sketch, stk);
ED_area_tag_redraw(CTX_wm_area(C));
MEM_freeN(op->customdata);
retval = OPERATOR_FINISHED;
@@ -3248,11 +3297,11 @@ static int sketch_draw_modal(bContext *C, wmOperator *op, wmEvent *event, short
if (stk->nb_points > 1)
{
/* apply gesture here */
- sk_applyGesture(C, GLOBAL_sketch);
+ sk_applyGesture(C, sketch);
}
sk_freeStroke(stk);
- GLOBAL_sketch->gesture = NULL;
+ sketch->gesture = NULL;
ED_area_tag_redraw(CTX_wm_area(C));
MEM_freeN(op->customdata);
@@ -3267,21 +3316,23 @@ static int sketch_draw_modal(bContext *C, wmOperator *op, wmEvent *event, short
static int sketch_draw_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
{
- return sketch_draw_modal(C, op, event, 0, GLOBAL_sketch->active_stroke);
+ SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
+ return sketch_draw_modal(C, op, event, 0, sketch->active_stroke);
}
static int sketch_draw_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
{
- return sketch_draw_modal(C, op, event, 1, GLOBAL_sketch->gesture);
+ SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
+ return sketch_draw_modal(C, op, event, 1, sketch->gesture);
}
static int sketch_draw_preview(bContext *C, wmOperator *op, wmEvent *event)
{
short snap = RNA_boolean_get(op->ptr, "snap");
+ SK_Sketch *sketch = contextSketch(C, 0);
- if (GLOBAL_sketch != NULL)
+ if (sketch)
{
- SK_Sketch *sketch = GLOBAL_sketch;
SK_DrawData dd;
sk_initDrawData(&dd, event->mval);
@@ -3296,14 +3347,12 @@ static int sketch_draw_preview(bContext *C, wmOperator *op, wmEvent *event)
int ED_operator_sketch_mode_active_stroke(bContext *C)
{
- Object *obedit = CTX_data_edit_object(C);
ToolSettings *ts = CTX_data_tool_settings(C);
+ SK_Sketch *sketch = contextSketch(C, 0);
- if (obedit &&
- obedit->type == OB_ARMATURE &&
- ts->bone_sketching & BONE_SKETCHING &&
- GLOBAL_sketch != NULL &&
- GLOBAL_sketch->active_stroke != NULL)
+ if (ts->bone_sketching & BONE_SKETCHING &&
+ sketch != NULL &&
+ sketch->active_stroke != NULL)
{
return 1;
}
@@ -3315,15 +3364,13 @@ int ED_operator_sketch_mode_active_stroke(bContext *C)
int ED_operator_sketch_mode_gesture(bContext *C)
{
- Object *obedit = CTX_data_edit_object(C);
ToolSettings *ts = CTX_data_tool_settings(C);
+ SK_Sketch *sketch = contextSketch(C, 0);
- if (obedit &&
- obedit->type == OB_ARMATURE &&
- ts->bone_sketching & BONE_SKETCHING &&
+ if (ts->bone_sketching & BONE_SKETCHING &&
(ts->bone_sketching & BONE_SKETCHING_QUICK) == 0 &&
- GLOBAL_sketch != NULL &&
- GLOBAL_sketch->active_stroke == NULL)
+ sketch != NULL &&
+ sketch->active_stroke == NULL)
{
return 1;
}
diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c
index 93611a30bd8..ef2e5188487 100644
--- a/source/blender/editors/armature/poselib.c
+++ b/source/blender/editors/armature/poselib.c
@@ -37,6 +37,7 @@
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
+#include "BLI_dlrbTree.h"
#include "DNA_listBase.h"
#include "DNA_anim_types.h"
@@ -216,7 +217,7 @@ bAction *poselib_validate (Object *ob)
// TODO: operatorfy me!
void poselib_validate_act (bAction *act)
{
- ListBase keys = {NULL, NULL};
+ DLRBT_Tree keys = {NULL, NULL};
ActKeyColumn *ak;
TimeMarker *marker, *markern;
@@ -227,7 +228,9 @@ void poselib_validate_act (bAction *act)
}
/* determine which frames have keys */
+ BLI_dlrbTree_init(&keys);
action_to_keylist(NULL, act, &keys, NULL);
+ BLI_dlrbTree_linkedlist_sync(&keys);
/* for each key, make sure there is a correspnding pose */
for (ak= keys.first; ak; ak= ak->next) {
@@ -267,7 +270,7 @@ void poselib_validate_act (bAction *act)
}
/* free temp memory */
- BLI_freelistN(&keys);
+ BLI_freelistN((ListBase *)&keys);
BIF_undo_push("PoseLib Validate Action");
}
diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c
index 2913d1d13d9..9814a056b70 100644
--- a/source/blender/editors/armature/poseobject.c
+++ b/source/blender/editors/armature/poseobject.c
@@ -63,6 +63,7 @@
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_utildefines.h"
+#include "BKE_report.h"
#include "BIF_gl.h"
@@ -81,17 +82,17 @@
#include "ED_transform.h" /* for autokey TFM_TRANSLATION, etc */
#include "ED_view3d.h"
+#include "UI_interface.h"
+
#include "armature_intern.h"
/* ************* XXX *************** */
static int movetolayer_short_buts() {return 1;}
-static int okee() {return 0;}
static int pupmenu() {return 0;}
static void waitcursor() {};
static void error() {};
static void BIF_undo_push() {}
static void countall() {}
-static void add_constraint() {}
static void autokeyframe_pose_cb_func() {}
/* ************* XXX *************** */
@@ -399,7 +400,7 @@ void pose_clear_paths(Object *ob)
}
-
+// XXX this function is to be removed when the other stuff is recoded
void pose_select_constraint_target(Scene *scene)
{
Object *obedit= scene->obedit; // XXX context
@@ -587,92 +588,6 @@ void POSE_OT_select_hierarchy(wmOperatorType *ot)
}
-void pose_add_IK(Scene *scene)
-{
- Object *obedit= scene->obedit; // XXX context
- Object *ob= OBACT;
-
- /* paranoia checks */
- if(!ob && !ob->pose) return;
- if(ob==obedit || (ob->flag & OB_POSEMODE)==0) return;
-
- add_constraint(1); /* 1 means only IK */
-}
-
-/* context: all selected channels */
-void pose_clear_IK(Scene *scene)
-{
- Object *obedit= scene->obedit; // XXX context
- Object *ob= OBACT;
- bArmature *arm= ob->data;
- bPoseChannel *pchan;
- bConstraint *con;
- bConstraint *next;
-
- /* paranoia checks */
- if(!ob && !ob->pose) return;
- if(ob==obedit || (ob->flag & OB_POSEMODE)==0) return;
-
- if(pose_has_protected_selected(ob, 0, 1))
- return;
-
- if(okee("Remove IK constraint(s)")==0) return;
-
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if(arm->layer & pchan->bone->layer) {
- if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
-
- for(con= pchan->constraints.first; con; con= next) {
- next= con->next;
- if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
- BLI_remlink(&pchan->constraints, con);
- free_constraint_data(con);
- MEM_freeN(con);
- }
- }
- pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_TARGET);
- }
- }
- }
-
- DAG_object_flush_update(scene, ob, OB_RECALC_DATA); // and all its relations
-
- BIF_undo_push("Remove IK constraint(s)");
-}
-
-void pose_clear_constraints(Scene *scene)
-{
- Object *obedit= scene->obedit; // XXX context
- Object *ob= OBACT;
- bArmature *arm= ob->data;
- bPoseChannel *pchan;
-
- /* paranoia checks */
- if(!ob && !ob->pose) return;
- if(ob==obedit || (ob->flag & OB_POSEMODE)==0) return;
-
- if(pose_has_protected_selected(ob, 0, 1))
- return;
-
- if(okee("Remove Constraints")==0) return;
-
- /* find active */
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if(arm->layer & pchan->bone->layer) {
- if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
- free_constraints(&pchan->constraints);
- pchan->constflag= 0;
- }
- }
- }
-
- DAG_object_flush_update(scene, ob, OB_RECALC_DATA); // and all its relations
-
- BIF_undo_push("Remove Constraint(s)");
-
-}
-
-
void pose_copy_menu(Scene *scene)
{
Object *obedit= scene->obedit; // XXX context
@@ -865,81 +780,132 @@ void pose_copy_menu(Scene *scene)
/* ******************** copy/paste pose ********************** */
-static bPose *g_posebuf=NULL;
+/* Global copy/paste buffer for pose - cleared on start/end session + before every copy operation */
+static bPose *g_posebuf = NULL;
void free_posebuf(void)
{
if (g_posebuf) {
- // was copied without constraints
- BLI_freelistN (&g_posebuf->chanbase);
- MEM_freeN (g_posebuf);
+ /* was copied without constraints */
+ BLI_freelistN(&g_posebuf->chanbase);
+ MEM_freeN(g_posebuf);
}
+
g_posebuf=NULL;
}
-void copy_posebuf (Scene *scene)
-{
- Object *ob= OBACT;
+/* ---- */
- if (!ob || !ob->pose){
- error ("No Pose");
- return;
+static int pose_copy_exec (bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_active_object(C);
+
+ /* sanity checking */
+ if ELEM(NULL, ob, ob->pose) {
+ BKE_report(op->reports, RPT_ERROR, "No Pose to Copy");
+ return OPERATOR_CANCELLED;
}
+ /* free existing pose buffer */
free_posebuf();
- set_pose_keys(ob); // sets chan->flag to POSE_KEY if bone selected
+ /* sets chan->flag to POSE_KEY if bone selected, then copy those bones to the buffer */
+ set_pose_keys(ob);
copy_pose(&g_posebuf, ob->pose, 0);
+
+
+ return OPERATOR_FINISHED;
+}
+void POSE_OT_copy (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Copy Pose";
+ ot->idname= "POSE_OT_copy";
+ ot->description= "Copies the current pose of the selected bones to copy/paste buffer.";
+
+ /* api callbacks */
+ ot->exec= pose_copy_exec;
+ ot->poll= ED_operator_posemode;
+
+ /* flag */
+ ot->flag= OPTYPE_REGISTER;
}
-void paste_posebuf (Scene *scene, int flip)
+/* ---- */
+
+static int pose_paste_exec (bContext *C, wmOperator *op)
{
- Object *ob= OBACT;
+ Scene *scene= CTX_data_scene(C);
+ Object *ob= CTX_data_active_object(C);
bPoseChannel *chan, *pchan;
- float eul[4];
char name[32];
+ int flip= RNA_boolean_get(op->ptr, "flipped");
- if (!ob || !ob->pose)
- return;
+ /* sanity checks */
+ if ELEM(NULL, ob, ob->pose)
+ return OPERATOR_CANCELLED;
- if (!g_posebuf){
- error ("Copy buffer is empty");
- return;
+ if (g_posebuf == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Copy buffer is empty");
+ return OPERATOR_CANCELLED;
}
- /*
- // disabled until protected bones in proxies follow the rules everywhere else!
- if(pose_has_protected_selected(ob, 1, 1))
- return;
- */
-
- /* Safely merge all of the channels in this pose into
- any existing pose */
- for (chan=g_posebuf->chanbase.first; chan; chan=chan->next) {
+ /* Safely merge all of the channels in the buffer pose into any existing pose */
+ for (chan= g_posebuf->chanbase.first; chan; chan=chan->next) {
if (chan->flag & POSE_KEY) {
+ /* get the name - if flipping, we must flip this first */
BLI_strncpy(name, chan->name, sizeof(name));
if (flip)
- bone_flip_name (name, 0); // 0 = don't strip off number extensions
+ bone_flip_name(name, 0); /* 0 = don't strip off number extensions */
/* only copy when channel exists, poses are not meant to add random channels to anymore */
pchan= get_pose_channel(ob->pose, name);
if (pchan) {
- /* only loc rot size */
- /* only copies transform info for the pose */
+ /* only loc rot size
+ * - only copies transform info for the pose
+ */
VECCOPY(pchan->loc, chan->loc);
VECCOPY(pchan->size, chan->size);
- QUATCOPY(pchan->quat, chan->quat);
pchan->flag= chan->flag;
+ /* check if rotation modes are compatible (i.e. do they need any conversions) */
+ if (pchan->rotmode == chan->rotmode) {
+ /* copy the type of rotation in use */
+ if (pchan->rotmode) {
+ VECCOPY(pchan->eul, chan->eul);
+ }
+ else {
+ QUATCOPY(pchan->quat, chan->quat);
+ }
+ }
+ else if (pchan->rotmode) {
+ /* quat to euler */
+ QuatToEul(chan->quat, pchan->eul);
+ }
+ else {
+ /* euler to quat */
+ EulToQuat(chan->eul, pchan->quat);
+ }
+
+ /* paste flipped pose? */
if (flip) {
pchan->loc[0]*= -1;
- QuatToEul(pchan->quat, eul);
- eul[1]*= -1;
- eul[2]*= -1;
- EulToQuat(eul, pchan->quat);
+ /* has to be done as eulers... */
+ if (pchan->rotmode) {
+ pchan->eul[1] *= -1;
+ pchan->eul[2] *= -1;
+ }
+ else {
+ float eul[3];
+
+ QuatToEul(pchan->quat, eul);
+ eul[1]*= -1;
+ eul[2]*= -1;
+ EulToQuat(eul, pchan->quat);
+ }
}
#if 0 // XXX old animation system
@@ -947,6 +913,7 @@ void paste_posebuf (Scene *scene, int flip)
ID *id= &ob->id;
/* Set keys on pose */
+ // TODO: make these use keyingsets....
if (chan->flag & POSE_ROT) {
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, 0);
insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, 0);
@@ -989,8 +956,29 @@ void paste_posebuf (Scene *scene, int flip)
where_is_pose(scene, ob);
ob->recalc= 0;
}
+
+ /* notifiers for updates */
+ WM_event_add_notifier(C, NC_OBJECT|ND_POSE|ND_TRANSFORM, ob);
- BIF_undo_push("Paste Action Pose");
+ return OPERATOR_FINISHED;
+}
+
+void POSE_OT_paste (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Paste Pose";
+ ot->idname= "POSE_OT_paste";
+ ot->description= "Pastes the stored pose on to the current pose.";
+
+ /* api callbacks */
+ ot->exec= pose_paste_exec;
+ ot->poll= ED_operator_posemode;
+
+ /* flag */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_boolean(ot->srna, "flipped", 0, "Flipped on X-Axis", "");
}
/* ********************************************** */
@@ -1020,216 +1008,320 @@ void pose_adds_vgroups(Scene *scene, Object *meshobj, int heatweights)
/* ********************************************** */
-/* adds a new pose-group */
-void pose_add_posegroup (Scene *scene)
+
+static int pose_group_add_exec (bContext *C, wmOperator *op)
{
- Object *ob= OBACT;
- bPose *pose= (ob) ? ob->pose : NULL;
- bActionGroup *grp;
+ ScrArea *sa= CTX_wm_area(C);
+ Object *ob;
- if (ELEM(NULL, ob, ob->pose))
- return;
+ /* 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)
+ ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ else
+ ob= CTX_data_active_object(C);
+
+ /* only continue if there's an object */
+ if (ob == NULL)
+ return OPERATOR_CANCELLED;
+
+ /* for now, just call the API function for this */
+ pose_add_group(ob);
- grp= MEM_callocN(sizeof(bActionGroup), "PoseGroup");
- strcpy(grp->name, "Group");
- BLI_addtail(&pose->agroups, grp);
- BLI_uniquename(&pose->agroups, grp, "Group", '.', offsetof(bActionGroup, name), 32);
+ /* notifiers for updates */
+ WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
- pose->active_group= BLI_countlist(&pose->agroups);
+ return OPERATOR_FINISHED;
+}
+
+void POSE_OT_group_add (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Add Bone Group";
+ ot->idname= "POSE_OT_group_add";
+ ot->description= "Add a new bone group.";
- BIF_undo_push("Add Bone Group");
+ /* api callbacks */
+ ot->exec= pose_group_add_exec;
+ ot->poll= ED_operator_posemode;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
-/* Remove the active bone-group */
-void pose_remove_posegroup (Scene *scene)
+
+static int pose_group_remove_exec (bContext *C, wmOperator *op)
{
- Object *ob= OBACT;
- bPose *pose= (ob) ? ob->pose : NULL;
- bActionGroup *grp = NULL;
- bPoseChannel *pchan;
+ ScrArea *sa= CTX_wm_area(C);
+ Object *ob;
- /* sanity checks */
- if (ELEM(NULL, ob, pose))
- return;
- if (pose->active_group <= 0)
- return;
+ /* 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)
+ ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ else
+ ob= CTX_data_active_object(C);
- /* get group to remove */
- grp= BLI_findlink(&pose->agroups, pose->active_group-1);
- if (grp) {
- /* adjust group references (the trouble of using indices!):
- * - firstly, make sure nothing references it
- * - also, make sure that those after this item get corrected
- */
- for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
- if (pchan->agrp_index == pose->active_group)
- pchan->agrp_index= 0;
- else if (pchan->agrp_index > pose->active_group)
- pchan->agrp_index--;
- }
-
- /* now, remove it from the pose */
- BLI_freelinkN(&pose->agroups, grp);
- pose->active_group= 0;
-
- BIF_undo_push("Remove Bone Group");
- }
+ /* only continue if there's an object */
+ if (ob == NULL)
+ return OPERATOR_CANCELLED;
+ /* for now, just call the API function for this */
+ pose_remove_group(ob);
+
+ /* notifiers for updates */
+ WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
+
+ return OPERATOR_FINISHED;
}
-char *build_posegroups_menustr (bPose *pose, short for_pupmenu)
+void POSE_OT_group_remove (wmOperatorType *ot)
{
- DynStr *pupds= BLI_dynstr_new();
+ /* identifiers */
+ ot->name= "Remove Bone Group";
+ ot->idname= "POSE_OT_group_remove";
+ ot->description= "Removes the active bone group.";
+
+ /* api callbacks */
+ ot->exec= pose_group_remove_exec;
+ ot->poll= ED_operator_posemode;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/* ------------ */
+
+/* invoke callback which presents a list of bone-groups for the user to choose from */
+static int pose_groups_menu_invoke (bContext *C, wmOperator *op, wmEvent *evt)
+{
+ ScrArea *sa= CTX_wm_area(C);
+ Object *ob;
+ bPose *pose;
+
+ uiPopupMenu *pup;
+ uiLayout *layout;
bActionGroup *grp;
- char *str;
- char buf[16];
int i;
- /* add title first (and the "none" entry) */
- BLI_dynstr_append(pupds, "Bone Group%t|");
- if (for_pupmenu)
- BLI_dynstr_append(pupds, "Add New%x0|");
+ /* 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)
+ ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
else
- BLI_dynstr_append(pupds, "BG: [None]%x0|");
+ ob= CTX_data_active_object(C);
+
+ /* only continue if there's an object, and a pose there too */
+ if (ELEM(NULL, ob, ob->pose))
+ return OPERATOR_CANCELLED;
+ pose= ob->pose;
- /* loop through groups, adding them */
- for (grp= pose->agroups.first, i=1; grp; grp=grp->next, i++) {
- if (for_pupmenu == 0)
- BLI_dynstr_append(pupds, "BG: ");
- BLI_dynstr_append(pupds, grp->name);
+ /* if there's no active group (or active is invalid), create a new menu to find it */
+ if (pose->active_group <= 0) {
+ /* create a new menu, and start populating it with group names */
+ pup= uiPupMenuBegin(C, op->type->name, 0);
+ layout= uiPupMenuLayout(pup);
- sprintf(buf, "%%x%d", i);
- BLI_dynstr_append(pupds, buf);
+ /* special entry - allow to create new group, then use that
+ * (not to be used for removing though)
+ */
+ if (strstr(op->idname, "assign")) {
+ uiItemIntO(layout, "New Group", 0, op->idname, "type", 0);
+ uiItemS(layout);
+ }
- if (grp->next)
- BLI_dynstr_append(pupds, "|");
+ /* add entries for each group */
+ for (grp= pose->agroups.first, i=1; grp; grp=grp->next, i++)
+ uiItemIntO(layout, grp->name, 0, op->idname, "type", i);
+
+ /* finish building the menu, and process it (should result in calling self again) */
+ uiPupMenuEnd(C, pup);
+
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ /* just use the active group index, and call the exec callback for the calling operator */
+ RNA_int_set(op->ptr, "type", pose->active_group);
+ return op->type->exec(C, op);
}
-
- /* convert to normal MEM_malloc'd string */
- str= BLI_dynstr_get_cstring(pupds);
- BLI_dynstr_free(pupds);
-
- return str;
}
/* Assign selected pchans to the bone group that the user selects */
-void pose_assign_to_posegroup (Scene *scene, short active)
+static int pose_group_assign_exec (bContext *C, wmOperator *op)
{
- Object *ob= OBACT;
- bArmature *arm= (ob) ? ob->data : NULL;
- bPose *pose= (ob) ? ob->pose : NULL;
+ ScrArea *sa= CTX_wm_area(C);
+ Object *ob;
+ bArmature *arm;
+ bPose *pose;
bPoseChannel *pchan;
- char *menustr;
- int nr;
short done= 0;
- /* sanity checks */
- if (ELEM3(NULL, ob, pose, arm))
- return;
-
- /* get group to affect */
- if ((active==0) || (pose->active_group <= 0)) {
- menustr= build_posegroups_menustr(pose, 1);
- nr= 0; // XXX pupmenu_col(menustr, 20);
- MEM_freeN(menustr);
-
- if (nr < 0)
- return;
- else if (nr == 0) {
- /* add new - note: this does an undo push and sets active group */
- pose_add_posegroup(scene);
- }
- else
- pose->active_group= nr;
- }
+ /* 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)
+ ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ else
+ ob= CTX_data_active_object(C);
+
+ /* only continue if there's an object, and a pose there too */
+ if (ELEM(NULL, ob, ob->pose))
+ return OPERATOR_CANCELLED;
+ arm= ob->data;
+ pose= ob->pose;
+
+ /* set the active group number to the one from operator props
+ * - if 0 after this, make a new group...
+ */
+ pose->active_group= RNA_int_get(op->ptr, "type");
+ if (pose->active_group == 0)
+ pose_add_group(ob);
/* add selected bones to group then */
+ // NOTE: unfortunately, we cannot use the context-iterators here, since they might not be defined...
+ // CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans)
for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
- if ((pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) {
- pchan->agrp_index= pose->active_group;
- done= 1;
+ /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
+ // NOTE: sync this view3d_context() in space_view3d.c
+ if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) {
+ if (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) {
+ pchan->agrp_index= pose->active_group;
+ done= 1;
+ }
}
}
+ /* notifiers for updates */
+ WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
+
+ /* report done status */
if (done)
- BIF_undo_push("Add Bones To Group");
-
+ return OPERATOR_FINISHED;
+ else
+ return OPERATOR_CANCELLED;
}
-/* Remove selected pchans from their bone groups */
-void pose_remove_from_posegroups (Scene *scene)
+void POSE_OT_group_assign (wmOperatorType *ot)
{
- Object *ob= OBACT;
- bArmature *arm= (ob) ? ob->data : NULL;
- bPose *pose= (ob) ? ob->pose : NULL;
+ /* identifiers */
+ ot->name= "Add Selected to Bone Group";
+ ot->idname= "POSE_OT_group_assign";
+ ot->description= "Add selected bones to the chosen bone group.";
+
+ /* api callbacks */
+ ot->invoke= pose_groups_menu_invoke;
+ ot->exec= pose_group_assign_exec;
+ ot->poll= ED_operator_posemode;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_int(ot->srna, "type", 0, 0, 10, "Bone Group Index", "", 0, INT_MAX);
+}
+
+
+static int pose_group_unassign_exec (bContext *C, wmOperator *op)
+{
+ ScrArea *sa= CTX_wm_area(C);
+ Object *ob;
+ bArmature *arm;
+ bPose *pose;
bPoseChannel *pchan;
short done= 0;
- /* sanity checks */
- if (ELEM3(NULL, ob, pose, arm))
- return;
+ /* 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)
+ ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ else
+ ob= CTX_data_active_object(C);
+
+ /* only continue if there's an object, and a pose there too */
+ if (ELEM(NULL, ob, ob->pose))
+ return OPERATOR_CANCELLED;
+ pose= ob->pose;
+ arm= ob->data;
- /* remove selected bones from their groups */
+ /* add selected bones to ungroup then */
+ // NOTE: unfortunately, we cannot use the context-iterators here, since they might not be defined...
+ // CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans)
for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
- if ((pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) {
- if (pchan->agrp_index) {
- pchan->agrp_index= 0;
- done= 1;
+ /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
+ // NOTE: sync this view3d_context() in space_view3d.c
+ if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) {
+ if (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) {
+ if (pchan->agrp_index) {
+ pchan->agrp_index= 0;
+ done= 1;
+ }
}
}
}
+ /* notifiers for updates */
+ WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
+
+ /* report done status */
if (done)
- BIF_undo_push("Remove Bones From Groups");
-
+ return OPERATOR_FINISHED;
+ else
+ return OPERATOR_CANCELLED;
}
-/* Ctrl-G in 3D-View while in PoseMode */
-void pgroup_operation_with_menu (Scene *scene)
+void POSE_OT_group_unassign (wmOperatorType *ot)
{
- Object *ob= OBACT;
- bArmature *arm= (ob) ? ob->data : NULL;
- bPose *pose= (ob) ? ob->pose : NULL;
- bPoseChannel *pchan= NULL;
- int mode;
+ /* identifiers */
+ ot->name= "Remove Selected from Bone Groups";
+ ot->idname= "POSE_OT_group_unassign";
+ ot->description= "Add selected bones from all bone groups";
- /* sanity checks */
- if (ELEM3(NULL, ob, pose, arm))
- return;
+ /* api callbacks */
+ ot->exec= pose_group_unassign_exec;
+ ot->poll= ED_operator_posemode;
- /* check that something is selected */
- for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
- if ((pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer))
- break;
- }
- if (pchan == NULL)
- return;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/* ----------------- */
+
+static int pose_groupOps_menu_invoke (bContext *C, wmOperator *op, wmEvent *evt)
+{
+ Object *ob= CTX_data_active_object(C);
+ uiPopupMenu *pup= uiPupMenuBegin(C, op->type->name, 0);
+ uiLayout *layout= uiPupMenuLayout(pup);
+
+ /* sanity check - must have object with pose */
+ if ELEM(NULL, ob, ob->pose)
+ return OPERATOR_CANCELLED;
/* get mode of action */
- if (pchan)
- mode= pupmenu("Bone Groups%t|Add Selected to Active Group%x1|Add Selected to Group%x2|%|Remove Selected From Groups%x3|Remove Active Group%x4");
- else
- mode= pupmenu("Bone Groups%t|Add New Group%x5|Remove Active Group%x4");
+ if (CTX_DATA_COUNT(C, selected_pchans)) {
+ /* if selected bone(s), include options to add/remove to active group */
+ uiItemO(layout, "Add Selected to Active Group", 0, "POSE_OT_group_assign");
- /* handle mode */
- switch (mode) {
- case 1:
- pose_assign_to_posegroup(scene, 1);
- break;
- case 2:
- pose_assign_to_posegroup(scene, 0);
- break;
- case 5:
- pose_add_posegroup(scene);
- break;
- case 3:
- pose_remove_from_posegroups(scene);
- break;
- case 4:
- pose_remove_posegroup(scene);
- break;
+ uiItemS(layout);
+
+ uiItemO(layout, "Remove Selected from All Groups", 0, "POSE_OT_group_unassign");
+ uiItemO(layout, "Remove Active Group", 0, "POSE_OT_group_remove");
+ }
+ else {
+ /* no selected bones - so just options for groups management */
+ uiItemO(layout, "Add New Group", 0, "POSE_OT_group_add");
+ uiItemO(layout, "Remove Active Group", 0, "POSE_OT_group_remove");
}
+
+ return OPERATOR_CANCELLED;
+}
+
+void POSE_OT_groups_menu (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Bone Group Tools";
+ ot->idname= "POSE_OT_groups_menu";
+ ot->description= "Menu displaying available tools for Bone Groups.";
+
+ /* api callbacks (only invoke needed) */
+ ot->invoke= pose_groupOps_menu_invoke;
+ ot->poll= ED_operator_posemode;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER;
}
/* ********************************************** */
@@ -1346,7 +1438,7 @@ void pose_flip_names(Scene *scene)
if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
BLI_strncpy(newname, pchan->name, sizeof(newname));
bone_flip_name(newname, 1); // 1 = do strip off number extensions
- armature_bone_rename(ob, pchan->name, newname);
+ ED_armature_bone_rename(arm, pchan->name, newname);
}
}
}
@@ -1375,7 +1467,7 @@ void pose_autoside_names(Scene *scene, short axis)
if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
BLI_strncpy(newname, pchan->name, sizeof(newname));
bone_autoside_name(newname, 1, axis, pchan->bone->head[axis], pchan->bone->tail[axis]);
- armature_bone_rename(ob, pchan->name, newname);
+ ED_armature_bone_rename(arm, pchan->name, newname);
}
}
}