View3D: Cursor Snap Refactor
Make the snap system consistent with the placement tool and leak-safe. **Changes:** - Store `SnapCursorDataIntern` in a `static` variable; - Initialize (lazily) `SnapCursorDataIntern` only once (for the keymap). - Move setup members of `V3DSnapCursorData` to a new struct `V3DSnapCursorState` - Merge `ED_view3d_cursor_snap_activate_point` and `ED_view3d_cursor_snap_activate_plane` into `state = ED_view3d_cursor_snap_active()` - Merge `ED_view3d_cursor_snap_deactivate_point` and `ED_view3d_cursor_snap_deactivate_plane` into `ED_view3d_cursor_snap_deactive(state)` - Be sure to free the snap context when closing via `ED_view3d_cursor_snap_exit` - Use RNA properties callbacks to update the properties of the `"Add Primitive Object"` operator
This commit is contained in:
@@ -53,22 +53,18 @@
|
|||||||
|
|
||||||
typedef struct SnapGizmo3D {
|
typedef struct SnapGizmo3D {
|
||||||
wmGizmo gizmo;
|
wmGizmo gizmo;
|
||||||
V3DSnapCursorData *cursor_handle;
|
V3DSnapCursorState *snap_state;
|
||||||
} SnapGizmo3D;
|
} SnapGizmo3D;
|
||||||
|
|
||||||
static void snap_gizmo_snap_elements_update(SnapGizmo3D *snap_gizmo)
|
static void snap_gizmo_snap_elements_update(SnapGizmo3D *snap_gizmo)
|
||||||
{
|
{
|
||||||
V3DSnapCursorData *snap_data = snap_gizmo->cursor_handle;
|
|
||||||
wmGizmoProperty *gz_prop_snap;
|
wmGizmoProperty *gz_prop_snap;
|
||||||
gz_prop_snap = WM_gizmo_target_property_find(&snap_gizmo->gizmo, "snap_elements");
|
gz_prop_snap = WM_gizmo_target_property_find(&snap_gizmo->gizmo, "snap_elements");
|
||||||
|
|
||||||
if (gz_prop_snap->prop) {
|
if (gz_prop_snap->prop) {
|
||||||
snap_data->snap_elem_force |= RNA_property_enum_get(&gz_prop_snap->ptr, gz_prop_snap->prop);
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
|
snap_state->snap_elem_force |= RNA_property_enum_get(&gz_prop_snap->ptr, gz_prop_snap->prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
UI_GetThemeColor3ubv(TH_TRANSFORM, snap_data->color_line);
|
|
||||||
snap_data->color_line[3] = 128;
|
|
||||||
rgba_float_to_uchar(snap_data->color_point, snap_gizmo->gizmo.color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
@@ -77,49 +73,47 @@ static void snap_gizmo_snap_elements_update(SnapGizmo3D *snap_gizmo)
|
|||||||
|
|
||||||
SnapObjectContext *ED_gizmotypes_snap_3d_context_ensure(Scene *scene, wmGizmo *UNUSED(gz))
|
SnapObjectContext *ED_gizmotypes_snap_3d_context_ensure(Scene *scene, wmGizmo *UNUSED(gz))
|
||||||
{
|
{
|
||||||
ED_view3d_cursor_snap_activate_point();
|
|
||||||
return ED_view3d_cursor_snap_context_ensure(scene);
|
return ED_view3d_cursor_snap_context_ensure(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ED_gizmotypes_snap_3d_flag_set(struct wmGizmo *gz, int flag)
|
void ED_gizmotypes_snap_3d_flag_set(struct wmGizmo *UNUSED(gz), int flag)
|
||||||
{
|
{
|
||||||
SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
snap_gizmo->cursor_handle->flag |= flag;
|
snap_state->flag |= flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ED_gizmotypes_snap_3d_flag_clear(struct wmGizmo *gz, int flag)
|
void ED_gizmotypes_snap_3d_flag_clear(struct wmGizmo *UNUSED(gz), int flag)
|
||||||
{
|
{
|
||||||
SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
snap_gizmo->cursor_handle->flag &= ~flag;
|
snap_state->flag &= ~flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ED_gizmotypes_snap_3d_flag_test(struct wmGizmo *gz, int flag)
|
bool ED_gizmotypes_snap_3d_flag_test(struct wmGizmo *UNUSED(gz), int flag)
|
||||||
{
|
{
|
||||||
SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
return (snap_gizmo->cursor_handle->flag & flag) != 0;
|
return (snap_state->flag & flag) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ED_gizmotypes_snap_3d_invert_snap_get(struct wmGizmo *gz)
|
bool ED_gizmotypes_snap_3d_invert_snap_get(struct wmGizmo *UNUSED(gz))
|
||||||
{
|
{
|
||||||
SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
|
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get(NULL, NULL, 0, 0);
|
||||||
return snap_gizmo->cursor_handle->is_snap_invert;
|
return snap_data->is_snap_invert;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ED_gizmotypes_snap_3d_is_enabled(const wmGizmo *gz)
|
bool ED_gizmotypes_snap_3d_is_enabled(const wmGizmo *gz)
|
||||||
{
|
{
|
||||||
const SnapGizmo3D *snap_gizmo = (const SnapGizmo3D *)gz;
|
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get(NULL, NULL, 0, 0);
|
||||||
return snap_gizmo->cursor_handle->is_enabled;
|
return snap_data->is_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ED_gizmotypes_snap_3d_data_get(const struct bContext *C,
|
void ED_gizmotypes_snap_3d_data_get(const struct bContext *C,
|
||||||
wmGizmo *gz,
|
wmGizmo *UNUSED(gz),
|
||||||
float r_loc[3],
|
float r_loc[3],
|
||||||
float r_nor[3],
|
float r_nor[3],
|
||||||
int r_elem_index[3],
|
int r_elem_index[3],
|
||||||
int *r_snap_elem)
|
int *r_snap_elem)
|
||||||
{
|
{
|
||||||
V3DSnapCursorData *snap_data = ((SnapGizmo3D *)gz)->cursor_handle;
|
V3DSnapCursorData *snap_data = NULL;
|
||||||
|
|
||||||
if (C) {
|
if (C) {
|
||||||
/* Snap values are updated too late at the cursor. Be sure to update ahead of time. */
|
/* Snap values are updated too late at the cursor. Be sure to update ahead of time. */
|
||||||
wmWindowManager *wm = CTX_wm_manager(C);
|
wmWindowManager *wm = CTX_wm_manager(C);
|
||||||
@@ -128,9 +122,12 @@ void ED_gizmotypes_snap_3d_data_get(const struct bContext *C,
|
|||||||
ARegion *region = CTX_wm_region(C);
|
ARegion *region = CTX_wm_region(C);
|
||||||
int x = event->x - region->winrct.xmin;
|
int x = event->x - region->winrct.xmin;
|
||||||
int y = event->y - region->winrct.ymin;
|
int y = event->y - region->winrct.ymin;
|
||||||
ED_view3d_cursor_snap_update(C, x, y, snap_data);
|
snap_data = ED_view3d_cursor_snap_data_get(NULL, C, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!snap_data) {
|
||||||
|
snap_data = ED_view3d_cursor_snap_data_get(NULL, NULL, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (r_loc) {
|
if (r_loc) {
|
||||||
copy_v3_v3(r_loc, snap_data->loc);
|
copy_v3_v3(r_loc, snap_data->loc);
|
||||||
@@ -155,30 +152,25 @@ void ED_gizmotypes_snap_3d_data_get(const struct bContext *C,
|
|||||||
static int gizmo_snap_rna_snap_elements_force_get_fn(struct PointerRNA *UNUSED(ptr),
|
static int gizmo_snap_rna_snap_elements_force_get_fn(struct PointerRNA *UNUSED(ptr),
|
||||||
struct PropertyRNA *UNUSED(prop))
|
struct PropertyRNA *UNUSED(prop))
|
||||||
{
|
{
|
||||||
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get();
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
if (snap_data) {
|
return snap_state->snap_elem_force;
|
||||||
return snap_data->snap_elem_force;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gizmo_snap_rna_snap_elements_force_set_fn(struct PointerRNA *UNUSED(ptr),
|
static void gizmo_snap_rna_snap_elements_force_set_fn(struct PointerRNA *UNUSED(ptr),
|
||||||
struct PropertyRNA *UNUSED(prop),
|
struct PropertyRNA *UNUSED(prop),
|
||||||
int value)
|
int value)
|
||||||
{
|
{
|
||||||
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get();
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
if (snap_data) {
|
snap_state->snap_elem_force = (short)value;
|
||||||
snap_data->snap_elem_force = (short)value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gizmo_snap_rna_prevpoint_get_fn(struct PointerRNA *UNUSED(ptr),
|
static void gizmo_snap_rna_prevpoint_get_fn(struct PointerRNA *UNUSED(ptr),
|
||||||
struct PropertyRNA *UNUSED(prop),
|
struct PropertyRNA *UNUSED(prop),
|
||||||
float *values)
|
float *values)
|
||||||
{
|
{
|
||||||
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get();
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
if (snap_data && snap_data->prevpoint) {
|
if (snap_state->prevpoint) {
|
||||||
copy_v3_v3(values, snap_data->prevpoint);
|
copy_v3_v3(values, snap_state->prevpoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,47 +178,40 @@ static void gizmo_snap_rna_prevpoint_set_fn(struct PointerRNA *UNUSED(ptr),
|
|||||||
struct PropertyRNA *UNUSED(prop),
|
struct PropertyRNA *UNUSED(prop),
|
||||||
const float *values)
|
const float *values)
|
||||||
{
|
{
|
||||||
ED_view3d_cursor_snap_prevpoint_set(values);
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
|
ED_view3d_cursor_snap_prevpoint_set(snap_state, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gizmo_snap_rna_location_get_fn(struct PointerRNA *UNUSED(ptr),
|
static void gizmo_snap_rna_location_get_fn(struct PointerRNA *UNUSED(ptr),
|
||||||
struct PropertyRNA *UNUSED(prop),
|
struct PropertyRNA *UNUSED(prop),
|
||||||
float *values)
|
float *values)
|
||||||
{
|
{
|
||||||
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get();
|
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get(NULL, NULL, 0, 0);
|
||||||
if (snap_data) {
|
copy_v3_v3(values, snap_data->loc);
|
||||||
copy_v3_v3(values, snap_data->loc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gizmo_snap_rna_location_set_fn(struct PointerRNA *UNUSED(ptr),
|
static void gizmo_snap_rna_location_set_fn(struct PointerRNA *UNUSED(ptr),
|
||||||
struct PropertyRNA *UNUSED(prop),
|
struct PropertyRNA *UNUSED(prop),
|
||||||
const float *values)
|
const float *values)
|
||||||
{
|
{
|
||||||
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get();
|
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get(NULL, NULL, 0, 0);
|
||||||
if (snap_data) {
|
copy_v3_v3(snap_data->loc, values);
|
||||||
copy_v3_v3(snap_data->loc, values);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gizmo_snap_rna_normal_get_fn(struct PointerRNA *UNUSED(ptr),
|
static void gizmo_snap_rna_normal_get_fn(struct PointerRNA *UNUSED(ptr),
|
||||||
struct PropertyRNA *UNUSED(prop),
|
struct PropertyRNA *UNUSED(prop),
|
||||||
float *values)
|
float *values)
|
||||||
{
|
{
|
||||||
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get();
|
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get(NULL, NULL, 0, 0);
|
||||||
if (snap_data) {
|
copy_v3_v3(values, snap_data->nor);
|
||||||
copy_v3_v3(values, snap_data->nor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gizmo_snap_rna_snap_elem_index_get_fn(struct PointerRNA *UNUSED(ptr),
|
static void gizmo_snap_rna_snap_elem_index_get_fn(struct PointerRNA *UNUSED(ptr),
|
||||||
struct PropertyRNA *UNUSED(prop),
|
struct PropertyRNA *UNUSED(prop),
|
||||||
int *values)
|
int *values)
|
||||||
{
|
{
|
||||||
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get();
|
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get(NULL, NULL, 0, 0);
|
||||||
if (snap_data) {
|
copy_v3_v3_int(values, snap_data->elem_index);
|
||||||
copy_v3_v3_int(values, snap_data->elem_index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
@@ -239,8 +224,11 @@ static void snap_gizmo_setup(wmGizmo *gz)
|
|||||||
{
|
{
|
||||||
gz->flag |= WM_GIZMO_NO_TOOLTIP;
|
gz->flag |= WM_GIZMO_NO_TOOLTIP;
|
||||||
SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
|
SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
|
||||||
ED_view3d_cursor_snap_activate_point();
|
snap_gizmo->snap_state = ED_view3d_cursor_snap_active();
|
||||||
snap_gizmo->cursor_handle = ED_view3d_cursor_snap_data_get();
|
snap_gizmo->snap_state->draw_point = true;
|
||||||
|
snap_gizmo->snap_state->draw_plane = false;
|
||||||
|
|
||||||
|
rgba_float_to_uchar(snap_gizmo->snap_state->color_point, gz->color);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void snap_gizmo_draw(const bContext *UNUSED(C), wmGizmo *UNUSED(gz))
|
static void snap_gizmo_draw(const bContext *UNUSED(C), wmGizmo *UNUSED(gz))
|
||||||
@@ -251,7 +239,6 @@ static void snap_gizmo_draw(const bContext *UNUSED(C), wmGizmo *UNUSED(gz))
|
|||||||
static int snap_gizmo_test_select(bContext *C, wmGizmo *gz, const int mval[2])
|
static int snap_gizmo_test_select(bContext *C, wmGizmo *gz, const int mval[2])
|
||||||
{
|
{
|
||||||
SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
|
SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
|
||||||
V3DSnapCursorData *snap_data = snap_gizmo->cursor_handle;
|
|
||||||
|
|
||||||
/* Snap Elements can change while the gizmo is active. Need to be updated somewhere. */
|
/* Snap Elements can change while the gizmo is active. Need to be updated somewhere. */
|
||||||
snap_gizmo_snap_elements_update(snap_gizmo);
|
snap_gizmo_snap_elements_update(snap_gizmo);
|
||||||
@@ -271,9 +258,9 @@ static int snap_gizmo_test_select(bContext *C, wmGizmo *gz, const int mval[2])
|
|||||||
y = mval[1];
|
y = mval[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ED_view3d_cursor_snap_update(C, x, y, snap_data);
|
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get(snap_gizmo->snap_state, C, x, y);
|
||||||
|
|
||||||
if (snap_data && snap_data->snap_elem) {
|
if (snap_data->snap_elem) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@@ -297,10 +284,7 @@ static int snap_gizmo_invoke(bContext *UNUSED(C),
|
|||||||
static void snap_gizmo_free(wmGizmo *gz)
|
static void snap_gizmo_free(wmGizmo *gz)
|
||||||
{
|
{
|
||||||
SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
|
SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
|
||||||
V3DSnapCursorData *snap_data = snap_gizmo->cursor_handle;
|
ED_view3d_cursor_snap_deactive(snap_gizmo->snap_state);
|
||||||
if (snap_data) {
|
|
||||||
ED_view3d_cursor_snap_deactivate_point();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GIZMO_GT_snap_3d(wmGizmoType *gzt)
|
static void GIZMO_GT_snap_3d(wmGizmoType *gzt)
|
||||||
|
@@ -257,18 +257,6 @@ typedef enum {
|
|||||||
} eV3DPlaceOrient;
|
} eV3DPlaceOrient;
|
||||||
|
|
||||||
typedef struct V3DSnapCursorData {
|
typedef struct V3DSnapCursorData {
|
||||||
/* Setup. */
|
|
||||||
eV3DSnapCursor flag;
|
|
||||||
eV3DPlaceDepth plane_depth;
|
|
||||||
eV3DPlaceOrient plane_orient;
|
|
||||||
uchar color_line[4];
|
|
||||||
uchar color_point[4];
|
|
||||||
float *prevpoint;
|
|
||||||
short snap_elem_force; /* If zero, use scene settings. */
|
|
||||||
short plane_axis;
|
|
||||||
bool use_plane_axis_auto;
|
|
||||||
|
|
||||||
/* Return values. */
|
|
||||||
short snap_elem;
|
short snap_elem;
|
||||||
float loc[3];
|
float loc[3];
|
||||||
float nor[3];
|
float nor[3];
|
||||||
@@ -281,16 +269,31 @@ typedef struct V3DSnapCursorData {
|
|||||||
bool is_enabled;
|
bool is_enabled;
|
||||||
} V3DSnapCursorData;
|
} V3DSnapCursorData;
|
||||||
|
|
||||||
V3DSnapCursorData *ED_view3d_cursor_snap_data_get(void);
|
typedef struct V3DSnapCursorState {
|
||||||
void ED_view3d_cursor_snap_activate_point(void);
|
/* Setup. */
|
||||||
void ED_view3d_cursor_snap_activate_plane(void);
|
eV3DSnapCursor flag;
|
||||||
void ED_view3d_cursor_snap_deactivate_point(void);
|
eV3DPlaceDepth plane_depth;
|
||||||
void ED_view3d_cursor_snap_deactivate_plane(void);
|
eV3DPlaceOrient plane_orient;
|
||||||
void ED_view3d_cursor_snap_prevpoint_set(const float prev_point[3]);
|
uchar color_line[4];
|
||||||
void ED_view3d_cursor_snap_update(const struct bContext *C,
|
uchar color_point[4];
|
||||||
const int x,
|
float *prevpoint;
|
||||||
const int y,
|
short snap_elem_force; /* If zero, use scene settings. */
|
||||||
V3DSnapCursorData *snap_data);
|
short plane_axis;
|
||||||
|
bool use_plane_axis_auto;
|
||||||
|
bool draw_point;
|
||||||
|
bool draw_plane;
|
||||||
|
} V3DSnapCursorState;
|
||||||
|
|
||||||
|
void ED_view3d_cursor_snap_state_default_set(V3DSnapCursorState *state);
|
||||||
|
V3DSnapCursorState *ED_view3d_cursor_snap_state_get(void);
|
||||||
|
V3DSnapCursorState *ED_view3d_cursor_snap_active(void);
|
||||||
|
void ED_view3d_cursor_snap_deactive(V3DSnapCursorState *state);
|
||||||
|
void ED_view3d_cursor_snap_prevpoint_set(V3DSnapCursorState *state, const float prev_point[3]);
|
||||||
|
V3DSnapCursorData *ED_view3d_cursor_snap_data_get(V3DSnapCursorState *state,
|
||||||
|
const struct bContext *C,
|
||||||
|
const int x,
|
||||||
|
const int y);
|
||||||
|
|
||||||
struct SnapObjectContext *ED_view3d_cursor_snap_context_ensure(struct Scene *scene);
|
struct SnapObjectContext *ED_view3d_cursor_snap_context_ensure(struct Scene *scene);
|
||||||
void ED_view3d_cursor_snap_draw_util(struct RegionView3D *rv3d,
|
void ED_view3d_cursor_snap_draw_util(struct RegionView3D *rv3d,
|
||||||
const float loc_prev[3],
|
const float loc_prev[3],
|
||||||
@@ -299,6 +302,7 @@ void ED_view3d_cursor_snap_draw_util(struct RegionView3D *rv3d,
|
|||||||
const uchar color_line[4],
|
const uchar color_line[4],
|
||||||
const uchar color_point[4],
|
const uchar color_point[4],
|
||||||
const short snap_elem_type);
|
const short snap_elem_type);
|
||||||
|
void ED_view3d_cursor_snap_exit(void);
|
||||||
|
|
||||||
/* view3d_iterators.c */
|
/* view3d_iterators.c */
|
||||||
|
|
||||||
|
@@ -355,10 +355,6 @@ static void view3d_exit(wmWindowManager *UNUSED(wm), ScrArea *area)
|
|||||||
BLI_assert(area->spacetype == SPACE_VIEW3D);
|
BLI_assert(area->spacetype == SPACE_VIEW3D);
|
||||||
View3D *v3d = area->spacedata.first;
|
View3D *v3d = area->spacedata.first;
|
||||||
MEM_SAFE_FREE(v3d->runtime.local_stats);
|
MEM_SAFE_FREE(v3d->runtime.local_stats);
|
||||||
|
|
||||||
/* Be sure to release the #V3DSnapCursorData from the cursor, or it will get lost. */
|
|
||||||
ED_view3d_cursor_snap_deactivate_point();
|
|
||||||
ED_view3d_cursor_snap_deactivate_plane();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static SpaceLink *view3d_duplicate(SpaceLink *sl)
|
static SpaceLink *view3d_duplicate(SpaceLink *sl)
|
||||||
|
@@ -53,14 +53,26 @@
|
|||||||
#include "DEG_depsgraph_query.h"
|
#include "DEG_depsgraph_query.h"
|
||||||
|
|
||||||
#include "WM_api.h"
|
#include "WM_api.h"
|
||||||
#include "wm.h"
|
|
||||||
|
#define STATE_LEN 3
|
||||||
|
|
||||||
|
typedef struct SnapStateIntern {
|
||||||
|
V3DSnapCursorState snap_state;
|
||||||
|
float prevpoint_stack[3];
|
||||||
|
int state_active_prev;
|
||||||
|
bool is_active;
|
||||||
|
} SnapStateIntern;
|
||||||
|
|
||||||
typedef struct SnapCursorDataIntern {
|
typedef struct SnapCursorDataIntern {
|
||||||
/* Keep as first member. */
|
V3DSnapCursorState state_default;
|
||||||
struct V3DSnapCursorData snap_data;
|
SnapStateIntern state_intern[STATE_LEN];
|
||||||
|
V3DSnapCursorData snap_data;
|
||||||
|
|
||||||
|
int state_active_len;
|
||||||
|
int state_active;
|
||||||
|
|
||||||
struct SnapObjectContext *snap_context_v3d;
|
struct SnapObjectContext *snap_context_v3d;
|
||||||
float prevpoint_stack[3];
|
const Scene *scene;
|
||||||
short snap_elem_hidden;
|
short snap_elem_hidden;
|
||||||
|
|
||||||
/* Copy of the parameters of the last event state in order to detect updates. */
|
/* Copy of the parameters of the last event state in order to detect updates. */
|
||||||
@@ -79,10 +91,11 @@ typedef struct SnapCursorDataIntern {
|
|||||||
|
|
||||||
struct wmPaintCursor *handle;
|
struct wmPaintCursor *handle;
|
||||||
|
|
||||||
bool draw_point;
|
bool is_initiated;
|
||||||
bool draw_plane;
|
|
||||||
} SnapCursorDataIntern;
|
} SnapCursorDataIntern;
|
||||||
|
|
||||||
|
static SnapCursorDataIntern g_data_intern = {{0}};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate a 3x3 orientation matrix from the surface under the cursor.
|
* Calculate a 3x3 orientation matrix from the surface under the cursor.
|
||||||
*/
|
*/
|
||||||
@@ -437,23 +450,23 @@ void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d,
|
|||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
/* Checks if the current event is different from the one captured in the last update. */
|
/* Checks if the current event is different from the one captured in the last update. */
|
||||||
static bool v3d_cursor_eventstate_has_changed(SnapCursorDataIntern *sdata_intern,
|
static bool v3d_cursor_eventstate_has_changed(SnapCursorDataIntern *data_intern,
|
||||||
|
V3DSnapCursorState *state,
|
||||||
const wmWindowManager *wm,
|
const wmWindowManager *wm,
|
||||||
const int x,
|
const int x,
|
||||||
const int y)
|
const int y)
|
||||||
{
|
{
|
||||||
V3DSnapCursorData *snap_data = (V3DSnapCursorData *)sdata_intern;
|
|
||||||
if (wm && wm->winactive) {
|
if (wm && wm->winactive) {
|
||||||
const wmEvent *event = wm->winactive->eventstate;
|
const wmEvent *event = wm->winactive->eventstate;
|
||||||
if ((x != sdata_intern->last_eventstate.x) || (y != sdata_intern->last_eventstate.y)) {
|
if ((x != data_intern->last_eventstate.x) || (y != data_intern->last_eventstate.y)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
|
#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
|
||||||
if (!(snap_data && (snap_data->flag & V3D_SNAPCURSOR_TOGGLE_ALWAYS_TRUE))) {
|
if (!(state && (state->flag & V3D_SNAPCURSOR_TOGGLE_ALWAYS_TRUE))) {
|
||||||
if ((event->ctrl != sdata_intern->last_eventstate.ctrl) ||
|
if ((event->ctrl != data_intern->last_eventstate.ctrl) ||
|
||||||
(event->shift != sdata_intern->last_eventstate.shift) ||
|
(event->shift != data_intern->last_eventstate.shift) ||
|
||||||
(event->alt != sdata_intern->last_eventstate.alt) ||
|
(event->alt != data_intern->last_eventstate.alt) ||
|
||||||
(event->oskey != sdata_intern->last_eventstate.oskey)) {
|
(event->oskey != data_intern->last_eventstate.oskey)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -472,31 +485,30 @@ static void v3d_cursor_eventstate_save_xy(SnapCursorDataIntern *cursor_snap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
|
#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
|
||||||
static bool v3d_cursor_is_snap_invert(SnapCursorDataIntern *sdata_intern,
|
static bool v3d_cursor_is_snap_invert(SnapCursorDataIntern *data_intern, const wmWindowManager *wm)
|
||||||
const wmWindowManager *wm)
|
|
||||||
{
|
{
|
||||||
if (!wm || !wm->winactive) {
|
if (!wm || !wm->winactive) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const wmEvent *event = wm->winactive->eventstate;
|
const wmEvent *event = wm->winactive->eventstate;
|
||||||
if ((event->ctrl == sdata_intern->last_eventstate.ctrl) &&
|
if ((event->ctrl == data_intern->last_eventstate.ctrl) &&
|
||||||
(event->shift == sdata_intern->last_eventstate.shift) &&
|
(event->shift == data_intern->last_eventstate.shift) &&
|
||||||
(event->alt == sdata_intern->last_eventstate.alt) &&
|
(event->alt == data_intern->last_eventstate.alt) &&
|
||||||
(event->oskey == sdata_intern->last_eventstate.oskey)) {
|
(event->oskey == data_intern->last_eventstate.oskey)) {
|
||||||
/* Nothing has changed. */
|
/* Nothing has changed. */
|
||||||
return sdata_intern->snap_data.is_snap_invert;
|
return data_intern->snap_data.is_snap_invert;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save new eventstate. */
|
/* Save new eventstate. */
|
||||||
sdata_intern->last_eventstate.ctrl = event->ctrl;
|
data_intern->last_eventstate.ctrl = event->ctrl;
|
||||||
sdata_intern->last_eventstate.shift = event->shift;
|
data_intern->last_eventstate.shift = event->shift;
|
||||||
sdata_intern->last_eventstate.alt = event->alt;
|
data_intern->last_eventstate.alt = event->alt;
|
||||||
sdata_intern->last_eventstate.oskey = event->oskey;
|
data_intern->last_eventstate.oskey = event->oskey;
|
||||||
|
|
||||||
const int snap_on = sdata_intern->snap_on;
|
const int snap_on = data_intern->snap_on;
|
||||||
|
|
||||||
wmKeyMap *keymap = WM_keymap_active(wm, sdata_intern->keymap);
|
wmKeyMap *keymap = WM_keymap_active(wm, data_intern->keymap);
|
||||||
for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) {
|
for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) {
|
||||||
if (kmi->flag & KMI_INACTIVE) {
|
if (kmi->flag & KMI_INACTIVE) {
|
||||||
continue;
|
continue;
|
||||||
@@ -521,34 +533,41 @@ static bool v3d_cursor_is_snap_invert(SnapCursorDataIntern *sdata_intern,
|
|||||||
/** \name Update
|
/** \name Update
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
static short v3d_cursor_snap_elements(V3DSnapCursorData *cursor_snap, Scene *scene)
|
static short v3d_cursor_snap_elements(V3DSnapCursorState *snap_state, Scene *scene)
|
||||||
{
|
{
|
||||||
short snap_elements = cursor_snap->snap_elem_force;
|
short snap_elements = snap_state->snap_elem_force;
|
||||||
if (!snap_elements) {
|
if (!snap_elements) {
|
||||||
return scene->toolsettings->snap_mode;
|
return scene->toolsettings->snap_mode;
|
||||||
}
|
}
|
||||||
return snap_elements;
|
return snap_elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void v3d_cursor_snap_context_ensure(SnapCursorDataIntern *sdata_intern, Scene *scene)
|
static void v3d_cursor_snap_context_ensure(Scene *scene)
|
||||||
{
|
{
|
||||||
if (sdata_intern->snap_context_v3d == NULL) {
|
SnapCursorDataIntern *data_intern = &g_data_intern;
|
||||||
sdata_intern->snap_context_v3d = ED_transform_snap_object_context_create(scene, 0);
|
if (data_intern->snap_context_v3d && (data_intern->scene != scene)) {
|
||||||
|
ED_transform_snap_object_context_destroy(data_intern->snap_context_v3d);
|
||||||
|
data_intern->snap_context_v3d = NULL;
|
||||||
|
}
|
||||||
|
if (data_intern->snap_context_v3d == NULL) {
|
||||||
|
data_intern->snap_context_v3d = ED_transform_snap_object_context_create(scene, 0);
|
||||||
|
data_intern->scene = scene;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void v3d_cursor_snap_update(const bContext *C,
|
static void v3d_cursor_snap_update(V3DSnapCursorState *state,
|
||||||
|
const bContext *C,
|
||||||
wmWindowManager *wm,
|
wmWindowManager *wm,
|
||||||
Depsgraph *depsgraph,
|
Depsgraph *depsgraph,
|
||||||
Scene *scene,
|
Scene *scene,
|
||||||
ARegion *region,
|
ARegion *region,
|
||||||
View3D *v3d,
|
View3D *v3d,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y)
|
||||||
SnapCursorDataIntern *sdata_intern)
|
|
||||||
{
|
{
|
||||||
v3d_cursor_snap_context_ensure(sdata_intern, scene);
|
SnapCursorDataIntern *data_intern = &g_data_intern;
|
||||||
V3DSnapCursorData *snap_data = (V3DSnapCursorData *)sdata_intern;
|
V3DSnapCursorData *snap_data = &data_intern->snap_data;
|
||||||
|
v3d_cursor_snap_context_ensure(scene);
|
||||||
|
|
||||||
float co[3], no[3], face_nor[3], obmat[4][4], omat[3][3];
|
float co[3], no[3], face_nor[3], obmat[4][4], omat[3][3];
|
||||||
short snap_elem = 0;
|
short snap_elem = 0;
|
||||||
@@ -560,18 +579,18 @@ static void v3d_cursor_snap_update(const bContext *C,
|
|||||||
zero_v3(face_nor);
|
zero_v3(face_nor);
|
||||||
unit_m3(omat);
|
unit_m3(omat);
|
||||||
|
|
||||||
ushort snap_elements = v3d_cursor_snap_elements(snap_data, scene);
|
ushort snap_elements = v3d_cursor_snap_elements(state, scene);
|
||||||
sdata_intern->snap_elem_hidden = 0;
|
data_intern->snap_elem_hidden = 0;
|
||||||
const bool draw_plane = sdata_intern->draw_plane;
|
const bool draw_plane = state->draw_plane;
|
||||||
if (draw_plane && !(snap_elements & SCE_SNAP_MODE_FACE)) {
|
if (draw_plane && !(snap_elements & SCE_SNAP_MODE_FACE)) {
|
||||||
sdata_intern->snap_elem_hidden = SCE_SNAP_MODE_FACE;
|
data_intern->snap_elem_hidden = SCE_SNAP_MODE_FACE;
|
||||||
snap_elements |= SCE_SNAP_MODE_FACE;
|
snap_elements |= SCE_SNAP_MODE_FACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
snap_data->is_enabled = true;
|
snap_data->is_enabled = true;
|
||||||
#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
|
#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
|
||||||
if (!(snap_data->flag & V3D_SNAPCURSOR_TOGGLE_ALWAYS_TRUE)) {
|
if (!(state->flag & V3D_SNAPCURSOR_TOGGLE_ALWAYS_TRUE)) {
|
||||||
snap_data->is_snap_invert = v3d_cursor_is_snap_invert(sdata_intern, wm);
|
snap_data->is_snap_invert = v3d_cursor_is_snap_invert(data_intern, wm);
|
||||||
|
|
||||||
const ToolSettings *ts = scene->toolsettings;
|
const ToolSettings *ts = scene->toolsettings;
|
||||||
if (snap_data->is_snap_invert != !(ts->snap_flag & SCE_SNAP)) {
|
if (snap_data->is_snap_invert != !(ts->snap_flag & SCE_SNAP)) {
|
||||||
@@ -580,7 +599,7 @@ static void v3d_cursor_snap_update(const bContext *C,
|
|||||||
snap_data->snap_elem = 0;
|
snap_data->snap_elem = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
snap_elements = sdata_intern->snap_elem_hidden = SCE_SNAP_MODE_FACE;
|
snap_elements = data_intern->snap_elem_hidden = SCE_SNAP_MODE_FACE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -588,30 +607,28 @@ static void v3d_cursor_snap_update(const bContext *C,
|
|||||||
if (snap_elements & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
|
if (snap_elements & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
|
||||||
SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
|
SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
|
||||||
float prev_co[3] = {0.0f};
|
float prev_co[3] = {0.0f};
|
||||||
if (snap_data->prevpoint) {
|
if (state->prevpoint) {
|
||||||
copy_v3_v3(prev_co, snap_data->prevpoint);
|
copy_v3_v3(prev_co, state->prevpoint);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
snap_elements &= ~SCE_SNAP_MODE_EDGE_PERPENDICULAR;
|
snap_elements &= ~SCE_SNAP_MODE_EDGE_PERPENDICULAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
eSnapSelect snap_select = (snap_data->flag & V3D_SNAPCURSOR_SNAP_ONLY_ACTIVE) ?
|
eSnapSelect snap_select = (state->flag & V3D_SNAPCURSOR_SNAP_ONLY_ACTIVE) ? SNAP_ONLY_ACTIVE :
|
||||||
SNAP_ONLY_ACTIVE :
|
SNAP_ALL;
|
||||||
SNAP_ALL;
|
|
||||||
|
|
||||||
eSnapEditType edit_mode_type = (snap_data->flag & V3D_SNAPCURSOR_SNAP_EDIT_GEOM_FINAL) ?
|
eSnapEditType edit_mode_type = (state->flag & V3D_SNAPCURSOR_SNAP_EDIT_GEOM_FINAL) ?
|
||||||
SNAP_GEOM_FINAL :
|
SNAP_GEOM_FINAL :
|
||||||
(snap_data->flag & V3D_SNAPCURSOR_SNAP_EDIT_GEOM_CAGE) ?
|
(state->flag & V3D_SNAPCURSOR_SNAP_EDIT_GEOM_CAGE) ?
|
||||||
SNAP_GEOM_CAGE :
|
SNAP_GEOM_CAGE :
|
||||||
SNAP_GEOM_EDIT;
|
SNAP_GEOM_EDIT;
|
||||||
|
|
||||||
bool use_occlusion_test = (snap_data->flag & V3D_SNAPCURSOR_OCCLUSION_ALWAYS_TRUE) ? false :
|
bool use_occlusion_test = (state->flag & V3D_SNAPCURSOR_OCCLUSION_ALWAYS_TRUE) ? false : true;
|
||||||
true;
|
|
||||||
|
|
||||||
float dist_px = 12.0f * U.pixelsize;
|
float dist_px = 12.0f * U.pixelsize;
|
||||||
|
|
||||||
snap_elem = ED_transform_snap_object_project_view3d_ex(
|
snap_elem = ED_transform_snap_object_project_view3d_ex(
|
||||||
sdata_intern->snap_context_v3d,
|
data_intern->snap_context_v3d,
|
||||||
depsgraph,
|
depsgraph,
|
||||||
region,
|
region,
|
||||||
v3d,
|
v3d,
|
||||||
@@ -633,11 +650,11 @@ static void v3d_cursor_snap_update(const bContext *C,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_zero_v3(face_nor)) {
|
if (is_zero_v3(face_nor)) {
|
||||||
face_nor[snap_data->plane_axis] = 1.0f;
|
face_nor[state->plane_axis] = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (draw_plane) {
|
if (draw_plane) {
|
||||||
bool orient_surface = snap_elem && (snap_data->plane_orient == V3D_PLACE_ORIENT_SURFACE);
|
bool orient_surface = snap_elem && (state->plane_orient == V3D_PLACE_ORIENT_SURFACE);
|
||||||
if (orient_surface) {
|
if (orient_surface) {
|
||||||
copy_m3_m4(omat, obmat);
|
copy_m3_m4(omat, obmat);
|
||||||
}
|
}
|
||||||
@@ -650,8 +667,8 @@ static void v3d_cursor_snap_update(const bContext *C,
|
|||||||
scene, view_layer, v3d, region->regiondata, ob, ob, orient_index, pivot_point, omat);
|
scene, view_layer, v3d, region->regiondata, ob, ob, orient_index, pivot_point, omat);
|
||||||
|
|
||||||
RegionView3D *rv3d = region->regiondata;
|
RegionView3D *rv3d = region->regiondata;
|
||||||
if (snap_data->use_plane_axis_auto) {
|
if (state->use_plane_axis_auto) {
|
||||||
mat3_align_axis_to_v3(omat, snap_data->plane_axis, rv3d->viewinv[2]);
|
mat3_align_axis_to_v3(omat, state->plane_axis, rv3d->viewinv[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -659,7 +676,7 @@ static void v3d_cursor_snap_update(const bContext *C,
|
|||||||
*
|
*
|
||||||
* While making orthogonal doesn't always work well (especially with gimbal orientation for
|
* While making orthogonal doesn't always work well (especially with gimbal orientation for
|
||||||
* e.g.) it's a corner case, without better alternatives as objects don't support shear. */
|
* e.g.) it's a corner case, without better alternatives as objects don't support shear. */
|
||||||
orthogonalize_m3(omat, snap_data->plane_axis);
|
orthogonalize_m3(omat, state->plane_axis);
|
||||||
|
|
||||||
if (orient_surface) {
|
if (orient_surface) {
|
||||||
v3d_cursor_poject_surface_normal(face_nor, obmat, omat);
|
v3d_cursor_poject_surface_normal(face_nor, obmat, omat);
|
||||||
@@ -667,21 +684,21 @@ static void v3d_cursor_snap_update(const bContext *C,
|
|||||||
}
|
}
|
||||||
|
|
||||||
float *co_depth = snap_elem ? co : scene->cursor.location;
|
float *co_depth = snap_elem ? co : scene->cursor.location;
|
||||||
snap_elem &= ~sdata_intern->snap_elem_hidden;
|
snap_elem &= ~data_intern->snap_elem_hidden;
|
||||||
if (snap_elem == 0) {
|
if (snap_elem == 0) {
|
||||||
float plane[4];
|
float plane[4];
|
||||||
if (snap_data->plane_depth != V3D_PLACE_DEPTH_CURSOR_VIEW) {
|
if (state->plane_depth != V3D_PLACE_DEPTH_CURSOR_VIEW) {
|
||||||
const float *plane_normal = omat[snap_data->plane_axis];
|
const float *plane_normal = omat[state->plane_axis];
|
||||||
plane_from_point_normal_v3(plane, co_depth, plane_normal);
|
plane_from_point_normal_v3(plane, co_depth, plane_normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((snap_data->plane_depth == V3D_PLACE_DEPTH_CURSOR_VIEW) ||
|
if ((state->plane_depth == V3D_PLACE_DEPTH_CURSOR_VIEW) ||
|
||||||
!ED_view3d_win_to_3d_on_plane(region, plane, mval_fl, true, co)) {
|
!ED_view3d_win_to_3d_on_plane(region, plane, mval_fl, true, co)) {
|
||||||
ED_view3d_win_to_3d(v3d, region, co_depth, mval_fl, co);
|
ED_view3d_win_to_3d(v3d, region, co_depth, mval_fl, co);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snap_data->is_enabled && (snap_elements & SCE_SNAP_MODE_INCREMENT)) {
|
if (snap_data->is_enabled && (snap_elements & SCE_SNAP_MODE_INCREMENT)) {
|
||||||
v3d_cursor_snap_calc_incremental(scene, v3d, region, snap_data->prevpoint, co);
|
v3d_cursor_snap_calc_incremental(scene, v3d, region, state->prevpoint, co);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (snap_elem == SCE_SNAP_MODE_VERTEX) {
|
else if (snap_elem == SCE_SNAP_MODE_VERTEX) {
|
||||||
@@ -703,7 +720,7 @@ static void v3d_cursor_snap_update(const bContext *C,
|
|||||||
|
|
||||||
copy_m3_m3(snap_data->plane_omat, omat);
|
copy_m3_m3(snap_data->plane_omat, omat);
|
||||||
|
|
||||||
v3d_cursor_eventstate_save_xy(sdata_intern, x, y);
|
v3d_cursor_eventstate_save_xy(data_intern, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
@@ -739,21 +756,22 @@ static bool v3d_cursor_snap_pool_fn(bContext *C)
|
|||||||
|
|
||||||
static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *customdata)
|
static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *customdata)
|
||||||
{
|
{
|
||||||
V3DSnapCursorData *snap_data = customdata;
|
SnapCursorDataIntern *data_intern = &g_data_intern;
|
||||||
SnapCursorDataIntern *sdata_intern = customdata;
|
V3DSnapCursorState *state = ED_view3d_cursor_snap_state_get();
|
||||||
|
V3DSnapCursorData *snap_data = &data_intern->snap_data;
|
||||||
|
|
||||||
wmWindowManager *wm = CTX_wm_manager(C);
|
wmWindowManager *wm = CTX_wm_manager(C);
|
||||||
ARegion *region = CTX_wm_region(C);
|
ARegion *region = CTX_wm_region(C);
|
||||||
x -= region->winrct.xmin;
|
x -= region->winrct.xmin;
|
||||||
y -= region->winrct.ymin;
|
y -= region->winrct.ymin;
|
||||||
if (v3d_cursor_eventstate_has_changed(sdata_intern, wm, x, y)) {
|
if (v3d_cursor_eventstate_has_changed(data_intern, state, wm, x, y)) {
|
||||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||||
Scene *scene = DEG_get_input_scene(depsgraph);
|
Scene *scene = DEG_get_input_scene(depsgraph);
|
||||||
View3D *v3d = CTX_wm_view3d(C);
|
View3D *v3d = CTX_wm_view3d(C);
|
||||||
v3d_cursor_snap_update(C, wm, depsgraph, scene, region, v3d, x, y, sdata_intern);
|
v3d_cursor_snap_update(state, C, wm, depsgraph, scene, region, v3d, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool draw_plane = sdata_intern->draw_plane;
|
const bool draw_plane = state->draw_plane;
|
||||||
if (!snap_data->snap_elem && !draw_plane) {
|
if (!snap_data->snap_elem && !draw_plane) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -773,12 +791,12 @@ static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *customdata)
|
|||||||
copy_m4_m3(matrix, snap_data->plane_omat);
|
copy_m4_m3(matrix, snap_data->plane_omat);
|
||||||
copy_v3_v3(matrix[3], snap_data->loc);
|
copy_v3_v3(matrix[3], snap_data->loc);
|
||||||
|
|
||||||
v3d_cursor_plane_draw(rv3d, snap_data->plane_axis, matrix);
|
v3d_cursor_plane_draw(rv3d, state->plane_axis, matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snap_data->snap_elem && sdata_intern->draw_point) {
|
if (snap_data->snap_elem && state->draw_point) {
|
||||||
const float *prev_point = (snap_data->snap_elem & SCE_SNAP_MODE_EDGE_PERPENDICULAR) ?
|
const float *prev_point = (snap_data->snap_elem & SCE_SNAP_MODE_EDGE_PERPENDICULAR) ?
|
||||||
snap_data->prevpoint :
|
state->prevpoint :
|
||||||
NULL;
|
NULL;
|
||||||
|
|
||||||
GPU_line_smooth(false);
|
GPU_line_smooth(false);
|
||||||
@@ -788,8 +806,8 @@ static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *customdata)
|
|||||||
prev_point,
|
prev_point,
|
||||||
snap_data->loc,
|
snap_data->loc,
|
||||||
NULL,
|
NULL,
|
||||||
snap_data->color_line,
|
state->color_line,
|
||||||
snap_data->color_point,
|
state->color_point,
|
||||||
snap_data->snap_elem);
|
snap_data->snap_elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -802,158 +820,177 @@ static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *customdata)
|
|||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
V3DSnapCursorData *ED_view3d_cursor_snap_data_get(void)
|
V3DSnapCursorState *ED_view3d_cursor_snap_state_get(void)
|
||||||
{
|
{
|
||||||
LISTBASE_FOREACH_MUTABLE (wmWindowManager *, wm, &G.main->wm) {
|
if (!g_data_intern.state_active_len) {
|
||||||
LISTBASE_FOREACH_MUTABLE (wmPaintCursor *, pc, &wm->paintcursors) {
|
return &g_data_intern.state_default;
|
||||||
if (pc->draw == v3d_cursor_snap_draw_fn) {
|
}
|
||||||
return (V3DSnapCursorData *)pc->customdata;
|
return (V3DSnapCursorState *)&g_data_intern.state_intern[g_data_intern.state_active];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void v3d_cursor_snap_state_init(V3DSnapCursorState *state)
|
||||||
|
{
|
||||||
|
state->prevpoint = NULL;
|
||||||
|
state->snap_elem_force = (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
|
||||||
|
SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_EDGE_MIDPOINT);
|
||||||
|
state->plane_axis = 2;
|
||||||
|
rgba_uchar_args_set(state->color_point, 255, 255, 255, 255);
|
||||||
|
UI_GetThemeColor3ubv(TH_TRANSFORM, state->color_line);
|
||||||
|
state->color_line[3] = 128;
|
||||||
|
state->draw_point = true;
|
||||||
|
state->draw_plane = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void v3d_cursor_snap_activate(void)
|
||||||
|
{
|
||||||
|
SnapCursorDataIntern *data_intern = &g_data_intern;
|
||||||
|
if (!data_intern->handle) {
|
||||||
|
if (!data_intern->is_initiated) {
|
||||||
|
/* Only initiate intern data once.
|
||||||
|
* TODO: ED_view3d_cursor_snap_init */
|
||||||
|
|
||||||
|
#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
|
||||||
|
struct wmKeyConfig *keyconf = ((wmWindowManager *)G.main->wm.first)->defaultconf;
|
||||||
|
|
||||||
|
data_intern->keymap = WM_modalkeymap_find(keyconf, "Generic Gizmo Tweak Modal Map");
|
||||||
|
RNA_enum_value_from_id(data_intern->keymap->modal_items, "SNAP_ON", &data_intern->snap_on);
|
||||||
|
#endif
|
||||||
|
V3DSnapCursorState *state_default = &data_intern->state_default;
|
||||||
|
state_default->prevpoint = NULL;
|
||||||
|
state_default->snap_elem_force = (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE |
|
||||||
|
SCE_SNAP_MODE_FACE | SCE_SNAP_MODE_EDGE_PERPENDICULAR |
|
||||||
|
SCE_SNAP_MODE_EDGE_MIDPOINT);
|
||||||
|
state_default->plane_axis = 2;
|
||||||
|
rgba_uchar_args_set(state_default->color_point, 255, 255, 255, 255);
|
||||||
|
UI_GetThemeColor3ubv(TH_TRANSFORM, state_default->color_line);
|
||||||
|
state_default->color_line[3] = 128;
|
||||||
|
state_default->draw_point = true;
|
||||||
|
state_default->draw_plane = false;
|
||||||
|
|
||||||
|
data_intern->is_initiated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wmPaintCursor *pc = WM_paint_cursor_activate(
|
||||||
|
SPACE_VIEW3D, RGN_TYPE_WINDOW, v3d_cursor_snap_pool_fn, v3d_cursor_snap_draw_fn, NULL);
|
||||||
|
data_intern->handle = pc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void v3d_cursor_snap_free(void)
|
||||||
|
{
|
||||||
|
SnapCursorDataIntern *data_intern = &g_data_intern;
|
||||||
|
if (data_intern->handle) {
|
||||||
|
WM_paint_cursor_end(data_intern->handle);
|
||||||
|
data_intern->handle = NULL;
|
||||||
|
}
|
||||||
|
if (data_intern->snap_context_v3d) {
|
||||||
|
ED_transform_snap_object_context_destroy(data_intern->snap_context_v3d);
|
||||||
|
data_intern->snap_context_v3d = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (SnapStateIntern *state_intern = data_intern->state_intern;
|
||||||
|
state_intern < &data_intern->state_intern[STATE_LEN];
|
||||||
|
state_intern++) {
|
||||||
|
state_intern->is_active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ED_view3d_cursor_snap_state_default_set(V3DSnapCursorState *state)
|
||||||
|
{
|
||||||
|
g_data_intern.state_default = *state;
|
||||||
|
}
|
||||||
|
|
||||||
|
V3DSnapCursorState *ED_view3d_cursor_snap_active(void)
|
||||||
|
{
|
||||||
|
SnapCursorDataIntern *data_intern = &g_data_intern;
|
||||||
|
if (!data_intern->state_active_len) {
|
||||||
|
v3d_cursor_snap_activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
data_intern->state_active_len++;
|
||||||
|
for (int i = 0; i < STATE_LEN; i++) {
|
||||||
|
SnapStateIntern *state_intern = &g_data_intern.state_intern[i];
|
||||||
|
if (!state_intern->is_active) {
|
||||||
|
state_intern->snap_state = g_data_intern.state_default;
|
||||||
|
state_intern->is_active = true;
|
||||||
|
state_intern->state_active_prev = data_intern->state_active;
|
||||||
|
data_intern->state_active = i;
|
||||||
|
return (V3DSnapCursorState *)state_intern;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BLI_assert(false);
|
||||||
|
data_intern->state_active_len--;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void v3d_cursor_snap_data_init(SnapCursorDataIntern *sdata_intern)
|
void ED_view3d_cursor_snap_deactive(V3DSnapCursorState *state)
|
||||||
{
|
{
|
||||||
#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
|
SnapCursorDataIntern *data_intern = &g_data_intern;
|
||||||
struct wmKeyConfig *keyconf = ((wmWindowManager *)G.main->wm.first)->defaultconf;
|
if (!data_intern->state_active_len) {
|
||||||
|
BLI_assert(false);
|
||||||
sdata_intern->keymap = WM_modalkeymap_find(keyconf, "Generic Gizmo Tweak Modal Map");
|
|
||||||
RNA_enum_value_from_id(sdata_intern->keymap->modal_items, "SNAP_ON", &sdata_intern->snap_on);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
V3DSnapCursorData *snap_data = &sdata_intern->snap_data;
|
|
||||||
snap_data->snap_elem_force = (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
|
|
||||||
SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_EDGE_MIDPOINT);
|
|
||||||
snap_data->plane_axis = 2;
|
|
||||||
rgba_uchar_args_set(snap_data->color_point, 255, 255, 255, 255);
|
|
||||||
UI_GetThemeColor3ubv(TH_TRANSFORM, snap_data->color_line);
|
|
||||||
snap_data->color_line[3] = 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
static SnapCursorDataIntern *v3d_cursor_snap_ensure(void)
|
|
||||||
{
|
|
||||||
SnapCursorDataIntern *sdata_intern = (SnapCursorDataIntern *)ED_view3d_cursor_snap_data_get();
|
|
||||||
if (!sdata_intern) {
|
|
||||||
sdata_intern = MEM_callocN(sizeof(*sdata_intern), __func__);
|
|
||||||
v3d_cursor_snap_data_init(sdata_intern);
|
|
||||||
|
|
||||||
struct wmPaintCursor *pc = WM_paint_cursor_activate(SPACE_VIEW3D,
|
|
||||||
RGN_TYPE_WINDOW,
|
|
||||||
v3d_cursor_snap_pool_fn,
|
|
||||||
v3d_cursor_snap_draw_fn,
|
|
||||||
sdata_intern);
|
|
||||||
sdata_intern->handle = pc;
|
|
||||||
}
|
|
||||||
return sdata_intern;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ED_view3d_cursor_snap_activate_point(void)
|
|
||||||
{
|
|
||||||
SnapCursorDataIntern *sdata_intern = v3d_cursor_snap_ensure();
|
|
||||||
sdata_intern->draw_point = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ED_view3d_cursor_snap_activate_plane(void)
|
|
||||||
{
|
|
||||||
SnapCursorDataIntern *sdata_intern = v3d_cursor_snap_ensure();
|
|
||||||
sdata_intern->draw_plane = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void v3d_cursor_snap_free(SnapCursorDataIntern *sdata_intern)
|
|
||||||
{
|
|
||||||
WM_paint_cursor_end(sdata_intern->handle);
|
|
||||||
if (sdata_intern->snap_context_v3d) {
|
|
||||||
ED_transform_snap_object_context_destroy(sdata_intern->snap_context_v3d);
|
|
||||||
}
|
|
||||||
MEM_freeN(sdata_intern);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ED_view3d_cursor_snap_deactivate_point(void)
|
|
||||||
{
|
|
||||||
SnapCursorDataIntern *sdata_intern = (SnapCursorDataIntern *)ED_view3d_cursor_snap_data_get();
|
|
||||||
if (!sdata_intern) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdata_intern->draw_point = false;
|
SnapStateIntern *state_intern = (SnapStateIntern *)state;
|
||||||
sdata_intern->snap_data.prevpoint = NULL;
|
if (!state_intern->is_active) {
|
||||||
if (sdata_intern->draw_plane) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
v3d_cursor_snap_free(sdata_intern);
|
state_intern->is_active = false;
|
||||||
}
|
data_intern->state_active_len--;
|
||||||
|
if (!data_intern->state_active_len) {
|
||||||
void ED_view3d_cursor_snap_deactivate_plane(void)
|
v3d_cursor_snap_free();
|
||||||
{
|
|
||||||
SnapCursorDataIntern *sdata_intern = (SnapCursorDataIntern *)ED_view3d_cursor_snap_data_get();
|
|
||||||
if (!sdata_intern) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sdata_intern->draw_plane = false;
|
|
||||||
sdata_intern->snap_data.prevpoint = NULL;
|
|
||||||
if (sdata_intern->draw_point) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
v3d_cursor_snap_free(sdata_intern);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ED_view3d_cursor_snap_prevpoint_set(const float prev_point[3])
|
|
||||||
{
|
|
||||||
SnapCursorDataIntern *sdata_intern = (SnapCursorDataIntern *)ED_view3d_cursor_snap_data_get();
|
|
||||||
if (!sdata_intern) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (prev_point) {
|
|
||||||
copy_v3_v3(sdata_intern->prevpoint_stack, prev_point);
|
|
||||||
sdata_intern->snap_data.prevpoint = sdata_intern->prevpoint_stack;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sdata_intern->snap_data.prevpoint = NULL;
|
data_intern->state_active = state_intern->state_active_prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ED_view3d_cursor_snap_update(const bContext *C,
|
void ED_view3d_cursor_snap_prevpoint_set(V3DSnapCursorState *state, const float prev_point[3])
|
||||||
const int x,
|
|
||||||
const int y,
|
|
||||||
V3DSnapCursorData *snap_data)
|
|
||||||
{
|
{
|
||||||
SnapCursorDataIntern stack = {0}, *sdata_intern;
|
SnapStateIntern *state_intern = (SnapStateIntern *)state;
|
||||||
sdata_intern = (SnapCursorDataIntern *)ED_view3d_cursor_snap_data_get();
|
if (prev_point) {
|
||||||
if (!sdata_intern) {
|
copy_v3_v3(state_intern->prevpoint_stack, prev_point);
|
||||||
sdata_intern = &stack;
|
state->prevpoint = state_intern->prevpoint_stack;
|
||||||
v3d_cursor_snap_data_init(sdata_intern);
|
|
||||||
sdata_intern->draw_plane = true;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
wmWindowManager *wm = CTX_wm_manager(C);
|
state->prevpoint = NULL;
|
||||||
if (v3d_cursor_eventstate_has_changed(sdata_intern, wm, x, y)) {
|
|
||||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
|
||||||
Scene *scene = DEG_get_input_scene(depsgraph);
|
|
||||||
ARegion *region = CTX_wm_region(C);
|
|
||||||
View3D *v3d = CTX_wm_view3d(C);
|
|
||||||
|
|
||||||
v3d_cursor_snap_update(C, wm, depsgraph, scene, region, v3d, x, y, sdata_intern);
|
|
||||||
}
|
}
|
||||||
if ((void *)snap_data != (void *)sdata_intern) {
|
}
|
||||||
if ((sdata_intern == &stack) && sdata_intern->snap_context_v3d) {
|
|
||||||
ED_transform_snap_object_context_destroy(sdata_intern->snap_context_v3d);
|
V3DSnapCursorData *ED_view3d_cursor_snap_data_get(V3DSnapCursorState *state,
|
||||||
sdata_intern->snap_context_v3d = NULL;
|
const bContext *C,
|
||||||
|
const int x,
|
||||||
|
const int y)
|
||||||
|
{
|
||||||
|
SnapCursorDataIntern *data_intern = &g_data_intern;
|
||||||
|
if (C && data_intern->state_active_len) {
|
||||||
|
wmWindowManager *wm = CTX_wm_manager(C);
|
||||||
|
if (v3d_cursor_eventstate_has_changed(data_intern, state, wm, x, y)) {
|
||||||
|
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||||
|
Scene *scene = DEG_get_input_scene(depsgraph);
|
||||||
|
ARegion *region = CTX_wm_region(C);
|
||||||
|
View3D *v3d = CTX_wm_view3d(C);
|
||||||
|
|
||||||
|
if (!state) {
|
||||||
|
state = ED_view3d_cursor_snap_state_get();
|
||||||
|
}
|
||||||
|
v3d_cursor_snap_update(state, C, wm, depsgraph, scene, region, v3d, x, y);
|
||||||
}
|
}
|
||||||
*snap_data = *(V3DSnapCursorData *)sdata_intern;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return &data_intern->snap_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SnapObjectContext *ED_view3d_cursor_snap_context_ensure(struct Scene *scene)
|
struct SnapObjectContext *ED_view3d_cursor_snap_context_ensure(Scene *scene)
|
||||||
{
|
{
|
||||||
SnapCursorDataIntern *sdata_intern = (SnapCursorDataIntern *)ED_view3d_cursor_snap_data_get();
|
SnapCursorDataIntern *data_intern = &g_data_intern;
|
||||||
if (!sdata_intern) {
|
v3d_cursor_snap_context_ensure(scene);
|
||||||
return NULL;
|
return data_intern->snap_context_v3d;
|
||||||
}
|
}
|
||||||
v3d_cursor_snap_context_ensure(sdata_intern, scene);
|
|
||||||
return sdata_intern->snap_context_v3d;
|
void ED_view3d_cursor_snap_exit(void)
|
||||||
|
{
|
||||||
|
v3d_cursor_snap_free();
|
||||||
}
|
}
|
||||||
|
@@ -45,11 +45,11 @@
|
|||||||
|
|
||||||
#include "view3d_intern.h"
|
#include "view3d_intern.h"
|
||||||
|
|
||||||
static const char *view3d_gzgt_placement_id = "VIEW3D_GGT_placement";
|
#define SNAP_MODE_GEOM \
|
||||||
|
(SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE | \
|
||||||
|
SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_EDGE_MIDPOINT)
|
||||||
|
|
||||||
static void preview_plane_cursor_visible_set(wmGizmoGroup *gzgroup,
|
static const char *view3d_gzgt_placement_id = "VIEW3D_GGT_placement";
|
||||||
bool do_draw_plane,
|
|
||||||
bool do_draw_point);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dot products below this will be considered view aligned.
|
* Dot products below this will be considered view aligned.
|
||||||
@@ -151,6 +151,7 @@ struct InteractivePlaceData {
|
|||||||
float matrix_orient[3][3];
|
float matrix_orient[3][3];
|
||||||
int orient_axis;
|
int orient_axis;
|
||||||
|
|
||||||
|
V3DSnapCursorState *snap_state;
|
||||||
bool use_snap, is_snap_found, is_snap_invert;
|
bool use_snap, is_snap_found, is_snap_invert;
|
||||||
float snap_co[3];
|
float snap_co[3];
|
||||||
|
|
||||||
@@ -693,18 +694,25 @@ static void draw_primitive_view(const struct bContext *C, ARegion *UNUSED(region
|
|||||||
* Use by both the operator and placement cursor.
|
* Use by both the operator and placement cursor.
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
static bool view3d_interactive_add_calc_plane(bContext *C,
|
static bool view3d_interactive_add_calc_snap(bContext *C,
|
||||||
const wmEvent *event,
|
const wmEvent *event,
|
||||||
float r_co_src[3],
|
float r_co_src[3],
|
||||||
float r_matrix_orient[3][3])
|
float r_matrix_orient[3][3],
|
||||||
|
bool *r_is_enabled,
|
||||||
|
bool *r_is_snap_invert)
|
||||||
{
|
{
|
||||||
V3DSnapCursorData snap_data;
|
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get(NULL, NULL, 0, 0);
|
||||||
ED_view3d_cursor_snap_update(C, UNPACK2(event->mval), &snap_data);
|
copy_v3_v3(r_co_src, snap_data->loc);
|
||||||
copy_v3_v3(r_co_src, snap_data.loc);
|
|
||||||
if (r_matrix_orient) {
|
if (r_matrix_orient) {
|
||||||
copy_m3_m3(r_matrix_orient, snap_data.plane_omat);
|
copy_m3_m3(r_matrix_orient, snap_data->plane_omat);
|
||||||
}
|
}
|
||||||
return snap_data.snap_elem != 0;
|
if (r_is_enabled) {
|
||||||
|
*r_is_enabled = snap_data->is_enabled;
|
||||||
|
}
|
||||||
|
if (r_is_snap_invert) {
|
||||||
|
*r_is_snap_invert = snap_data->is_snap_invert;
|
||||||
|
}
|
||||||
|
return snap_data->snap_elem != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
@@ -715,12 +723,11 @@ static bool view3d_interactive_add_calc_plane(bContext *C,
|
|||||||
|
|
||||||
static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEvent *event)
|
static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEvent *event)
|
||||||
{
|
{
|
||||||
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
|
|
||||||
const int plane_axis = RNA_enum_get(op->ptr, "plane_axis");
|
const int plane_axis = snap_state->plane_axis;
|
||||||
const bool plane_axis_auto = RNA_boolean_get(op->ptr, "plane_axis_auto");
|
|
||||||
const enum ePlace_SnapTo snap_to = RNA_enum_get(op->ptr, "snap_target");
|
const enum ePlace_SnapTo snap_to = RNA_enum_get(op->ptr, "snap_target");
|
||||||
const eV3DPlaceDepth plane_depth = RNA_enum_get(op->ptr, "plane_depth");
|
|
||||||
const eV3DPlaceOrient plane_orient = RNA_enum_get(op->ptr, "plane_orient");
|
|
||||||
const enum ePlace_Origin plane_origin[2] = {
|
const enum ePlace_Origin plane_origin[2] = {
|
||||||
RNA_enum_get(op->ptr, "plane_origin_base"),
|
RNA_enum_get(op->ptr, "plane_origin_base"),
|
||||||
RNA_enum_get(op->ptr, "plane_origin_depth"),
|
RNA_enum_get(op->ptr, "plane_origin_depth"),
|
||||||
@@ -734,24 +741,16 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
|
|||||||
|
|
||||||
ipd->launch_event = WM_userdef_event_type_from_keymap_type(event->type);
|
ipd->launch_event = WM_userdef_event_type_from_keymap_type(event->type);
|
||||||
|
|
||||||
ED_view3d_cursor_snap_activate_point();
|
ipd->snap_state = ED_view3d_cursor_snap_active();
|
||||||
{
|
ipd->snap_state->draw_point = true;
|
||||||
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get();
|
ipd->snap_state->draw_plane = true;
|
||||||
snap_data->plane_depth = plane_depth;
|
|
||||||
snap_data->plane_orient = plane_orient;
|
|
||||||
snap_data->plane_axis = plane_axis;
|
|
||||||
snap_data->use_plane_axis_auto = plane_axis_auto;
|
|
||||||
|
|
||||||
ED_view3d_cursor_snap_activate_plane();
|
ipd->is_snap_found =
|
||||||
view3d_interactive_add_calc_plane(C, event, ipd->co_src, ipd->matrix_orient);
|
view3d_interactive_add_calc_snap(
|
||||||
ED_view3d_cursor_snap_deactivate_plane();
|
C, event, ipd->co_src, ipd->matrix_orient, &ipd->use_snap, &ipd->is_snap_invert) != 0;
|
||||||
|
|
||||||
ED_view3d_cursor_snap_prevpoint_set(ipd->co_src);
|
ipd->snap_state->draw_plane = false;
|
||||||
|
ED_view3d_cursor_snap_prevpoint_set(ipd->snap_state, ipd->co_src);
|
||||||
ipd->use_snap = snap_data->is_enabled;
|
|
||||||
ipd->is_snap_invert = snap_data->is_snap_invert;
|
|
||||||
ipd->is_snap_found = snap_data->snap_elem != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ipd->orient_axis = plane_axis;
|
ipd->orient_axis = plane_axis;
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
@@ -905,14 +904,7 @@ static void view3d_interactive_add_exit(bContext *C, wmOperator *op)
|
|||||||
UNUSED_VARS(C);
|
UNUSED_VARS(C);
|
||||||
|
|
||||||
struct InteractivePlaceData *ipd = op->customdata;
|
struct InteractivePlaceData *ipd = op->customdata;
|
||||||
|
ED_view3d_cursor_snap_deactive(ipd->snap_state);
|
||||||
wmGizmoGroup *gzgroup = idp_gizmogroup_from_region(ipd->region);
|
|
||||||
if (gzgroup != NULL) {
|
|
||||||
preview_plane_cursor_visible_set(gzgroup, true, true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ED_view3d_cursor_snap_deactivate_point();
|
|
||||||
}
|
|
||||||
|
|
||||||
ED_region_draw_cb_exit(ipd->region->type, ipd->draw_handle_view);
|
ED_region_draw_cb_exit(ipd->region->type, ipd->draw_handle_view);
|
||||||
|
|
||||||
@@ -1035,7 +1027,7 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
|
|||||||
if (ipd->step_index == STEP_BASE) {
|
if (ipd->step_index == STEP_BASE) {
|
||||||
if (ELEM(event->type, ipd->launch_event, LEFTMOUSE)) {
|
if (ELEM(event->type, ipd->launch_event, LEFTMOUSE)) {
|
||||||
if (event->val == KM_RELEASE) {
|
if (event->val == KM_RELEASE) {
|
||||||
ED_view3d_cursor_snap_prevpoint_set(ipd->co_src);
|
ED_view3d_cursor_snap_prevpoint_set(ipd->snap_state, ipd->co_src);
|
||||||
|
|
||||||
/* Set secondary plane. */
|
/* Set secondary plane. */
|
||||||
|
|
||||||
@@ -1184,7 +1176,8 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
|
|||||||
/* Calculate the snap location on mouse-move or when toggling snap. */
|
/* Calculate the snap location on mouse-move or when toggling snap. */
|
||||||
ipd->is_snap_found = false;
|
ipd->is_snap_found = false;
|
||||||
if (ipd->use_snap) {
|
if (ipd->use_snap) {
|
||||||
ipd->is_snap_found = view3d_interactive_add_calc_plane(C, event, ipd->snap_co, NULL);
|
ipd->is_snap_found = view3d_interactive_add_calc_snap(
|
||||||
|
C, event, ipd->snap_co, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ipd->step_index == STEP_BASE) {
|
if (ipd->step_index == STEP_BASE) {
|
||||||
@@ -1254,6 +1247,98 @@ static bool view3d_interactive_add_poll(bContext *C)
|
|||||||
return ELEM(mode, CTX_MODE_OBJECT, CTX_MODE_EDIT_MESH);
|
return ELEM(mode, CTX_MODE_OBJECT, CTX_MODE_EDIT_MESH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int idp_rna_plane_axis_get_fn(struct PointerRNA *UNUSED(ptr),
|
||||||
|
struct PropertyRNA *UNUSED(prop))
|
||||||
|
{
|
||||||
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
|
return snap_state->plane_axis;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void idp_rna_plane_axis_set_fn(struct PointerRNA *UNUSED(ptr),
|
||||||
|
struct PropertyRNA *UNUSED(prop),
|
||||||
|
int value)
|
||||||
|
{
|
||||||
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
|
snap_state->plane_axis = value;
|
||||||
|
ED_view3d_cursor_snap_state_default_set(snap_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int idp_rna_plane_depth_get_fn(struct PointerRNA *UNUSED(ptr),
|
||||||
|
struct PropertyRNA *UNUSED(prop))
|
||||||
|
{
|
||||||
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
|
return snap_state->plane_depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void idp_rna_plane_depth_set_fn(struct PointerRNA *UNUSED(ptr),
|
||||||
|
struct PropertyRNA *UNUSED(prop),
|
||||||
|
int value)
|
||||||
|
{
|
||||||
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
|
snap_state->plane_depth = value;
|
||||||
|
ED_view3d_cursor_snap_state_default_set(snap_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int idp_rna_plane_orient_get_fn(struct PointerRNA *UNUSED(ptr),
|
||||||
|
struct PropertyRNA *UNUSED(prop))
|
||||||
|
{
|
||||||
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
|
return snap_state->plane_orient;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void idp_rna_plane_orient_set_fn(struct PointerRNA *UNUSED(ptr),
|
||||||
|
struct PropertyRNA *UNUSED(prop),
|
||||||
|
int value)
|
||||||
|
{
|
||||||
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
|
snap_state->plane_orient = value;
|
||||||
|
ED_view3d_cursor_snap_state_default_set(snap_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int idp_rna_snap_target_get_fn(struct PointerRNA *UNUSED(ptr),
|
||||||
|
struct PropertyRNA *UNUSED(prop))
|
||||||
|
{
|
||||||
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
|
if (!snap_state->snap_elem_force) {
|
||||||
|
return PLACE_SNAP_TO_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure you keep a consistent #snap_mode. */
|
||||||
|
snap_state->snap_elem_force = SNAP_MODE_GEOM;
|
||||||
|
return PLACE_SNAP_TO_GEOMETRY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void idp_rna_snap_target_set_fn(struct PointerRNA *UNUSED(ptr),
|
||||||
|
struct PropertyRNA *UNUSED(prop),
|
||||||
|
int value)
|
||||||
|
{
|
||||||
|
short snap_mode = 0; /* #toolsettings->snap_mode. */
|
||||||
|
const enum ePlace_SnapTo snap_to = value;
|
||||||
|
if (snap_to == PLACE_SNAP_TO_GEOMETRY) {
|
||||||
|
snap_mode = SNAP_MODE_GEOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
|
snap_state->snap_elem_force = snap_mode;
|
||||||
|
ED_view3d_cursor_snap_state_default_set(snap_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool idp_rna_use_plane_axis_auto_get_fn(struct PointerRNA *UNUSED(ptr),
|
||||||
|
struct PropertyRNA *UNUSED(prop))
|
||||||
|
{
|
||||||
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
|
return snap_state->use_plane_axis_auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void idp_rna_use_plane_axis_auto_set_fn(struct PointerRNA *UNUSED(ptr),
|
||||||
|
struct PropertyRNA *UNUSED(prop),
|
||||||
|
bool value)
|
||||||
|
{
|
||||||
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
|
snap_state->use_plane_axis_auto = value;
|
||||||
|
ED_view3d_cursor_snap_state_default_set(snap_state);
|
||||||
|
}
|
||||||
|
|
||||||
void VIEW3D_OT_interactive_add(struct wmOperatorType *ot)
|
void VIEW3D_OT_interactive_add(struct wmOperatorType *ot)
|
||||||
{
|
{
|
||||||
/* identifiers */
|
/* identifiers */
|
||||||
@@ -1294,6 +1379,8 @@ void VIEW3D_OT_interactive_add(struct wmOperatorType *ot)
|
|||||||
RNA_def_property_enum_default(prop, 2);
|
RNA_def_property_enum_default(prop, 2);
|
||||||
RNA_def_property_enum_items(prop, rna_enum_axis_xyz_items);
|
RNA_def_property_enum_items(prop, rna_enum_axis_xyz_items);
|
||||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||||
|
RNA_def_property_enum_funcs_runtime(
|
||||||
|
prop, idp_rna_plane_axis_get_fn, idp_rna_plane_axis_set_fn, NULL);
|
||||||
|
|
||||||
prop = RNA_def_boolean(ot->srna,
|
prop = RNA_def_boolean(ot->srna,
|
||||||
"plane_axis_auto",
|
"plane_axis_auto",
|
||||||
@@ -1302,6 +1389,8 @@ void VIEW3D_OT_interactive_add(struct wmOperatorType *ot)
|
|||||||
"Select the closest axis when placing objects "
|
"Select the closest axis when placing objects "
|
||||||
"(surface overrides)");
|
"(surface overrides)");
|
||||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||||
|
RNA_def_property_boolean_funcs_runtime(
|
||||||
|
prop, idp_rna_use_plane_axis_auto_get_fn, idp_rna_use_plane_axis_auto_set_fn);
|
||||||
|
|
||||||
static const EnumPropertyItem plane_depth_items[] = {
|
static const EnumPropertyItem plane_depth_items[] = {
|
||||||
{V3D_PLACE_DEPTH_SURFACE,
|
{V3D_PLACE_DEPTH_SURFACE,
|
||||||
@@ -1327,6 +1416,8 @@ void VIEW3D_OT_interactive_add(struct wmOperatorType *ot)
|
|||||||
RNA_def_property_enum_default(prop, V3D_PLACE_DEPTH_SURFACE);
|
RNA_def_property_enum_default(prop, V3D_PLACE_DEPTH_SURFACE);
|
||||||
RNA_def_property_enum_items(prop, plane_depth_items);
|
RNA_def_property_enum_items(prop, plane_depth_items);
|
||||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||||
|
RNA_def_property_enum_funcs_runtime(
|
||||||
|
prop, idp_rna_plane_depth_get_fn, idp_rna_plane_depth_set_fn, NULL);
|
||||||
|
|
||||||
static const EnumPropertyItem plane_orientation_items[] = {
|
static const EnumPropertyItem plane_orientation_items[] = {
|
||||||
{V3D_PLACE_ORIENT_SURFACE,
|
{V3D_PLACE_ORIENT_SURFACE,
|
||||||
@@ -1346,6 +1437,8 @@ void VIEW3D_OT_interactive_add(struct wmOperatorType *ot)
|
|||||||
RNA_def_property_enum_default(prop, V3D_PLACE_ORIENT_SURFACE);
|
RNA_def_property_enum_default(prop, V3D_PLACE_ORIENT_SURFACE);
|
||||||
RNA_def_property_enum_items(prop, plane_orientation_items);
|
RNA_def_property_enum_items(prop, plane_orientation_items);
|
||||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||||
|
RNA_def_property_enum_funcs_runtime(
|
||||||
|
prop, idp_rna_plane_orient_get_fn, idp_rna_plane_orient_set_fn, NULL);
|
||||||
|
|
||||||
static const EnumPropertyItem snap_to_items[] = {
|
static const EnumPropertyItem snap_to_items[] = {
|
||||||
{PLACE_SNAP_TO_GEOMETRY, "GEOMETRY", 0, "Geometry", "Snap to all geometry"},
|
{PLACE_SNAP_TO_GEOMETRY, "GEOMETRY", 0, "Geometry", "Snap to all geometry"},
|
||||||
@@ -1357,6 +1450,8 @@ void VIEW3D_OT_interactive_add(struct wmOperatorType *ot)
|
|||||||
RNA_def_property_enum_default(prop, PLACE_SNAP_TO_GEOMETRY);
|
RNA_def_property_enum_default(prop, PLACE_SNAP_TO_GEOMETRY);
|
||||||
RNA_def_property_enum_items(prop, snap_to_items);
|
RNA_def_property_enum_items(prop, snap_to_items);
|
||||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||||
|
RNA_def_property_enum_funcs_runtime(
|
||||||
|
prop, idp_rna_snap_target_get_fn, idp_rna_snap_target_set_fn, NULL);
|
||||||
|
|
||||||
{ /* Plane Origin. */
|
{ /* Plane Origin. */
|
||||||
static const EnumPropertyItem items[] = {
|
static const EnumPropertyItem items[] = {
|
||||||
@@ -1404,77 +1499,21 @@ void VIEW3D_OT_interactive_add(struct wmOperatorType *ot)
|
|||||||
* we could show a placement plane here.
|
* we could show a placement plane here.
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
static void preview_plane_cursor_visible_set(wmGizmoGroup *UNUSED(gzgroup),
|
|
||||||
bool do_draw_plane,
|
|
||||||
bool do_draw_point)
|
|
||||||
{
|
|
||||||
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get();
|
|
||||||
|
|
||||||
if (do_draw_point) {
|
|
||||||
ED_view3d_cursor_snap_activate_point();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (do_draw_plane) {
|
|
||||||
ED_view3d_cursor_snap_activate_plane();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ED_view3d_cursor_snap_deactivate_plane();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!do_draw_point) {
|
|
||||||
ED_view3d_cursor_snap_deactivate_point();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!snap_data && (do_draw_point || do_draw_plane)) {
|
|
||||||
snap_data = ED_view3d_cursor_snap_data_get();
|
|
||||||
UI_GetThemeColor3ubv(TH_TRANSFORM, snap_data->color_line);
|
|
||||||
snap_data->color_line[3] = 128;
|
|
||||||
rgba_uchar_args_set(snap_data->color_point, 255, 255, 255, 255);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void preview_plane_free_fn(void *customdata)
|
static void preview_plane_free_fn(void *customdata)
|
||||||
{
|
{
|
||||||
preview_plane_cursor_visible_set(customdata, false, false);
|
V3DSnapCursorState *snap_state = customdata;
|
||||||
|
ED_view3d_cursor_snap_deactive(snap_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WIDGETGROUP_placement_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
|
static void WIDGETGROUP_placement_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
|
||||||
{
|
{
|
||||||
preview_plane_cursor_visible_set(gzgroup, true, true);
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_active();
|
||||||
gzgroup->customdata = gzgroup;
|
snap_state->draw_plane = true;
|
||||||
|
|
||||||
|
gzgroup->customdata = snap_state;
|
||||||
gzgroup->customdata_free = preview_plane_free_fn;
|
gzgroup->customdata_free = preview_plane_free_fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WIDGETGROUP_placement_draw_prepare(const bContext *C, wmGizmoGroup *UNUSED(gzgroup))
|
|
||||||
{
|
|
||||||
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get();
|
|
||||||
if (!snap_data) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PointerRNA ptr;
|
|
||||||
{
|
|
||||||
wmOperatorType *ot = WM_operatortype_find("VIEW3D_OT_interactive_add", true);
|
|
||||||
BLI_assert(ot != NULL);
|
|
||||||
|
|
||||||
ScrArea *area = CTX_wm_area(C);
|
|
||||||
bToolRef *tref = area->runtime.tool;
|
|
||||||
WM_toolsystem_ref_properties_ensure_from_operator(tref, ot, &ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
short snap_mode = 0; /* #toolsettings->snap_mode. */
|
|
||||||
const enum ePlace_SnapTo snap_to = RNA_enum_get(&ptr, "snap_target");
|
|
||||||
if (snap_to == PLACE_SNAP_TO_GEOMETRY) {
|
|
||||||
snap_mode = (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
|
|
||||||
SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_EDGE_MIDPOINT);
|
|
||||||
}
|
|
||||||
snap_data->snap_elem_force = snap_mode;
|
|
||||||
snap_data->plane_depth = (eV3DPlaceDepth)RNA_enum_get(&ptr, "plane_depth");
|
|
||||||
snap_data->plane_orient = (eV3DPlaceOrient)RNA_enum_get(&ptr, "plane_orientation");
|
|
||||||
snap_data->plane_axis = RNA_enum_get(&ptr, "plane_axis");
|
|
||||||
snap_data->use_plane_axis_auto = RNA_boolean_get(&ptr, "plane_axis_auto");
|
|
||||||
}
|
|
||||||
|
|
||||||
void VIEW3D_GGT_placement(wmGizmoGroupType *gzgt)
|
void VIEW3D_GGT_placement(wmGizmoGroupType *gzgt)
|
||||||
{
|
{
|
||||||
gzgt->name = "Placement Widget";
|
gzgt->name = "Placement Widget";
|
||||||
@@ -1487,7 +1526,6 @@ void VIEW3D_GGT_placement(wmGizmoGroupType *gzgt)
|
|||||||
|
|
||||||
gzgt->poll = ED_gizmo_poll_or_unlink_delayed_from_tool;
|
gzgt->poll = ED_gizmo_poll_or_unlink_delayed_from_tool;
|
||||||
gzgt->setup = WIDGETGROUP_placement_setup;
|
gzgt->setup = WIDGETGROUP_placement_setup;
|
||||||
gzgt->draw_prepare = WIDGETGROUP_placement_draw_prepare;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
@@ -119,6 +119,7 @@
|
|||||||
#include "ED_space_api.h"
|
#include "ED_space_api.h"
|
||||||
#include "ED_undo.h"
|
#include "ED_undo.h"
|
||||||
#include "ED_util.h"
|
#include "ED_util.h"
|
||||||
|
#include "ED_view3d.h"
|
||||||
|
|
||||||
#include "BLF_api.h"
|
#include "BLF_api.h"
|
||||||
#include "BLT_lang.h"
|
#include "BLT_lang.h"
|
||||||
@@ -547,6 +548,7 @@ void WM_exit_ex(bContext *C, const bool do_python)
|
|||||||
|
|
||||||
ED_preview_free_dbase(); /* frees a Main dbase, before BKE_blender_free! */
|
ED_preview_free_dbase(); /* frees a Main dbase, before BKE_blender_free! */
|
||||||
ED_assetlist_storage_exit();
|
ED_assetlist_storage_exit();
|
||||||
|
ED_view3d_cursor_snap_exit();
|
||||||
|
|
||||||
if (wm) {
|
if (wm) {
|
||||||
/* Before BKE_blender_free! - since the ListBases get freed there. */
|
/* Before BKE_blender_free! - since the ListBases get freed there. */
|
||||||
|
Reference in New Issue
Block a user