Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/transform/transform_snap.cc
- This file was moved from source/blender/editors/transform/transform_snap.c.
| /* SPDX-License-Identifier: GPL-2.0-or-later | /* SPDX-License-Identifier: GPL-2.0-or-later | ||||
| * Copyright 2001-2002 NaN Holding BV. All rights reserved. */ | * Copyright 2001-2002 NaN Holding BV. All rights reserved. */ | ||||
| /** \file | /** \file | ||||
| * \ingroup edtransform | * \ingroup edtransform | ||||
| */ | */ | ||||
| #include <float.h> | #include <float.h> | ||||
| #include "PIL_time.h" | #include "PIL_time.h" | ||||
| #include "DNA_windowmanager_types.h" | #include "DNA_windowmanager_types.h" | ||||
| #include "BLI_blenlib.h" | #include "BLI_blenlib.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BLI_utildefines.h" | |||||
| #include "GPU_immediate.h" | #include "GPU_immediate.h" | ||||
| #include "GPU_matrix.h" | #include "GPU_matrix.h" | ||||
| #include "GPU_state.h" | #include "GPU_state.h" | ||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_editmesh.h" | #include "BKE_editmesh.h" | ||||
| #include "BKE_layer.h" | #include "BKE_layer.h" | ||||
| ▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | int BIF_snappingSupported(Object *obedit) | ||||
| return status; | return status; | ||||
| } | } | ||||
| #endif | #endif | ||||
| static bool snap_use_backface_culling(const TransInfo *t) | static bool snap_use_backface_culling(const TransInfo *t) | ||||
| { | { | ||||
| BLI_assert(t->spacetype == SPACE_VIEW3D); | BLI_assert(t->spacetype == SPACE_VIEW3D); | ||||
| View3D *v3d = t->view; | View3D *v3d = static_cast<View3D *>(t->view); | ||||
| if ((v3d->shading.type == OB_SOLID) && (v3d->shading.flag & V3D_SHADING_BACKFACE_CULLING)) { | if ((v3d->shading.type == OB_SOLID) && (v3d->shading.flag & V3D_SHADING_BACKFACE_CULLING)) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| if (v3d->shading.type == OB_RENDER && | if (v3d->shading.type == OB_RENDER && | ||||
| (t->scene->display.shading.flag & V3D_SHADING_BACKFACE_CULLING) && | (t->scene->display.shading.flag & V3D_SHADING_BACKFACE_CULLING) && | ||||
| BKE_scene_uses_blender_workbench(t->scene)) { | BKE_scene_uses_blender_workbench(t->scene)) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 186 Lines • ▼ Show 20 Lines | else if (t->spacetype == SPACE_NODE) { | ||||
| size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE); | size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE); | ||||
| GPU_blend(GPU_BLEND_ALPHA); | GPU_blend(GPU_BLEND_ALPHA); | ||||
| uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); | uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); | ||||
| immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); | immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); | ||||
| for (p = t->tsnap.points.first; p; p = p->next) { | for (p = static_cast<TransSnapPoint *>(t->tsnap.points.first); p; p = p->next) { | ||||
| if (p == t->tsnap.selectedPoint) { | if (p == t->tsnap.selectedPoint) { | ||||
| immUniformColor4ubv(selectedCol); | immUniformColor4ubv(selectedCol); | ||||
| } | } | ||||
| else { | else { | ||||
| immUniformColor4ubv(col); | immUniformColor4ubv(col); | ||||
| } | } | ||||
| ED_node_draw_snap(®ion->v2d, p->co, size, 0, pos); | ED_node_draw_snap(®ion->v2d, p->co, size, NodeBorder(0), pos); | ||||
| } | } | ||||
| if (t->tsnap.status & POINT_INIT) { | if (t->tsnap.status & POINT_INIT) { | ||||
| immUniformColor4ubv(activeCol); | immUniformColor4ubv(activeCol); | ||||
| ED_node_draw_snap(®ion->v2d, t->tsnap.snapPoint, size, t->tsnap.snapNodeBorder, pos); | ED_node_draw_snap( | ||||
| ®ion->v2d, t->tsnap.snapPoint, size, NodeBorder(t->tsnap.snapNodeBorder), pos); | |||||
| } | } | ||||
| immUnbindProgram(); | immUnbindProgram(); | ||||
| GPU_blend(GPU_BLEND_NONE); | GPU_blend(GPU_BLEND_NONE); | ||||
| } | } | ||||
| else if (t->spacetype == SPACE_SEQ) { | else if (t->spacetype == SPACE_SEQ) { | ||||
| const ARegion *region = CTX_wm_region(C); | const ARegion *region = CTX_wm_region(C); | ||||
| ▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | else if (t->options & CTX_OBJECT) { | ||||
| copy_v3_v3(iloc, td->ob->object_to_world[3]); | copy_v3_v3(iloc, td->ob->object_to_world[3]); | ||||
| } | } | ||||
| if (ED_view3d_project_float_global(t->region, iloc, mval_fl, V3D_PROJ_TEST_NOP) != | if (ED_view3d_project_float_global(t->region, iloc, mval_fl, V3D_PROJ_TEST_NOP) != | ||||
| V3D_PROJ_RET_OK) { | V3D_PROJ_RET_OK) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| eSnapMode hit = ED_transform_snap_object_project_view3d( | SnapObjectParams snap_object_params{}; | ||||
| t->tsnap.object_context, | snap_object_params.snap_target_select = t->tsnap.target_select; | ||||
| snap_object_params.edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL; | |||||
| snap_object_params.use_occlusion_test = false; | |||||
| snap_object_params.use_backface_culling = t->tsnap.use_backface_culling; | |||||
| eSnapMode hit = ED_transform_snap_object_project_view3d(t->tsnap.object_context, | |||||
| t->depsgraph, | t->depsgraph, | ||||
| t->region, | t->region, | ||||
| t->view, | static_cast<const View3D *>(t->view), | ||||
| SCE_SNAP_MODE_FACE_RAYCAST, | SCE_SNAP_MODE_FACE_RAYCAST, | ||||
| &(const struct SnapObjectParams){ | &snap_object_params, | ||||
| .snap_target_select = t->tsnap.target_select, | |||||
| .edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL, | |||||
| .use_occlusion_test = false, | |||||
| .use_backface_culling = t->tsnap.use_backface_culling, | |||||
| }, | |||||
| NULL, | NULL, | ||||
| mval_fl, | mval_fl, | ||||
| NULL, | NULL, | ||||
| 0, | 0, | ||||
| loc, | loc, | ||||
| no); | no); | ||||
| if (hit != SCE_SNAP_MODE_FACE_RAYCAST) { | if (hit != SCE_SNAP_MODE_FACE_RAYCAST) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| float tvec[3]; | float tvec[3]; | ||||
| sub_v3_v3v3(tvec, loc, iloc); | sub_v3_v3v3(tvec, loc, iloc); | ||||
| mul_m3_v3(td->smtx, tvec); | mul_m3_v3(td->smtx, tvec); | ||||
| Show All 33 Lines | if (tc->use_local_mat) { | ||||
| mul_m4_v3(tc->mat, init_loc); | mul_m4_v3(tc->mat, init_loc); | ||||
| mul_m4_v3(tc->mat, prev_loc); | mul_m4_v3(tc->mat, prev_loc); | ||||
| } | } | ||||
| else if (t->options & CTX_OBJECT) { | else if (t->options & CTX_OBJECT) { | ||||
| BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob); | BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob); | ||||
| copy_v3_v3(init_loc, td->ob->object_to_world[3]); | copy_v3_v3(init_loc, td->ob->object_to_world[3]); | ||||
| } | } | ||||
| eSnapMode hit = ED_transform_snap_object_project_view3d( | SnapObjectParams snap_object_params{}; | ||||
| t->tsnap.object_context, | snap_object_params.snap_target_select = t->tsnap.target_select; | ||||
| snap_object_params.edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL; | |||||
| snap_object_params.use_occlusion_test = false; | |||||
| snap_object_params.use_backface_culling = false; | |||||
| snap_object_params.face_nearest_steps = t->tsnap.face_nearest_steps; | |||||
| snap_object_params.keep_on_same_target = t->tsnap.flag & SCE_SNAP_KEEP_ON_SAME_OBJECT; | |||||
| eSnapMode hit = ED_transform_snap_object_project_view3d(t->tsnap.object_context, | |||||
| t->depsgraph, | t->depsgraph, | ||||
| t->region, | t->region, | ||||
| t->view, | static_cast<const View3D *>(t->view), | ||||
| SCE_SNAP_MODE_FACE_NEAREST, | SCE_SNAP_MODE_FACE_NEAREST, | ||||
| &(const struct SnapObjectParams){ | &snap_object_params, | ||||
| .snap_target_select = t->tsnap.target_select, | |||||
| .edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL, | |||||
| .use_occlusion_test = false, | |||||
| .use_backface_culling = false, | |||||
| .face_nearest_steps = t->tsnap.face_nearest_steps, | |||||
| .keep_on_same_target = t->tsnap.flag & SCE_SNAP_KEEP_ON_SAME_OBJECT, | |||||
| }, | |||||
| init_loc, | init_loc, | ||||
| NULL, | NULL, | ||||
| prev_loc, | prev_loc, | ||||
| 0, | 0, | ||||
| snap_loc, | snap_loc, | ||||
| snap_no); | snap_no); | ||||
| if (hit != SCE_SNAP_MODE_FACE_NEAREST) { | if (hit != SCE_SNAP_MODE_FACE_NEAREST) { | ||||
| return; | return; | ||||
| } | } | ||||
| float tvec[3]; | float tvec[3]; | ||||
| sub_v3_v3v3(tvec, snap_loc, prev_loc); | sub_v3_v3v3(tvec, snap_loc, prev_loc); | ||||
| mul_m3_v3(td->smtx, tvec); | mul_m3_v3(td->smtx, tvec); | ||||
| ▲ Show 20 Lines • Show All 127 Lines • ▼ Show 20 Lines | static bool bm_face_is_snap_target(BMFace *f, void *UNUSED(user_data)) | ||||
| return true; | return true; | ||||
| } | } | ||||
| static eSnapFlag snap_flag_from_spacetype(TransInfo *t) | static eSnapFlag snap_flag_from_spacetype(TransInfo *t) | ||||
| { | { | ||||
| ToolSettings *ts = t->settings; | ToolSettings *ts = t->settings; | ||||
| if (t->spacetype == SPACE_NODE) { | if (t->spacetype == SPACE_NODE) { | ||||
| return ts->snap_flag_node; | return eSnapFlag(ts->snap_flag_node); | ||||
| } | } | ||||
| if (t->spacetype == SPACE_IMAGE) { | if (t->spacetype == SPACE_IMAGE) { | ||||
| return ts->snap_uv_flag; | return eSnapFlag(ts->snap_uv_flag); | ||||
| } | } | ||||
| if (t->spacetype == SPACE_SEQ) { | if (t->spacetype == SPACE_SEQ) { | ||||
| return ts->snap_flag_seq; | return eSnapFlag(ts->snap_flag_seq); | ||||
| } | } | ||||
| return ts->snap_flag; | return eSnapFlag(ts->snap_flag); | ||||
| } | } | ||||
| static eSnapMode snap_mode_from_spacetype(TransInfo *t) | static eSnapMode snap_mode_from_spacetype(TransInfo *t) | ||||
| { | { | ||||
| ToolSettings *ts = t->settings; | ToolSettings *ts = t->settings; | ||||
| if (t->spacetype == SPACE_NODE) { | if (t->spacetype == SPACE_NODE) { | ||||
| return ts->snap_node_mode; | return eSnapMode(ts->snap_node_mode); | ||||
| } | } | ||||
| if (t->spacetype == SPACE_IMAGE) { | if (t->spacetype == SPACE_IMAGE) { | ||||
| eSnapMode snap_mode = ts->snap_uv_mode; | eSnapMode snap_mode = eSnapMode(ts->snap_uv_mode); | ||||
| if ((snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_uv_flag & SCE_SNAP_ABS_GRID) && | if ((snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_uv_flag & SCE_SNAP_ABS_GRID) && | ||||
| (t->mode == TFM_TRANSLATION)) { | (t->mode == TFM_TRANSLATION)) { | ||||
| snap_mode &= ~SCE_SNAP_MODE_INCREMENT; | snap_mode &= ~SCE_SNAP_MODE_INCREMENT; | ||||
| snap_mode |= SCE_SNAP_MODE_GRID; | snap_mode |= SCE_SNAP_MODE_GRID; | ||||
| } | } | ||||
| return snap_mode; | return snap_mode; | ||||
| } | } | ||||
| if (t->spacetype == SPACE_SEQ) { | if (t->spacetype == SPACE_SEQ) { | ||||
| return SEQ_tool_settings_snap_mode_get(t->scene); | return eSnapMode(SEQ_tool_settings_snap_mode_get(t->scene)); | ||||
| } | } | ||||
| if (t->spacetype == SPACE_VIEW3D) { | if (t->spacetype == SPACE_VIEW3D) { | ||||
| if (t->options & (CTX_CAMERA | CTX_EDGE_DATA | CTX_PAINT_CURVE)) { | if (t->options & (CTX_CAMERA | CTX_EDGE_DATA | CTX_PAINT_CURVE)) { | ||||
| return SCE_SNAP_MODE_INCREMENT; | return SCE_SNAP_MODE_INCREMENT; | ||||
| } | } | ||||
| eSnapMode snap_mode = ts->snap_mode; | eSnapMode snap_mode = eSnapMode(ts->snap_mode); | ||||
| if ((snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_flag & SCE_SNAP_ABS_GRID) && | if ((snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_flag & SCE_SNAP_ABS_GRID) && | ||||
| (t->mode == TFM_TRANSLATION)) { | (t->mode == TFM_TRANSLATION)) { | ||||
| /* Special case in which snap to increments is transformed to snap to grid. */ | /* Special case in which snap to increments is transformed to snap to grid. */ | ||||
| snap_mode &= ~SCE_SNAP_MODE_INCREMENT; | snap_mode &= ~SCE_SNAP_MODE_INCREMENT; | ||||
| snap_mode |= SCE_SNAP_MODE_GRID; | snap_mode |= SCE_SNAP_MODE_GRID; | ||||
| } | } | ||||
| return snap_mode; | return snap_mode; | ||||
| } | } | ||||
| if (ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA)) { | if (ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA)) { | ||||
| /* No incremental snapping. */ | /* No incremental snapping. */ | ||||
| return 0; | return eSnapMode(0); | ||||
| } | } | ||||
| return SCE_SNAP_MODE_INCREMENT; | return SCE_SNAP_MODE_INCREMENT; | ||||
| } | } | ||||
| static eSnapTargetSelect snap_target_select_from_spacetype(TransInfo *t) | static eSnapTargetSelect snap_target_select_from_spacetype(TransInfo *t) | ||||
| { | { | ||||
| BKE_view_layer_synced_ensure(t->scene, t->view_layer); | BKE_view_layer_synced_ensure(t->scene, t->view_layer); | ||||
| ▲ Show 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | if (t->tsnap.seq_context == NULL) { | ||||
| t->tsnap.seq_context = transform_snap_sequencer_data_alloc(t); | t->tsnap.seq_context = transform_snap_sequencer_data_alloc(t); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void initSnapping(TransInfo *t, wmOperator *op) | void initSnapping(TransInfo *t, wmOperator *op) | ||||
| { | { | ||||
| ToolSettings *ts = t->settings; | ToolSettings *ts = t->settings; | ||||
| eSnapSourceSelect snap_source = ts->snap_target; | eSnapSourceSelect snap_source = eSnapSourceSelect(ts->snap_target); | ||||
| resetSnapping(t); | resetSnapping(t); | ||||
| t->tsnap.mode = snap_mode_from_spacetype(t); | t->tsnap.mode = snap_mode_from_spacetype(t); | ||||
| t->tsnap.flag = snap_flag_from_spacetype(t); | t->tsnap.flag = snap_flag_from_spacetype(t); | ||||
| t->tsnap.target_select = snap_target_select_from_spacetype(t); | t->tsnap.target_select = snap_target_select_from_spacetype(t); | ||||
| t->tsnap.face_nearest_steps = max_ii(ts->snap_face_nearest_steps, 1); | t->tsnap.face_nearest_steps = max_ii(ts->snap_face_nearest_steps, 1); | ||||
| /* if snap property exists */ | /* if snap property exists */ | ||||
| PropertyRNA *prop; | PropertyRNA *prop; | ||||
| if (op && (prop = RNA_struct_find_property(op->ptr, "snap")) && | if (op && (prop = RNA_struct_find_property(op->ptr, "snap")) && | ||||
| RNA_property_is_set(op->ptr, prop)) { | RNA_property_is_set(op->ptr, prop)) { | ||||
| if (RNA_property_boolean_get(op->ptr, prop)) { | if (RNA_property_boolean_get(op->ptr, prop)) { | ||||
| t->modifiers |= MOD_SNAP; | t->modifiers |= MOD_SNAP; | ||||
| if ((prop = RNA_struct_find_property(op->ptr, "snap_elements")) && | if ((prop = RNA_struct_find_property(op->ptr, "snap_elements")) && | ||||
| RNA_property_is_set(op->ptr, prop)) { | RNA_property_is_set(op->ptr, prop)) { | ||||
| t->tsnap.mode = RNA_property_enum_get(op->ptr, prop); | t->tsnap.mode = eSnapMode(RNA_property_enum_get(op->ptr, prop)); | ||||
| } | } | ||||
| /* TODO(@gfxcoder): Rename `snap_target` to `snap_source` to avoid previous ambiguity of | /* TODO(@gfxcoder): Rename `snap_target` to `snap_source` to avoid previous ambiguity of | ||||
| * "target" (now, "source" is geometry to be moved and "target" is geometry to which moved | * "target" (now, "source" is geometry to be moved and "target" is geometry to which moved | ||||
| * geometry is snapped). */ | * geometry is snapped). */ | ||||
| if ((prop = RNA_struct_find_property(op->ptr, "snap_target")) && | if ((prop = RNA_struct_find_property(op->ptr, "snap_target")) && | ||||
| RNA_property_is_set(op->ptr, prop)) { | RNA_property_is_set(op->ptr, prop)) { | ||||
| snap_source = RNA_property_enum_get(op->ptr, prop); | snap_source = eSnapSourceSelect(RNA_property_enum_get(op->ptr, prop)); | ||||
| } | } | ||||
| if ((prop = RNA_struct_find_property(op->ptr, "snap_point")) && | if ((prop = RNA_struct_find_property(op->ptr, "snap_point")) && | ||||
| RNA_property_is_set(op->ptr, prop)) { | RNA_property_is_set(op->ptr, prop)) { | ||||
| RNA_property_float_get_array(op->ptr, prop, t->tsnap.snapPoint); | RNA_property_float_get_array(op->ptr, prop, t->tsnap.snapPoint); | ||||
| t->tsnap.status |= SNAP_FORCED | POINT_INIT; | t->tsnap.status |= SNAP_FORCED | POINT_INIT; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| static void setSnappingCallback(TransInfo *t) | static void setSnappingCallback(TransInfo *t) | ||||
| { | { | ||||
| if (t->spacetype == SPACE_VIEW3D) { | if (t->spacetype == SPACE_VIEW3D) { | ||||
| t->tsnap.calcSnap = snap_calc_view3d_fn; | t->tsnap.calcSnap = snap_calc_view3d_fn; | ||||
| } | } | ||||
| else if (t->spacetype == SPACE_IMAGE) { | else if (t->spacetype == SPACE_IMAGE) { | ||||
| SpaceImage *sima = t->area->spacedata.first; | SpaceImage *sima = static_cast<SpaceImage *>(t->area->spacedata.first); | ||||
| BKE_view_layer_synced_ensure(t->scene, t->view_layer); | BKE_view_layer_synced_ensure(t->scene, t->view_layer); | ||||
| Object *obact = BKE_view_layer_active_object_get(t->view_layer); | Object *obact = BKE_view_layer_active_object_get(t->view_layer); | ||||
| const bool is_uv_editor = sima->mode == SI_MODE_UV; | const bool is_uv_editor = sima->mode == SI_MODE_UV; | ||||
| const bool has_edit_object = obact && BKE_object_is_in_editmode(obact); | const bool has_edit_object = obact && BKE_object_is_in_editmode(obact); | ||||
| if (is_uv_editor && has_edit_object) { | if (is_uv_editor && has_edit_object) { | ||||
| t->tsnap.calcSnap = snap_calc_uv_fn; | t->tsnap.calcSnap = snap_calc_uv_fn; | ||||
| } | } | ||||
| Show All 27 Lines | case SCE_SNAP_SOURCE_ACTIVE: | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| void addSnapPoint(TransInfo *t) | void addSnapPoint(TransInfo *t) | ||||
| { | { | ||||
| /* Currently only 3D viewport works for snapping points. */ | /* Currently only 3D viewport works for snapping points. */ | ||||
| if (t->tsnap.status & POINT_INIT && t->spacetype == SPACE_VIEW3D) { | if (t->tsnap.status & POINT_INIT && t->spacetype == SPACE_VIEW3D) { | ||||
| TransSnapPoint *p = MEM_callocN(sizeof(TransSnapPoint), "SnapPoint"); | TransSnapPoint *p = MEM_cnew<TransSnapPoint>("SnapPoint"); | ||||
| t->tsnap.selectedPoint = p; | t->tsnap.selectedPoint = p; | ||||
| copy_v3_v3(p->co, t->tsnap.snapPoint); | copy_v3_v3(p->co, t->tsnap.snapPoint); | ||||
| BLI_addtail(&t->tsnap.points, p); | BLI_addtail(&t->tsnap.points, p); | ||||
| t->tsnap.status |= MULTI_POINTS; | t->tsnap.status |= MULTI_POINTS; | ||||
| } | } | ||||
| } | } | ||||
| eRedrawFlag updateSelectedSnapPoint(TransInfo *t) | eRedrawFlag updateSelectedSnapPoint(TransInfo *t) | ||||
| { | { | ||||
| eRedrawFlag status = TREDRAW_NOTHING; | eRedrawFlag status = TREDRAW_NOTHING; | ||||
| if (t->tsnap.status & MULTI_POINTS) { | if (t->tsnap.status & MULTI_POINTS) { | ||||
| TransSnapPoint *p, *closest_p = NULL; | TransSnapPoint *p, *closest_p = NULL; | ||||
| float dist_min_sq = TRANSFORM_SNAP_MAX_PX; | float dist_min_sq = TRANSFORM_SNAP_MAX_PX; | ||||
| const float mval_fl[2] = {t->mval[0], t->mval[1]}; | const float mval_fl[2] = {float(t->mval[0]), float(t->mval[1])}; | ||||
| float screen_loc[2]; | float screen_loc[2]; | ||||
| for (p = t->tsnap.points.first; p; p = p->next) { | for (p = static_cast<TransSnapPoint *>(t->tsnap.points.first); p; p = p->next) { | ||||
| float dist_sq; | float dist_sq; | ||||
| if (ED_view3d_project_float_global(t->region, p->co, screen_loc, V3D_PROJ_TEST_NOP) != | if (ED_view3d_project_float_global(t->region, p->co, screen_loc, V3D_PROJ_TEST_NOP) != | ||||
| V3D_PROJ_RET_OK) { | V3D_PROJ_RET_OK) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| dist_sq = len_squared_v2v2(mval_fl, screen_loc); | dist_sq = len_squared_v2v2(mval_fl, screen_loc); | ||||
| Show All 36 Lines | |||||
| void getSnapPoint(const TransInfo *t, float vec[3]) | void getSnapPoint(const TransInfo *t, float vec[3]) | ||||
| { | { | ||||
| if (t->tsnap.points.first) { | if (t->tsnap.points.first) { | ||||
| TransSnapPoint *p; | TransSnapPoint *p; | ||||
| int total = 0; | int total = 0; | ||||
| vec[0] = vec[1] = vec[2] = 0; | vec[0] = vec[1] = vec[2] = 0; | ||||
| for (p = t->tsnap.points.first; p; p = p->next, total++) { | for (p = static_cast<TransSnapPoint *>(t->tsnap.points.first); p; p = p->next, total++) { | ||||
| add_v3_v3(vec, p->co); | add_v3_v3(vec, p->co); | ||||
| } | } | ||||
| if (t->tsnap.status & POINT_INIT) { | if (t->tsnap.status & POINT_INIT) { | ||||
| add_v3_v3(vec, t->tsnap.snapPoint); | add_v3_v3(vec, t->tsnap.snapPoint); | ||||
| total++; | total++; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 150 Lines • ▼ Show 20 Lines | void tranform_snap_target_median_calc(const TransInfo *t, float r_median[3]) | ||||
| mul_v3_fl(r_median, 1.0 / i_accum); | mul_v3_fl(r_median, 1.0 / i_accum); | ||||
| // TargetSnapOffset(t, NULL); | // TargetSnapOffset(t, NULL); | ||||
| } | } | ||||
| static void TargetSnapOffset(TransInfo *t, TransData *td) | static void TargetSnapOffset(TransInfo *t, TransData *td) | ||||
| { | { | ||||
| if (t->spacetype == SPACE_NODE && td != NULL) { | if (t->spacetype == SPACE_NODE && td != NULL) { | ||||
| bNode *node = td->extra; | bNode *node = static_cast<bNode *>(td->extra); | ||||
| char border = t->tsnap.snapNodeBorder; | char border = t->tsnap.snapNodeBorder; | ||||
| float width = BLI_rctf_size_x(&node->totr); | float width = BLI_rctf_size_x(&node->totr); | ||||
| float height = BLI_rctf_size_y(&node->totr); | float height = BLI_rctf_size_y(&node->totr); | ||||
| #ifdef USE_NODE_CENTER | #ifdef USE_NODE_CENTER | ||||
| if (border & NODE_LEFT) { | if (border & NODE_LEFT) { | ||||
| t->tsnap.snapTarget[0] -= 0.5f * width; | t->tsnap.snapTarget[0] -= 0.5f * width; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 155 Lines • ▼ Show 20 Lines | |||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Snap Objects | /** \name Snap Objects | ||||
| * \{ */ | * \{ */ | ||||
| eSnapMode snapObjectsTransform( | eSnapMode snapObjectsTransform( | ||||
| TransInfo *t, const float mval[2], float *dist_px, float r_loc[3], float r_no[3]) | TransInfo *t, const float mval[2], float *dist_px, float r_loc[3], float r_no[3]) | ||||
| { | { | ||||
| SnapObjectParams snap_object_params{}; | |||||
| snap_object_params.snap_target_select = t->tsnap.target_select; | |||||
| snap_object_params.edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL; | |||||
| snap_object_params.use_occlusion_test = t->settings->snap_mode != SCE_SNAP_MODE_FACE_RAYCAST; | |||||
| snap_object_params.use_backface_culling = t->tsnap.use_backface_culling; | |||||
| float *target = (t->tsnap.status & TARGET_INIT) ? t->tsnap.snapTarget : t->center_global; | float *target = (t->tsnap.status & TARGET_INIT) ? t->tsnap.snapTarget : t->center_global; | ||||
| return ED_transform_snap_object_project_view3d( | return ED_transform_snap_object_project_view3d(t->tsnap.object_context, | ||||
| t->tsnap.object_context, | |||||
| t->depsgraph, | t->depsgraph, | ||||
| t->region, | t->region, | ||||
| t->view, | static_cast<const View3D *>(t->view), | ||||
| t->tsnap.mode, | t->tsnap.mode, | ||||
| &(const struct SnapObjectParams){ | &snap_object_params, | ||||
| .snap_target_select = t->tsnap.target_select, | |||||
| .edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL, | |||||
| .use_occlusion_test = t->settings->snap_mode != SCE_SNAP_MODE_FACE_RAYCAST, | |||||
| .use_backface_culling = t->tsnap.use_backface_culling, | |||||
| }, | |||||
| NULL, | NULL, | ||||
| mval, | mval, | ||||
| target, | target, | ||||
| dist_px, | dist_px, | ||||
| r_loc, | r_loc, | ||||
| r_no); | r_no); | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Peeling | /** \name Peeling | ||||
| * \{ */ | * \{ */ | ||||
| bool peelObjectsTransform(TransInfo *t, | bool peelObjectsTransform(TransInfo *t, | ||||
| const float mval[2], | const float mval[2], | ||||
| const bool use_peel_object, | const bool use_peel_object, | ||||
| /* return args */ | /* return args */ | ||||
| float r_loc[3], | float r_loc[3], | ||||
| float r_no[3], | float r_no[3], | ||||
| float *r_thickness) | float *r_thickness) | ||||
| { | { | ||||
| SnapObjectParams snap_object_params{}; | |||||
| snap_object_params.snap_target_select = t->tsnap.target_select; | |||||
| snap_object_params.edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL; | |||||
| ListBase depths_peel = {0}; | ListBase depths_peel = {0}; | ||||
| ED_transform_snap_object_project_all_view3d_ex( | ED_transform_snap_object_project_all_view3d_ex(t->tsnap.object_context, | ||||
| t->tsnap.object_context, | |||||
| t->depsgraph, | t->depsgraph, | ||||
| t->region, | t->region, | ||||
| t->view, | static_cast<const View3D *>(t->view), | ||||
| &(const struct SnapObjectParams){ | &snap_object_params, | ||||
| .snap_target_select = t->tsnap.target_select, | |||||
| .edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL, | |||||
| }, | |||||
| mval, | mval, | ||||
| -1.0f, | -1.0f, | ||||
| false, | false, | ||||
| &depths_peel); | &depths_peel); | ||||
| if (!BLI_listbase_is_empty(&depths_peel)) { | if (!BLI_listbase_is_empty(&depths_peel)) { | ||||
| /* At the moment we only use the hits of the first object */ | /* At the moment we only use the hits of the first object */ | ||||
| struct SnapObjectHitDepth *hit_min = depths_peel.first; | struct SnapObjectHitDepth *hit_min = static_cast<SnapObjectHitDepth *>(depths_peel.first); | ||||
| for (struct SnapObjectHitDepth *iter = hit_min->next; iter; iter = iter->next) { | for (struct SnapObjectHitDepth *iter = hit_min->next; iter; iter = iter->next) { | ||||
| if (iter->depth < hit_min->depth) { | if (iter->depth < hit_min->depth) { | ||||
| hit_min = iter; | hit_min = iter; | ||||
| } | } | ||||
| } | } | ||||
| struct SnapObjectHitDepth *hit_max = NULL; | struct SnapObjectHitDepth *hit_max = NULL; | ||||
| if (use_peel_object) { | if (use_peel_object) { | ||||
| /* if peeling objects, take the first and last from each object */ | /* if peeling objects, take the first and last from each object */ | ||||
| hit_max = hit_min; | hit_max = hit_min; | ||||
| for (struct SnapObjectHitDepth *iter = depths_peel.first; iter; iter = iter->next) { | for (SnapObjectHitDepth *iter = static_cast<SnapObjectHitDepth *>(depths_peel.first); iter; | ||||
| iter = iter->next) { | |||||
| if ((iter->depth > hit_max->depth) && (iter->ob_uuid == hit_min->ob_uuid)) { | if ((iter->depth > hit_max->depth) && (iter->ob_uuid == hit_min->ob_uuid)) { | ||||
| hit_max = iter; | hit_max = iter; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* otherwise, pair first with second and so on */ | /* otherwise, pair first with second and so on */ | ||||
| for (struct SnapObjectHitDepth *iter = depths_peel.first; iter; iter = iter->next) { | for (SnapObjectHitDepth *iter = static_cast<SnapObjectHitDepth *>(depths_peel.first); iter; | ||||
| iter = iter->next) { | |||||
| if ((iter != hit_min) && (iter->ob_uuid == hit_min->ob_uuid)) { | if ((iter != hit_min) && (iter->ob_uuid == hit_min->ob_uuid)) { | ||||
| if (hit_max == NULL) { | if (hit_max == NULL) { | ||||
| hit_max = iter; | hit_max = iter; | ||||
| } | } | ||||
| else if (iter->depth < hit_max->depth) { | else if (iter->depth < hit_max->depth) { | ||||
| hit_max = iter; | hit_max = iter; | ||||
| } | } | ||||
| } | } | ||||
| Show All 33 Lines | static bool snapNodeTest(View2D *v2d, bNode *node, eSnapTargetSelect snap_target_select) | ||||
| return (((snap_target_select & SCE_SNAP_TARGET_NOT_SELECTED) && !(node->flag & NODE_SELECT)) || | return (((snap_target_select & SCE_SNAP_TARGET_NOT_SELECTED) && !(node->flag & NODE_SELECT)) || | ||||
| (snap_target_select == SCE_SNAP_TARGET_ALL && !(node->flag & NODE_ACTIVE))) && | (snap_target_select == SCE_SNAP_TARGET_ALL && !(node->flag & NODE_ACTIVE))) && | ||||
| (node->totr.xmin < v2d->cur.xmax && node->totr.xmax > v2d->cur.xmin && | (node->totr.xmin < v2d->cur.xmax && node->totr.xmax > v2d->cur.xmin && | ||||
| node->totr.ymin < v2d->cur.ymax && node->totr.ymax > v2d->cur.ymin); | node->totr.ymin < v2d->cur.ymax && node->totr.ymax > v2d->cur.ymin); | ||||
| } | } | ||||
| static NodeBorder snapNodeBorder(eSnapMode snap_node_mode) | static NodeBorder snapNodeBorder(eSnapMode snap_node_mode) | ||||
| { | { | ||||
| NodeBorder flag = 0; | NodeBorder flag = NodeBorder(0); | ||||
| if (snap_node_mode & SCE_SNAP_MODE_NODE_X) { | if (snap_node_mode & SCE_SNAP_MODE_NODE_X) { | ||||
| flag |= NODE_LEFT | NODE_RIGHT; | flag |= NODE_LEFT | NODE_RIGHT; | ||||
| } | } | ||||
| if (snap_node_mode & SCE_SNAP_MODE_NODE_Y) { | if (snap_node_mode & SCE_SNAP_MODE_NODE_Y) { | ||||
| flag |= NODE_TOP | NODE_BOTTOM; | flag |= NODE_TOP | NODE_BOTTOM; | ||||
| } | } | ||||
| return flag; | return flag; | ||||
| } | } | ||||
| static bool snapNode(ToolSettings *ts, | static bool snapNode(ToolSettings *ts, | ||||
| SpaceNode *UNUSED(snode), | SpaceNode *UNUSED(snode), | ||||
| ARegion *region, | ARegion *region, | ||||
| bNode *node, | bNode *node, | ||||
| const int mval[2], | const int mval[2], | ||||
| float r_loc[2], | float r_loc[2], | ||||
| float *r_dist_px, | float *r_dist_px, | ||||
| char *r_node_border) | char *r_node_border) | ||||
| { | { | ||||
| View2D *v2d = ®ion->v2d; | View2D *v2d = ®ion->v2d; | ||||
| NodeBorder border = snapNodeBorder(ts->snap_node_mode); | NodeBorder border = snapNodeBorder(eSnapMode(ts->snap_node_mode)); | ||||
| bool retval = false; | bool retval = false; | ||||
| rcti totr; | rcti totr; | ||||
| int new_dist; | int new_dist; | ||||
| UI_view2d_view_to_region_rcti(v2d, &node->totr, &totr); | UI_view2d_view_to_region_rcti(v2d, &node->totr, &totr); | ||||
| if (border & NODE_LEFT) { | if (border & NODE_LEFT) { | ||||
| new_dist = abs(totr.xmin - mval[0]); | new_dist = abs(totr.xmin - mval[0]); | ||||
| ▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | static bool snapNodes(ToolSettings *ts, | ||||
| char *r_node_border) | char *r_node_border) | ||||
| { | { | ||||
| bNodeTree *ntree = snode->edittree; | bNodeTree *ntree = snode->edittree; | ||||
| bNode *node; | bNode *node; | ||||
| bool retval = false; | bool retval = false; | ||||
| *r_node_border = 0; | *r_node_border = 0; | ||||
| for (node = ntree->nodes.first; node; node = node->next) { | for (node = static_cast<bNode *>(ntree->nodes.first); node; node = node->next) { | ||||
| if (snapNodeTest(®ion->v2d, node, snap_target_select)) { | if (snapNodeTest(®ion->v2d, node, snap_target_select)) { | ||||
| retval |= snapNode(ts, snode, region, node, mval, r_loc, r_dist_px, r_node_border); | retval |= snapNode(ts, snode, region, node, mval, r_loc, r_dist_px, r_node_border); | ||||
| } | } | ||||
| } | } | ||||
| return retval; | return retval; | ||||
| } | } | ||||
| bool snapNodesTransform( | bool snapNodesTransform( | ||||
| TransInfo *t, const int mval[2], float r_loc[2], float *r_dist_px, char *r_node_border) | TransInfo *t, const int mval[2], float r_loc[2], float *r_dist_px, char *r_node_border) | ||||
| { | { | ||||
| return snapNodes(t->settings, | return snapNodes(t->settings, | ||||
| t->area->spacedata.first, | static_cast<SpaceNode *>(t->area->spacedata.first), | ||||
| t->region, | t->region, | ||||
| mval, | mval, | ||||
| t->tsnap.target_select, | t->tsnap.target_select, | ||||
| r_loc, | r_loc, | ||||
| r_dist_px, | r_dist_px, | ||||
| r_node_border); | r_node_border); | ||||
| } | } | ||||
| Show All 34 Lines | static void snap_increment_apply(const TransInfo *t, | ||||
| const bool use_aspect = ELEM(t->mode, TFM_TRANSLATION); | const bool use_aspect = ELEM(t->mode, TFM_TRANSLATION); | ||||
| const float *asp = use_aspect ? t->aspect : asp_local; | const float *asp = use_aspect ? t->aspect : asp_local; | ||||
| if (use_aspect) { | if (use_aspect) { | ||||
| /* custom aspect for fcurve */ | /* custom aspect for fcurve */ | ||||
| if (t->spacetype == SPACE_GRAPH) { | if (t->spacetype == SPACE_GRAPH) { | ||||
| View2D *v2d = &t->region->v2d; | View2D *v2d = &t->region->v2d; | ||||
| Scene *scene = t->scene; | Scene *scene = t->scene; | ||||
| SpaceGraph *sipo = t->area->spacedata.first; | SpaceGraph *sipo = static_cast<SpaceGraph *>(t->area->spacedata.first); | ||||
| asp_local[0] = UI_view2d_grid_resolution_x__frames_or_seconds( | asp_local[0] = UI_view2d_grid_resolution_x__frames_or_seconds( | ||||
| v2d, scene, sipo->flag & SIPO_DRAWTIME); | v2d, scene, sipo->flag & SIPO_DRAWTIME); | ||||
| asp_local[1] = UI_view2d_grid_resolution_y__values(v2d); | asp_local[1] = UI_view2d_grid_resolution_y__values(v2d); | ||||
| asp = asp_local; | asp = asp_local; | ||||
| } | } | ||||
| } | } | ||||
| snap_increment_apply_ex(t, max_index, increment_dist, asp, r_val, r_val); | snap_increment_apply_ex(t, max_index, increment_dist, asp, r_val, r_val); | ||||
| ▲ Show 20 Lines • Show All 62 Lines • Show Last 20 Lines | |||||