139 lines
3.9 KiB
C++
139 lines
3.9 KiB
C++
/* 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.hh"
|
|
#include "BKE_layer.hh"
|
|
#include "BKE_screen.hh"
|
|
|
|
#include "ED_view3d.hh"
|
|
|
|
#include "view3d_intern.hh"
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \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")) {
|
|
blender::Vector<PointerRNA> selected_objects;
|
|
CTX_data_selected_objects(C, &selected_objects);
|
|
for (const PointerRNA &ptr : selected_objects) {
|
|
ID *selected_id = ptr.owner_id;
|
|
CTX_data_id_list_add(result, selected_id);
|
|
}
|
|
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;
|
|
}
|
|
|
|
/** \} */
|