/* 'select_mode' is usual SEL_SELECT/SEL_DESELECT/SEL_TOGGLE/SEL_INVERT. * When true, 'ignore_visibility' makes this func also affect invisible bones (hidden or on hidden layers). */ void ED_pose_de_selectall(Object *ob, int select_mode, const bool ignore_visibility) { bArmature *arm = ob->data; bPoseChannel *pchan; /* we call this from outliner too */ if (ob->pose == NULL) { return; } /* Determine if we're selecting or deselecting */ if (select_mode == SEL_TOGGLE) { select_mode = SEL_SELECT; for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { if (ignore_visibility || PBONE_VISIBLE(arm, pchan->bone)) { if (pchan->bone->flag & BONE_SELECTED) { select_mode = SEL_DESELECT; break; } } } } /* Set the flags accordingly */ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { /* ignore the pchan if it isn't visible or if its selection cannot be changed */ if (ignore_visibility || PBONE_VISIBLE(arm, pchan->bone)) { pose_do_bone_select(pchan, select_mode); } } }
/* test==0: deselect all * test==1: swap select (apply to all the opposite of current situation) * test==2: only clear active tag * test==3: swap select (no test / inverse selection status of all independently) */ void ED_pose_deselectall(Object *ob, int test) { bArmature *arm = ob->data; bPoseChannel *pchan; int selectmode = 0; /* we call this from outliner too */ if (ob->pose == NULL) { return; } /* Determine if we're selecting or deselecting */ if (test == 1) { for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { if (PBONE_VISIBLE(arm, pchan->bone)) { if (pchan->bone->flag & BONE_SELECTED) break; } } if (pchan == NULL) selectmode = 1; } else if (test == 2) selectmode = 2; /* Set the flags accordingly */ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { /* ignore the pchan if it isn't visible or if its selection cannot be changed */ if ((pchan->bone->layer & arm->layer) && !(pchan->bone->flag & (BONE_HIDDEN_P | BONE_UNSELECTABLE))) { if (test == 3) { pchan->bone->flag ^= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); } else { if (selectmode == 0) pchan->bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); else if (selectmode == 1) pchan->bone->flag |= BONE_SELECTED; } } } }
/* almost _exact_ copy of #armature_foreachScreenBone */ void pose_foreachScreenBone( struct ViewContext *vc, void (*func)(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]), void *userData, const eV3DProjTest clip_flag) { bArmature *arm = vc->obact->data; bPose *pose = vc->obact->pose; bPoseChannel *pchan; ED_view3d_check_mats_rv3d(vc->rv3d); for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { if (PBONE_VISIBLE(arm, pchan->bone)) { float screen_co_a[2], screen_co_b[2]; int points_proj_tot = 0; /* project head location to screenspace */ if (ED_view3d_project_float_object(vc->ar, pchan->pose_head, screen_co_a, clip_flag) == V3D_PROJ_RET_OK) { points_proj_tot++; } else { screen_co_a[0] = IS_CLIPPED; /* weak */ /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */ } /* project tail location to screenspace */ if (ED_view3d_project_float_object(vc->ar, pchan->pose_tail, screen_co_b, clip_flag) == V3D_PROJ_RET_OK) { points_proj_tot++; } else { screen_co_b[0] = IS_CLIPPED; /* weak */ /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */ } if (points_proj_tot) { /* at least one point's projection worked */ func(userData, pchan, screen_co_a, screen_co_b); } } } }
static int snap_selected_to_location(bContext *C, const float snap_target_global[3], const bool use_offset) { Scene *scene = CTX_data_scene(C); Object *obedit = CTX_data_edit_object(C); Object *obact = CTX_data_active_object(C); View3D *v3d = CTX_wm_view3d(C); TransVertStore tvs = {NULL}; TransVert *tv; float imat[3][3], bmat[3][3]; float center_global[3]; float offset_global[3]; int a; if (use_offset) { if ((v3d && v3d->around == V3D_AROUND_ACTIVE) && snap_calc_active_center(C, true, center_global)) { /* pass */ } else { snap_curs_to_sel_ex(C, center_global); } sub_v3_v3v3(offset_global, snap_target_global, center_global); } if (obedit) { float snap_target_local[3]; if (ED_transverts_check_obedit(obedit)) ED_transverts_create_from_obedit(&tvs, obedit, 0); if (tvs.transverts_tot == 0) return OPERATOR_CANCELLED; copy_m3_m4(bmat, obedit->obmat); invert_m3_m3(imat, bmat); /* get the cursor in object space */ sub_v3_v3v3(snap_target_local, snap_target_global, obedit->obmat[3]); mul_m3_v3(imat, snap_target_local); if (use_offset) { float offset_local[3]; mul_v3_m3v3(offset_local, imat, offset_global); tv = tvs.transverts; for (a = 0; a < tvs.transverts_tot; a++, tv++) { add_v3_v3(tv->loc, offset_local); } } else { tv = tvs.transverts; for (a = 0; a < tvs.transverts_tot; a++, tv++) { copy_v3_v3(tv->loc, snap_target_local); } } ED_transverts_update_obedit(&tvs, obedit); ED_transverts_free(&tvs); } else if (obact && (obact->mode & OB_MODE_POSE)) { struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID); bPoseChannel *pchan; bArmature *arm = obact->data; float snap_target_local[3]; invert_m4_m4(obact->imat, obact->obmat); mul_v3_m4v3(snap_target_local, obact->imat, snap_target_global); for (pchan = obact->pose->chanbase.first; pchan; pchan = pchan->next) { if ((pchan->bone->flag & BONE_SELECTED) && (PBONE_VISIBLE(arm, pchan->bone)) && /* if the bone has a parent and is connected to the parent, * don't do anything - will break chain unless we do auto-ik. */ (pchan->bone->flag & BONE_CONNECTED) == 0) { pchan->bone->flag |= BONE_TRANSFORM; } else { pchan->bone->flag &= ~BONE_TRANSFORM; } } for (pchan = obact->pose->chanbase.first; pchan; pchan = pchan->next) { if ((pchan->bone->flag & BONE_TRANSFORM) && /* check that our parents not transformed (if we have one) */ ((pchan->bone->parent && BKE_armature_bone_flag_test_recursive(pchan->bone->parent, BONE_TRANSFORM)) == 0)) { /* Get position in pchan (pose) space. */ float cursor_pose[3]; if (use_offset) { mul_v3_m4v3(cursor_pose, obact->obmat, pchan->pose_mat[3]); add_v3_v3(cursor_pose, offset_global); mul_m4_v3(obact->imat, cursor_pose); BKE_armature_loc_pose_to_bone(pchan, cursor_pose, cursor_pose); } else { BKE_armature_loc_pose_to_bone(pchan, snap_target_local, cursor_pose); } /* copy new position */ if ((pchan->protectflag & OB_LOCK_LOCX) == 0) pchan->loc[0] = cursor_pose[0]; if ((pchan->protectflag & OB_LOCK_LOCY) == 0) pchan->loc[1] = cursor_pose[1]; if ((pchan->protectflag & OB_LOCK_LOCZ) == 0) pchan->loc[2] = cursor_pose[2]; /* auto-keyframing */ ED_autokeyframe_pchan(C, scene, obact, pchan, ks); } } for (pchan = obact->pose->chanbase.first; pchan; pchan = pchan->next) { pchan->bone->flag &= ~BONE_TRANSFORM; } obact->pose->flag |= (POSE_LOCKED | POSE_DO_UNLOCK); DAG_id_tag_update(&obact->id, OB_RECALC_DATA); } else { struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID); Main *bmain = CTX_data_main(C); ListBase ctx_data_list; CollectionPointerLink *ctx_ob; Object *ob; CTX_data_selected_editable_objects(C, &ctx_data_list); /* reset flags */ for (ob = bmain->object.first; ob; ob = ob->id.next) { ob->flag &= ~OB_DONE; } /* tag objects we're transforming */ for (ctx_ob = ctx_data_list.first; ctx_ob; ctx_ob = ctx_ob->next) { ob = ctx_ob->ptr.data; ob->flag |= OB_DONE; } for (ctx_ob = ctx_data_list.first; ctx_ob; ctx_ob = ctx_ob->next) { ob = ctx_ob->ptr.data; if ((ob->parent && BKE_object_flag_test_recursive(ob->parent, OB_DONE)) == 0) { float cursor_parent[3]; /* parent-relative */ if (use_offset) { add_v3_v3v3(cursor_parent, ob->obmat[3], offset_global); } else { copy_v3_v3(cursor_parent, snap_target_global); } sub_v3_v3(cursor_parent, ob->obmat[3]); if (ob->parent) { float originmat[3][3]; BKE_object_where_is_calc_ex(scene, NULL, ob, originmat); invert_m3_m3(imat, originmat); mul_m3_v3(imat, cursor_parent); } if ((ob->protectflag & OB_LOCK_LOCX) == 0) ob->loc[0] += cursor_parent[0]; if ((ob->protectflag & OB_LOCK_LOCY) == 0) ob->loc[1] += cursor_parent[1]; if ((ob->protectflag & OB_LOCK_LOCZ) == 0) ob->loc[2] += cursor_parent[2]; /* auto-keyframing */ ED_autokeyframe_object(C, scene, ob, ks); DAG_id_tag_update(&ob->id, OB_RECALC_OB); } } BLI_freelistN(&ctx_data_list); } WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); return OPERATOR_FINISHED; }
int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result) { bScreen *sc= CTX_wm_screen(C); Scene *scene= sc->scene; Base *base; unsigned int lay = scene->lay; #if 0 /* Using the context breaks adding objects in the UI. Need to find out why - campbell */ Object *obact= CTX_data_active_object(C); Object *obedit= CTX_data_edit_object(C); base= CTX_data_active_base(C); #else Object *obedit= scene->obedit; Object *obact= OBACT; base= BASACT; #endif if(CTX_data_dir(member)) { CTX_data_dir_set(result, screen_context_dir); return 1; } else if(CTX_data_equals(member, "scene")) { CTX_data_id_pointer_set(result, &scene->id); return 1; } else if(CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) { int visible_objects= CTX_data_equals(member, "visible_objects"); for(base=scene->base.first; base; base=base->next) { if(((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) && (base->lay & scene->lay)) { if(visible_objects) CTX_data_id_list_add(result, &base->object->id); else CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } else if(CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) { int selectable_objects= CTX_data_equals(member, "selectable_objects"); for(base=scene->base.first; base; base=base->next) { if(base->lay & lay) { if((base->object->restrictflag & OB_RESTRICT_VIEW)==0 && (base->object->restrictflag & OB_RESTRICT_SELECT)==0) { if(selectable_objects) CTX_data_id_list_add(result, &base->object->id); else CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); } } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } else if(CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) { int selected_objects= CTX_data_equals(member, "selected_objects"); for(base=scene->base.first; base; base=base->next) { if((base->flag & SELECT) && (base->lay & scene->lay)) { if(selected_objects) CTX_data_id_list_add(result, &base->object->id); else CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } else if(CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) { int selected_editable_objects= CTX_data_equals(member, "selected_editable_objects"); for(base=scene->base.first; base; base=base->next) { if((base->flag & SELECT) && (base->lay & scene->lay)) { if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) { if(0==object_is_libdata(base->object)) { if(selected_editable_objects) CTX_data_id_list_add(result, &base->object->id); else CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); } } } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } else if(CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) { bArmature *arm= (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL; EditBone *ebone, *flipbone=NULL; int editable_bones= CTX_data_equals(member, "editable_bones"); if (arm && arm->edbo) { /* Attention: X-Axis Mirroring is also handled here... */ for (ebone= arm->edbo->first; ebone; ebone= ebone->next) { /* first and foremost, bone must be visible and selected */ if (EBONE_VISIBLE(arm, ebone)) { /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled * so that most users of this data don't need to explicitly check for it themselves. * * We need to make sure that these mirrored copies are not selected, otherwise some * bones will be operated on twice. */ if (arm->flag & ARM_MIRROR_EDIT) flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone); /* if we're filtering for editable too, use the check for that instead, as it has selection check too */ if (editable_bones) { /* only selected + editable */ if (EBONE_EDITABLE(ebone)) { CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone); if ((flipbone) && !(flipbone->flag & BONE_SELECTED)) CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone); } } else { /* only include bones if visible */ CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone); if ((flipbone) && EBONE_VISIBLE(arm, flipbone)==0) CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone); } } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } else if(CTX_data_equals(member, "selected_bones") || CTX_data_equals(member, "selected_editable_bones")) { bArmature *arm= (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL; EditBone *ebone, *flipbone=NULL; int selected_editable_bones= CTX_data_equals(member, "selected_editable_bones"); if (arm && arm->edbo) { /* Attention: X-Axis Mirroring is also handled here... */ for (ebone= arm->edbo->first; ebone; ebone= ebone->next) { /* first and foremost, bone must be visible and selected */ if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_SELECTED)) { /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled * so that most users of this data don't need to explicitly check for it themselves. * * We need to make sure that these mirrored copies are not selected, otherwise some * bones will be operated on twice. */ if (arm->flag & ARM_MIRROR_EDIT) flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone); /* if we're filtering for editable too, use the check for that instead, as it has selection check too */ if (selected_editable_bones) { /* only selected + editable */ if (EBONE_EDITABLE(ebone)) { CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone); if ((flipbone) && !(flipbone->flag & BONE_SELECTED)) CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone); } } else { /* only include bones if selected */ CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone); if ((flipbone) && !(flipbone->flag & BONE_SELECTED)) CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone); } } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } else if(CTX_data_equals(member, "visible_pose_bones")) { Object *obpose= ED_object_pose_armature(obact); bArmature *arm= (obpose) ? obpose->data : NULL; bPoseChannel *pchan; if (obpose && obpose->pose && arm) { for (pchan= obpose->pose->chanbase.first; pchan; pchan= pchan->next) { /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */ if (PBONE_VISIBLE(arm, pchan->bone)) { CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan); } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } else if(CTX_data_equals(member, "selected_pose_bones")) { Object *obpose= ED_object_pose_armature(obact); bArmature *arm= (obpose) ? obpose->data : NULL; bPoseChannel *pchan; if (obpose && obpose->pose && arm) { for (pchan= obpose->pose->chanbase.first; pchan; pchan= pchan->next) { /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */ if (PBONE_VISIBLE(arm, pchan->bone)) { if (pchan->bone->flag & BONE_SELECTED) CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan); } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } else if(CTX_data_equals(member, "active_bone")) { if(obact && obact->type == OB_ARMATURE) { bArmature *arm= obact->data; if(arm->edbo) { if(arm->act_edbone) { CTX_data_pointer_set(result, &arm->id, &RNA_EditBone, arm->act_edbone); return 1; } } else { if(arm->act_bone) { CTX_data_pointer_set(result, &arm->id, &RNA_Bone, arm->act_bone); return 1; } } } } else if(CTX_data_equals(member, "active_pose_bone")) { bPoseChannel *pchan; Object *obpose= ED_object_pose_armature(obact); pchan= get_active_posechannel(obpose); if (pchan) { CTX_data_pointer_set(result, &obpose->id, &RNA_PoseBone, pchan); return 1; } } else if(CTX_data_equals(member, "active_base")) { if(base) CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, base); return 1; } else if(CTX_data_equals(member, "active_object")) { if(obact) CTX_data_id_pointer_set(result, &obact->id); return 1; } else if(CTX_data_equals(member, "object")) { if(obact) CTX_data_id_pointer_set(result, &obact->id); return 1; } else if(CTX_data_equals(member, "edit_object")) { /* convenience for now, 1 object per scene in editmode */ if(obedit) CTX_data_id_pointer_set(result, &obedit->id); return 1; } else if(CTX_data_equals(member, "sculpt_object")) { if(obact && (obact->mode & OB_MODE_SCULPT)) CTX_data_id_pointer_set(result, &obact->id); return 1; } else if(CTX_data_equals(member, "vertex_paint_object")) { if(obact && (obact->mode & OB_MODE_VERTEX_PAINT)) CTX_data_id_pointer_set(result, &obact->id); return 1; } else if(CTX_data_equals(member, "weight_paint_object")) { if(obact && (obact->mode & OB_MODE_WEIGHT_PAINT)) CTX_data_id_pointer_set(result, &obact->id); return 1; } else if(CTX_data_equals(member, "image_paint_object")) { if(obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) CTX_data_id_pointer_set(result, &obact->id); return 1; } else if(CTX_data_equals(member, "particle_edit_object")) { if(obact && (obact->mode & OB_MODE_PARTICLE_EDIT)) CTX_data_id_pointer_set(result, &obact->id); return 1; } else if(CTX_data_equals(member, "sequences")) { Editing *ed= seq_give_editing(scene, FALSE); if(ed) { Sequence *seq; for (seq= ed->seqbasep->first; seq; seq= seq->next) { CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } else if(CTX_data_equals(member, "selected_sequences")) { Editing *ed= seq_give_editing(scene, FALSE); if(ed) { Sequence *seq; for (seq= ed->seqbasep->first; seq; seq= seq->next) { if (seq->flag & SELECT) { CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } else if(CTX_data_equals(member, "selected_editable_sequences")) { Editing *ed= seq_give_editing(scene, FALSE); if(ed) { Sequence *seq; for (seq= ed->seqbasep->first; seq; seq= seq->next) { if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) { CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } else { return 0; /* not found */ } return -1; /* found but not available */ }
int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result) { bScreen *sc = CTX_wm_screen(C); ScrArea *sa = CTX_wm_area(C); Scene *scene = sc->scene; Base *base; #if 0 /* Using the context breaks adding objects in the UI. Need to find out why - campbell */ Object *obact = CTX_data_active_object(C); Object *obedit = CTX_data_edit_object(C); base = CTX_data_active_base(C); #else Object *obedit = scene->obedit; Object *obact = OBACT; base = BASACT; #endif if (CTX_data_dir(member)) { CTX_data_dir_set(result, screen_context_dir); return 1; } else if (CTX_data_equals(member, "scene")) { CTX_data_id_pointer_set(result, &scene->id); return 1; } else if (CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) { const unsigned int lay = context_layers(sc, scene, sa); int visible_objects = CTX_data_equals(member, "visible_objects"); for (base = scene->base.first; base; base = base->next) { if (((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) && (base->lay & lay)) { if (visible_objects) CTX_data_id_list_add(result, &base->object->id); else CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } else if (CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) { const unsigned int lay = context_layers(sc, scene, sa); int selectable_objects = CTX_data_equals(member, "selectable_objects"); for (base = scene->base.first; base; base = base->next) { if (base->lay & lay) { if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0 && (base->object->restrictflag & OB_RESTRICT_SELECT) == 0) { if (selectable_objects) CTX_data_id_list_add(result, &base->object->id); else CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); } } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } else if (CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) { const unsigned int lay = context_layers(sc, scene, sa); int selected_objects = CTX_data_equals(member, "selected_objects"); for (base = scene->base.first; base; base = base->next) { if ((base->flag & SELECT) && (base->lay & lay)) { if (selected_objects) CTX_data_id_list_add(result, &base->object->id); else CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } else if (CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) { const unsigned int lay = context_layers(sc, scene, sa); int selected_editable_objects = CTX_data_equals(member, "selected_editable_objects"); for (base = scene->base.first; base; base = base->next) { if ((base->flag & SELECT) && (base->lay & lay)) { if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) { if (0 == BKE_object_is_libdata(base->object)) { if (selected_editable_objects) CTX_data_id_list_add(result, &base->object->id); else CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); } } } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } else if (CTX_data_equals(member, "editable_objects") || CTX_data_equals(member, "editable_bases")) { const unsigned int lay = context_layers(sc, scene, sa); int editable_objects = CTX_data_equals(member, "editable_objects"); /* Visible + Editable, but not necessarily selected */ for (base = scene->base.first; base; base = base->next) { if (((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) && (base->lay & lay)) { if (0 == BKE_object_is_libdata(base->object)) { if (editable_objects) CTX_data_id_list_add(result, &base->object->id); else CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); } } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } else if (CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) { bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL; EditBone *ebone, *flipbone = NULL; int editable_bones = CTX_data_equals(member, "editable_bones"); if (arm && arm->edbo) { /* Attention: X-Axis Mirroring is also handled here... */ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { /* first and foremost, bone must be visible and selected */ if (EBONE_VISIBLE(arm, ebone)) { /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled * so that most users of this data don't need to explicitly check for it themselves. * * We need to make sure that these mirrored copies are not selected, otherwise some * bones will be operated on twice. */ if (arm->flag & ARM_MIRROR_EDIT) flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone); /* if we're filtering for editable too, use the check for that instead, as it has selection check too */ if (editable_bones) { /* only selected + editable */ if (EBONE_EDITABLE(ebone)) { CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone); if ((flipbone) && !(flipbone->flag & BONE_SELECTED)) CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone); } } else { /* only include bones if visible */ CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone); if ((flipbone) && EBONE_VISIBLE(arm, flipbone) == 0) CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone); } } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } else if (CTX_data_equals(member, "selected_bones") || CTX_data_equals(member, "selected_editable_bones")) { bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL; EditBone *ebone, *flipbone = NULL; int selected_editable_bones = CTX_data_equals(member, "selected_editable_bones"); if (arm && arm->edbo) { /* Attention: X-Axis Mirroring is also handled here... */ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { /* first and foremost, bone must be visible and selected */ if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_SELECTED)) { /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled * so that most users of this data don't need to explicitly check for it themselves. * * We need to make sure that these mirrored copies are not selected, otherwise some * bones will be operated on twice. */ if (arm->flag & ARM_MIRROR_EDIT) flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone); /* if we're filtering for editable too, use the check for that instead, as it has selection check too */ if (selected_editable_bones) { /* only selected + editable */ if (EBONE_EDITABLE(ebone)) { CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone); if ((flipbone) && !(flipbone->flag & BONE_SELECTED)) CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone); } } else { /* only include bones if selected */ CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone); if ((flipbone) && !(flipbone->flag & BONE_SELECTED)) CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone); } } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } else if (CTX_data_equals(member, "visible_pose_bones")) { Object *obpose = BKE_object_pose_armature_get(obact); bArmature *arm = (obpose) ? obpose->data : NULL; bPoseChannel *pchan; if (obpose && obpose->pose && arm) { for (pchan = obpose->pose->chanbase.first; pchan; pchan = pchan->next) { /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */ if (PBONE_VISIBLE(arm, pchan->bone)) { CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan); } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } else if (CTX_data_equals(member, "selected_pose_bones")) { Object *obpose = BKE_object_pose_armature_get(obact); bArmature *arm = (obpose) ? obpose->data : NULL; bPoseChannel *pchan; if (obpose && obpose->pose && arm) { for (pchan = obpose->pose->chanbase.first; pchan; pchan = pchan->next) { /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */ if (PBONE_VISIBLE(arm, pchan->bone)) { if (pchan->bone->flag & BONE_SELECTED) CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan); } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } else if (CTX_data_equals(member, "active_bone")) { if (obact && obact->type == OB_ARMATURE) { bArmature *arm = obact->data; if (arm->edbo) { if (arm->act_edbone) { CTX_data_pointer_set(result, &arm->id, &RNA_EditBone, arm->act_edbone); return 1; } } else { if (arm->act_bone) { CTX_data_pointer_set(result, &arm->id, &RNA_Bone, arm->act_bone); return 1; } } } } else if (CTX_data_equals(member, "active_pose_bone")) { bPoseChannel *pchan; Object *obpose = BKE_object_pose_armature_get(obact); pchan = BKE_pose_channel_active(obpose); if (pchan) { CTX_data_pointer_set(result, &obpose->id, &RNA_PoseBone, pchan); return 1; } } else if (CTX_data_equals(member, "active_base")) { if (base) CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, base); return 1; } else if (CTX_data_equals(member, "active_object")) { if (obact) CTX_data_id_pointer_set(result, &obact->id); return 1; } else if (CTX_data_equals(member, "object")) { if (obact) CTX_data_id_pointer_set(result, &obact->id); return 1; } else if (CTX_data_equals(member, "edit_object")) { /* convenience for now, 1 object per scene in editmode */ if (obedit) CTX_data_id_pointer_set(result, &obedit->id); return 1; } else if (CTX_data_equals(member, "sculpt_object")) { if (obact && (obact->mode & OB_MODE_SCULPT)) CTX_data_id_pointer_set(result, &obact->id); return 1; } else if (CTX_data_equals(member, "vertex_paint_object")) { if (obact && (obact->mode & OB_MODE_VERTEX_PAINT)) CTX_data_id_pointer_set(result, &obact->id); return 1; } else if (CTX_data_equals(member, "weight_paint_object")) { if (obact && (obact->mode & OB_MODE_WEIGHT_PAINT)) CTX_data_id_pointer_set(result, &obact->id); return 1; } else if (CTX_data_equals(member, "image_paint_object")) { if (obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) CTX_data_id_pointer_set(result, &obact->id); return 1; } else if (CTX_data_equals(member, "particle_edit_object")) { if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT)) CTX_data_id_pointer_set(result, &obact->id); return 1; } else if (CTX_data_equals(member, "sequences")) { Editing *ed = BKE_sequencer_editing_get(scene, false); if (ed) { Sequence *seq; for (seq = ed->seqbasep->first; seq; seq = seq->next) { CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } else if (CTX_data_equals(member, "selected_sequences")) { Editing *ed = BKE_sequencer_editing_get(scene, false); if (ed) { Sequence *seq; for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->flag & SELECT) { CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } else if (CTX_data_equals(member, "selected_editable_sequences")) { Editing *ed = BKE_sequencer_editing_get(scene, false); if (ed) { Sequence *seq; for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) { CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } else if (CTX_data_equals(member, "gpencil_data")) { /* FIXME: for some reason, CTX_data_active_object(C) returns NULL when called from these situations * (as outlined above - see Campbell's #ifdefs). That causes the get_active function to fail when * called from context. For that reason, we end up using an alternative where we pass everything in! */ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); if (gpd) { CTX_data_id_pointer_set(result, &gpd->id); return 1; } } else if (CTX_data_equals(member, "gpencil_data_owner")) { /* pointer to which data/datablock owns the reference to the Grease Pencil data being used (as gpencil_data) * XXX: see comment for gpencil_data case... */ bGPdata **gpd_ptr = NULL; PointerRNA ptr; /* get pointer to Grease Pencil Data */ gpd_ptr = ED_gpencil_data_get_pointers_direct((ID *)sc, scene, sa, obact, &ptr); if (gpd_ptr) { CTX_data_pointer_set(result, ptr.id.data, ptr.type, ptr.data); return 1; } } else if (CTX_data_equals(member, "active_gpencil_layer")) { /* XXX: see comment for gpencil_data case... */ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); if (gpd) { bGPDlayer *gpl = gpencil_layer_getactive(gpd); if (gpl) { CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl); return 1; } } } else if (CTX_data_equals(member, "active_gpencil_frame")) { /* XXX: see comment for gpencil_data case... */ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); if (gpd) { bGPDlayer *gpl = gpencil_layer_getactive(gpd); if (gpl) { CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl->actframe); return 1; } } } else if (CTX_data_equals(member, "visible_gpencil_layers")) { /* XXX: see comment for gpencil_data case... */ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); if (gpd) { bGPDlayer *gpl; for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { if ((gpl->flag & GP_LAYER_HIDE) == 0) { CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl); } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } else if (CTX_data_equals(member, "editable_gpencil_layers")) { /* XXX: see comment for gpencil_data case... */ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); if (gpd) { bGPDlayer *gpl; for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { if (gpencil_layer_is_editable(gpl)) { CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl); } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } else if (CTX_data_equals(member, "editable_gpencil_strokes")) { /* XXX: see comment for gpencil_data case... */ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); if (gpd) { bGPDlayer *gpl; for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { if (gpencil_layer_is_editable(gpl) && (gpl->actframe)) { bGPDframe *gpf = gpl->actframe; bGPDstroke *gps; for (gps = gpf->strokes.first; gps; gps = gps->next) { if (ED_gpencil_stroke_can_use_direct(sa, gps)) { CTX_data_list_add(result, &gpd->id, &RNA_GPencilStroke, gps); } } } } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } } else if (CTX_data_equals(member, "active_operator")) { wmOperator *op = NULL; SpaceFile *sfile = CTX_wm_space_file(C); if (sfile) { op = sfile->op; } else if ((op = UI_context_active_operator_get(C))) { /* do nothing */ } else { /* note, this checks poll, could be a problem, but this also * happens for the toolbar */ op = WM_operator_last_redo(C); } /* TODO, get the operator from popup's */ if (op && op->ptr) { CTX_data_pointer_set(result, NULL, &RNA_Operator, op); return 1; } } else { return 0; /* not found */ } return -1; /* found but not available */ }