Cleanup: Move 3D View context functions to own file

Such context functions are often separated out to a context file, to
keep files more coherent and focused.
This commit is contained in:
Julian Eisel
2023-10-23 19:32:56 +02:00
parent da34c70916
commit 5fab6700cd
4 changed files with 148 additions and 107 deletions

View File

@@ -32,6 +32,7 @@ set(SRC
space_view3d.cc
view3d_buttons.cc
view3d_camera_control.cc
view3d_context.cc
view3d_cursor_snap.cc
view3d_draw.cc
view3d_edit.cc

View File

@@ -95,54 +95,6 @@
/* ******************** manage regions ********************* */
RegionView3D *ED_view3d_context_rv3d(bContext *C)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
if (rv3d == nullptr) {
ScrArea *area = CTX_wm_area(C);
if (area && area->spacetype == SPACE_VIEW3D) {
ARegion *region = BKE_area_find_region_active_win(area);
if (region) {
rv3d = static_cast<RegionView3D *>(region->regiondata);
}
}
}
return rv3d;
}
bool ED_view3d_context_user_region(bContext *C, View3D **r_v3d, ARegion **r_region)
{
ScrArea *area = CTX_wm_area(C);
*r_v3d = nullptr;
*r_region = nullptr;
if (area && area->spacetype == SPACE_VIEW3D) {
ARegion *region = CTX_wm_region(C);
View3D *v3d = (View3D *)area->spacedata.first;
if (region) {
RegionView3D *rv3d;
if ((region->regiontype == RGN_TYPE_WINDOW) &&
(rv3d = static_cast<RegionView3D *>(region->regiondata)) &&
(rv3d->viewlock & RV3D_LOCK_ROTATION) == 0)
{
*r_v3d = v3d;
*r_region = region;
return true;
}
if (ED_view3d_area_user_region(area, v3d, r_region)) {
*r_v3d = v3d;
return true;
}
}
}
return false;
}
bool ED_view3d_area_user_region(const ScrArea *area, const View3D *v3d, ARegion **r_region)
{
RegionView3D *rv3d = nullptr;
@@ -2040,65 +1992,6 @@ static void space_view3d_refresh(const bContext *C, ScrArea *area)
MEM_SAFE_FREE(v3d->runtime.local_stats);
}
const char *view3d_context_dir[] = {
"active_object",
"selected_ids",
nullptr,
};
static int view3d_context(const bContext *C, const char *member, bContextDataResult *result)
{
/* fallback to the scene layer,
* allows duplicate and other object operators to run outside the 3d view */
if (CTX_data_dir(member)) {
CTX_data_dir_set(result, view3d_context_dir);
return CTX_RESULT_OK;
}
if (CTX_data_equals(member, "active_object")) {
/* In most cases the active object is the `view_layer->basact->object`.
* For the 3D view however it can be nullptr when hidden.
*
* This is ignored in the case the object is in any mode (besides object-mode),
* since the object's mode impacts the current tool, cursor, gizmos etc.
* If we didn't have this exception, changing visibility would need to perform
* many of the same updates as changing the objects mode.
*
* Further, there are multiple ways to hide objects - by collection, by object type, etc.
* it's simplest if all these methods behave consistently - respecting the object-mode
* without showing the object.
*
* See #85532 for alternatives that were considered. */
const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_active_base_get(view_layer);
if (base) {
Object *ob = base->object;
/* if hidden but in edit mode, we still display, can happen with animation */
if ((base->flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT) != 0 ||
(ob->mode != OB_MODE_OBJECT)) {
CTX_data_id_pointer_set(result, &ob->id);
}
}
return CTX_RESULT_OK;
}
if (CTX_data_equals(member, "selected_ids")) {
ListBase selected_objects;
CTX_data_selected_objects(C, &selected_objects);
LISTBASE_FOREACH (CollectionPointerLink *, object_ptr_link, &selected_objects) {
ID *selected_id = object_ptr_link->ptr.owner_id;
CTX_data_id_list_add(result, selected_id);
}
BLI_freelistN(&selected_objects);
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return CTX_RESULT_OK;
}
return CTX_RESULT_MEMBER_NOT_FOUND;
}
static void view3d_id_remap_v3d_ob_centers(View3D *v3d, const IDRemapper *mappings)
{
if (BKE_id_remapper_apply(mappings, (ID **)&v3d->ob_center, ID_REMAP_APPLY_DEFAULT) ==

View File

@@ -0,0 +1,142 @@
/* SPDX-FileCopyrightText: 2008 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup spview3d
*/
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "BKE_context.h"
#include "BKE_layer.h"
#include "BKE_screen.hh"
#include "BLI_listbase.h"
#include "ED_view3d.hh"
#include "RNA_types.hh"
#include "view3d_intern.h"
/* -------------------------------------------------------------------- */
/** \name View3D Context Callback
* \{ */
const char *view3d_context_dir[] = {
"active_object",
"selected_ids",
nullptr,
};
int view3d_context(const bContext *C, const char *member, bContextDataResult *result)
{
/* fallback to the scene layer,
* allows duplicate and other object operators to run outside the 3d view */
if (CTX_data_dir(member)) {
CTX_data_dir_set(result, view3d_context_dir);
return CTX_RESULT_OK;
}
if (CTX_data_equals(member, "active_object")) {
/* In most cases the active object is the `view_layer->basact->object`.
* For the 3D view however it can be nullptr when hidden.
*
* This is ignored in the case the object is in any mode (besides object-mode),
* since the object's mode impacts the current tool, cursor, gizmos etc.
* If we didn't have this exception, changing visibility would need to perform
* many of the same updates as changing the objects mode.
*
* Further, there are multiple ways to hide objects - by collection, by object type, etc.
* it's simplest if all these methods behave consistently - respecting the object-mode
* without showing the object.
*
* See #85532 for alternatives that were considered. */
const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_active_base_get(view_layer);
if (base) {
Object *ob = base->object;
/* if hidden but in edit mode, we still display, can happen with animation */
if ((base->flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT) != 0 ||
(ob->mode != OB_MODE_OBJECT)) {
CTX_data_id_pointer_set(result, &ob->id);
}
}
return CTX_RESULT_OK;
}
if (CTX_data_equals(member, "selected_ids")) {
ListBase selected_objects;
CTX_data_selected_objects(C, &selected_objects);
LISTBASE_FOREACH (CollectionPointerLink *, object_ptr_link, &selected_objects) {
ID *selected_id = object_ptr_link->ptr.owner_id;
CTX_data_id_list_add(result, selected_id);
}
BLI_freelistN(&selected_objects);
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return CTX_RESULT_OK;
}
return CTX_RESULT_MEMBER_NOT_FOUND;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name View3D Context Queries
* \{ */
RegionView3D *ED_view3d_context_rv3d(bContext *C)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
if (rv3d == nullptr) {
ScrArea *area = CTX_wm_area(C);
if (area && area->spacetype == SPACE_VIEW3D) {
ARegion *region = BKE_area_find_region_active_win(area);
if (region) {
rv3d = static_cast<RegionView3D *>(region->regiondata);
}
}
}
return rv3d;
}
bool ED_view3d_context_user_region(bContext *C, View3D **r_v3d, ARegion **r_region)
{
ScrArea *area = CTX_wm_area(C);
*r_v3d = nullptr;
*r_region = nullptr;
if (area && area->spacetype == SPACE_VIEW3D) {
ARegion *region = CTX_wm_region(C);
View3D *v3d = (View3D *)area->spacedata.first;
if (region) {
RegionView3D *rv3d;
if ((region->regiontype == RGN_TYPE_WINDOW) &&
(rv3d = static_cast<RegionView3D *>(region->regiondata)) &&
(rv3d->viewlock & RV3D_LOCK_ROTATION) == 0)
{
*r_v3d = v3d;
*r_region = region;
return true;
}
if (ED_view3d_area_user_region(area, v3d, r_region)) {
*r_v3d = v3d;
return true;
}
}
}
return false;
}
/** \} */

View File

@@ -25,6 +25,7 @@ struct Scene;
struct ViewContext;
struct ViewLayer;
struct bContext;
struct bContextDataResult;
struct wmGizmoGroupType;
struct wmGizmoType;
struct wmKeyConfig;
@@ -34,6 +35,10 @@ struct wmOperatorType;
void VIEW3D_OT_toggle_matcap_flip(struct wmOperatorType *ot);
/* `view3d_context.cc` */
int view3d_context(const bContext *C, const char *member, bContextDataResult *result);
/* `view3d_ops.cc` */
void view3d_operatortypes(void);