diff options
Diffstat (limited to 'source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c')
-rw-r--r-- | source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c | 311 |
1 files changed, 223 insertions, 88 deletions
diff --git a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c index b8ee1722cb3..f9b9afc4feb 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c @@ -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); @@ -410,25 +424,132 @@ 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 * \{ */ 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", - ""); - - 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); + 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_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); - - RNA_def_float_vector(gzt->srna, - "normal", - 3, - NULL, - FLT_MIN, - FLT_MAX, - "Normal", - "Snap Point Normal", - FLT_MIN, - FLT_MAX); - - 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_translation(gzt->srna, + "location", + 3, + NULL, + FLT_MIN, + FLT_MAX, + "Location", + "Snap Point Location", + 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); + + 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); |