Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/transform/transform_snap.cc
| Show First 20 Lines • Show All 141 Lines • ▼ Show 20 Lines | if (ELEM(t->mode, TFM_VERT_SLIDE, TFM_EDGE_SLIDE, TFM_SEQ_SLIDE)) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| static bool doForceIncrementSnap(const TransInfo *t) | static bool doForceIncrementSnap(const TransInfo *t) | ||||
| { | { | ||||
| if (t->tsnap.status & SNAP_FORCED) { | |||||
| return false; | |||||
| } | |||||
| return !transformModeUseSnap(t); | return !transformModeUseSnap(t); | ||||
| } | } | ||||
| void drawSnapping(const struct bContext *C, TransInfo *t) | void drawSnapping(const struct bContext *C, TransInfo *t) | ||||
| { | { | ||||
| uchar col[4], selectedCol[4], activeCol[4]; | uchar col[4], selectedCol[4], activeCol[4]; | ||||
| if (!transform_snap_is_active(t)) { | if (!(transform_snap_is_active(t) || t->modifiers & MOD_EDIT_SNAP_SOURCE)) { | ||||
| return; | return; | ||||
| } | } | ||||
| bool draw_source = (t->spacetype == SPACE_VIEW3D) && (t->tsnap.status & SNAP_SOURCE_FOUND) && | bool draw_source = (t->spacetype == SPACE_VIEW3D) && (t->tsnap.status & SNAP_SOURCE_FOUND) && | ||||
| (t->tsnap.mode & SCE_SNAP_MODE_EDGE_PERPENDICULAR); | (t->tsnap.mode & SCE_SNAP_MODE_EDGE_PERPENDICULAR); | ||||
| if (!(draw_source || validSnap(t))) { | if (!(draw_source || validSnap(t))) { | ||||
| return; | return; | ||||
| Show All 39 Lines | if (!BLI_listbase_is_empty(&t->tsnap.points)) { | ||||
| immUniformColor4ubv(selectedCol); | immUniformColor4ubv(selectedCol); | ||||
| } | } | ||||
| else { | else { | ||||
| immUniformColor4ubv(col); | immUniformColor4ubv(col); | ||||
| } | } | ||||
| imm_drawcircball(p->co, ED_view3d_pixel_size(rv3d, p->co) * size, view_inv, pos); | imm_drawcircball(p->co, ED_view3d_pixel_size(rv3d, p->co) * size, view_inv, pos); | ||||
| } | } | ||||
| if (t->modifiers & MOD_EDIT_SNAP_SOURCE) { | |||||
| /* Indicate the new snap source position. */ | |||||
| float snap_point[3]; | |||||
| getSnapPoint(t, snap_point); | |||||
| float vx[3], vy[3], v[3]; | |||||
| float size_tmp = ED_view3d_pixel_size(rv3d, snap_point) * size; | |||||
| float size_fac = 0.5f; | |||||
| mul_v3_v3fl(vx, view_inv[0], size_tmp); | |||||
| mul_v3_v3fl(vy, view_inv[1], size_tmp); | |||||
| immUniformColor4ubv(col); | |||||
| imm_drawcircball(snap_point, size_tmp, view_inv, pos); | |||||
| immBegin(GPU_PRIM_LINES, 8); | |||||
| add_v3_v3v3(v, snap_point, vx); | |||||
| immVertex3fv(pos, v); | |||||
| madd_v3_v3fl(v, vx, size_fac); | |||||
| immVertex3fv(pos, v); | |||||
| sub_v3_v3v3(v, snap_point, vx); | |||||
| immVertex3fv(pos, v); | |||||
| madd_v3_v3fl(v, vx, -size_fac); | |||||
| immVertex3fv(pos, v); | |||||
| add_v3_v3v3(v, snap_point, vy); | |||||
| immVertex3fv(pos, v); | |||||
| madd_v3_v3fl(v, vy, size_fac); | |||||
| immVertex3fv(pos, v); | |||||
| sub_v3_v3v3(v, snap_point, vy); | |||||
| immVertex3fv(pos, v); | |||||
| madd_v3_v3fl(v, vy, -size_fac); | |||||
| immVertex3fv(pos, v); | |||||
| immEnd(); | |||||
| } | |||||
| immUnbindProgram(); | immUnbindProgram(); | ||||
| } | } | ||||
| /* draw normal if needed */ | /* draw normal if needed */ | ||||
| if (usingSnappingNormal(t) && validSnappingNormal(t)) { | if (usingSnappingNormal(t) && validSnappingNormal(t)) { | ||||
| normal = t->tsnap.snapNormal; | normal = t->tsnap.snapNormal; | ||||
| } | } | ||||
| if (draw_source) { | if (draw_source) { | ||||
| loc_prev = t->tsnap.snap_source; | loc_prev = t->tsnap.snap_source; | ||||
| } | } | ||||
| if (validSnap(t)) { | if (t->tsnap.status & SNAP_TARGET_FOUND) { | ||||
| loc_cur = t->tsnap.snap_target; | loc_cur = t->tsnap.snap_target; | ||||
| } | } | ||||
| ED_view3d_cursor_snap_draw_util( | ED_view3d_cursor_snap_draw_util( | ||||
| rv3d, loc_prev, loc_cur, normal, col, activeCol, t->tsnap.snapElem); | rv3d, loc_prev, loc_cur, normal, col, activeCol, t->tsnap.snapElem); | ||||
| GPU_depth_test(GPU_DEPTH_LESS_EQUAL); | GPU_depth_test(GPU_DEPTH_LESS_EQUAL); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 218 Lines • ▼ Show 20 Lines | bool transform_snap_project_individual_is_active(const TransInfo *t) | ||||
| if (!transform_snap_is_active(t)) { | if (!transform_snap_is_active(t)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (t->flag & T_NO_PROJECT) { | if (t->flag & T_NO_PROJECT) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (t->modifiers & MOD_EDIT_SNAP_SOURCE) { | |||||
| return false; | |||||
| } | |||||
| if (!(t->tsnap.project || (t->tsnap.mode & SCE_SNAP_MODE_FACE_NEAREST))) { | if (!(t->tsnap.project || (t->tsnap.mode & SCE_SNAP_MODE_FACE_NEAREST))) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (doForceIncrementSnap(t)) { | if (doForceIncrementSnap(t)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| void transform_snap_mixed_apply(TransInfo *t, float *vec) | void transform_snap_mixed_apply(TransInfo *t, float *vec) | ||||
| { | { | ||||
| if (!transform_snap_mixed_is_active(t)) { | if (!transform_snap_mixed_is_active(t)) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (t->tsnap.status & SNAP_FORCED) { | if (t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) { | ||||
| t->tsnap.snap_source_fn(t); | |||||
| t->tsnap.snap_mode_apply_fn(t, vec); | |||||
| } | |||||
| else if (((t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) != 0) && | |||||
| transform_snap_is_active(t)) { | |||||
| double current = PIL_check_seconds_timer(); | double current = PIL_check_seconds_timer(); | ||||
| /* Time base quirky code to go around find-nearest slowness. */ | /* Time base quirky code to go around find-nearest slowness. */ | ||||
| /* TODO: add exception for object mode, no need to slow it down then. */ | /* TODO: add exception for object mode, no need to slow it down then. */ | ||||
| if (current - t->tsnap.last >= 0.01) { | if (current - t->tsnap.last >= 0.01) { | ||||
| if (t->tsnap.snap_target_fn) { | if (t->tsnap.snap_target_fn) { | ||||
| t->tsnap.snap_target_fn(t, vec); | t->tsnap.snap_target_fn(t, vec); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 187 Lines • ▼ Show 20 Lines | static eSnapTargetOP snap_target_select_from_spacetype(TransInfo *t) | ||||
| } | } | ||||
| else if (ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) { | else if (ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) { | ||||
| ret |= SCE_SNAP_TARGET_NOT_SELECTED; | ret |= SCE_SNAP_TARGET_NOT_SELECTED; | ||||
| } | } | ||||
| return ret; | return ret; | ||||
| } | } | ||||
| static void initSnappingMode(TransInfo *t) | static void snap_object_context_init(TransInfo *t) | ||||
| { | { | ||||
| if ((t->spacetype != SPACE_VIEW3D) || !(t->tsnap.mode & SCE_SNAP_MODE_FACE_RAYCAST)) { | |||||
| /* Force project off when not supported. */ | |||||
| t->tsnap.project = false; | |||||
| } | |||||
| setSnappingCallback(t); | |||||
| if (t->spacetype == SPACE_VIEW3D) { | |||||
| if (t->tsnap.object_context == nullptr) { | |||||
| t->tsnap.use_backface_culling = snap_use_backface_culling(t); | |||||
| t->tsnap.object_context = ED_transform_snap_object_context_create(t->scene, 0); | |||||
| if (t->data_type == &TransConvertType_Mesh) { | if (t->data_type == &TransConvertType_Mesh) { | ||||
| /* Ignore elements being transformed. */ | /* Ignore elements being transformed. */ | ||||
| ED_transform_snap_object_context_set_editmesh_callbacks( | ED_transform_snap_object_context_set_editmesh_callbacks( | ||||
| t->tsnap.object_context, | t->tsnap.object_context, | ||||
| (bool (*)(BMVert *, void *))BM_elem_cb_check_hflag_disabled, | (bool (*)(BMVert *, void *))BM_elem_cb_check_hflag_disabled, | ||||
| bm_edge_is_snap_target, | bm_edge_is_snap_target, | ||||
| bm_face_is_snap_target, | bm_face_is_snap_target, | ||||
| POINTER_FROM_UINT(BM_ELEM_SELECT | BM_ELEM_HIDDEN)); | POINTER_FROM_UINT(BM_ELEM_SELECT | BM_ELEM_HIDDEN)); | ||||
| } | } | ||||
| else { | else { | ||||
| /* Ignore hidden geometry in the general case. */ | /* Ignore hidden geometry in the general case. */ | ||||
| ED_transform_snap_object_context_set_editmesh_callbacks( | ED_transform_snap_object_context_set_editmesh_callbacks( | ||||
| t->tsnap.object_context, | t->tsnap.object_context, | ||||
| (bool (*)(BMVert *, void *))BM_elem_cb_check_hflag_disabled, | (bool (*)(BMVert *, void *))BM_elem_cb_check_hflag_disabled, | ||||
| (bool (*)(BMEdge *, void *))BM_elem_cb_check_hflag_disabled, | (bool (*)(BMEdge *, void *))BM_elem_cb_check_hflag_disabled, | ||||
| (bool (*)(BMFace *, void *))BM_elem_cb_check_hflag_disabled, | (bool (*)(BMFace *, void *))BM_elem_cb_check_hflag_disabled, | ||||
| POINTER_FROM_UINT(BM_ELEM_HIDDEN)); | POINTER_FROM_UINT(BM_ELEM_HIDDEN)); | ||||
| } | } | ||||
| } | } | ||||
| static void initSnappingMode(TransInfo *t) | |||||
| { | |||||
| if ((t->spacetype != SPACE_VIEW3D) || !(t->tsnap.mode & SCE_SNAP_MODE_FACE_RAYCAST)) { | |||||
| /* Force project off when not supported. */ | |||||
| t->tsnap.project = false; | |||||
| } | |||||
| setSnappingCallback(t); | |||||
| if (t->spacetype == SPACE_VIEW3D) { | |||||
| if (t->tsnap.object_context == nullptr) { | |||||
| t->tsnap.use_backface_culling = snap_use_backface_culling(t); | |||||
| t->tsnap.object_context = ED_transform_snap_object_context_create(t->scene, 0); | |||||
| snap_object_context_init(t); | |||||
| } | |||||
| } | } | ||||
| else if (t->spacetype == SPACE_SEQ) { | else if (t->spacetype == SPACE_SEQ) { | ||||
| if (t->tsnap.seq_context == nullptr) { | if (t->tsnap.seq_context == nullptr) { | ||||
| t->tsnap.seq_context = transform_snap_sequencer_data_alloc(t); | t->tsnap.seq_context = transform_snap_sequencer_data_alloc(t); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 260 Lines • ▼ Show 20 Lines | if (t->tsnap.points.first) { | ||||
| mul_v3_fl(vec, 1.0f / total); | mul_v3_fl(vec, 1.0f / total); | ||||
| } | } | ||||
| else { | else { | ||||
| copy_v3_v3(vec, t->tsnap.snap_target); | copy_v3_v3(vec, t->tsnap.snap_target); | ||||
| } | } | ||||
| } | } | ||||
| static void snap_multipoints_free(TransInfo *t) | |||||
| { | |||||
| if (t->tsnap.status & SNAP_MULTI_POINTS) { | |||||
| BLI_freelistN(&t->tsnap.points); | |||||
| t->tsnap.status &= ~SNAP_MULTI_POINTS; | |||||
| t->tsnap.selectedPoint = NULL; | |||||
| } | |||||
| } | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Calc Snap | /** \name Calc Snap | ||||
| * \{ */ | * \{ */ | ||||
| static void snap_target_view3d_fn(TransInfo *t, float * /*vec*/) | static void snap_target_view3d_fn(TransInfo *t, float * /*vec*/) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 612 Lines • ▼ Show 20 Lines | |||||
| bool transform_snap_increment(const TransInfo *t, float *r_val) | bool transform_snap_increment(const TransInfo *t, float *r_val) | ||||
| { | { | ||||
| return transform_snap_increment_ex(t, false, r_val); | return transform_snap_increment_ex(t, false, r_val); | ||||
| } | } | ||||
| float transform_snap_increment_get(const TransInfo *t) | float transform_snap_increment_get(const TransInfo *t) | ||||
| { | { | ||||
| if (transform_snap_is_active(t) && | if (transform_snap_is_active(t) && | ||||
| (!transformModeUseSnap(t) || | (doForceIncrementSnap(t) || | ||||
| (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) { | (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) { | ||||
| return (t->modifiers & MOD_PRECISION) ? t->snap[1] : t->snap[0]; | return (t->modifiers & MOD_PRECISION) ? t->snap[1] : t->snap[0]; | ||||
| } | } | ||||
| return 0.0f; | return 0.0f; | ||||
| } | } | ||||
| void tranform_snap_source_restore_context(TransInfo *t) | |||||
| { | |||||
| snap_object_context_init(t); | |||||
| snap_multipoints_free(t); | |||||
| } | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Generic callbacks | /** \name Generic callbacks | ||||
| * \{ */ | * \{ */ | ||||
| float transform_snap_distance_len_squared_fn(TransInfo * /*t*/, | float transform_snap_distance_len_squared_fn(TransInfo * /*t*/, | ||||
| const float p1[3], | const float p1[3], | ||||
| const float p2[3]) | const float p2[3]) | ||||
| { | { | ||||
| return len_squared_v3v3(p1, p2); | return len_squared_v3v3(p1, p2); | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||