Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/transform/transform_convert_mesh.c
| Show First 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | |||||
| #include "WM_api.h" /* for WM_event_add_notifier to deal with stabilization nodes */ | #include "WM_api.h" /* for WM_event_add_notifier to deal with stabilization nodes */ | ||||
| #include "DEG_depsgraph.h" | #include "DEG_depsgraph.h" | ||||
| #include "DEG_depsgraph_query.h" | #include "DEG_depsgraph_query.h" | ||||
| #include "transform.h" | #include "transform.h" | ||||
| #include "transform_convert.h" | #include "transform_convert.h" | ||||
| #include "transform_data.h" | |||||
| #include "transform_snap.h" | #include "transform_snap.h" | ||||
| #include "bmesh.h" | #include "bmesh.h" | ||||
| /* Used for both mirror epsilon and TD_MIRROR_EDGE_ */ | /* Used for both mirror epsilon and TD_MIRROR_EDGE_ */ | ||||
| #define TRANSFORM_MAXDIST_MIRROR 0.00002f | #define TRANSFORM_MAXDIST_MIRROR 0.00002f | ||||
| /* when transforming islands */ | /* when transforming islands */ | ||||
| ▲ Show 20 Lines • Show All 507 Lines • ▼ Show 20 Lines | static TransDataMirror *editmesh_mirror_data_calc(BMEditMesh *em, | ||||
| bm->elem_index_dirty |= BM_VERT; | bm->elem_index_dirty |= BM_VERT; | ||||
| *r_mirror_data_len = mirror_elem_len; | *r_mirror_data_len = mirror_elem_len; | ||||
| return mirror_data; | return mirror_data; | ||||
| } | } | ||||
| /* way to overwrite what data is edited with transform */ | /* way to overwrite what data is edited with transform */ | ||||
| static void VertsToTransData(TransInfo *t, | static void VertsToTransData(TransInfo *t, | ||||
| TransData *td, | const TransData *td, | ||||
| TransDataExtension *tx, | const int tdi, | ||||
| BMEditMesh *em, | BMEditMesh *em, | ||||
| BMVert *eve, | BMVert *eve, | ||||
| float *bweight, | float *bweight, | ||||
| const struct TransIslandData *island_data, | const struct TransIslandData *island_data, | ||||
| const int island_index, | const int island_index, | ||||
| const bool no_island_center) | const bool no_island_center) | ||||
| { | { | ||||
| float *no, _no[3]; | float *no, _no[3]; | ||||
| BLI_assert(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) == 0); | BLI_assert(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) == 0); | ||||
| td->flag = 0; | td->basic[tdi].flag = 0; | ||||
| // if (key) | // if (key) | ||||
| // td->loc = key->co; | // td->basic[tdi].loc = key->co; | ||||
| // else | // else | ||||
| td->loc = eve->co; | td->basic[tdi].loc = eve->co; | ||||
| copy_v3_v3(td->iloc, td->loc); | copy_v3_v3(td->basic[tdi].iloc, td->basic[tdi].loc); | ||||
| if ((t->mode == TFM_SHRINKFATTEN) && (em->selectmode & SCE_SELECT_FACE) && | if ((t->mode == TFM_SHRINKFATTEN) && (em->selectmode & SCE_SELECT_FACE) && | ||||
| BM_elem_flag_test(eve, BM_ELEM_SELECT) && | BM_elem_flag_test(eve, BM_ELEM_SELECT) && | ||||
| (BM_vert_calc_normal_ex(eve, BM_ELEM_SELECT, _no))) { | (BM_vert_calc_normal_ex(eve, BM_ELEM_SELECT, _no))) { | ||||
| no = _no; | no = _no; | ||||
| } | } | ||||
| else { | else { | ||||
| no = eve->no; | no = eve->no; | ||||
| } | } | ||||
| if (island_index != -1) { | if (island_index != -1) { | ||||
| if (no_island_center) { | if (no_island_center) { | ||||
| copy_v3_v3(td->center, td->loc); | copy_v3_v3(td->center[tdi], td->basic[tdi].loc); | ||||
| } | } | ||||
| else { | else { | ||||
| copy_v3_v3(td->center, island_data->center[island_index]); | copy_v3_v3(td->center[tdi], island_data->center[island_index]); | ||||
| } | } | ||||
| } | } | ||||
| if ((island_index != -1) && island_data->axismtx) { | if ((island_index != -1) && island_data->axismtx) { | ||||
| copy_m3_m3(td->axismtx, island_data->axismtx[island_index]); | copy_m3_m3(td->space[tdi].axismtx, island_data->axismtx[island_index]); | ||||
| } | } | ||||
| else if (t->around == V3D_AROUND_LOCAL_ORIGINS) { | else if (t->around == V3D_AROUND_LOCAL_ORIGINS) { | ||||
| copy_v3_v3(td->center, td->loc); | copy_v3_v3(td->center[tdi], td->basic[tdi].loc); | ||||
| createSpaceNormal(td->axismtx, no); | createSpaceNormal(td->space[tdi].axismtx, no); | ||||
| } | } | ||||
| else { | else { | ||||
| copy_v3_v3(td->center, td->loc); | copy_v3_v3(td->center[tdi], td->basic[tdi].loc); | ||||
| /* Setting normals */ | /* Setting normals */ | ||||
| copy_v3_v3(td->axismtx[2], no); | float axismtx[3][3] = {{0.0f}}; | ||||
| td->axismtx[0][0] = td->axismtx[0][1] = td->axismtx[0][2] = td->axismtx[1][0] = | copy_v3_v3(axismtx[2], no); | ||||
| td->axismtx[1][1] = td->axismtx[1][2] = 0.0f; | copy_m3_m3(td->space[tdi].axismtx, axismtx); | ||||
| } | } | ||||
| td->ext = NULL; | td->special[tdi].val = NULL; | ||||
| td->val = NULL; | td->basic[tdi].extra = eve; | ||||
| td->extra = eve; | |||||
| if (t->mode == TFM_BWEIGHT) { | if (t->mode == TFM_BWEIGHT) { | ||||
| td->val = bweight; | td->special[tdi].val = bweight; | ||||
| td->ival = *bweight; | td->special[tdi].ival = *bweight; | ||||
| } | } | ||||
| else if (t->mode == TFM_SKIN_RESIZE) { | else if (t->mode == TFM_SKIN_RESIZE) { | ||||
| MVertSkin *vs = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MVERT_SKIN); | MVertSkin *vs = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MVERT_SKIN); | ||||
| if (vs) { | if (vs) { | ||||
| /* skin node size */ | /* skin node size */ | ||||
| td->ext = tx; | copy_v3_v3(td->ext[tdi].isize, vs->radius); | ||||
| copy_v3_v3(tx->isize, vs->radius); | td->ext[tdi].size = vs->radius; | ||||
| tx->size = vs->radius; | td->special[tdi].val = vs->radius; | ||||
| td->val = vs->radius; | |||||
| } | } | ||||
| else { | else { | ||||
| td->flag |= TD_SKIP; | td->basic[tdi].flag |= TD_SKIP; | ||||
| } | } | ||||
| } | } | ||||
| else if (t->mode == TFM_SHRINKFATTEN) { | else if (t->mode == TFM_SHRINKFATTEN) { | ||||
| td->ext = tx; | td->ext[tdi].isize[0] = BM_vert_calc_shell_factor_ex(eve, no, BM_ELEM_SELECT); | ||||
| tx->isize[0] = BM_vert_calc_shell_factor_ex(eve, no, BM_ELEM_SELECT); | |||||
| } | } | ||||
| } | } | ||||
| void createTransEditVerts(TransInfo *t) | void createTransEditVerts(TransInfo *t) | ||||
| { | { | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| TransData *tob = NULL; | |||||
| TransDataExtension *tx = NULL; | |||||
| BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); | BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); | ||||
| Mesh *me = tc->obedit->data; | Mesh *me = tc->obedit->data; | ||||
| BMesh *bm = em->bm; | BMesh *bm = em->bm; | ||||
| BMVert *eve; | BMVert *eve; | ||||
| BMIter iter; | BMIter iter; | ||||
| float(*mappedcos)[3] = NULL, (*quats)[4] = NULL; | float(*mappedcos)[3] = NULL, (*quats)[4] = NULL; | ||||
| float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL; | float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL; | ||||
| float *dists = NULL; | float *dists = NULL; | ||||
| ▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | if (mirror_bitmap) { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| BLI_assert(data_len != 0); | BLI_assert(data_len != 0); | ||||
| tc->data_len = data_len; | tc->data_len = data_len; | ||||
| tc->data = tob = MEM_callocN(data_len * sizeof(TransData), "TransObData(Mesh EditMode)"); | eTransDataDescr descriptor = TD_BASIC_COMP; | ||||
| if (ELEM(t->mode, TFM_SKIN_RESIZE, TFM_SHRINKFATTEN)) { | if (t->mode == TFM_SHRINKFATTEN || | ||||
| /* warning, this is overkill, we only need 2 extra floats, | (t->mode == TFM_SKIN_RESIZE && CustomData_has_layer(&em->bm->vdata, CD_MVERT_SKIN))) { | ||||
| /* warning, `TD_EXT` is overkill, we only need 2 extra floats, | |||||
| * but this stores loads of extra stuff, for TFM_SHRINKFATTEN its even more overkill | * but this stores loads of extra stuff, for TFM_SHRINKFATTEN its even more overkill | ||||
| * since we may not use the 'alt' transform mode to maintain shell thickness, | * since we may not use the 'alt' transform mode to maintain shell thickness, | ||||
| * but with generic transform code its hard to lazy init vars */ | * but with generic transform code its hard to lazy init vars */ | ||||
| tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), | descriptor |= TD_EXT; | ||||
| "TransObData ext"); | |||||
| } | } | ||||
| TransData *td = tc->data = transform_data_alloc(tc->data_len, descriptor); | |||||
| int tdi = 0; | |||||
| copy_m3_m4(mtx, tc->obedit->obmat); | copy_m3_m4(mtx, tc->obedit->obmat); | ||||
| /* we use a pseudo-inverse so that when one of the axes is scaled to 0, | /* we use a pseudo-inverse so that when one of the axes is scaled to 0, | ||||
| * matrix inversion still works and we can still moving along the other */ | * matrix inversion still works and we can still moving along the other */ | ||||
| pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); | pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); | ||||
| if (prop_mode & T_PROP_CONNECTED) { | if (prop_mode & T_PROP_CONNECTED) { | ||||
| editmesh_set_connectivity_distance(em->bm, mtx, dists, dists_index); | editmesh_set_connectivity_distance(em->bm, mtx, dists, dists_index); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) { | ||||
| int island_index = -1; | int island_index = -1; | ||||
| if (island_data.island_vert_map) { | if (island_data.island_vert_map) { | ||||
| const int connected_index = (dists_index && dists_index[a] != -1) ? dists_index[a] : a; | const int connected_index = (dists_index && dists_index[a] != -1) ? dists_index[a] : a; | ||||
| island_index = island_data.island_vert_map[connected_index]; | island_index = island_data.island_vert_map[connected_index]; | ||||
| } | } | ||||
| /* Do not use the island center in case we are using islands | /* Do not use the island center in case we are using islands | ||||
| * only to get axis for snap/rotate to normal... */ | * only to get axis for snap/rotate to normal... */ | ||||
| VertsToTransData(t, tob, tx, em, eve, bweight, &island_data, island_index, is_snap_rotate); | VertsToTransData(t, td, tdi, em, eve, bweight, &island_data, island_index, is_snap_rotate); | ||||
| if (tx) { | |||||
| tx++; | |||||
| } | |||||
| /* selected */ | /* selected */ | ||||
| if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { | if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { | ||||
| tob->flag |= TD_SELECTED; | td->basic[tdi].flag |= TD_SELECTED; | ||||
| } | } | ||||
| if (prop_mode) { | if (prop_mode) { | ||||
| if (prop_mode & T_PROP_CONNECTED) { | if (prop_mode & T_PROP_CONNECTED) { | ||||
| tob->dist = dists[a]; | td->prop[tdi].dist = dists[a]; | ||||
| } | } | ||||
| else { | else { | ||||
| tob->flag |= TD_NOTCONNECTED; | td->basic[tdi].flag |= TD_NOTCONNECTED; | ||||
| tob->dist = FLT_MAX; | td->prop[tdi].dist = FLT_MAX; | ||||
| } | } | ||||
| } | } | ||||
| /* CrazySpace */ | /* CrazySpace */ | ||||
| const bool use_quats = quats && BM_elem_flag_test(eve, BM_ELEM_TAG); | const bool use_quats = quats && BM_elem_flag_test(eve, BM_ELEM_TAG); | ||||
| if (use_quats || defmats) { | if (use_quats || defmats) { | ||||
| float mat[3][3], qmat[3][3], imat[3][3]; | float mat[3][3], qmat[3][3], imat[3][3]; | ||||
| Show All 9 Lines | BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) { | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| mul_m3_m3m3(mat, mtx, defmats[a]); | mul_m3_m3m3(mat, mtx, defmats[a]); | ||||
| } | } | ||||
| invert_m3_m3(imat, mat); | invert_m3_m3(imat, mat); | ||||
| copy_m3_m3(tob->smtx, imat); | copy_m3_m3(td->space[tdi].smtx, imat); | ||||
| copy_m3_m3(tob->mtx, mat); | copy_m3_m3(td->space[tdi].mtx, mat); | ||||
| } | } | ||||
| else { | else { | ||||
| copy_m3_m3(tob->smtx, smtx); | copy_m3_m3(td->space[tdi].smtx, smtx); | ||||
| copy_m3_m3(tob->mtx, mtx); | copy_m3_m3(td->space[tdi].mtx, mtx); | ||||
| } | } | ||||
| if (tc->mirror.use_mirror_any) { | if (tc->mirror.use_mirror_any) { | ||||
| if (tc->mirror.axis_x && fabsf(tob->loc[0]) < TRANSFORM_MAXDIST_MIRROR) { | if (tc->mirror.axis_x && fabsf(td->basic[tdi].loc[0]) < TRANSFORM_MAXDIST_MIRROR) { | ||||
| tob->flag |= TD_MIRROR_EDGE_X; | td->basic[tdi].flag |= TD_MIRROR_EDGE_X; | ||||
| } | } | ||||
| if (tc->mirror.axis_y && fabsf(tob->loc[1]) < TRANSFORM_MAXDIST_MIRROR) { | if (tc->mirror.axis_y && fabsf(td->basic[tdi].loc[1]) < TRANSFORM_MAXDIST_MIRROR) { | ||||
| tob->flag |= TD_MIRROR_EDGE_Y; | td->basic[tdi].flag |= TD_MIRROR_EDGE_Y; | ||||
| } | } | ||||
| if (tc->mirror.axis_z && fabsf(tob->loc[2]) < TRANSFORM_MAXDIST_MIRROR) { | if (tc->mirror.axis_z && fabsf(td->basic[tdi].loc[2]) < TRANSFORM_MAXDIST_MIRROR) { | ||||
| tob->flag |= TD_MIRROR_EDGE_Z; | td->basic[tdi].flag |= TD_MIRROR_EDGE_Z; | ||||
| } | } | ||||
| } | } | ||||
| tob++; | tdi++; | ||||
| } | } | ||||
| } | } | ||||
| if (island_data.center) { | if (island_data.center) { | ||||
| MEM_freeN(island_data.center); | MEM_freeN(island_data.center); | ||||
| } | } | ||||
| if (island_data.axismtx) { | if (island_data.axismtx) { | ||||
| ▲ Show 20 Lines • Show All 216 Lines • ▼ Show 20 Lines | if (use_origfaces) { | ||||
| int data_len = tc->data_len + tc->mirror.data_len; | int data_len = tc->data_len + tc->mirror.data_len; | ||||
| struct GHash *origverts = BLI_ghash_ptr_new_ex(__func__, data_len); | struct GHash *origverts = BLI_ghash_ptr_new_ex(__func__, data_len); | ||||
| tcld->origverts = origverts; | tcld->origverts = origverts; | ||||
| struct TransCustomDataLayerVert *tcld_vert, *tcld_vert_iter; | struct TransCustomDataLayerVert *tcld_vert, *tcld_vert_iter; | ||||
| tcld_vert = BLI_memarena_alloc(tcld->arena, data_len * sizeof(*tcld_vert)); | tcld_vert = BLI_memarena_alloc(tcld->arena, data_len * sizeof(*tcld_vert)); | ||||
| tcld_vert_iter = &tcld_vert[0]; | tcld_vert_iter = &tcld_vert[0]; | ||||
| TransData *tob; | TransData *td = tc->data; | ||||
| for (i = tc->data_len, tob = tc->data; i--; tob++, tcld_vert_iter++) { | int tdi = 0; | ||||
| BMVert *v = tob->extra; | for (i = tc->data_len; i--; tcld_vert_iter++, tdi++) { | ||||
| BMVert *v = td->basic[tdi].extra; | |||||
| create_trans_vert_customdata_layer(v, tcld, tcld_vert_iter); | create_trans_vert_customdata_layer(v, tcld, tcld_vert_iter); | ||||
| } | } | ||||
| TransDataMirror *tdm; | TransDataMirror *tdm; | ||||
| for (i = tc->mirror.data_len, tdm = tc->mirror.data; i--; tdm++, tcld_vert_iter++) { | for (i = tc->mirror.data_len, tdm = tc->mirror.data; i--; tdm++, tcld_vert_iter++) { | ||||
| BMVert *v = tdm->extra; | BMVert *v = tdm->extra; | ||||
| create_trans_vert_customdata_layer(v, tcld, tcld_vert_iter); | create_trans_vert_customdata_layer(v, tcld, tcld_vert_iter); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 169 Lines • ▼ Show 20 Lines | |||||
| * | * | ||||
| * \{ */ | * \{ */ | ||||
| void createTransEdge(TransInfo *t) | void createTransEdge(TransInfo *t) | ||||
| { | { | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); | BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); | ||||
| TransData *td = NULL; | |||||
| BMEdge *eed; | BMEdge *eed; | ||||
| BMIter iter; | BMIter iter; | ||||
| float mtx[3][3], smtx[3][3]; | float mtx[3][3], smtx[3][3]; | ||||
| int count = 0, countsel = 0; | int count = 0, countsel = 0; | ||||
| const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0; | const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0; | ||||
| int cd_edge_float_offset; | int cd_edge_float_offset; | ||||
| BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { | BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { | ||||
| Show All 14 Lines | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| if (is_prop_edit) { | if (is_prop_edit) { | ||||
| tc->data_len = count; | tc->data_len = count; | ||||
| } | } | ||||
| else { | else { | ||||
| tc->data_len = countsel; | tc->data_len = countsel; | ||||
| } | } | ||||
| td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransCrease"); | TransData *td = tc->data = transform_data_alloc(tc->data_len, TD_BASIC_COMP); | ||||
| int tdi = 0; | |||||
| copy_m3_m4(mtx, tc->obedit->obmat); | copy_m3_m4(mtx, tc->obedit->obmat); | ||||
| pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); | pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); | ||||
| /* create data we need */ | /* create data we need */ | ||||
| if (t->mode == TFM_BWEIGHT) { | if (t->mode == TFM_BWEIGHT) { | ||||
| BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_BWEIGHT); | BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_BWEIGHT); | ||||
| cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT); | cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT); | ||||
| } | } | ||||
| else { // if (t->mode == TFM_CREASE) { | else { // if (t->mode == TFM_CREASE) { | ||||
| BLI_assert(t->mode == TFM_CREASE); | BLI_assert(t->mode == TFM_CREASE); | ||||
| BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_CREASE); | BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_CREASE); | ||||
| cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE); | cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE); | ||||
| } | } | ||||
| BLI_assert(cd_edge_float_offset != -1); | BLI_assert(cd_edge_float_offset != -1); | ||||
| BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { | BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { | ||||
| if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && | if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && | ||||
| (BM_elem_flag_test(eed, BM_ELEM_SELECT) || is_prop_edit)) { | (BM_elem_flag_test(eed, BM_ELEM_SELECT) || is_prop_edit)) { | ||||
| float *fl_ptr; | float *fl_ptr; | ||||
| /* need to set center for center calculations */ | /* need to set center for center calculations */ | ||||
| mid_v3_v3v3(td->center, eed->v1->co, eed->v2->co); | mid_v3_v3v3(td->center[tdi], eed->v1->co, eed->v2->co); | ||||
| td->loc = NULL; | td->basic[tdi].loc = NULL; | ||||
| if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { | if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { | ||||
| td->flag = TD_SELECTED; | td->basic[tdi].flag = TD_SELECTED; | ||||
| } | } | ||||
| else { | else { | ||||
| td->flag = 0; | td->basic[tdi].flag = 0; | ||||
| } | } | ||||
| copy_m3_m3(td->smtx, smtx); | copy_m3_m3(td->space[tdi].smtx, smtx); | ||||
| copy_m3_m3(td->mtx, mtx); | copy_m3_m3(td->space[tdi].mtx, mtx); | ||||
| td->ext = NULL; | |||||
| fl_ptr = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_float_offset); | fl_ptr = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_float_offset); | ||||
| td->val = fl_ptr; | td->special[tdi].val = fl_ptr; | ||||
| td->ival = *fl_ptr; | td->special[tdi].ival = *fl_ptr; | ||||
| td++; | tdi++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name UVs Transform Creation | /** \name UVs Transform Creation | ||||
| * | * | ||||
| * \{ */ | * \{ */ | ||||
| static void UVsToTransData(const float aspect[2], | static void UVsToTransData(const float aspect[2], | ||||
| TransData *td, | const TransData *td, | ||||
| const int tdi, | |||||
| TransData2D *td2d, | TransData2D *td2d, | ||||
| float *uv, | float *uv, | ||||
| const float *center, | const float *center, | ||||
| bool selected) | bool selected) | ||||
| { | { | ||||
| /* uv coords are scaled by aspects. this is needed for rotations and | /* uv coords are scaled by aspects. this is needed for rotations and | ||||
| * proportional editing to be consistent with the stretched uv coords | * proportional editing to be consistent with the stretched uv coords | ||||
| * that are displayed. this also means that for display and numinput, | * that are displayed. this also means that for display and numinput, | ||||
| * and when the uv coords are flushed, these are converted each time */ | * and when the uv coords are flushed, these are converted each time */ | ||||
| td2d->loc[0] = uv[0] * aspect[0]; | td2d->loc[0] = uv[0] * aspect[0]; | ||||
| td2d->loc[1] = uv[1] * aspect[1]; | td2d->loc[1] = uv[1] * aspect[1]; | ||||
| td2d->loc[2] = 0.0f; | td2d->loc[2] = 0.0f; | ||||
| td2d->loc2d = uv; | td2d->loc2d = uv; | ||||
| td->flag = 0; | td->basic[tdi].flag = 0; | ||||
| td->loc = td2d->loc; | td->basic[tdi].loc = td2d->loc; | ||||
| copy_v2_v2(td->center, center ? center : td->loc); | copy_v2_v2(td->center[tdi], center ? center : td2d->loc); | ||||
| td->center[2] = 0.0f; | td->center[tdi][2] = 0.0f; | ||||
| copy_v3_v3(td->iloc, td->loc); | copy_v3_v3(td->basic[tdi].iloc, td2d->loc); | ||||
| memset(td->axismtx, 0, sizeof(td->axismtx)); | const float axismtx[3][3] = {{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}; | ||||
| td->axismtx[2][2] = 1.0f; | copy_m3_m3(td->space[tdi].axismtx, axismtx); | ||||
| td->ext = NULL; | td->special[tdi].val = NULL; | ||||
| td->val = NULL; | |||||
| if (selected) { | if (selected) { | ||||
| td->flag |= TD_SELECTED; | td->basic[tdi].flag |= TD_SELECTED; | ||||
| td->dist = 0.0; | td->prop[tdi].dist = 0.0; | ||||
| } | } | ||||
| else { | else { | ||||
| td->dist = FLT_MAX; | td->prop[tdi].dist = FLT_MAX; | ||||
| } | } | ||||
| unit_m3(td->mtx); | unit_m3(td->space[tdi].mtx); | ||||
| unit_m3(td->smtx); | unit_m3(td->space[tdi].smtx); | ||||
| } | } | ||||
| void createTransUVs(bContext *C, TransInfo *t) | void createTransUVs(bContext *C, TransInfo *t) | ||||
| { | { | ||||
| SpaceImage *sima = CTX_wm_space_image(C); | SpaceImage *sima = CTX_wm_space_image(C); | ||||
| Scene *scene = t->scene; | Scene *scene = t->scene; | ||||
| ToolSettings *ts = CTX_data_tool_settings(C); | ToolSettings *ts = CTX_data_tool_settings(C); | ||||
| const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0; | const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0; | ||||
| const bool is_prop_connected = (t->flag & T_PROP_CONNECTED) != 0; | const bool is_prop_connected = (t->flag & T_PROP_CONNECTED) != 0; | ||||
| const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS); | const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS); | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| TransData *td = NULL; | |||||
| TransData2D *td2d = NULL; | TransData2D *td2d = NULL; | ||||
| BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); | BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); | ||||
| BMFace *efa; | BMFace *efa; | ||||
| BMIter iter, liter; | BMIter iter, liter; | ||||
| UvElementMap *elementmap = NULL; | UvElementMap *elementmap = NULL; | ||||
| BLI_bitmap *island_enabled = NULL; | BLI_bitmap *island_enabled = NULL; | ||||
| struct { | struct { | ||||
| float co[2]; | float co[2]; | ||||
| ▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | if (is_island_center) { | ||||
| int i; | int i; | ||||
| for (i = 0; i < elementmap->totalIslands; i++) { | for (i = 0; i < elementmap->totalIslands; i++) { | ||||
| mul_v2_fl(island_center[i].co, 1.0f / island_center[i].co_num); | mul_v2_fl(island_center[i].co, 1.0f / island_center[i].co_num); | ||||
| mul_v2_v2(island_center[i].co, t->aspect); | mul_v2_v2(island_center[i].co, t->aspect); | ||||
| } | } | ||||
| } | } | ||||
| TransData *td; | |||||
| tc->data_len = (is_prop_edit) ? count : countsel; | tc->data_len = (is_prop_edit) ? count : countsel; | ||||
| tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(UV Editing)"); | tc->data = td = transform_data_alloc(tc->data_len, TD_BASIC_COMP); | ||||
| /* for each 2d uv coord a 3d vector is allocated, so that they can be | /* for each 2d uv coord a 3d vector is allocated, so that they can be | ||||
| * treated just as if they were 3d verts */ | * treated just as if they were 3d verts */ | ||||
| tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransObData2D(UV Editing)"); | tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransObData2D(UV Editing)"); | ||||
| if (sima->flag & SI_CLIP_UV) { | if (sima->flag & SI_CLIP_UV) { | ||||
| t->flag |= T_CLIP_UV; | t->flag |= T_CLIP_UV; | ||||
| } | } | ||||
| td = tc->data; | int tdi = 0; | ||||
| td2d = tc->data_2d; | td2d = tc->data_2d; | ||||
| BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { | BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { | ||||
| BMLoop *l; | BMLoop *l; | ||||
| if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) { | if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { | BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { | ||||
| Show All 18 Lines | BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { | ||||
| if (is_island_center) { | if (is_island_center) { | ||||
| center = island_center[element->island].co; | center = island_center[element->island].co; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| BM_elem_flag_enable(l, BM_ELEM_TAG); | BM_elem_flag_enable(l, BM_ELEM_TAG); | ||||
| luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); | luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); | ||||
| UVsToTransData(t->aspect, td++, td2d++, luv->uv, center, selected); | UVsToTransData(t->aspect, td, tdi, td2d++, luv->uv, center, selected); | ||||
| tdi++; | |||||
| } | } | ||||
| } | } | ||||
| if (is_prop_connected) { | if (is_prop_connected) { | ||||
| tc->data_len -= count_rejected; | tc->data_len -= count_rejected; | ||||
| } | } | ||||
| if (sima->flag & SI_LIVE_UNWRAP) { | if (sima->flag & SI_LIVE_UNWRAP) { | ||||
| ▲ Show 20 Lines • Show All 74 Lines • Show Last 20 Lines | |||||