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:
Diffstat (limited to 'source/blender/editors/screen/screen_context.c')
-rw-r--r--source/blender/editors/screen/screen_context.c327
1 files changed, 177 insertions, 150 deletions
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index b90430f27e2..864150be9da 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -30,6 +30,8 @@
#include <stdlib.h>
#include <string.h>
+#include "MEM_guardedalloc.h"
+
#include "DNA_object_types.h"
#include "DNA_armature_types.h"
#include "DNA_gpencil_types.h"
@@ -38,17 +40,21 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_windowmanager_types.h"
+#include "DNA_workspace_types.h"
#include "BLI_utildefines.h"
-
#include "BKE_context.h"
#include "BKE_object.h"
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_gpencil.h"
+#include "BKE_layer.h"
#include "BKE_screen.h"
#include "BKE_sequencer.h"
+#include "BKE_workspace.h"
+
+#include "DEG_depsgraph.h"
#include "RNA_access.h"
@@ -61,20 +67,8 @@
#include "screen_intern.h"
-static unsigned int context_layers(bScreen *sc, Scene *scene, ScrArea *sa_ctx)
-{
- /* needed for 'USE_ALLSELECT' define, otherwise we end up editing off-screen layers. */
- if (sc && sa_ctx && (sa_ctx->spacetype == SPACE_BUTS)) {
- const unsigned int lay = BKE_screen_view3d_layer_all(sc);
- if (lay) {
- return lay;
- }
- }
- return scene->lay;
-}
-
const char *screen_context_dir[] = {
- "scene", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases",
+ "scene", "view_layer", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases",
"selected_objects", "selected_bases",
"editable_objects", "editable_bases",
"selected_editable_objects", "selected_editable_bases",
@@ -93,20 +87,14 @@ const char *screen_context_dir[] = {
int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result)
{
+ wmWindow *win = CTX_wm_window(C);
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
+ Scene *scene = WM_window_get_active_scene(win);
+ WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
+ ViewLayer *view_layer = BKE_view_layer_from_workspace_get(scene, workspace);
+ Object *obact = (view_layer && view_layer->basact) ? view_layer->basact->object : NULL;
+ Object *obedit = view_layer ? OBEDIT_FROM_VIEW_LAYER(view_layer) : NULL;
if (CTX_data_dir(member)) {
CTX_data_dir_set(result, screen_context_dir);
@@ -116,84 +104,100 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
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);
- const bool 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);
+ else if (CTX_data_equals(member, "visible_objects")) {
+ FOREACH_VISIBLE_OBJECT_BEGIN(view_layer, ob)
+ {
+ CTX_data_id_list_add(result, &ob->id);
+ }
+ FOREACH_VISIBLE_BASE_END;
+ CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
+ return 1;
+ }
+ else if (CTX_data_equals(member, "selectable_objects")) {
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if (((base->flag & BASE_VISIBLED) != 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
+ CTX_data_id_list_add(result, &base->object->id);
}
}
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);
- const bool 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);
- }
+ else if (CTX_data_equals(member, "selected_objects")) {
+ FOREACH_SELECTED_OBJECT_BEGIN(view_layer, ob)
+ {
+ CTX_data_id_list_add(result, &ob->id);
+ }
+ FOREACH_SELECTED_OBJECT_END;
+ CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
+ return 1;
+ }
+ else if (CTX_data_equals(member, "selected_editable_objects")) {
+ FOREACH_SELECTED_OBJECT_BEGIN(view_layer, ob)
+ {
+ if (0 == BKE_object_is_libdata(ob)) {
+ CTX_data_id_list_add(result, &ob->id);
}
}
+ FOREACH_SELECTED_OBJECT_END;
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);
- const bool 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);
+ else if (CTX_data_equals(member, "editable_objects")) {
+ /* Visible + Editable, but not necessarily selected */
+ FOREACH_VISIBLE_OBJECT_BEGIN(view_layer, ob)
+ {
+ if (0 == BKE_object_is_libdata(ob)) {
+ CTX_data_id_list_add(result, &ob->id);
}
}
+ FOREACH_VISIBLE_OBJECT_END;
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);
- const bool 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);
- }
+ else if ( CTX_data_equals(member, "visible_bases")) {
+ FOREACH_VISIBLE_BASE_BEGIN(view_layer, base)
+ {
+ CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
+ }
+ FOREACH_VISIBLE_BASE_END;
+ CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
+ return 1;
+ }
+ else if (CTX_data_equals(member, "selectable_bases")) {
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_SELECTABLED) != 0) {
+ 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_bases")) {
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_SELECTED) != 0) {
+ 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_bases")) {
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_SELECTED) != 0) {
+ if (0 == BKE_object_is_libdata(base->object)) {
+ 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);
- const bool editable_objects = CTX_data_equals(member, "editable_objects");
-
+ else if (CTX_data_equals(member, "editable_bases")) {
/* 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)) {
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_VISIBLED) != 0) {
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_list_add(result, &scene->id, &RNA_ObjectBase, base);
}
}
}
@@ -206,38 +210,47 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
const bool 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_ebone_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)) {
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
+ for (uint i = 0; i < objects_len; i++) {
+ Object *ob = objects[i];
+ arm = ob->data;
+
+ /* 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_ebone_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) && !(flipbone->flag & BONE_SELECTED))
+ if ((flipbone) && EBONE_VISIBLE(arm, flipbone) == 0)
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);
- }
}
}
+ MEM_freeN(objects);
+
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
@@ -248,53 +261,65 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
const bool 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_ebone_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)) {
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
+ for (uint i = 0; i < objects_len; i++) {
+ Object *ob = objects[i];
+ arm = ob->data;
+
+ /* 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_ebone_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);
}
}
- 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);
- }
}
}
+ MEM_freeN(objects);
+
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)) {
+ if (obpose && obpose->pose && obpose->data) {
+ if (obpose != obact) {
+ FOREACH_PCHAN_VISIBLE_IN_OBJECT_BEGIN (obpose, pchan) {
CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan);
- }
+ } FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
+ }
+ else if (obact->mode & OB_MODE_POSE) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, OB_MODE_POSE, ob_iter) {
+ FOREACH_PCHAN_VISIBLE_IN_OBJECT_BEGIN (ob_iter, pchan) {
+ CTX_data_list_add(result, &ob_iter->id, &RNA_PoseBone, pchan);
+ } FOREACH_PCHAN_VISIBLE_IN_OBJECT_END;
+ } FOREACH_OBJECT_IN_MODE_END;
}
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
@@ -302,16 +327,18 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
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);
- }
+ if (obpose && obpose->pose && obpose->data) {
+ if (obpose != obact) {
+ FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (obpose, pchan) {
+ CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan);
+ } FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
+ }
+ else if (obact->mode & OB_MODE_POSE) {
+ FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, OB_MODE_POSE, ob_iter) {
+ FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan) {
+ CTX_data_list_add(result, &ob_iter->id, &RNA_PoseBone, pchan);
+ } FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
+ } FOREACH_OBJECT_IN_MODE_END;
}
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
@@ -345,8 +372,8 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
}
else if (CTX_data_equals(member, "active_base")) {
- if (base)
- CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, base);
+ if (view_layer->basact)
+ CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, view_layer->basact);
return 1;
}