Snap Gizmo: Minor optimization when updating gizmo properties

As the Snap Gizmo properties are used as return of snapping values and
therefore updated with each change, use callbacks to get these values
through RNA properties.

Differential Revision: https://developer.blender.org/D8525
This commit is contained in:
Germano Cavalcante 2021-03-29 13:57:10 -03:00 committed by Germano Cavalcante
parent a702ca3faa
commit d0dd85a820
1 changed files with 220 additions and 85 deletions

View File

@ -27,11 +27,14 @@
* \brief Snap gizmo which exposes the location, normal and index in the props.
*/
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "DNA_scene_types.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "GPU_immediate.h"
#include "GPU_state.h"
@ -57,11 +60,6 @@
typedef struct SnapGizmo3D {
wmGizmo gizmo;
PropertyRNA *prop_prevpoint;
PropertyRNA *prop_location;
PropertyRNA *prop_normal;
PropertyRNA *prop_elem_index;
PropertyRNA *prop_snap_force;
/* We could have other snap contexts, for now only support 3D view. */
SnapObjectContext *snap_context_v3d;
@ -78,8 +76,18 @@ typedef struct SnapGizmo3D {
int snap_on;
bool invert_snap;
#endif
/* Setup. */
float *prevpoint;
float prevpoint_stack[3];
int use_snap_override;
short snap_elem_force;
/* Return values. */
short snap_elem;
float loc[3];
float nor[3];
int elem_index[3];
/** Enabled when snap is activated, even if it didn't find anything. */
bool is_enabled;
@ -158,6 +166,19 @@ static bool invert_snap(SnapGizmo3D *snap_gizmo, const wmWindowManager *wm)
}
#endif
static short snap_gizmo_snap_elements(SnapGizmo3D *snap_gizmo)
{
int snap_elements = snap_gizmo->snap_elem_force;
wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(&snap_gizmo->gizmo, "snap_elements");
if (gz_prop->prop) {
snap_elements |= RNA_property_enum_get(&gz_prop->ptr, gz_prop->prop);
}
snap_elements &= (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR);
return (ushort)snap_elements;
}
/* -------------------------------------------------------------------- */
/** \name ED_gizmo_library specific API
* \{ */
@ -336,19 +357,12 @@ short ED_gizmotypes_snap_3d_update(wmGizmo *gz,
int snap_elem_index[3] = {-1, -1, -1};
int index = -1;
wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "snap_elements");
int snap_elements = RNA_property_enum_get(&gz_prop->ptr, gz_prop->prop);
if (gz_prop->prop != snap_gizmo->prop_snap_force) {
int snap_elements_force = RNA_property_enum_get(gz->ptr, snap_gizmo->prop_snap_force);
snap_elements |= snap_elements_force;
}
snap_elements &= (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR);
ushort snap_elements = snap_gizmo_snap_elements(snap_gizmo);
if (snap_elements) {
float prev_co[3] = {0.0f};
if (RNA_property_is_set(gz->ptr, snap_gizmo->prop_prevpoint)) {
RNA_property_float_get_array(gz->ptr, snap_gizmo->prop_prevpoint, prev_co);
if (snap_gizmo->prevpoint) {
copy_v3_v3(prev_co, snap_gizmo->prevpoint);
}
else {
snap_elements &= ~SCE_SNAP_MODE_EDGE_PERPENDICULAR;
@ -392,9 +406,9 @@ short ED_gizmotypes_snap_3d_update(wmGizmo *gz,
}
snap_gizmo->snap_elem = snap_elem;
RNA_property_float_set_array(gz->ptr, snap_gizmo->prop_location, co);
RNA_property_float_set_array(gz->ptr, snap_gizmo->prop_normal, no);
RNA_property_int_set_array(gz->ptr, snap_gizmo->prop_elem_index, snap_elem_index);
copy_v3_v3(snap_gizmo->loc, co);
copy_v3_v3(snap_gizmo->nor, no);
copy_v3_v3_int(snap_gizmo->elem_index, snap_elem_index);
if (r_loc) {
copy_v3_v3(r_loc, co);
@ -409,6 +423,124 @@ short ED_gizmotypes_snap_3d_update(wmGizmo *gz,
/** \} */
/* -------------------------------------------------------------------- */
/** \name RNA callbacks
* \{ */
/* Based on 'rna_GizmoProperties_find_operator'. */
static struct SnapGizmo3D *gizmo_snap_rna_find_operator(PointerRNA *ptr)
{
IDProperty *properties = ptr->data;
for (bScreen *screen = G_MAIN->screens.first; screen; screen = screen->id.next) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
if (area->spacetype != SPACE_VIEW3D) {
continue;
}
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->regiontype == RGN_TYPE_WINDOW && region->gizmo_map) {
wmGizmoMap *gzmap = region->gizmo_map;
LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, WM_gizmomap_group_list(gzmap)) {
LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
if (gz->properties == properties) {
return (SnapGizmo3D *)gz;
}
}
}
}
}
}
}
return NULL;
}
static int gizmo_snap_rna_snap_elements_force_get_fn(struct PointerRNA *ptr,
struct PropertyRNA *UNUSED(prop))
{
SnapGizmo3D *snap_gizmo = gizmo_snap_rna_find_operator(ptr);
if (snap_gizmo) {
return snap_gizmo->snap_elem_force;
}
return 0;
}
static void gizmo_snap_rna_snap_elements_force_set_fn(struct PointerRNA *ptr,
struct PropertyRNA *UNUSED(prop),
int value)
{
SnapGizmo3D *snap_gizmo = gizmo_snap_rna_find_operator(ptr);
if (snap_gizmo) {
snap_gizmo->snap_elem_force = (short)value;
}
}
static void gizmo_snap_rna_prevpoint_get_fn(struct PointerRNA *ptr,
struct PropertyRNA *UNUSED(prop),
float *values)
{
SnapGizmo3D *snap_gizmo = gizmo_snap_rna_find_operator(ptr);
if (snap_gizmo) {
copy_v3_v3(values, snap_gizmo->prevpoint_stack);
}
}
static void gizmo_snap_rna_prevpoint_set_fn(struct PointerRNA *ptr,
struct PropertyRNA *UNUSED(prop),
const float *values)
{
SnapGizmo3D *snap_gizmo = gizmo_snap_rna_find_operator(ptr);
if (snap_gizmo) {
if (values) {
copy_v3_v3(snap_gizmo->prevpoint_stack, values);
snap_gizmo->prevpoint = snap_gizmo->prevpoint_stack;
}
else {
snap_gizmo->prevpoint = NULL;
}
}
}
static void gizmo_snap_rna_location_get_fn(struct PointerRNA *ptr,
struct PropertyRNA *UNUSED(prop),
float *values)
{
SnapGizmo3D *snap_gizmo = gizmo_snap_rna_find_operator(ptr);
if (snap_gizmo) {
copy_v3_v3(values, snap_gizmo->loc);
}
}
static void gizmo_snap_rna_location_set_fn(struct PointerRNA *ptr,
struct PropertyRNA *UNUSED(prop),
const float *values)
{
SnapGizmo3D *snap_gizmo = gizmo_snap_rna_find_operator(ptr);
if (snap_gizmo) {
copy_v3_v3(snap_gizmo->loc, values);
}
}
static void gizmo_snap_rna_normal_get_fn(struct PointerRNA *ptr,
struct PropertyRNA *UNUSED(prop),
float *values)
{
SnapGizmo3D *snap_gizmo = gizmo_snap_rna_find_operator(ptr);
if (snap_gizmo) {
copy_v3_v3(values, snap_gizmo->nor);
}
}
static void gizmo_snap_rna_snap_elem_index_get_fn(struct PointerRNA *ptr,
struct PropertyRNA *UNUSED(prop),
int *values)
{
SnapGizmo3D *snap_gizmo = gizmo_snap_rna_find_operator(ptr);
if (snap_gizmo) {
copy_v3_v3_int(values, snap_gizmo->elem_index);
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name GIZMO_GT_snap_3d
* \{ */
@ -416,19 +548,8 @@ short ED_gizmotypes_snap_3d_update(wmGizmo *gz,
static void snap_gizmo_setup(wmGizmo *gz)
{
SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
/* For quick access to the props. */
snap_gizmo->prop_prevpoint = RNA_struct_find_property(gz->ptr, "prev_point");
snap_gizmo->prop_location = RNA_struct_find_property(gz->ptr, "location");
snap_gizmo->prop_normal = RNA_struct_find_property(gz->ptr, "normal");
snap_gizmo->prop_elem_index = RNA_struct_find_property(gz->ptr, "snap_elem_index");
snap_gizmo->prop_snap_force = RNA_struct_find_property(gz->ptr, "snap_elements_force");
snap_gizmo->use_snap_override = -1;
/* Prop fallback. */
WM_gizmo_target_property_def_rna(gz, "snap_elements", gz->ptr, "snap_elements_force", -1);
/* Flags. */
gz->flag |= WM_GIZMO_NO_TOOLTIP;
}
@ -455,26 +576,23 @@ static void snap_gizmo_draw(const bContext *C, wmGizmo *gz)
return;
}
float location[3], prev_point_stack[3], *prev_point = NULL;
uchar color_line[4], color_point[4];
RNA_property_float_get_array(gz->ptr, snap_gizmo->prop_location, location);
UI_GetThemeColor3ubv(TH_TRANSFORM, color_line);
color_line[3] = 128;
rgba_float_to_uchar(color_point, gz->color);
if (RNA_property_is_set(gz->ptr, snap_gizmo->prop_prevpoint)) {
RNA_property_float_get_array(gz->ptr, snap_gizmo->prop_prevpoint, prev_point_stack);
prev_point = prev_point_stack;
}
GPU_line_smooth(false);
GPU_line_width(1.0f);
const float *prev_point = snap_gizmo_snap_elements(snap_gizmo) &
SCE_SNAP_MODE_EDGE_PERPENDICULAR ?
snap_gizmo->prevpoint :
NULL;
ED_gizmotypes_snap_3d_draw_util(
rv3d, prev_point, location, NULL, color_line, color_point, snap_gizmo->snap_elem);
rv3d, prev_point, snap_gizmo->loc, NULL, color_line, color_point, snap_gizmo->snap_elem);
}
static int snap_gizmo_test_select(bContext *C, wmGizmo *gz, const int mval[2])
@ -553,57 +671,74 @@ static void GIZMO_GT_snap_3d(wmGizmoType *gzt)
}
/* Setup. */
RNA_def_enum_flag(gzt->srna,
"snap_elements_force",
rna_enum_snap_element_items,
SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE,
"Snap Elements",
"");
PropertyRNA *prop;
prop = RNA_def_enum_flag(gzt->srna,
"snap_elements_force",
rna_enum_snap_element_items,
SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE,
"Snap Elements",
"");
RNA_def_float_vector(gzt->srna,
"prev_point",
3,
NULL,
FLT_MIN,
FLT_MAX,
"Previous Point",
"Point that defines the location of the perpendicular snap",
FLT_MIN,
FLT_MAX);
RNA_def_property_enum_funcs_runtime(prop,
gizmo_snap_rna_snap_elements_force_get_fn,
gizmo_snap_rna_snap_elements_force_set_fn,
NULL);
prop = RNA_def_float_array(gzt->srna,
"prev_point",
3,
NULL,
FLT_MIN,
FLT_MAX,
"Previous Point",
"Point that defines the location of the perpendicular snap",
FLT_MIN,
FLT_MAX);
RNA_def_property_float_array_funcs_runtime(
prop, gizmo_snap_rna_prevpoint_get_fn, gizmo_snap_rna_prevpoint_set_fn, NULL);
/* Returns. */
RNA_def_float_vector(gzt->srna,
"location",
3,
NULL,
FLT_MIN,
FLT_MAX,
"Location",
"Snap Point Location",
FLT_MIN,
FLT_MAX);
prop = RNA_def_float_translation(gzt->srna,
"location",
3,
NULL,
FLT_MIN,
FLT_MAX,
"Location",
"Snap Point Location",
FLT_MIN,
FLT_MAX);
RNA_def_float_vector(gzt->srna,
"normal",
3,
NULL,
FLT_MIN,
FLT_MAX,
"Normal",
"Snap Point Normal",
FLT_MIN,
FLT_MAX);
RNA_def_property_float_array_funcs_runtime(
prop, gizmo_snap_rna_location_get_fn, gizmo_snap_rna_location_set_fn, NULL);
RNA_def_int_vector(gzt->srna,
"snap_elem_index",
3,
NULL,
INT_MIN,
INT_MAX,
"Snap Element",
"Array index of face, edge and vert snapped",
INT_MIN,
INT_MAX);
prop = RNA_def_float_vector_xyz(gzt->srna,
"normal",
3,
NULL,
FLT_MIN,
FLT_MAX,
"Normal",
"Snap Point Normal",
FLT_MIN,
FLT_MAX);
RNA_def_property_float_array_funcs_runtime(prop, gizmo_snap_rna_normal_get_fn, NULL, NULL);
prop = RNA_def_int_vector(gzt->srna,
"snap_elem_index",
3,
NULL,
INT_MIN,
INT_MAX,
"Snap Element",
"Array index of face, edge and vert snapped",
INT_MIN,
INT_MAX);
RNA_def_property_int_array_funcs_runtime(
prop, gizmo_snap_rna_snap_elem_index_get_fn, NULL, NULL);
/* Read/Write. */
WM_gizmotype_target_property_def(gzt, "snap_elements", PROP_ENUM, 1);