Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/transform/transform_snap.c
| Show First 20 Lines • Show All 172 Lines • ▼ Show 20 Lines | void drawSnapping(const struct bContext *C, TransInfo *t) | ||||
| UI_GetThemeColor3ubv(TH_SELECT, selectedCol); | UI_GetThemeColor3ubv(TH_SELECT, selectedCol); | ||||
| selectedCol[3] = 128; | selectedCol[3] = 128; | ||||
| UI_GetThemeColor3ubv(TH_ACTIVE, activeCol); | UI_GetThemeColor3ubv(TH_ACTIVE, activeCol); | ||||
| activeCol[3] = 192; | activeCol[3] = 192; | ||||
| if (t->spacetype == SPACE_VIEW3D) { | if (t->spacetype == SPACE_VIEW3D) { | ||||
| bool draw_target = (t->tsnap.status & TARGET_INIT) && | bool draw_target = (t->tsnap.status & TARGET_INIT) && | ||||
| (t->scene->toolsettings->snap_mode & SCE_SNAP_MODE_EDGE_PERPENDICULAR); | ((t->modifiers & MOD_EDIT_BASEPOINT) || | ||||
| (t->settings->snap_mode & SCE_SNAP_MODE_EDGE_PERPENDICULAR)); | |||||
| if (draw_target || validSnap(t)) { | if (draw_target || validSnap(t)) { | ||||
| const float *loc_cur = NULL; | const float *loc_cur = NULL; | ||||
| const float *loc_prev = NULL; | const float *loc_prev = NULL; | ||||
| const float *normal = NULL; | const float *normal = NULL; | ||||
| GPU_depth_test(GPU_DEPTH_NONE); | GPU_depth_test(GPU_DEPTH_NONE); | ||||
| Show All 27 Lines | if (draw_target || validSnap(t)) { | ||||
| if (usingSnappingNormal(t) && validSnappingNormal(t)) { | if (usingSnappingNormal(t) && validSnappingNormal(t)) { | ||||
| normal = t->tsnap.snapNormal; | normal = t->tsnap.snapNormal; | ||||
| } | } | ||||
| if (draw_target) { | if (draw_target) { | ||||
| loc_prev = t->tsnap.snapTarget; | loc_prev = t->tsnap.snapTarget; | ||||
| } | } | ||||
| if (validSnap(t)) { | if ((t->tsnap.status & (POINT_INIT | TARGET_INIT)) == (POINT_INIT | TARGET_INIT)) { | ||||
| loc_cur = t->tsnap.snapPoint; | loc_cur = t->tsnap.snapPoint; | ||||
| } | } | ||||
| ED_gizmotypes_snap_3d_draw_util( | ED_gizmotypes_snap_3d_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 192 Lines • ▼ Show 20 Lines | for (i = 0, td = tc->data; i < tc->data_len; i++, td++) { | ||||
| mul_m3_v3(td->smtx, tvec); | mul_m3_v3(td->smtx, tvec); | ||||
| add_v3_v3(td->loc, tvec); | add_v3_v3(td->loc, tvec); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void applySnapping(TransInfo *t, float *vec) | void applySnapping(TransInfo *t, float *vec) | ||||
| { | { | ||||
| /* Each Trans Data already makes the snap to face */ | if (!transformModeUseSnap(t) && !((t->modifiers & MOD_SNAP_TEMP) == MOD_SNAP_TEMP)) { | ||||
| if (doForceIncrementSnap(t)) { | |||||
| return; | return; | ||||
| } | } | ||||
| if (t->tsnap.project && t->tsnap.mode == SCE_SNAP_MODE_FACE) { | if (t->tsnap.project && t->tsnap.mode == SCE_SNAP_MODE_FACE) { | ||||
| /* The snap has already been resolved for each transdata. */ | /* The snap will be resolved for each transdata. */ | ||||
| return; | return; | ||||
| } | } | ||||
| if (t->tsnap.status & SNAP_FORCED) { | if (t->tsnap.status & CUSTOM_SNAPPOINT) { | ||||
| t->tsnap.targetSnap(t); | t->tsnap.targetSnap(t); | ||||
| t->tsnap.applySnap(t, vec); | t->tsnap.applySnap(t, vec); | ||||
| } | } | ||||
| else if (((t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) != 0) && | else if (((t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) != 0) && | ||||
| activeSnap(t)) { | activeSnap(t)) { | ||||
| double current = PIL_check_seconds_timer(); | double current = PIL_check_seconds_timer(); | ||||
| /* Time base quirky code to go around findnearest slowness */ | /* Time base quirky code to go around findnearest 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. */ | ||||
| ▲ Show 20 Lines • Show All 161 Lines • ▼ Show 20 Lines | else { | ||||
| t->tsnap.mode = SCE_SNAP_MODE_INCREMENT; | t->tsnap.mode = SCE_SNAP_MODE_INCREMENT; | ||||
| } | } | ||||
| if (t->spacetype == SPACE_VIEW3D) { | if (t->spacetype == SPACE_VIEW3D) { | ||||
| if (t->tsnap.object_context == NULL) { | if (t->tsnap.object_context == NULL) { | ||||
| t->tsnap.use_backface_culling = snap_use_backface_culling(t); | t->tsnap.use_backface_culling = snap_use_backface_culling(t); | ||||
| t->tsnap.object_context = ED_transform_snap_object_context_create_view3d( | t->tsnap.object_context = ED_transform_snap_object_context_create_view3d( | ||||
| t->scene, 0, t->region, t->view); | t->scene, 0, t->region, t->view); | ||||
| if (t->data_type == TC_MESH_VERTS) { | |||||
| /* Ignore elements being transformed. */ | |||||
| ED_transform_snap_object_context_set_editmesh_callbacks( | |||||
| t->tsnap.object_context, | |||||
| (bool (*)(BMVert *, void *))BM_elem_cb_check_hflag_disabled, | |||||
| bm_edge_is_snap_target, | |||||
| bm_face_is_snap_target, | |||||
| POINTER_FROM_UINT((BM_ELEM_SELECT | BM_ELEM_HIDDEN))); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void initSnapping(TransInfo *t, wmOperator *op) | void initSnapping(TransInfo *t, wmOperator *op) | ||||
| { | { | ||||
| ToolSettings *ts = t->settings; | ToolSettings *ts = t->settings; | ||||
| short snap_target = t->settings->snap_target; | short snap_target = t->settings->snap_target; | ||||
| resetSnapping(t); | resetSnapping(t); | ||||
| /* if snap property exists */ | /* if snap property exists */ | ||||
| if (op && RNA_struct_find_property(op->ptr, "snap") && | if (op && RNA_struct_find_property(op->ptr, "snap") && | ||||
| RNA_struct_property_is_set(op->ptr, "snap")) { | RNA_struct_property_is_set(op->ptr, "snap")) { | ||||
| if (RNA_boolean_get(op->ptr, "snap")) { | if (RNA_boolean_get(op->ptr, "snap")) { | ||||
| t->modifiers |= MOD_SNAP; | t->modifiers |= MOD_SNAP; | ||||
| if (RNA_struct_property_is_set(op->ptr, "snap_target")) { | if (RNA_struct_property_is_set(op->ptr, "snap_target")) { | ||||
| snap_target = RNA_enum_get(op->ptr, "snap_target"); | snap_target = RNA_enum_get(op->ptr, "snap_target"); | ||||
| } | } | ||||
| if (RNA_struct_property_is_set(op->ptr, "snap_point")) { | if (RNA_struct_property_is_set(op->ptr, "snap_point")) { | ||||
| RNA_float_get_array(op->ptr, "snap_point", t->tsnap.snapPoint); | RNA_float_get_array(op->ptr, "snap_point", t->tsnap.snapPoint); | ||||
| t->tsnap.status |= SNAP_FORCED | POINT_INIT; | t->tsnap.status |= CUSTOM_SNAPPOINT | POINT_INIT; | ||||
| } | } | ||||
| /* snap align only defined in specific cases */ | /* snap align only defined in specific cases */ | ||||
| if (RNA_struct_find_property(op->ptr, "snap_align")) { | if (RNA_struct_find_property(op->ptr, "snap_align")) { | ||||
| t->tsnap.align = RNA_boolean_get(op->ptr, "snap_align"); | t->tsnap.align = RNA_boolean_get(op->ptr, "snap_align"); | ||||
| RNA_float_get_array(op->ptr, "snap_normal", t->tsnap.snapNormal); | RNA_float_get_array(op->ptr, "snap_normal", t->tsnap.snapNormal); | ||||
| normalize_v3(t->tsnap.snapNormal); | normalize_v3(t->tsnap.snapNormal); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 149 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.snapPoint); | copy_v3_v3(vec, t->tsnap.snapPoint); | ||||
| } | } | ||||
| } | } | ||||
| static void transform_snap_multipoints_free(TransInfo *t) | |||||
| { | |||||
| if (t->tsnap.status & MULTI_POINTS) { | |||||
| BLI_freelistN(&t->tsnap.points); | |||||
| t->tsnap.status &= ~MULTI_POINTS; | |||||
| t->tsnap.selectedPoint = NULL; | |||||
| } | |||||
| } | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Calc Snap (Generic) | /** \name Calc Snap (Generic) | ||||
| * \{ */ | * \{ */ | ||||
| static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec)) | static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec)) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 279 Lines • ▼ Show 20 Lines | if (t->tsnap.status & POINT_INIT) { | ||||
| } | } | ||||
| TargetSnapOffset(t, closest); | TargetSnapOffset(t, closest); | ||||
| t->tsnap.status |= TARGET_INIT; | t->tsnap.status |= TARGET_INIT; | ||||
| } | } | ||||
| } | } | ||||
| static void TargetSnapCustom(TransInfo *t) | |||||
| { | |||||
| t->tsnap.status |= TARGET_INIT; | |||||
| } | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Snap Objects | /** \name Snap Objects | ||||
| * \{ */ | * \{ */ | ||||
| short snapObjectsTransform( | short 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]) | ||||
| { | { | ||||
| char snap_select; | |||||
| 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; | ||||
| if (t->modifiers & MOD_EDIT_BASEPOINT) { | |||||
| snap_select = SNAP_ALL; | |||||
| if (t->data_type == TC_MESH_VERTS) { | |||||
| ED_transform_snap_object_context_set_editmesh_callbacks( | |||||
| t->tsnap.object_context, NULL, NULL, NULL, NULL); | |||||
| } | |||||
| } | |||||
| else { | |||||
| snap_select = t->tsnap.modeSelect; | |||||
| if (t->data_type == TC_MESH_VERTS) { | |||||
| /* Ignore elements being transformed. */ | |||||
| ED_transform_snap_object_context_set_editmesh_callbacks( | |||||
| t->tsnap.object_context, | |||||
| (bool (*)(BMVert *, void *))BM_elem_cb_check_hflag_disabled, | |||||
| bm_edge_is_snap_target, | |||||
| bm_face_is_snap_target, | |||||
| POINTER_FROM_UINT((BM_ELEM_SELECT | BM_ELEM_HIDDEN))); | |||||
| } | |||||
| } | |||||
| return ED_transform_snap_object_project_view3d_ex( | return ED_transform_snap_object_project_view3d_ex( | ||||
| t->tsnap.object_context, | t->tsnap.object_context, | ||||
| t->depsgraph, | t->depsgraph, | ||||
| t->settings->snap_mode, | t->tsnap.mode, | ||||
| &(const struct SnapObjectParams){ | &(const struct SnapObjectParams){ | ||||
| .snap_select = t->tsnap.modeSelect, | .snap_select = snap_select, | ||||
| .use_object_edit_cage = (t->flag & T_EDIT) != 0, | .use_object_edit_cage = (t->flag & T_EDIT) != 0, | ||||
| .use_occlusion_test = t->settings->snap_mode != SCE_SNAP_MODE_FACE, | .use_occlusion_test = t->settings->snap_mode != SCE_SNAP_MODE_FACE, | ||||
| .use_backface_culling = t->tsnap.use_backface_culling, | .use_backface_culling = t->tsnap.use_backface_culling, | ||||
| }, | }, | ||||
| mval, | mval, | ||||
| target, | target, | ||||
| dist_px, | dist_px, | ||||
| r_loc, | r_loc, | ||||
| ▲ Show 20 Lines • Show All 399 Lines • ▼ Show 20 Lines | bool transform_snap_increment(TransInfo *t, float *val) | ||||
| } | } | ||||
| float increment_dist = (t->modifiers & MOD_PRECISION) ? t->snap[1] : t->snap[0]; | float increment_dist = (t->modifiers & MOD_PRECISION) ? t->snap[1] : t->snap[0]; | ||||
| snap_increment_apply(t, t->idx_max, increment_dist, val); | snap_increment_apply(t, t->idx_max, increment_dist, val); | ||||
| return true; | return true; | ||||
| } | } | ||||
| void tranform_snap_editbasepoint_toggle(TransInfo *t) | |||||
| { | |||||
| if (!(t->modifiers & MOD_EDIT_BASEPOINT)) { | |||||
| /* Init. */ | |||||
| t->modifiers |= MOD_EDIT_BASEPOINT; | |||||
| t->tsnap.status |= TARGET_INIT; | |||||
| t->tsnap.targetSnap = TargetSnapCustom; | |||||
| if ((t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) == 0) { | |||||
| /* Init basic snap modes. */ | |||||
| t->tsnap.mode &= ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID); | |||||
| t->tsnap.mode |= SCE_SNAP_MODE_FACE | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_VERTEX; | |||||
| } | |||||
| if (!activeSnap(t)) { | |||||
| t->modifiers |= MOD_SNAP_TEMP; | |||||
| } | |||||
| restoreTransObjects(t); | |||||
| t->redraw |= TREDRAW_SOFT; | |||||
| } | |||||
| else if (t->modifiers & MOD_EDIT_BASEPOINT) { | |||||
| /* Cancel. */ | |||||
| t->modifiers &= ~MOD_EDIT_BASEPOINT; | |||||
| if (t->modifiers & MOD_SNAP_TEMP) { | |||||
| t->modifiers &= ~MOD_SNAP_TEMP; | |||||
| } | |||||
| initSnappingMode(t); | |||||
| setSnappingCallback(t); | |||||
| } | |||||
| } | |||||
| void tranform_snap_editbasepoint_update(TransInfo *t) | |||||
| { | |||||
| BLI_assert(t->modifiers & MOD_EDIT_BASEPOINT); | |||||
| if (!activeSnap(t)) { | |||||
| return; | |||||
| } | |||||
| /* Time base quirky code to go around findnearest slowness */ | |||||
| /* TODO: add exception for object mode, no need to slow it down then. */ | |||||
| double current = PIL_check_seconds_timer(); | |||||
| if (current - t->tsnap.last >= 0.01) { | |||||
| t->tsnap.calcSnap(t, NULL); | |||||
| t->tsnap.last = current; | |||||
| if (validSnap(t)) { | |||||
| getSnapPoint(t, t->tsnap.snapTarget); | |||||
| } | |||||
| } | |||||
| t->redraw |= TREDRAW_SOFT; | |||||
| } | |||||
| void tranform_snap_editbasepoint_confirm(TransInfo *t) | |||||
| { | |||||
| BLI_assert(t->modifiers & MOD_EDIT_BASEPOINT); | |||||
| t->modifiers &= ~MOD_EDIT_BASEPOINT; | |||||
| getSnapPoint(t, t->tsnap.snapTarget); | |||||
| applyMouseInput(t, &t->mouse, t->mval, t->values); | |||||
| sub_v3_v3(t->values_modal_offset, t->values); | |||||
| transform_snap_multipoints_free(t); | |||||
| } | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Generic callbacks | /** \name Generic callbacks | ||||
| * \{ */ | * \{ */ | ||||
| float transform_snap_distance_len_squared_fn(TransInfo *UNUSED(t), | float transform_snap_distance_len_squared_fn(TransInfo *UNUSED(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); | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||