Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/transform/transform.c
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
| Show First 20 Lines • Show All 6,370 Lines • ▼ Show 20 Lines | static void applyBoneEnvelope(TransInfo *t, const int UNUSED(mval[2])) | ||||
| recalcData(t); | recalcData(t); | ||||
| ED_area_status_text(t->sa, str); | ED_area_status_text(t->sa, str); | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /* Original Data Store */ | |||||
| /** \name Orig-Data Store Utility Functions | |||||
| * \{ */ | |||||
| static void slide_origdata_init_flag(TransInfo *t, TransDataContainer *tc, SlideOrigData *sod) | |||||
| { | |||||
| BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); | |||||
| BMesh *bm = em->bm; | |||||
| const bool has_layer_math = CustomData_has_math(&bm->ldata); | |||||
| const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS); | |||||
| if ((t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) && | |||||
| /* don't do this at all for non-basis shape keys, too easy to | |||||
| * accidentally break uv maps or vertex colors then */ | |||||
| (bm->shapenr <= 1) && (has_layer_math || (cd_loop_mdisp_offset != -1))) { | |||||
| sod->use_origfaces = true; | |||||
| sod->cd_loop_mdisp_offset = cd_loop_mdisp_offset; | |||||
| } | |||||
| else { | |||||
| sod->use_origfaces = false; | |||||
| sod->cd_loop_mdisp_offset = -1; | |||||
| } | |||||
| } | |||||
| static void slide_origdata_init_data(TransDataContainer *tc, SlideOrigData *sod) | |||||
| { | |||||
| if (sod->use_origfaces) { | |||||
| BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); | |||||
| BMesh *bm = em->bm; | |||||
| sod->origfaces = BLI_ghash_ptr_new(__func__); | |||||
| sod->bm_origfaces = BM_mesh_create(&bm_mesh_allocsize_default, | |||||
| &((struct BMeshCreateParams){ | |||||
| .use_toolflags = false, | |||||
| })); | |||||
| /* we need to have matching customdata */ | |||||
| BM_mesh_copy_init_customdata(sod->bm_origfaces, bm, NULL); | |||||
| } | |||||
| } | |||||
| static void slide_origdata_create_data_vert(BMesh *bm, | |||||
| SlideOrigData *sod, | |||||
| TransDataGenericSlideVert *sv) | |||||
| { | |||||
| BMIter liter; | |||||
| int j, l_num; | |||||
| float *loop_weights; | |||||
| /* copy face data */ | |||||
| // BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) { | |||||
| BM_iter_init(&liter, bm, BM_LOOPS_OF_VERT, sv->v); | |||||
| l_num = liter.count; | |||||
| loop_weights = BLI_array_alloca(loop_weights, l_num); | |||||
| for (j = 0; j < l_num; j++) { | |||||
| BMLoop *l = BM_iter_step(&liter); | |||||
| BMLoop *l_prev, *l_next; | |||||
| void **val_p; | |||||
| if (!BLI_ghash_ensure_p(sod->origfaces, l->f, &val_p)) { | |||||
| BMFace *f_copy = BM_face_copy(sod->bm_origfaces, bm, l->f, true, true); | |||||
| *val_p = f_copy; | |||||
| } | |||||
| if ((l_prev = BM_loop_find_prev_nodouble(l, l->next, FLT_EPSILON)) && | |||||
| (l_next = BM_loop_find_next_nodouble(l, l_prev, FLT_EPSILON))) { | |||||
| loop_weights[j] = angle_v3v3v3(l_prev->v->co, l->v->co, l_next->v->co); | |||||
| } | |||||
| else { | |||||
| loop_weights[j] = 0.0f; | |||||
| } | |||||
| } | |||||
| /* store cd_loop_groups */ | |||||
| if (sod->layer_math_map_num && (l_num != 0)) { | |||||
| sv->cd_loop_groups = BLI_memarena_alloc(sod->arena, sod->layer_math_map_num * sizeof(void *)); | |||||
| for (j = 0; j < sod->layer_math_map_num; j++) { | |||||
| const int layer_nr = sod->layer_math_map[j]; | |||||
| sv->cd_loop_groups[j] = BM_vert_loop_groups_data_layer_create( | |||||
| bm, sv->v, layer_nr, loop_weights, sod->arena); | |||||
| } | |||||
| } | |||||
| else { | |||||
| sv->cd_loop_groups = NULL; | |||||
| } | |||||
| BLI_ghash_insert(sod->origverts, sv->v, sv); | |||||
| } | |||||
| static void slide_origdata_create_data(TransDataContainer *tc, | |||||
| SlideOrigData *sod, | |||||
| TransDataGenericSlideVert *sv_array, | |||||
| unsigned int v_stride, | |||||
| unsigned int v_num) | |||||
| { | |||||
| if (sod->use_origfaces) { | |||||
| BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); | |||||
| BMesh *bm = em->bm; | |||||
| unsigned int i; | |||||
| TransDataGenericSlideVert *sv; | |||||
| int layer_index_dst; | |||||
| int j; | |||||
| layer_index_dst = 0; | |||||
| /* TODO: We don't need `sod->layer_math_map` when there are no loops linked | |||||
| * to one of the sliding vertices. */ | |||||
| if (CustomData_has_math(&bm->ldata)) { | |||||
| /* over alloc, only 'math' layers are indexed */ | |||||
| sod->layer_math_map = MEM_mallocN(bm->ldata.totlayer * sizeof(int), __func__); | |||||
| for (j = 0; j < bm->ldata.totlayer; j++) { | |||||
| if (CustomData_layer_has_math(&bm->ldata, j)) { | |||||
| sod->layer_math_map[layer_index_dst++] = j; | |||||
| } | |||||
| } | |||||
| BLI_assert(layer_index_dst != 0); | |||||
| } | |||||
| sod->layer_math_map_num = layer_index_dst; | |||||
| sod->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); | |||||
| sod->origverts = BLI_ghash_ptr_new_ex(__func__, v_num); | |||||
| for (i = 0, sv = sv_array; i < v_num; i++, sv = POINTER_OFFSET(sv, v_stride)) { | |||||
| slide_origdata_create_data_vert(bm, sod, sv); | |||||
| } | |||||
| if (tc->mirror.axis_flag) { | |||||
| TransData *td = tc->data; | |||||
| TransDataGenericSlideVert *sv_mirror; | |||||
| sod->sv_mirror = MEM_callocN(sizeof(*sv_mirror) * tc->data_len, __func__); | |||||
| sod->totsv_mirror = tc->data_len; | |||||
| sv_mirror = sod->sv_mirror; | |||||
| for (i = 0; i < tc->data_len; i++, td++) { | |||||
| BMVert *eve = td->extra; | |||||
| /* Check the vertex has been used since both sides | |||||
| * of the mirror may be selected & sliding. */ | |||||
| if (eve && !BLI_ghash_haskey(sod->origverts, eve)) { | |||||
| sv_mirror->v = eve; | |||||
| copy_v3_v3(sv_mirror->co_orig_3d, eve->co); | |||||
| slide_origdata_create_data_vert(bm, sod, sv_mirror); | |||||
| sv_mirror++; | |||||
| } | |||||
| else { | |||||
| sod->totsv_mirror--; | |||||
| } | |||||
| } | |||||
| if (sod->totsv_mirror == 0) { | |||||
| MEM_freeN(sod->sv_mirror); | |||||
| sod->sv_mirror = NULL; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * If we're sliding the vert, return its original location, if not, the current location is good. | |||||
| */ | |||||
| static const float *slide_origdata_orig_vert_co(SlideOrigData *sod, BMVert *v) | |||||
| { | |||||
| TransDataGenericSlideVert *sv = BLI_ghash_lookup(sod->origverts, v); | |||||
| return sv ? sv->co_orig_3d : v->co; | |||||
| } | |||||
| static void slide_origdata_interp_data_vert(SlideOrigData *sod, | |||||
| BMesh *bm, | |||||
| bool is_final, | |||||
| TransDataGenericSlideVert *sv) | |||||
| { | |||||
| BMIter liter; | |||||
| int j, l_num; | |||||
| float *loop_weights; | |||||
| const bool is_moved = (len_squared_v3v3(sv->v->co, sv->co_orig_3d) > FLT_EPSILON); | |||||
| const bool do_loop_weight = sod->layer_math_map_num && is_moved; | |||||
| const bool do_loop_mdisps = is_final && is_moved && (sod->cd_loop_mdisp_offset != -1); | |||||
| const float *v_proj_axis = sv->v->no; | |||||
| /* original (l->prev, l, l->next) projections for each loop ('l' remains unchanged) */ | |||||
| float v_proj[3][3]; | |||||
| if (do_loop_weight || do_loop_mdisps) { | |||||
| project_plane_normalized_v3_v3v3(v_proj[1], sv->co_orig_3d, v_proj_axis); | |||||
| } | |||||
| // BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) | |||||
| BM_iter_init(&liter, bm, BM_LOOPS_OF_VERT, sv->v); | |||||
| l_num = liter.count; | |||||
| loop_weights = do_loop_weight ? BLI_array_alloca(loop_weights, l_num) : NULL; | |||||
| for (j = 0; j < l_num; j++) { | |||||
| BMFace *f_copy; /* the copy of 'f' */ | |||||
| BMLoop *l = BM_iter_step(&liter); | |||||
| f_copy = BLI_ghash_lookup(sod->origfaces, l->f); | |||||
| /* only loop data, no vertex data since that contains shape keys, | |||||
| * and we do not want to mess up other shape keys */ | |||||
| BM_loop_interp_from_face(bm, l, f_copy, false, false); | |||||
| /* make sure face-attributes are correct (e.g. #MLoopUV, #MLoopCol) */ | |||||
| BM_elem_attrs_copy_ex(sod->bm_origfaces, bm, f_copy, l->f, 0x0, CD_MASK_NORMAL); | |||||
| /* weight the loop */ | |||||
| if (do_loop_weight) { | |||||
| const float eps = 1.0e-8f; | |||||
| const BMLoop *l_prev = l->prev; | |||||
| const BMLoop *l_next = l->next; | |||||
| const float *co_prev = slide_origdata_orig_vert_co(sod, l_prev->v); | |||||
| const float *co_next = slide_origdata_orig_vert_co(sod, l_next->v); | |||||
| bool co_prev_ok; | |||||
| bool co_next_ok; | |||||
| /* In the unlikely case that we're next to a zero length edge - | |||||
| * walk around the to the next. | |||||
| * | |||||
| * Since we only need to check if the vertex is in this corner, | |||||
| * its not important _which_ loop - as long as its not overlapping | |||||
| * 'sv->co_orig_3d', see: T45096. */ | |||||
| project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis); | |||||
| while (UNLIKELY(((co_prev_ok = (len_squared_v3v3(v_proj[1], v_proj[0]) > eps)) == false) && | |||||
| ((l_prev = l_prev->prev) != l->next))) { | |||||
| co_prev = slide_origdata_orig_vert_co(sod, l_prev->v); | |||||
| project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis); | |||||
| } | |||||
| project_plane_normalized_v3_v3v3(v_proj[2], co_next, v_proj_axis); | |||||
| while (UNLIKELY(((co_next_ok = (len_squared_v3v3(v_proj[1], v_proj[2]) > eps)) == false) && | |||||
| ((l_next = l_next->next) != l->prev))) { | |||||
| co_next = slide_origdata_orig_vert_co(sod, l_next->v); | |||||
| project_plane_normalized_v3_v3v3(v_proj[2], co_next, v_proj_axis); | |||||
| } | |||||
| if (co_prev_ok && co_next_ok) { | |||||
| const float dist = dist_signed_squared_to_corner_v3v3v3( | |||||
| sv->v->co, UNPACK3(v_proj), v_proj_axis); | |||||
| loop_weights[j] = (dist >= 0.0f) ? 1.0f : ((dist <= -eps) ? 0.0f : (1.0f + (dist / eps))); | |||||
| if (UNLIKELY(!isfinite(loop_weights[j]))) { | |||||
| loop_weights[j] = 0.0f; | |||||
| } | |||||
| } | |||||
| else { | |||||
| loop_weights[j] = 0.0f; | |||||
| } | |||||
| } | |||||
| } | |||||
| if (sod->layer_math_map_num && sv->cd_loop_groups) { | |||||
| if (do_loop_weight) { | |||||
| for (j = 0; j < sod->layer_math_map_num; j++) { | |||||
| BM_vert_loop_groups_data_layer_merge_weights( | |||||
| bm, sv->cd_loop_groups[j], sod->layer_math_map[j], loop_weights); | |||||
| } | |||||
| } | |||||
| else { | |||||
| for (j = 0; j < sod->layer_math_map_num; j++) { | |||||
| BM_vert_loop_groups_data_layer_merge(bm, sv->cd_loop_groups[j], sod->layer_math_map[j]); | |||||
| } | |||||
| } | |||||
| } | |||||
| /* Special handling for multires | |||||
| * | |||||
| * Interpolate from every other loop (not ideal) | |||||
| * However values will only be taken from loops which overlap other mdisps. | |||||
| * */ | |||||
| if (do_loop_mdisps) { | |||||
| float(*faces_center)[3] = BLI_array_alloca(faces_center, l_num); | |||||
| BMLoop *l; | |||||
| BM_ITER_ELEM_INDEX (l, &liter, sv->v, BM_LOOPS_OF_VERT, j) { | |||||
| BM_face_calc_center_median(l->f, faces_center[j]); | |||||
| } | |||||
| BM_ITER_ELEM_INDEX (l, &liter, sv->v, BM_LOOPS_OF_VERT, j) { | |||||
| BMFace *f_copy = BLI_ghash_lookup(sod->origfaces, l->f); | |||||
| float f_copy_center[3]; | |||||
| BMIter liter_other; | |||||
| BMLoop *l_other; | |||||
| int j_other; | |||||
| BM_face_calc_center_median(f_copy, f_copy_center); | |||||
| BM_ITER_ELEM_INDEX (l_other, &liter_other, sv->v, BM_LOOPS_OF_VERT, j_other) { | |||||
| BM_face_interp_multires_ex(bm, | |||||
| l_other->f, | |||||
| f_copy, | |||||
| faces_center[j_other], | |||||
| f_copy_center, | |||||
| sod->cd_loop_mdisp_offset); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| static void slide_origdata_interp_data(Object *obedit, | |||||
| SlideOrigData *sod, | |||||
| TransDataGenericSlideVert *sv, | |||||
| unsigned int v_stride, | |||||
| unsigned int v_num, | |||||
| bool is_final) | |||||
| { | |||||
| if (sod->use_origfaces) { | |||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | |||||
| BMesh *bm = em->bm; | |||||
| unsigned int i; | |||||
| const bool has_mdisps = (sod->cd_loop_mdisp_offset != -1); | |||||
| for (i = 0; i < v_num; i++, sv = POINTER_OFFSET(sv, v_stride)) { | |||||
| if (sv->cd_loop_groups || has_mdisps) { | |||||
| slide_origdata_interp_data_vert(sod, bm, is_final, sv); | |||||
| } | |||||
| } | |||||
| if (sod->sv_mirror) { | |||||
| sv = sod->sv_mirror; | |||||
| for (i = 0; i < v_num; i++, sv++) { | |||||
| if (sv->cd_loop_groups || has_mdisps) { | |||||
| slide_origdata_interp_data_vert(sod, bm, is_final, sv); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| static void slide_origdata_free_date(SlideOrigData *sod) | |||||
| { | |||||
| if (sod->use_origfaces) { | |||||
| if (sod->bm_origfaces) { | |||||
| BM_mesh_free(sod->bm_origfaces); | |||||
| sod->bm_origfaces = NULL; | |||||
| } | |||||
| if (sod->origfaces) { | |||||
| BLI_ghash_free(sod->origfaces, NULL, NULL); | |||||
| sod->origfaces = NULL; | |||||
| } | |||||
| if (sod->origverts) { | |||||
| BLI_ghash_free(sod->origverts, NULL, NULL); | |||||
| sod->origverts = NULL; | |||||
| } | |||||
| if (sod->arena) { | |||||
| BLI_memarena_free(sod->arena); | |||||
| sod->arena = NULL; | |||||
| } | |||||
| MEM_SAFE_FREE(sod->layer_math_map); | |||||
| MEM_SAFE_FREE(sod->sv_mirror); | |||||
| } | |||||
| } | |||||
| /** \} */ | |||||
| /* -------------------------------------------------------------------- */ | |||||
| /* Transform (Edge Slide) */ | /* Transform (Edge Slide) */ | ||||
| /** \name Transform Edge Slide | /** \name Transform Edge Slide | ||||
| * \{ */ | * \{ */ | ||||
| /** | /** | ||||
| * Get the first valid EdgeSlideData. | * Get the first valid EdgeSlideData. | ||||
| * | * | ||||
| ▲ Show 20 Lines • Show All 434 Lines • ▼ Show 20 Lines | static bool createEdgeSlideVerts_double_side(TransInfo *t, TransDataContainer *tc) | ||||
| int *sv_table; /* BMVert -> sv_array index */ | int *sv_table; /* BMVert -> sv_array index */ | ||||
| EdgeSlideData *sld = MEM_callocN(sizeof(*sld), "sld"); | EdgeSlideData *sld = MEM_callocN(sizeof(*sld), "sld"); | ||||
| float mval[2] = {(float)t->mval[0], (float)t->mval[1]}; | float mval[2] = {(float)t->mval[0], (float)t->mval[1]}; | ||||
| int numsel, i, loop_nr; | int numsel, i, loop_nr; | ||||
| bool use_occlude_geometry = false; | bool use_occlude_geometry = false; | ||||
| View3D *v3d = NULL; | View3D *v3d = NULL; | ||||
| RegionView3D *rv3d = NULL; | RegionView3D *rv3d = NULL; | ||||
| slide_origdata_init_flag(t, tc, &sld->orig_data); | |||||
| sld->curr_sv_index = 0; | sld->curr_sv_index = 0; | ||||
| /*ensure valid selection*/ | /*ensure valid selection*/ | ||||
| BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { | BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { | ||||
| if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { | if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { | ||||
| BMIter iter2; | BMIter iter2; | ||||
| numsel = 0; | numsel = 0; | ||||
| BM_ITER_ELEM (e, &iter2, v, BM_EDGES_OF_VERT) { | BM_ITER_ELEM (e, &iter2, v, BM_EDGES_OF_VERT) { | ||||
| ▲ Show 20 Lines • Show All 314 Lines • ▼ Show 20 Lines | if (t->spacetype == SPACE_VIEW3D) { | ||||
| v3d = t->sa ? t->sa->spacedata.first : NULL; | v3d = t->sa ? t->sa->spacedata.first : NULL; | ||||
| rv3d = t->ar ? t->ar->regiondata : NULL; | rv3d = t->ar ? t->ar->regiondata : NULL; | ||||
| use_occlude_geometry = (v3d && TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->dt > OB_WIRE && | use_occlude_geometry = (v3d && TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->dt > OB_WIRE && | ||||
| !XRAY_ENABLED(v3d)); | !XRAY_ENABLED(v3d)); | ||||
| } | } | ||||
| calcEdgeSlide_mval_range(t, tc, sld, sv_table, loop_nr, mval, use_occlude_geometry, true); | calcEdgeSlide_mval_range(t, tc, sld, sv_table, loop_nr, mval, use_occlude_geometry, true); | ||||
| /* create copies of faces for customdata projection */ | |||||
| bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES); | |||||
| slide_origdata_init_data(tc, &sld->orig_data); | |||||
| slide_origdata_create_data( | |||||
| tc, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv); | |||||
| if (rv3d) { | if (rv3d) { | ||||
| calcEdgeSlide_even(t, tc, sld, mval); | calcEdgeSlide_even(t, tc, sld, mval); | ||||
| } | } | ||||
| sld->em = em; | |||||
| tc->custom.mode.data = sld; | tc->custom.mode.data = sld; | ||||
| MEM_freeN(sv_table); | MEM_freeN(sv_table); | ||||
| return true; | return true; | ||||
| } | } | ||||
| /** | /** | ||||
| Show All 17 Lines | static bool createEdgeSlideVerts_single_side(TransInfo *t, TransDataContainer *tc) | ||||
| RegionView3D *rv3d = NULL; | RegionView3D *rv3d = NULL; | ||||
| if (t->spacetype == SPACE_VIEW3D) { | if (t->spacetype == SPACE_VIEW3D) { | ||||
| /* background mode support */ | /* background mode support */ | ||||
| v3d = t->sa ? t->sa->spacedata.first : NULL; | v3d = t->sa ? t->sa->spacedata.first : NULL; | ||||
| rv3d = t->ar ? t->ar->regiondata : NULL; | rv3d = t->ar ? t->ar->regiondata : NULL; | ||||
| } | } | ||||
| slide_origdata_init_flag(t, tc, &sld->orig_data); | |||||
| sld->curr_sv_index = 0; | sld->curr_sv_index = 0; | ||||
| /* ensure valid selection */ | /* ensure valid selection */ | ||||
| { | { | ||||
| int i = 0, j = 0; | int i = 0, j = 0; | ||||
| BMVert *v; | BMVert *v; | ||||
| BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) { | BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) { | ||||
| if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { | if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { | ||||
| ▲ Show 20 Lines • Show All 132 Lines • ▼ Show 20 Lines | if (t->spacetype == SPACE_VIEW3D) { | ||||
| v3d = t->sa ? t->sa->spacedata.first : NULL; | v3d = t->sa ? t->sa->spacedata.first : NULL; | ||||
| rv3d = t->ar ? t->ar->regiondata : NULL; | rv3d = t->ar ? t->ar->regiondata : NULL; | ||||
| use_occlude_geometry = (v3d && TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->dt > OB_WIRE && | use_occlude_geometry = (v3d && TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->dt > OB_WIRE && | ||||
| !XRAY_ENABLED(v3d)); | !XRAY_ENABLED(v3d)); | ||||
| } | } | ||||
| calcEdgeSlide_mval_range(t, tc, sld, sv_table, loop_nr, mval, use_occlude_geometry, false); | calcEdgeSlide_mval_range(t, tc, sld, sv_table, loop_nr, mval, use_occlude_geometry, false); | ||||
| /* create copies of faces for customdata projection */ | |||||
| bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES); | |||||
| slide_origdata_init_data(tc, &sld->orig_data); | |||||
| slide_origdata_create_data( | |||||
| tc, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv); | |||||
| if (rv3d) { | if (rv3d) { | ||||
| calcEdgeSlide_even(t, tc, sld, mval); | calcEdgeSlide_even(t, tc, sld, mval); | ||||
| } | } | ||||
| sld->em = em; | |||||
| tc->custom.mode.data = sld; | tc->custom.mode.data = sld; | ||||
| MEM_freeN(sv_table); | MEM_freeN(sv_table); | ||||
| return true; | return true; | ||||
| } | } | ||||
| void projectEdgeSlideData(TransInfo *t, bool is_final) | void projectEdgeSlideData(TransInfo *t, bool is_final) | ||||
| { | { | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| EdgeSlideData *sld = tc->custom.mode.data; | EdgeSlideData *sld = tc->custom.mode.data; | ||||
| if (sld == NULL) { | if (sld == NULL) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| SlideOrigData *sod = &sld->orig_data; | trans_mesh_customdata_correction_apply(tc, is_final); | ||||
| if (sod->use_origfaces == false) { | |||||
| continue; | |||||
| } | |||||
| slide_origdata_interp_data(tc->obedit, | |||||
| sod, | |||||
| (TransDataGenericSlideVert *)sld->sv, | |||||
| sizeof(*sld->sv), | |||||
| sld->totsv, | |||||
| is_final); | |||||
| } | } | ||||
| } | } | ||||
| void freeEdgeSlideTempFaces(EdgeSlideData *sld) | |||||
| { | |||||
| slide_origdata_free_date(&sld->orig_data); | |||||
| } | |||||
| void freeEdgeSlideVerts(TransInfo *UNUSED(t), | void freeEdgeSlideVerts(TransInfo *UNUSED(t), | ||||
| TransDataContainer *UNUSED(tc), | TransDataContainer *UNUSED(tc), | ||||
| TransCustomData *custom_data) | TransCustomData *custom_data) | ||||
| { | { | ||||
| EdgeSlideData *sld = custom_data->data; | EdgeSlideData *sld = custom_data->data; | ||||
| if (sld == NULL) { | if (sld == NULL) { | ||||
| return; | return; | ||||
| } | } | ||||
| freeEdgeSlideTempFaces(sld); | |||||
| bmesh_edit_end(sld->em->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES); | |||||
| MEM_freeN(sld->sv); | MEM_freeN(sld->sv); | ||||
| MEM_freeN(sld); | MEM_freeN(sld); | ||||
| custom_data->data = NULL; | custom_data->data = NULL; | ||||
| } | } | ||||
| static void initEdgeSlide_ex( | static void initEdgeSlide_ex( | ||||
| TransInfo *t, bool use_double_side, bool use_even, bool flipped, bool use_clamp) | TransInfo *t, bool use_double_side, bool use_even, bool flipped, bool use_clamp) | ||||
| ▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | static void initEdgeSlide_ex( | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| sld = tc->custom.mode.data; | sld = tc->custom.mode.data; | ||||
| if (!sld) { | if (!sld) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| tc->custom.mode.free_cb = freeEdgeSlideVerts; | tc->custom.mode.free_cb = freeEdgeSlideVerts; | ||||
| } | } | ||||
| trans_mesh_customdata_correction_init(t); | |||||
| /* set custom point first if you want value to be initialized by init */ | /* set custom point first if you want value to be initialized by init */ | ||||
| calcEdgeSlideCustomPoints(t); | calcEdgeSlideCustomPoints(t); | ||||
| initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO_FLIP); | initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO_FLIP); | ||||
| t->idx_max = 0; | t->idx_max = 0; | ||||
| t->num.idx_max = 0; | t->num.idx_max = 0; | ||||
| t->snap[0] = 0.0f; | t->snap[0] = 0.0f; | ||||
| t->snap[1] = 0.1f; | t->snap[1] = 0.1f; | ||||
| ▲ Show 20 Lines • Show All 459 Lines • ▼ Show 20 Lines | static bool createVertSlideVerts(TransInfo *t, TransDataContainer *tc) | ||||
| BMIter iter; | BMIter iter; | ||||
| BMIter eiter; | BMIter eiter; | ||||
| BMEdge *e; | BMEdge *e; | ||||
| BMVert *v; | BMVert *v; | ||||
| TransDataVertSlideVert *sv_array; | TransDataVertSlideVert *sv_array; | ||||
| VertSlideData *sld = MEM_callocN(sizeof(*sld), "sld"); | VertSlideData *sld = MEM_callocN(sizeof(*sld), "sld"); | ||||
| int j; | int j; | ||||
| slide_origdata_init_flag(t, tc, &sld->orig_data); | |||||
| sld->curr_sv_index = 0; | sld->curr_sv_index = 0; | ||||
| j = 0; | j = 0; | ||||
| BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { | BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { | ||||
| bool ok = false; | bool ok = false; | ||||
| if (BM_elem_flag_test(v, BM_ELEM_SELECT) && v->e) { | if (BM_elem_flag_test(v, BM_ELEM_SELECT) && v->e) { | ||||
| BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { | BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { | ||||
| if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { | if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { | ||||
| ▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | if (BM_elem_flag_test(v, BM_ELEM_TAG)) { | ||||
| } | } | ||||
| j++; | j++; | ||||
| } | } | ||||
| } | } | ||||
| sld->sv = sv_array; | sld->sv = sv_array; | ||||
| sld->totsv = j; | sld->totsv = j; | ||||
| bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES); | |||||
| slide_origdata_init_data(tc, &sld->orig_data); | |||||
| slide_origdata_create_data( | |||||
| tc, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv); | |||||
| sld->em = em; | |||||
| tc->custom.mode.data = sld; | tc->custom.mode.data = sld; | ||||
| /* most likely will be set below */ | /* most likely will be set below */ | ||||
| unit_m4(sld->proj_mat); | unit_m4(sld->proj_mat); | ||||
| if (t->spacetype == SPACE_VIEW3D) { | if (t->spacetype == SPACE_VIEW3D) { | ||||
| /* view vars */ | /* view vars */ | ||||
| RegionView3D *rv3d = NULL; | RegionView3D *rv3d = NULL; | ||||
| Show All 13 Lines | static bool createVertSlideVerts(TransInfo *t, TransDataContainer *tc) | ||||
| return true; | return true; | ||||
| } | } | ||||
| void projectVertSlideData(TransInfo *t, bool is_final) | void projectVertSlideData(TransInfo *t, bool is_final) | ||||
| { | { | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| VertSlideData *sld = tc->custom.mode.data; | VertSlideData *sld = tc->custom.mode.data; | ||||
| SlideOrigData *sod = &sld->orig_data; | trans_mesh_customdata_correction_apply(tc, is_final); | ||||
| if (sod->use_origfaces == true) { | |||||
| slide_origdata_interp_data(tc->obedit, | |||||
| sod, | |||||
| (TransDataGenericSlideVert *)sld->sv, | |||||
| sizeof(*sld->sv), | |||||
| sld->totsv, | |||||
| is_final); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| void freeVertSlideTempFaces(VertSlideData *sld) | |||||
| { | |||||
| slide_origdata_free_date(&sld->orig_data); | |||||
| } | |||||
| void freeVertSlideVerts(TransInfo *UNUSED(t), | void freeVertSlideVerts(TransInfo *UNUSED(t), | ||||
| TransDataContainer *UNUSED(tc), | TransDataContainer *UNUSED(tc), | ||||
| TransCustomData *custom_data) | TransCustomData *custom_data) | ||||
| { | { | ||||
| VertSlideData *sld = custom_data->data; | VertSlideData *sld = custom_data->data; | ||||
| if (!sld) { | if (!sld) { | ||||
| return; | return; | ||||
| } | } | ||||
| freeVertSlideTempFaces(sld); | |||||
| bmesh_edit_end(sld->em->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES); | |||||
| if (sld->totsv > 0) { | if (sld->totsv > 0) { | ||||
| TransDataVertSlideVert *sv = sld->sv; | TransDataVertSlideVert *sv = sld->sv; | ||||
| int i = 0; | int i = 0; | ||||
| for (i = 0; i < sld->totsv; i++, sv++) { | for (i = 0; i < sld->totsv; i++, sv++) { | ||||
| MEM_freeN(sv->co_link_orig_3d); | MEM_freeN(sv->co_link_orig_3d); | ||||
| } | } | ||||
| } | } | ||||
| Show All 33 Lines | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| } | } | ||||
| } | } | ||||
| if (ok == false) { | if (ok == false) { | ||||
| t->state = TRANS_CANCEL; | t->state = TRANS_CANCEL; | ||||
| return; | return; | ||||
| } | } | ||||
| trans_mesh_customdata_correction_init(t); | |||||
| /* set custom point first if you want value to be initialized by init */ | /* set custom point first if you want value to be initialized by init */ | ||||
| calcVertSlideCustomPoints(t); | calcVertSlideCustomPoints(t); | ||||
| initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO); | initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO); | ||||
| t->idx_max = 0; | t->idx_max = 0; | ||||
| t->num.idx_max = 0; | t->num.idx_max = 0; | ||||
| t->snap[0] = 0.0f; | t->snap[0] = 0.0f; | ||||
| t->snap[1] = 0.1f; | t->snap[1] = 0.1f; | ||||
| ▲ Show 20 Lines • Show All 1,360 Lines • Show Last 20 Lines | |||||