2023-08-16 00:20:26 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2014 Blender Authors
|
2023-05-31 16:19:06 +02:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2016-10-07 16:34:55 +02:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup wm
|
2016-10-07 16:34:55 +02:00
|
|
|
*/
|
|
|
|
|
|
2017-11-20 14:11:45 +11:00
|
|
|
#include "MEM_guardedalloc.h"
|
2016-10-07 16:34:55 +02:00
|
|
|
|
|
|
|
|
#include "BLI_listbase.h"
|
Cleanup: reduce amount of math-related includes
Using ClangBuildAnalyzer on the whole Blender build, it was pointing
out that BLI_math.h is the heaviest "header hub" (i.e. non tiny file
that is included a lot).
However, there's very little (actually zero) source files in Blender
that need "all the math" (base, colors, vectors, matrices,
quaternions, intersection, interpolation, statistics, solvers and
time). A common use case is source files needing just vectors, or
just vectors & matrices, or just colors etc. Actually, 181 files
were including the whole math thing without needing it at all.
This change removes BLI_math.h completely, and instead in all the
places that need it, includes BLI_math_vector.h or BLI_math_color.h
and so on.
Change from that:
- BLI_math_color.h was included 1399 times -> now 408 (took 114.0sec
to parse -> now 36.3sec)
- BLI_simd.h 1403 -> 418 (109.7sec -> 34.9sec).
Full rebuild of Blender (Apple M1, Xcode, RelWithDebInfo) is not
affected much (342sec -> 334sec). Most of benefit would be when
someone's changing BLI_simd.h or BLI_math_color.h or similar files,
that now there's 3x fewer files result in a recompile.
Pull Request #110944
2023-08-09 11:39:20 +03:00
|
|
|
#include "BLI_math_matrix.h"
|
2025-01-26 20:07:59 +01:00
|
|
|
#include "BLI_math_vector.h"
|
2016-10-07 16:34:55 +02:00
|
|
|
|
2023-11-16 11:41:55 +01:00
|
|
|
#include "BKE_context.hh"
|
2016-10-07 16:34:55 +02:00
|
|
|
|
2023-08-10 22:40:27 +02:00
|
|
|
#include "RNA_access.hh"
|
|
|
|
|
#include "RNA_define.hh"
|
2024-07-10 18:30:02 +02:00
|
|
|
#include "RNA_prototypes.hh"
|
2017-06-21 13:54:46 +10:00
|
|
|
|
2024-02-10 18:25:14 +01:00
|
|
|
#include "BKE_global.hh"
|
2024-03-26 12:57:30 -04:00
|
|
|
#include "BKE_idprop.hh"
|
2023-12-01 19:43:16 +01:00
|
|
|
#include "BKE_main.hh"
|
2016-10-07 16:34:55 +02:00
|
|
|
|
2023-08-04 23:11:22 +02:00
|
|
|
#include "WM_api.hh"
|
2024-01-04 14:30:21 -05:00
|
|
|
#include "WM_toolsystem.hh"
|
2023-08-04 23:11:22 +02:00
|
|
|
#include "WM_types.hh"
|
2016-10-07 16:34:55 +02:00
|
|
|
|
2023-08-04 23:11:22 +02:00
|
|
|
#include "ED_screen.hh"
|
2023-08-05 02:57:52 +02:00
|
|
|
#include "ED_view3d.hh"
|
2017-11-20 14:11:45 +11:00
|
|
|
|
2017-06-10 10:42:35 +10:00
|
|
|
#ifdef WITH_PYTHON
|
2024-09-24 17:07:49 +02:00
|
|
|
# include "BPY_extern.hh"
|
2017-06-10 10:42:35 +10:00
|
|
|
#endif
|
|
|
|
|
|
2024-03-09 23:25:40 +11:00
|
|
|
/* Own includes. */
|
2024-01-04 14:30:21 -05:00
|
|
|
#include "wm_gizmo_intern.hh"
|
|
|
|
|
#include "wm_gizmo_wmapi.hh"
|
2016-10-07 16:34:55 +02:00
|
|
|
|
2025-02-04 13:53:30 +01:00
|
|
|
using blender::StringRef;
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
static void wm_gizmo_register(wmGizmoGroup *gzgroup, wmGizmo *gz);
|
2017-06-08 05:27:14 +10:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \note Follow #wm_operator_create convention.
|
|
|
|
|
*/
|
2018-07-14 23:49:00 +02:00
|
|
|
static wmGizmo *wm_gizmo_create(const wmGizmoType *gzt, PointerRNA *properties)
|
2017-06-08 05:27:14 +10:00
|
|
|
{
|
2023-07-20 22:12:29 +02:00
|
|
|
BLI_assert(gzt != nullptr);
|
2018-07-15 14:24:10 +02:00
|
|
|
BLI_assert(gzt->struct_size >= sizeof(wmGizmo));
|
2017-06-08 05:27:14 +10:00
|
|
|
|
2024-10-08 15:37:12 +02:00
|
|
|
/* FIXME: Old C-style allocation is not trivial to port to C++ here, because actual allocation
|
|
|
|
|
* depends on the 'subtype' of gizmo. The whole gizmo type hierarchy should probably be moved to
|
|
|
|
|
* proper C++ virtual inheritance at some point. */
|
|
|
|
|
wmGizmo *gz = static_cast<wmGizmo *>(MEM_callocN(gzt->struct_size, __func__));
|
2024-08-27 20:21:48 +02:00
|
|
|
new (gz) wmGizmo();
|
2018-07-15 14:24:10 +02:00
|
|
|
gz->type = gzt;
|
2017-06-18 05:38:10 +10:00
|
|
|
|
2024-03-09 23:25:40 +11:00
|
|
|
/* Initialize properties, either copy or create. */
|
2024-08-27 20:21:48 +02:00
|
|
|
gz->ptr = MEM_new<PointerRNA>("wmGizmoPtrRNA");
|
2017-06-21 13:54:46 +10:00
|
|
|
if (properties && properties->data) {
|
2023-07-20 22:12:29 +02:00
|
|
|
gz->properties = IDP_CopyProperty(static_cast<const IDProperty *>(properties->data));
|
2017-06-21 13:54:46 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2024-03-26 15:39:34 -04:00
|
|
|
gz->properties = blender::bke::idprop::create_group("wmGizmoProperties").release();
|
2017-06-21 13:54:46 +10:00
|
|
|
}
|
2025-01-24 16:45:32 +01:00
|
|
|
*gz->ptr = RNA_pointer_create_discrete(
|
|
|
|
|
static_cast<ID *>(G_MAIN->wm.first), gzt->srna, gz->properties);
|
2017-06-21 13:54:46 +10:00
|
|
|
|
2023-07-22 11:36:59 +10:00
|
|
|
WM_gizmo_properties_sanitize(gz->ptr, false);
|
2017-06-21 13:54:46 +10:00
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
unit_m4(gz->matrix_space);
|
|
|
|
|
unit_m4(gz->matrix_basis);
|
|
|
|
|
unit_m4(gz->matrix_offset);
|
2017-06-18 05:38:10 +10:00
|
|
|
|
2019-05-28 13:26:50 +10:00
|
|
|
gz->drag_part = -1;
|
|
|
|
|
|
2024-10-08 15:37:12 +02:00
|
|
|
/* Only ensure expected size for the target properties array. Actual initialization of these
|
|
|
|
|
* happen separately (see e.g. #WM_gizmo_target_property_def_rna and related). */
|
|
|
|
|
gz->target_properties.resize(gzt->target_property_defs_len);
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
return gz;
|
2017-06-08 05:27:14 +10:00
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
wmGizmo *WM_gizmo_new_ptr(const wmGizmoType *gzt, wmGizmoGroup *gzgroup, PointerRNA *properties)
|
2017-06-06 17:07:26 +10:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
wmGizmo *gz = wm_gizmo_create(gzt, properties);
|
2017-06-06 17:07:26 +10:00
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
wm_gizmo_register(gzgroup, gz);
|
2017-06-06 17:07:26 +10:00
|
|
|
|
2023-07-20 22:12:29 +02:00
|
|
|
if (gz->type->setup != nullptr) {
|
2018-07-15 14:24:10 +02:00
|
|
|
gz->type->setup(gz);
|
2017-06-17 10:01:22 +10:00
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
return gz;
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
|
2025-02-04 13:53:30 +01:00
|
|
|
wmGizmo *WM_gizmo_new(const StringRef idname, wmGizmoGroup *gzgroup, PointerRNA *properties)
|
2017-06-10 10:42:35 +10:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
const wmGizmoType *gzt = WM_gizmotype_find(idname, false);
|
|
|
|
|
return WM_gizmo_new_ptr(gzt, gzgroup, properties);
|
2017-06-26 13:16:25 +10:00
|
|
|
}
|
|
|
|
|
|
2016-10-07 16:34:55 +02:00
|
|
|
/**
|
|
|
|
|
* Initialize default values and allocate needed memory for members.
|
|
|
|
|
*/
|
2018-07-15 14:24:10 +02:00
|
|
|
static void gizmo_init(wmGizmo *gz)
|
2016-10-07 16:34:55 +02:00
|
|
|
{
|
2017-06-10 10:42:35 +10:00
|
|
|
const float color_default[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
2016-10-07 16:34:55 +02:00
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
gz->scale_basis = 1.0f;
|
|
|
|
|
gz->line_width = 1.0f;
|
2016-10-07 16:34:55 +02:00
|
|
|
|
2024-03-09 23:25:40 +11:00
|
|
|
/* Defaults. */
|
2018-07-15 14:24:10 +02:00
|
|
|
copy_v4_v4(gz->color, color_default);
|
|
|
|
|
copy_v4_v4(gz->color_hi, color_default);
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2018-07-14 23:49:00 +02:00
|
|
|
* Register \a gizmo.
|
2016-10-07 16:34:55 +02:00
|
|
|
*
|
2017-06-10 10:42:35 +10:00
|
|
|
* \note Not to be confused with type registration from RNA.
|
2016-10-07 16:34:55 +02:00
|
|
|
*/
|
2018-07-15 14:24:10 +02:00
|
|
|
static void wm_gizmo_register(wmGizmoGroup *gzgroup, wmGizmo *gz)
|
2016-10-07 16:34:55 +02:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
gizmo_init(gz);
|
|
|
|
|
wm_gizmogroup_gizmo_register(gzgroup, gz);
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
void WM_gizmo_free(wmGizmo *gz)
|
2016-10-07 16:34:55 +02:00
|
|
|
{
|
2023-07-20 22:12:29 +02:00
|
|
|
if (gz->type->free != nullptr) {
|
2018-07-15 14:24:10 +02:00
|
|
|
gz->type->free(gz);
|
2018-01-15 16:06:56 +11:00
|
|
|
}
|
|
|
|
|
|
2017-06-10 10:42:35 +10:00
|
|
|
#ifdef WITH_PYTHON
|
2018-07-15 14:24:10 +02:00
|
|
|
if (gz->py_instance) {
|
2024-03-09 23:25:40 +11:00
|
|
|
/* Do this first in case there are any `__del__` functions or
|
|
|
|
|
* similar that use properties. */
|
2018-07-15 14:24:10 +02:00
|
|
|
BPY_DECREF_RNA_INVALIDATE(gz->py_instance);
|
2017-06-10 10:42:35 +10:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-08-27 20:21:48 +02:00
|
|
|
for (wmGizmoOpElem &gzop : gz->op_data) {
|
|
|
|
|
WM_operator_properties_free(&gzop.ptr);
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
2017-06-21 13:54:46 +10:00
|
|
|
|
2023-07-20 22:12:29 +02:00
|
|
|
if (gz->ptr != nullptr) {
|
2018-07-15 14:24:10 +02:00
|
|
|
WM_gizmo_properties_free(gz->ptr);
|
2024-08-27 20:21:48 +02:00
|
|
|
MEM_delete(gz->ptr);
|
2017-06-21 13:54:46 +10:00
|
|
|
}
|
2016-10-07 16:34:55 +02:00
|
|
|
|
2024-10-08 15:37:12 +02:00
|
|
|
for (wmGizmoProperty &gz_prop : gz->target_properties) {
|
|
|
|
|
if (gz_prop.custom_func.free_fn) {
|
|
|
|
|
gz_prop.custom_func.free_fn(gz, &gz_prop);
|
2017-06-22 18:29:45 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-27 20:21:48 +02:00
|
|
|
/* Explicit calling of the destructor is needed here because allocation still happens 'the C
|
|
|
|
|
* way', see FIXME note in #wm_gizmo_create. */
|
|
|
|
|
gz->~wmGizmo();
|
2025-02-20 10:37:10 +01:00
|
|
|
MEM_freeN(static_cast<void *>(gz));
|
2017-07-31 06:41:10 +10:00
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
void WM_gizmo_unlink(ListBase *gizmolist, wmGizmoMap *gzmap, wmGizmo *gz, bContext *C)
|
2017-07-31 06:41:10 +10:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
if (gz->state & WM_GIZMO_STATE_HIGHLIGHT) {
|
2023-07-20 22:12:29 +02:00
|
|
|
wm_gizmomap_highlight_set(gzmap, C, nullptr, 0);
|
2017-07-31 06:41:10 +10:00
|
|
|
}
|
2018-07-15 14:24:10 +02:00
|
|
|
if (gz->state & WM_GIZMO_STATE_MODAL) {
|
2023-07-20 22:12:29 +02:00
|
|
|
wm_gizmomap_modal_set(gzmap, C, gz, nullptr, false);
|
2017-07-31 06:41:10 +10:00
|
|
|
}
|
|
|
|
|
/* Unlink instead of setting so we don't run callbacks. */
|
2018-07-15 14:24:10 +02:00
|
|
|
if (gz->state & WM_GIZMO_STATE_SELECT) {
|
|
|
|
|
WM_gizmo_select_unlink(gzmap, gz);
|
2017-07-31 06:41:10 +10:00
|
|
|
}
|
|
|
|
|
|
2018-07-14 23:49:00 +02:00
|
|
|
if (gizmolist) {
|
2018-07-15 14:24:10 +02:00
|
|
|
BLI_remlink(gizmolist, gz);
|
2017-06-16 08:20:27 +10:00
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
BLI_assert(gzmap->gzmap_context.highlight != gz);
|
|
|
|
|
BLI_assert(gzmap->gzmap_context.modal != gz);
|
2017-06-16 08:20:27 +10:00
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
WM_gizmo_free(gz);
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
2018-07-14 23:49:00 +02:00
|
|
|
/** \name Gizmo Creation API
|
2016-10-07 16:34:55 +02:00
|
|
|
*
|
2018-07-14 23:49:00 +02:00
|
|
|
* API for defining data on gizmo creation.
|
2016-10-07 16:34:55 +02:00
|
|
|
*
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
wmGizmoOpElem *WM_gizmo_operator_get(wmGizmo *gz, int part_index)
|
2017-08-28 00:48:43 +10:00
|
|
|
{
|
2024-10-02 15:42:49 +10:00
|
|
|
if ((part_index >= 0) && (part_index < gz->op_data.size())) {
|
2018-07-15 14:24:10 +02:00
|
|
|
return &gz->op_data[part_index];
|
2017-08-28 00:48:43 +10:00
|
|
|
}
|
2023-07-20 22:12:29 +02:00
|
|
|
return nullptr;
|
2017-08-28 00:48:43 +10:00
|
|
|
}
|
2016-10-07 16:34:55 +02:00
|
|
|
|
2018-07-14 23:49:00 +02:00
|
|
|
PointerRNA *WM_gizmo_operator_set(wmGizmo *gz,
|
2018-07-15 14:24:10 +02:00
|
|
|
int part_index,
|
2017-08-28 00:48:43 +10:00
|
|
|
wmOperatorType *ot,
|
|
|
|
|
IDProperty *properties)
|
2016-10-07 16:34:55 +02:00
|
|
|
{
|
2017-08-28 00:48:43 +10:00
|
|
|
BLI_assert(part_index < 255);
|
2024-08-27 20:21:48 +02:00
|
|
|
if (part_index >= gz->op_data.size()) {
|
|
|
|
|
gz->op_data.resize(part_index + 1);
|
2017-08-28 00:48:43 +10:00
|
|
|
}
|
2024-08-27 20:21:48 +02:00
|
|
|
wmGizmoOpElem &gzop = gz->op_data[part_index];
|
|
|
|
|
gzop.type = ot;
|
2016-10-07 16:34:55 +02:00
|
|
|
|
2024-08-27 20:21:48 +02:00
|
|
|
if (gzop.ptr.data) {
|
|
|
|
|
WM_operator_properties_free(&gzop.ptr);
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
2024-08-27 20:21:48 +02:00
|
|
|
WM_operator_properties_create_ptr(&gzop.ptr, ot);
|
2016-10-07 16:34:55 +02:00
|
|
|
|
2017-06-26 08:19:55 +10:00
|
|
|
if (properties) {
|
2024-08-27 20:21:48 +02:00
|
|
|
gzop.ptr.data = properties;
|
2017-06-26 08:19:55 +10:00
|
|
|
}
|
|
|
|
|
|
2024-08-27 20:21:48 +02:00
|
|
|
return &gzop.ptr;
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
|
2022-03-11 22:49:47 +11:00
|
|
|
int WM_gizmo_operator_invoke(bContext *C, wmGizmo *gz, wmGizmoOpElem *gzop, const wmEvent *event)
|
2019-01-23 16:14:52 +11:00
|
|
|
{
|
|
|
|
|
if (gz->flag & WM_GIZMO_OPERATOR_TOOL_INIT) {
|
2023-09-08 16:58:00 +10:00
|
|
|
/* Merge tool-settings into the gizmo properties. */
|
2019-01-23 16:14:52 +11:00
|
|
|
PointerRNA tref_ptr;
|
|
|
|
|
bToolRef *tref = WM_toolsystem_ref_from_context(C);
|
|
|
|
|
if (tref && WM_toolsystem_ref_properties_get_from_operator(tref, gzop->type, &tref_ptr)) {
|
2023-07-20 22:12:29 +02:00
|
|
|
if (gzop->ptr.data == nullptr) {
|
2024-03-26 15:39:34 -04:00
|
|
|
gzop->ptr.data = blender::bke::idprop::create_group("wmOperatorProperties").release();
|
2019-01-23 16:14:52 +11:00
|
|
|
}
|
2023-07-20 22:12:29 +02:00
|
|
|
IDP_MergeGroup(static_cast<IDProperty *>(gzop->ptr.data),
|
|
|
|
|
static_cast<const IDProperty *>(tref_ptr.data),
|
|
|
|
|
false);
|
2019-01-23 16:14:52 +11:00
|
|
|
}
|
|
|
|
|
}
|
2022-03-11 22:49:47 +11:00
|
|
|
return WM_operator_name_call_ptr(C, gzop->type, WM_OP_INVOKE_DEFAULT, &gzop->ptr, event);
|
2019-01-23 16:14:52 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-14 23:49:00 +02:00
|
|
|
static void wm_gizmo_set_matrix_rotation_from_z_axis__internal(float matrix[4][4],
|
2017-06-18 07:43:45 +10:00
|
|
|
const float z_axis[3])
|
|
|
|
|
{
|
2024-03-09 23:25:40 +11:00
|
|
|
/* Old code, seems we can use simpler method. */
|
2017-06-18 07:43:45 +10:00
|
|
|
#if 0
|
|
|
|
|
const float z_global[3] = {0.0f, 0.0f, 1.0f};
|
|
|
|
|
float rot[3][3];
|
|
|
|
|
|
|
|
|
|
rotation_between_vecs_to_mat3(rot, z_global, z_axis);
|
|
|
|
|
copy_v3_v3(matrix[0], rot[0]);
|
|
|
|
|
copy_v3_v3(matrix[1], rot[1]);
|
|
|
|
|
copy_v3_v3(matrix[2], rot[2]);
|
|
|
|
|
#else
|
|
|
|
|
normalize_v3_v3(matrix[2], z_axis);
|
|
|
|
|
ortho_basis_v3v3_v3(matrix[0], matrix[1], matrix[2]);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-14 23:49:00 +02:00
|
|
|
static void wm_gizmo_set_matrix_rotation_from_yz_axis__internal(float matrix[4][4],
|
2017-06-18 07:43:45 +10:00
|
|
|
const float y_axis[3],
|
|
|
|
|
const float z_axis[3])
|
|
|
|
|
{
|
|
|
|
|
normalize_v3_v3(matrix[1], y_axis);
|
|
|
|
|
normalize_v3_v3(matrix[2], z_axis);
|
|
|
|
|
cross_v3_v3v3(matrix[0], matrix[1], matrix[2]);
|
|
|
|
|
normalize_v3(matrix[0]);
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-14 23:49:00 +02:00
|
|
|
void WM_gizmo_set_matrix_rotation_from_z_axis(wmGizmo *gz, const float z_axis[3])
|
2017-06-18 07:43:45 +10:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
wm_gizmo_set_matrix_rotation_from_z_axis__internal(gz->matrix_basis, z_axis);
|
2017-06-18 07:43:45 +10:00
|
|
|
}
|
2018-07-14 23:49:00 +02:00
|
|
|
void WM_gizmo_set_matrix_rotation_from_yz_axis(wmGizmo *gz,
|
2018-07-15 14:24:10 +02:00
|
|
|
const float y_axis[3],
|
|
|
|
|
const float z_axis[3])
|
2017-06-18 07:43:45 +10:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
wm_gizmo_set_matrix_rotation_from_yz_axis__internal(gz->matrix_basis, y_axis, z_axis);
|
2017-06-18 07:43:45 +10:00
|
|
|
}
|
2018-07-15 14:24:10 +02:00
|
|
|
void WM_gizmo_set_matrix_location(wmGizmo *gz, const float origin[3])
|
2016-10-07 16:34:55 +02:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
copy_v3_v3(gz->matrix_basis[3], origin);
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-14 23:49:00 +02:00
|
|
|
void WM_gizmo_set_matrix_offset_rotation_from_z_axis(wmGizmo *gz, const float z_axis[3])
|
2017-06-18 07:43:45 +10:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
wm_gizmo_set_matrix_rotation_from_z_axis__internal(gz->matrix_offset, z_axis);
|
2017-06-18 07:43:45 +10:00
|
|
|
}
|
2018-07-14 23:49:00 +02:00
|
|
|
void WM_gizmo_set_matrix_offset_rotation_from_yz_axis(wmGizmo *gz,
|
2018-07-15 14:24:10 +02:00
|
|
|
const float y_axis[3],
|
|
|
|
|
const float z_axis[3])
|
2017-06-18 07:43:45 +10:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
wm_gizmo_set_matrix_rotation_from_yz_axis__internal(gz->matrix_offset, y_axis, z_axis);
|
2017-06-18 07:43:45 +10:00
|
|
|
}
|
2018-07-15 14:24:10 +02:00
|
|
|
void WM_gizmo_set_matrix_offset_location(wmGizmo *gz, const float offset[3])
|
2016-10-07 16:34:55 +02:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
copy_v3_v3(gz->matrix_offset[3], offset);
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
void WM_gizmo_set_flag(wmGizmo *gz, const int flag, const bool enable)
|
2016-10-07 16:34:55 +02:00
|
|
|
{
|
|
|
|
|
if (enable) {
|
2023-07-20 22:12:29 +02:00
|
|
|
gz->flag |= eWM_GizmoFlag(flag);
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2023-11-09 17:27:46 +11:00
|
|
|
gz->flag &= ~eWM_GizmoFlag(flag);
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
void WM_gizmo_set_scale(wmGizmo *gz, const float scale)
|
2016-10-07 16:34:55 +02:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
gz->scale_basis = scale;
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
void WM_gizmo_set_line_width(wmGizmo *gz, const float line_width)
|
2016-10-07 16:34:55 +02:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
gz->line_width = line_width;
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
void WM_gizmo_get_color(const wmGizmo *gz, float color[4])
|
2017-06-07 22:12:32 +10:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
copy_v4_v4(color, gz->color);
|
2017-06-07 22:12:32 +10:00
|
|
|
}
|
2018-07-15 14:24:10 +02:00
|
|
|
void WM_gizmo_set_color(wmGizmo *gz, const float color[4])
|
2016-10-07 16:34:55 +02:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
copy_v4_v4(gz->color, color);
|
2017-06-07 22:12:32 +10:00
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
void WM_gizmo_get_color_highlight(const wmGizmo *gz, float color_hi[4])
|
2017-06-07 22:12:32 +10:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
copy_v4_v4(color_hi, gz->color_hi);
|
2017-06-07 22:12:32 +10:00
|
|
|
}
|
2018-07-15 14:24:10 +02:00
|
|
|
void WM_gizmo_set_color_highlight(wmGizmo *gz, const float color_hi[4])
|
2017-06-07 22:12:32 +10:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
copy_v4_v4(gz->color_hi, color_hi);
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
2017-06-07 22:12:32 +10:00
|
|
|
|
2018-07-14 23:49:00 +02:00
|
|
|
/** \} */ /* Gizmo Creation API. */
|
2016-10-07 16:34:55 +02:00
|
|
|
|
2017-06-06 17:07:26 +10:00
|
|
|
/* -------------------------------------------------------------------- */
|
2018-07-14 23:49:00 +02:00
|
|
|
/** \name Gizmo Callback Assignment
|
2017-06-06 17:07:26 +10:00
|
|
|
* \{ */
|
|
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
void WM_gizmo_set_fn_custom_modal(wmGizmo *gz, wmGizmoFnModal fn)
|
2017-06-06 17:07:26 +10:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
gz->custom_modal = fn;
|
2017-06-06 17:07:26 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
2016-10-07 16:34:55 +02:00
|
|
|
/* -------------------------------------------------------------------- */
|
2021-12-08 17:12:41 +11:00
|
|
|
|
2018-07-14 23:49:00 +02:00
|
|
|
bool wm_gizmo_select_set_ex(
|
2018-07-15 14:24:10 +02:00
|
|
|
wmGizmoMap *gzmap, wmGizmo *gz, bool select, bool use_array, bool use_callback)
|
2016-10-07 16:34:55 +02:00
|
|
|
{
|
|
|
|
|
bool changed = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-07-26 08:12:46 +10:00
|
|
|
if (select) {
|
2018-07-15 14:24:10 +02:00
|
|
|
if ((gz->state & WM_GIZMO_STATE_SELECT) == 0) {
|
2017-07-26 08:12:46 +10:00
|
|
|
if (use_array) {
|
2018-07-15 14:24:10 +02:00
|
|
|
wm_gizmomap_select_array_push_back(gzmap, gz);
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
2018-07-15 14:24:10 +02:00
|
|
|
gz->state |= WM_GIZMO_STATE_SELECT;
|
2016-10-07 16:34:55 +02:00
|
|
|
changed = true;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2018-07-15 14:24:10 +02:00
|
|
|
if (gz->state & WM_GIZMO_STATE_SELECT) {
|
2017-07-26 08:12:46 +10:00
|
|
|
if (use_array) {
|
2018-07-15 14:24:10 +02:00
|
|
|
wm_gizmomap_select_array_remove(gzmap, gz);
|
2017-07-26 08:12:46 +10:00
|
|
|
}
|
2018-07-15 14:24:10 +02:00
|
|
|
gz->state &= ~WM_GIZMO_STATE_SELECT;
|
2017-07-26 08:12:46 +10:00
|
|
|
changed = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-07-31 06:41:10 +10:00
|
|
|
/* In the case of unlinking we only want to remove from the array
|
2024-03-09 23:25:40 +11:00
|
|
|
* and not write to the external state. */
|
2017-07-31 06:41:10 +10:00
|
|
|
if (use_callback && changed) {
|
2018-07-15 14:24:10 +02:00
|
|
|
if (gz->type->select_refresh) {
|
|
|
|
|
gz->type->select_refresh(gz);
|
2017-07-26 08:12:46 +10:00
|
|
|
}
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-10-07 16:34:55 +02:00
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
bool WM_gizmo_select_unlink(wmGizmoMap *gzmap, wmGizmo *gz)
|
2017-07-31 06:41:10 +10:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
return wm_gizmo_select_set_ex(gzmap, gz, false, true, false);
|
2017-07-31 06:41:10 +10:00
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
bool WM_gizmo_select_set(wmGizmoMap *gzmap, wmGizmo *gz, bool select)
|
2016-10-07 16:34:55 +02:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
return wm_gizmo_select_set_ex(gzmap, gz, select, true, true);
|
2017-07-26 08:12:46 +10:00
|
|
|
}
|
2016-10-07 16:34:55 +02:00
|
|
|
|
2019-06-24 17:05:22 +10:00
|
|
|
bool WM_gizmo_highlight_set(wmGizmoMap *gzmap, wmGizmo *gz)
|
2017-11-11 02:39:45 +11:00
|
|
|
{
|
2023-07-20 22:12:29 +02:00
|
|
|
return wm_gizmomap_highlight_set(gzmap, nullptr, gz, gz ? gz->highlight_part : 0);
|
2017-11-11 02:39:45 +11:00
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
bool wm_gizmo_select_and_highlight(bContext *C, wmGizmoMap *gzmap, wmGizmo *gz)
|
2017-07-26 08:12:46 +10:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
if (WM_gizmo_select_set(gzmap, gz, true)) {
|
|
|
|
|
wm_gizmomap_highlight_set(gzmap, C, gz, gz->highlight_part);
|
2017-07-26 08:12:46 +10:00
|
|
|
return true;
|
|
|
|
|
}
|
2020-08-07 11:23:02 +02:00
|
|
|
return false;
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
void WM_gizmo_modal_set_from_setup(
|
|
|
|
|
wmGizmoMap *gzmap, bContext *C, wmGizmo *gz, int part_index, const wmEvent *event)
|
2018-05-09 22:43:24 +02:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
gz->highlight_part = part_index;
|
|
|
|
|
WM_gizmo_highlight_set(gzmap, gz);
|
2018-05-09 22:43:24 +02:00
|
|
|
if (false) {
|
2018-07-15 14:24:10 +02:00
|
|
|
wm_gizmomap_modal_set(gzmap, C, gz, event, true);
|
2018-05-09 22:43:24 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* WEAK: but it works. */
|
2023-07-20 22:12:29 +02:00
|
|
|
WM_operator_name_call(C, "GIZMOGROUP_OT_gizmo_tweak", WM_OP_INVOKE_DEFAULT, nullptr, event);
|
2018-05-09 22:43:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
void WM_gizmo_modal_set_while_modal(wmGizmoMap *gzmap,
|
|
|
|
|
bContext *C,
|
|
|
|
|
wmGizmo *gz,
|
2023-01-26 07:54:04 -03:00
|
|
|
const wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
if (gzmap->gzmap_context.modal) {
|
|
|
|
|
wm_gizmomap_modal_set(gzmap, C, gzmap->gzmap_context.modal, event, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (gz) {
|
|
|
|
|
wm_gizmo_calculate_scale(gz, C);
|
|
|
|
|
|
|
|
|
|
/* Set `highlight_part` to -1 to skip operator invocation. */
|
|
|
|
|
const int highlight_part = gz->highlight_part;
|
|
|
|
|
gz->highlight_part = -1;
|
|
|
|
|
wm_gizmomap_modal_set(gzmap, C, gz, event, true);
|
|
|
|
|
gz->highlight_part = highlight_part;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
void wm_gizmo_calculate_scale(wmGizmo *gz, const bContext *C)
|
2016-10-07 16:34:55 +02:00
|
|
|
{
|
|
|
|
|
const RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
2023-03-17 04:19:05 +01:00
|
|
|
float scale = UI_SCALE_FAC;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
if ((gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_SCALE) == 0) {
|
2018-07-14 23:49:00 +02:00
|
|
|
scale *= U.gizmo_size;
|
2017-06-19 17:47:04 +10:00
|
|
|
if (rv3d) {
|
2017-06-19 18:22:04 +10:00
|
|
|
/* 'ED_view3d_pixel_size' includes 'U.pixelsize', remove it. */
|
2017-08-15 13:27:31 +10:00
|
|
|
float matrix_world[4][4];
|
2018-07-15 14:24:10 +02:00
|
|
|
if (gz->type->matrix_basis_get) {
|
2017-08-15 13:27:31 +10:00
|
|
|
float matrix_basis[4][4];
|
2018-07-15 14:24:10 +02:00
|
|
|
gz->type->matrix_basis_get(gz, matrix_basis);
|
|
|
|
|
mul_m4_m4m4(matrix_world, gz->matrix_space, matrix_basis);
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2018-07-15 14:24:10 +02:00
|
|
|
mul_m4_m4m4(matrix_world, gz->matrix_space, gz->matrix_basis);
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-15 13:27:31 +10:00
|
|
|
/* Exclude matrix_offset from scale. */
|
2018-05-25 10:07:28 +02:00
|
|
|
scale *= ED_view3d_pixel_size_no_ui_scale(rv3d, matrix_world[3]);
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
gz->scale_final = gz->scale_basis * scale;
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
static void gizmo_update_prop_data(wmGizmo *gz)
|
2016-10-07 16:34:55 +02:00
|
|
|
{
|
2024-03-09 23:25:40 +11:00
|
|
|
/* Gizmo property might have been changed, so update gizmo. */
|
2018-07-15 14:24:10 +02:00
|
|
|
if (gz->type->property_update) {
|
2024-10-08 15:37:12 +02:00
|
|
|
for (wmGizmoProperty &gz_prop : gz->target_properties) {
|
|
|
|
|
if (WM_gizmo_target_property_is_valid(&gz_prop)) {
|
|
|
|
|
gz->type->property_update(gz, &gz_prop);
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
void wm_gizmo_update(wmGizmo *gz, const bContext *C, const bool refresh_map)
|
2016-10-07 16:34:55 +02:00
|
|
|
{
|
|
|
|
|
if (refresh_map) {
|
2018-07-15 14:24:10 +02:00
|
|
|
gizmo_update_prop_data(gz);
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
2018-07-15 14:24:10 +02:00
|
|
|
wm_gizmo_calculate_scale(gz, C);
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
int wm_gizmo_is_visible(wmGizmo *gz)
|
2016-10-07 16:34:55 +02:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
if (gz->flag & WM_GIZMO_HIDDEN) {
|
2017-06-23 09:18:53 +10:00
|
|
|
return 0;
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
2018-07-15 14:24:10 +02:00
|
|
|
if ((gz->state & WM_GIZMO_STATE_MODAL) &&
|
|
|
|
|
!(gz->flag & (WM_GIZMO_DRAW_MODAL | WM_GIZMO_DRAW_VALUE)))
|
|
|
|
|
{
|
2024-03-09 23:25:40 +11:00
|
|
|
/* Don't draw while modal (dragging). */
|
2017-06-23 09:18:53 +10:00
|
|
|
return 0;
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
2018-07-15 14:24:10 +02:00
|
|
|
if ((gz->flag & WM_GIZMO_DRAW_HOVER) && !(gz->state & WM_GIZMO_STATE_HIGHLIGHT) &&
|
2024-03-09 23:25:40 +11:00
|
|
|
!(gz->state & WM_GIZMO_STATE_SELECT)) /* Still draw selected gizmos. */
|
2016-10-07 16:34:55 +02:00
|
|
|
{
|
2024-03-09 23:25:40 +11:00
|
|
|
/* Update but don't draw. */
|
2018-07-14 23:49:00 +02:00
|
|
|
return WM_GIZMO_IS_VISIBLE_UPDATE;
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-14 23:49:00 +02:00
|
|
|
return WM_GIZMO_IS_VISIBLE_UPDATE | WM_GIZMO_IS_VISIBLE_DRAW;
|
2016-10-07 16:34:55 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-14 23:49:00 +02:00
|
|
|
void WM_gizmo_calc_matrix_final_params(const wmGizmo *gz,
|
2023-07-21 10:59:54 +10:00
|
|
|
const WM_GizmoMatrixParams *params,
|
2017-08-09 22:24:05 +10:00
|
|
|
float r_mat[4][4])
|
|
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
const float(*const matrix_space)[4] = params->matrix_space ? params->matrix_space :
|
|
|
|
|
gz->matrix_space;
|
|
|
|
|
const float(*const matrix_basis)[4] = params->matrix_basis ? params->matrix_basis :
|
|
|
|
|
gz->matrix_basis;
|
|
|
|
|
const float(*const matrix_offset)[4] = params->matrix_offset ? params->matrix_offset :
|
|
|
|
|
gz->matrix_offset;
|
|
|
|
|
const float *scale_final = params->scale_final ? params->scale_final : &gz->scale_final;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-09 22:24:05 +10:00
|
|
|
float final_matrix[4][4];
|
2023-07-20 22:12:29 +02:00
|
|
|
if (params->matrix_basis == nullptr && gz->type->matrix_basis_get) {
|
2018-07-15 14:24:10 +02:00
|
|
|
gz->type->matrix_basis_get(gz, final_matrix);
|
2017-08-30 17:53:32 +10:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
copy_m4_m4(final_matrix, matrix_basis);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
if (gz->flag & WM_GIZMO_DRAW_NO_SCALE) {
|
2017-08-09 22:24:05 +10:00
|
|
|
mul_m4_m4m4(final_matrix, final_matrix, matrix_offset);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2018-07-15 14:24:10 +02:00
|
|
|
if (gz->flag & WM_GIZMO_DRAW_OFFSET_SCALE) {
|
2017-08-31 01:38:51 +10:00
|
|
|
mul_mat3_m4_fl(final_matrix, *scale_final);
|
|
|
|
|
mul_m4_m4m4(final_matrix, final_matrix, matrix_offset);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
mul_m4_m4m4(final_matrix, final_matrix, matrix_offset);
|
|
|
|
|
mul_mat3_m4_fl(final_matrix, *scale_final);
|
|
|
|
|
}
|
2017-08-09 22:24:05 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-09 22:55:18 +10:00
|
|
|
mul_m4_m4m4(r_mat, matrix_space, final_matrix);
|
2017-08-09 22:24:05 +10:00
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
void WM_gizmo_calc_matrix_final_no_offset(const wmGizmo *gz, float r_mat[4][4])
|
2018-05-14 23:15:15 +02:00
|
|
|
{
|
|
|
|
|
float mat_identity[4][4];
|
|
|
|
|
unit_m4(mat_identity);
|
|
|
|
|
|
2023-07-20 22:12:29 +02:00
|
|
|
WM_GizmoMatrixParams params{};
|
|
|
|
|
params.matrix_space = nullptr;
|
|
|
|
|
params.matrix_basis = nullptr;
|
|
|
|
|
params.matrix_offset = mat_identity;
|
|
|
|
|
params.scale_final = nullptr;
|
|
|
|
|
WM_gizmo_calc_matrix_final_params(gz, ¶ms, r_mat);
|
2018-05-14 23:15:15 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
void WM_gizmo_calc_matrix_final(const wmGizmo *gz, float r_mat[4][4])
|
2017-08-09 22:24:05 +10:00
|
|
|
{
|
2023-07-20 22:12:29 +02:00
|
|
|
WM_GizmoMatrixParams params{};
|
|
|
|
|
params.matrix_space = nullptr;
|
|
|
|
|
params.matrix_basis = nullptr;
|
|
|
|
|
params.matrix_offset = nullptr;
|
|
|
|
|
params.scale_final = nullptr;
|
|
|
|
|
WM_gizmo_calc_matrix_final_params(gz, ¶ms, r_mat);
|
2017-08-09 22:24:05 +10:00
|
|
|
}
|
2017-06-21 13:54:46 +10:00
|
|
|
|
2016-10-07 16:34:55 +02:00
|
|
|
/* -------------------------------------------------------------------- */
|
2018-09-24 18:46:51 +02:00
|
|
|
/** \name Gizmo Property Access
|
2017-06-21 13:54:46 +10:00
|
|
|
*
|
|
|
|
|
* Matches `WM_operator_properties` conventions.
|
|
|
|
|
*
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
void WM_gizmo_properties_create_ptr(PointerRNA *ptr, wmGizmoType *gzt)
|
2017-06-21 13:54:46 +10:00
|
|
|
{
|
2025-01-24 16:45:32 +01:00
|
|
|
*ptr = RNA_pointer_create_discrete(nullptr, gzt->srna, nullptr);
|
2017-06-21 13:54:46 +10:00
|
|
|
}
|
|
|
|
|
|
2025-02-04 13:53:30 +01:00
|
|
|
void WM_gizmo_properties_create(PointerRNA *ptr, const StringRef gtstring)
|
2017-06-21 13:54:46 +10:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
const wmGizmoType *gzt = WM_gizmotype_find(gtstring, false);
|
2017-06-21 13:54:46 +10:00
|
|
|
|
2019-04-13 09:15:15 +02:00
|
|
|
if (gzt) {
|
2018-07-15 14:24:10 +02:00
|
|
|
WM_gizmo_properties_create_ptr(ptr, (wmGizmoType *)gzt);
|
2019-04-13 09:15:15 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2025-01-24 16:45:32 +01:00
|
|
|
*ptr = RNA_pointer_create_discrete(nullptr, &RNA_GizmoProperties, nullptr);
|
2019-04-13 09:15:15 +02:00
|
|
|
}
|
2017-06-21 13:54:46 +10:00
|
|
|
}
|
|
|
|
|
|
2025-02-04 13:53:30 +01:00
|
|
|
void WM_gizmo_properties_alloc(PointerRNA **ptr, IDProperty **properties, const StringRef gtstring)
|
2017-06-21 13:54:46 +10:00
|
|
|
{
|
2023-07-20 22:12:29 +02:00
|
|
|
if (*properties == nullptr) {
|
2024-03-26 15:39:34 -04:00
|
|
|
*properties = blender::bke::idprop::create_group("wmOpItemProp").release();
|
2017-06-21 13:54:46 +10:00
|
|
|
}
|
|
|
|
|
|
2023-07-20 22:12:29 +02:00
|
|
|
if (*ptr == nullptr) {
|
2024-08-27 20:21:48 +02:00
|
|
|
*ptr = MEM_new<PointerRNA>("wmOpItemPtr");
|
2018-07-15 14:24:10 +02:00
|
|
|
WM_gizmo_properties_create(*ptr, gtstring);
|
2017-06-21 13:54:46 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(*ptr)->data = *properties;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-14 23:49:00 +02:00
|
|
|
void WM_gizmo_properties_sanitize(PointerRNA *ptr, const bool no_context)
|
2017-06-21 13:54:46 +10:00
|
|
|
{
|
|
|
|
|
RNA_STRUCT_BEGIN (ptr, prop) {
|
|
|
|
|
switch (RNA_property_type(prop)) {
|
|
|
|
|
case PROP_ENUM:
|
2019-04-13 09:15:15 +02:00
|
|
|
if (no_context) {
|
2017-06-21 13:54:46 +10:00
|
|
|
RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
|
2019-04-13 09:15:15 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2017-06-21 13:54:46 +10:00
|
|
|
RNA_def_property_clear_flag(prop, PROP_ENUM_NO_CONTEXT);
|
2019-04-13 09:15:15 +02:00
|
|
|
}
|
2017-06-21 13:54:46 +10:00
|
|
|
break;
|
|
|
|
|
case PROP_POINTER: {
|
|
|
|
|
StructRNA *ptype = RNA_property_pointer_type(ptr, prop);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-03-09 23:25:40 +11:00
|
|
|
/* Recurse into gizmo properties. */
|
2018-07-14 23:49:00 +02:00
|
|
|
if (RNA_struct_is_a(ptype, &RNA_GizmoProperties)) {
|
2017-06-21 13:54:46 +10:00
|
|
|
PointerRNA opptr = RNA_property_pointer_get(ptr, prop);
|
2018-07-14 23:49:00 +02:00
|
|
|
WM_gizmo_properties_sanitize(&opptr, no_context);
|
2017-06-21 13:54:46 +10:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
RNA_STRUCT_END;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-14 23:49:00 +02:00
|
|
|
bool WM_gizmo_properties_default(PointerRNA *ptr, const bool do_update)
|
2017-06-21 13:54:46 +10:00
|
|
|
{
|
|
|
|
|
bool changed = false;
|
|
|
|
|
RNA_STRUCT_BEGIN (ptr, prop) {
|
|
|
|
|
switch (RNA_property_type(prop)) {
|
|
|
|
|
case PROP_POINTER: {
|
|
|
|
|
StructRNA *ptype = RNA_property_pointer_type(ptr, prop);
|
|
|
|
|
if (ptype != &RNA_Struct) {
|
|
|
|
|
PointerRNA opptr = RNA_property_pointer_get(ptr, prop);
|
2018-07-14 23:49:00 +02:00
|
|
|
changed |= WM_gizmo_properties_default(&opptr, do_update);
|
2017-06-21 13:54:46 +10:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
if ((do_update == false) || (RNA_property_is_set(ptr, prop) == false)) {
|
|
|
|
|
if (RNA_property_reset(ptr, prop, -1)) {
|
|
|
|
|
changed = true;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2017-06-21 13:54:46 +10:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
RNA_STRUCT_END;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-06-21 13:54:46 +10:00
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
void WM_gizmo_properties_reset(wmGizmo *gz)
|
2017-06-21 13:54:46 +10:00
|
|
|
{
|
2018-07-15 14:24:10 +02:00
|
|
|
if (gz->ptr->data) {
|
2017-06-21 13:54:46 +10:00
|
|
|
PropertyRNA *iterprop;
|
2018-07-15 14:24:10 +02:00
|
|
|
iterprop = RNA_struct_iterator_property(gz->type->srna);
|
2017-06-21 13:54:46 +10:00
|
|
|
|
2018-07-15 14:24:10 +02:00
|
|
|
RNA_PROP_BEGIN (gz->ptr, itemptr, iterprop) {
|
2023-07-20 22:12:29 +02:00
|
|
|
PropertyRNA *prop = static_cast<PropertyRNA *>(itemptr.data);
|
2017-06-21 13:54:46 +10:00
|
|
|
|
|
|
|
|
if ((RNA_property_flag(prop) & PROP_SKIP_SAVE) == 0) {
|
|
|
|
|
const char *identifier = RNA_property_identifier(prop);
|
2018-07-15 14:24:10 +02:00
|
|
|
RNA_struct_idprops_unset(gz->ptr, identifier);
|
2017-06-21 13:54:46 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
RNA_PROP_END;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-14 23:49:00 +02:00
|
|
|
void WM_gizmo_properties_clear(PointerRNA *ptr)
|
2017-06-21 13:54:46 +10:00
|
|
|
{
|
2023-07-20 22:12:29 +02:00
|
|
|
IDProperty *properties = static_cast<IDProperty *>(ptr->data);
|
2017-06-21 13:54:46 +10:00
|
|
|
|
|
|
|
|
if (properties) {
|
|
|
|
|
IDP_ClearProperty(properties);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-14 23:49:00 +02:00
|
|
|
void WM_gizmo_properties_free(PointerRNA *ptr)
|
2017-06-21 13:54:46 +10:00
|
|
|
{
|
2023-07-20 22:12:29 +02:00
|
|
|
IDProperty *properties = static_cast<IDProperty *>(ptr->data);
|
2017-06-21 13:54:46 +10:00
|
|
|
|
|
|
|
|
if (properties) {
|
|
|
|
|
IDP_FreeProperty(properties);
|
2024-03-09 23:25:40 +11:00
|
|
|
ptr->data = nullptr; /* Just in case. */
|
2017-06-21 13:54:46 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
2018-01-24 17:31:11 +11:00
|
|
|
|
2016-10-07 16:34:55 +02:00
|
|
|
/* -------------------------------------------------------------------- */
|
2018-01-24 17:31:11 +11:00
|
|
|
/** \name General Utilities
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
bool WM_gizmo_context_check_drawstep(const bContext *C, eWM_GizmoFlagMapDrawStep step)
|
2018-01-24 17:31:11 +11:00
|
|
|
{
|
|
|
|
|
switch (step) {
|
2018-07-14 23:49:00 +02:00
|
|
|
case WM_GIZMOMAP_DRAWSTEP_2D: {
|
2018-01-24 17:31:11 +11:00
|
|
|
break;
|
|
|
|
|
}
|
2018-07-14 23:49:00 +02:00
|
|
|
case WM_GIZMOMAP_DRAWSTEP_3D: {
|
2018-01-24 17:31:11 +11:00
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
|
|
|
|
if (ED_screen_animation_playing(wm)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|