Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/transform/transform_conversions.c
| Show First 20 Lines • Show All 124 Lines • ▼ Show 20 Lines | |||||
| #include "bmesh.h" | #include "bmesh.h" | ||||
| /** | /** | ||||
| * Transforming around ourselves is no use, fallback to individual origins, | * Transforming around ourselves is no use, fallback to individual origins, | ||||
| * useful for curve/armatures. | * useful for curve/armatures. | ||||
| */ | */ | ||||
| static void transform_around_single_fallback(TransInfo *t) | static void transform_around_single_fallback(TransInfo *t) | ||||
| { | { | ||||
| if ((t->total == 1) && | if ((t->data_len_all == 1) && | ||||
| (ELEM(t->around, V3D_AROUND_CENTER_BOUNDS, V3D_AROUND_CENTER_MEAN, V3D_AROUND_ACTIVE)) && | (ELEM(t->around, V3D_AROUND_CENTER_BOUNDS, V3D_AROUND_CENTER_MEAN, V3D_AROUND_ACTIVE)) && | ||||
| (ELEM(t->mode, TFM_RESIZE, TFM_ROTATION, TFM_TRACKBALL))) | (ELEM(t->mode, TFM_RESIZE, TFM_ROTATION, TFM_TRACKBALL))) | ||||
| { | { | ||||
| t->around = V3D_AROUND_LOCAL_ORIGINS; | t->around = V3D_AROUND_LOCAL_ORIGINS; | ||||
| } | } | ||||
| } | } | ||||
| /* when transforming islands */ | /* when transforming islands */ | ||||
| Show All 24 Lines | static int trans_data_compare_rdist(const void *a, const void *b) | ||||
| if (td_a->rdist < td_b->rdist) return -1; | if (td_a->rdist < td_b->rdist) return -1; | ||||
| else if (td_a->rdist > td_b->rdist) return 1; | else if (td_a->rdist > td_b->rdist) return 1; | ||||
| else return 0; | else return 0; | ||||
| } | } | ||||
| void sort_trans_data_dist(TransInfo *t) | void sort_trans_data_dist(TransInfo *t) | ||||
| { | { | ||||
| TransData *start = t->data; | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| TransData *start = tc->data; | |||||
| int i; | int i; | ||||
| for (i = 0; i < t->total && start->flag & TD_SELECTED; i++) | for (i = 0; i < tc->data_len && start->flag & TD_SELECTED; i++) { | ||||
| start++; | start++; | ||||
| } | |||||
| if (i < t->total) { | if (i < tc->data_len) { | ||||
| if (t->flag & T_PROP_CONNECTED) | if (t->flag & T_PROP_CONNECTED) | ||||
| qsort(start, t->total - i, sizeof(TransData), trans_data_compare_dist); | qsort(start, tc->data_len - i, sizeof(TransData), trans_data_compare_dist); | ||||
| else | else | ||||
| qsort(start, t->total - i, sizeof(TransData), trans_data_compare_rdist); | qsort(start, tc->data_len - i, sizeof(TransData), trans_data_compare_rdist); | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| static void sort_trans_data(TransInfo *t) | static void sort_trans_data(TransInfo *t) | ||||
| { | { | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | |||||
| TransData *sel, *unsel; | TransData *sel, *unsel; | ||||
| TransData temp; | TransData temp; | ||||
| unsel = t->data; | unsel = tc->data; | ||||
| sel = t->data; | sel = tc->data; | ||||
| sel += t->total - 1; | sel += tc->data_len - 1; | ||||
| while (sel > unsel) { | while (sel > unsel) { | ||||
| while (unsel->flag & TD_SELECTED) { | while (unsel->flag & TD_SELECTED) { | ||||
| unsel++; | unsel++; | ||||
| if (unsel == sel) { | if (unsel == sel) { | ||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| while (!(sel->flag & TD_SELECTED)) { | while (!(sel->flag & TD_SELECTED)) { | ||||
| sel--; | sel--; | ||||
| if (unsel == sel) { | if (unsel == sel) { | ||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| temp = *unsel; | temp = *unsel; | ||||
| *unsel = *sel; | *unsel = *sel; | ||||
| *sel = temp; | *sel = temp; | ||||
| sel--; | sel--; | ||||
| unsel++; | unsel++; | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| /* distance calculated from not-selected vertex to nearest selected vertex | /* distance calculated from not-selected vertex to nearest selected vertex | ||||
| * warning; this is loops inside loop, has minor N^2 issues, but by sorting list it is OK */ | * warning; this is loops inside loop, has minor N^2 issues, but by sorting list it is OK */ | ||||
| static void set_prop_dist(TransInfo *t, const bool with_dist) | static void set_prop_dist(TransInfo *t, const bool with_dist) | ||||
| { | { | ||||
| TransData *tob; | |||||
| int a; | int a; | ||||
| float _proj_vec[3]; | float _proj_vec[3]; | ||||
| const float *proj_vec = NULL; | const float *proj_vec = NULL; | ||||
| /* support for face-islands */ | /* support for face-islands */ | ||||
| const bool use_island = transdata_check_local_islands(t, t->around); | const bool use_island = transdata_check_local_islands(t, t->around); | ||||
| if (t->flag & T_PROP_PROJECTED) { | if (t->flag & T_PROP_PROJECTED) { | ||||
| if (t->spacetype == SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW) { | if (t->spacetype == SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW) { | ||||
| RegionView3D *rv3d = t->ar->regiondata; | RegionView3D *rv3d = t->ar->regiondata; | ||||
| normalize_v3_v3(_proj_vec, rv3d->viewinv[2]); | normalize_v3_v3(_proj_vec, rv3d->viewinv[2]); | ||||
| proj_vec = _proj_vec; | proj_vec = _proj_vec; | ||||
| } | } | ||||
| } | } | ||||
| for (a = 0, tob = t->data; a < t->total; a++, tob++) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| TransData *tob = tc->data; | |||||
| for (a = 0; a < tc->data_len; a++, tob++) { | |||||
| tob->rdist = 0.0f; // init, it was mallocced | tob->rdist = 0.0f; // init, it was mallocced | ||||
| if ((tob->flag & TD_SELECTED) == 0) { | if ((tob->flag & TD_SELECTED) == 0) { | ||||
| TransData *td; | TransData *td; | ||||
| int i; | int i; | ||||
| float dist_sq, vec[3]; | float dist_sq, vec[3]; | ||||
| tob->rdist = -1.0f; // signal for next loop | tob->rdist = -1.0f; // signal for next loop | ||||
| for (i = 0, td = t->data; i < t->total; i++, td++) { | for (i = 0, td = tc->data; i < tc->data_len; i++, td++) { | ||||
| if (td->flag & TD_SELECTED) { | if (td->flag & TD_SELECTED) { | ||||
| if (use_island) { | if (use_island) { | ||||
| sub_v3_v3v3(vec, tob->iloc, td->iloc); | sub_v3_v3v3(vec, tob->iloc, td->iloc); | ||||
| } | } | ||||
| else { | else { | ||||
| sub_v3_v3v3(vec, tob->center, td->center); | sub_v3_v3v3(vec, tob->center, td->center); | ||||
| } | } | ||||
| mul_m3_v3(tob->mtx, vec); | mul_m3_v3(tob->mtx, vec); | ||||
| Show All 17 Lines | if ((tob->flag & TD_SELECTED) == 0) { | ||||
| break; /* by definition transdata has selected items in beginning */ | break; /* by definition transdata has selected items in beginning */ | ||||
| } | } | ||||
| } | } | ||||
| if (with_dist) { | if (with_dist) { | ||||
| tob->dist = tob->rdist; | tob->dist = tob->rdist; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| /* ************************** CONVERSIONS ************************* */ | /* ************************** CONVERSIONS ************************* */ | ||||
| /* ********************* texture space ********* */ | /* ********************* texture space ********* */ | ||||
| static void createTransTexspace(TransInfo *t) | static void createTransTexspace(TransInfo *t) | ||||
| { | { | ||||
| ViewLayer *view_layer = t->view_layer; | ViewLayer *view_layer = t->view_layer; | ||||
| TransData *td; | TransData *td; | ||||
| Object *ob; | Object *ob; | ||||
| ID *id; | ID *id; | ||||
| short *texflag; | short *texflag; | ||||
| ob = OBACT(view_layer); | ob = OBACT(view_layer); | ||||
| if (ob == NULL) { // Shouldn't logically happen, but still... | if (ob == NULL) { // Shouldn't logically happen, but still... | ||||
| t->total = 0; | t->data_len_all = 0; | ||||
| return; | return; | ||||
| } | } | ||||
| id = ob->data; | id = ob->data; | ||||
| if (id == NULL || !ELEM(GS(id->name), ID_ME, ID_CU, ID_MB)) { | if (id == NULL || !ELEM(GS(id->name), ID_ME, ID_CU, ID_MB)) { | ||||
| BKE_report(t->reports, RPT_ERROR, "Unsupported object type for text-space transform"); | BKE_report(t->reports, RPT_ERROR, "Unsupported object type for text-space transform"); | ||||
| t->total = 0; | t->data_len_all = 0; | ||||
| return; | return; | ||||
| } | } | ||||
| if (BKE_object_obdata_is_libdata(ob)) { | if (BKE_object_obdata_is_libdata(ob)) { | ||||
| BKE_report(t->reports, RPT_ERROR, "Linked data can't text-space transform"); | BKE_report(t->reports, RPT_ERROR, "Linked data can't text-space transform"); | ||||
| t->total = 0; | t->data_len_all = 0; | ||||
| return; | return; | ||||
| } | } | ||||
| t->total = 1; | |||||
| td = t->data = MEM_callocN(sizeof(TransData), "TransTexspace"); | { | ||||
| td->ext = t->ext = MEM_callocN(sizeof(TransDataExtension), "TransTexspace"); | TransDataContainer *tc = t->data_container = MEM_callocN(sizeof(*t->data_container), __func__); | ||||
| tc->data_len = 1; | |||||
| td = tc->data = MEM_callocN(sizeof(TransData), "TransTexspace"); | |||||
| td->ext = tc->data_ext = MEM_callocN(sizeof(TransDataExtension), "TransTexspace"); | |||||
| } | |||||
| t->data_len_all = 1; | |||||
| td->flag = TD_SELECTED; | td->flag = TD_SELECTED; | ||||
| copy_v3_v3(td->center, ob->obmat[3]); | copy_v3_v3(td->center, ob->obmat[3]); | ||||
| td->ob = ob; | td->ob = ob; | ||||
| copy_m3_m4(td->mtx, ob->obmat); | copy_m3_m4(td->mtx, ob->obmat); | ||||
| copy_m3_m4(td->axismtx, ob->obmat); | copy_m3_m4(td->axismtx, ob->obmat); | ||||
| normalize_m3(td->axismtx); | normalize_m3(td->axismtx); | ||||
| pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON); | pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON); | ||||
| if (BKE_object_obdata_texspace_get(ob, &texflag, &td->loc, &td->ext->size, &td->ext->rot)) { | if (BKE_object_obdata_texspace_get(ob, &texflag, &td->loc, &td->ext->size, &td->ext->rot)) { | ||||
| ob->dtx |= OB_TEXSPACE; | ob->dtx |= OB_TEXSPACE; | ||||
| *texflag &= ~ME_AUTOSPACE; | *texflag &= ~ME_AUTOSPACE; | ||||
| } | } | ||||
| copy_v3_v3(td->iloc, td->loc); | copy_v3_v3(td->iloc, td->loc); | ||||
| copy_v3_v3(td->ext->irot, td->ext->rot); | copy_v3_v3(td->ext->irot, td->ext->rot); | ||||
| copy_v3_v3(td->ext->isize, td->ext->size); | copy_v3_v3(td->ext->isize, td->ext->size); | ||||
| } | } | ||||
| /* ********************* edge (for crease) ***** */ | /* ********************* edge (for crease) ***** */ | ||||
| static void createTransEdge(TransInfo *t) | static void createTransEdge(TransInfo *t) | ||||
| { | { | ||||
| BMEditMesh *em = BKE_editmesh_from_object(t->obedit); | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); | |||||
| TransData *td = NULL; | 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) { | ||||
| if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { | if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { | ||||
| if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) countsel++; | if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) countsel++; | ||||
| if (is_prop_edit) count++; | if (is_prop_edit) count++; | ||||
| } | } | ||||
| } | } | ||||
| if (countsel == 0) | if (countsel == 0) { | ||||
| return; | tc->data_len = 0; | ||||
| continue; | |||||
| } | |||||
| if (is_prop_edit) { | if (is_prop_edit) { | ||||
| t->total = count; | tc->data_len = count; | ||||
| } | } | ||||
| else { | else { | ||||
| t->total = countsel; | tc->data_len = countsel; | ||||
| } | } | ||||
| td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransCrease"); | td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransCrease"); | ||||
| copy_m3_m4(mtx, t->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(t->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(t->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) && (BM_elem_flag_test(eed, BM_ELEM_SELECT) || is_prop_edit)) { | if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && (BM_elem_flag_test(eed, BM_ELEM_SELECT) || is_prop_edit)) { | ||||
| float *fl_ptr; | float *fl_ptr; | ||||
| Show All 13 Lines | if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && (BM_elem_flag_test(eed, BM_ELEM_SELECT) || is_prop_edit)) { | ||||
| 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->val = fl_ptr; | ||||
| td->ival = *fl_ptr; | td->ival = *fl_ptr; | ||||
| td++; | td++; | ||||
| } | } | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| /* ********************* pose mode ************* */ | /* ********************* pose mode ************* */ | ||||
| static bKinematicConstraint *has_targetless_ik(bPoseChannel *pchan) | static bKinematicConstraint *has_targetless_ik(bPoseChannel *pchan) | ||||
| { | { | ||||
| bConstraint *con = pchan->constraints.first; | bConstraint *con = pchan->constraints.first; | ||||
| ▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | if (data && (data->flag & CONSTRAINT_IK_AUTO)) { | ||||
| apply = 1; | apply = 1; | ||||
| data->flag &= ~CONSTRAINT_IK_AUTO; | data->flag &= ~CONSTRAINT_IK_AUTO; | ||||
| } | } | ||||
| } | } | ||||
| return apply; | return apply; | ||||
| } | } | ||||
| static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, TransData *td) | static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, TransDataContainer *tc, TransData *td) | ||||
| { | { | ||||
| Bone *bone = pchan->bone; | Bone *bone = pchan->bone; | ||||
| float pmat[3][3], omat[3][3]; | float pmat[3][3], omat[3][3]; | ||||
| float cmat[3][3], tmat[3][3]; | float cmat[3][3], tmat[3][3]; | ||||
| float vec[3]; | float vec[3]; | ||||
| copy_v3_v3(vec, pchan->pose_mat[3]); | copy_v3_v3(vec, pchan->pose_mat[3]); | ||||
| copy_v3_v3(td->center, vec); | copy_v3_v3(td->center, vec); | ||||
| ▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, TransDataContainer *tc, TransData *td) | ||||
| } | } | ||||
| /* for axismat we use bone's own transform */ | /* for axismat we use bone's own transform */ | ||||
| copy_m3_m4(pmat, pchan->pose_mat); | copy_m3_m4(pmat, pchan->pose_mat); | ||||
| mul_m3_m3m3(td->axismtx, omat, pmat); | mul_m3_m3m3(td->axismtx, omat, pmat); | ||||
| normalize_m3(td->axismtx); | normalize_m3(td->axismtx); | ||||
| if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) { | if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) { | ||||
| bArmature *arm = t->poseobj->data; | bArmature *arm = tc->poseobj->data; | ||||
| if ((t->mode == TFM_BONE_ENVELOPE_DIST) || (arm->drawtype == ARM_ENVELOPE)) { | if ((t->mode == TFM_BONE_ENVELOPE_DIST) || (arm->drawtype == ARM_ENVELOPE)) { | ||||
| td->loc = NULL; | td->loc = NULL; | ||||
| td->val = &bone->dist; | td->val = &bone->dist; | ||||
| td->ival = bone->dist; | td->ival = bone->dist; | ||||
| } | } | ||||
| else { | else { | ||||
| // abusive storage of scale in the loc pointer :) | // abusive storage of scale in the loc pointer :) | ||||
| ▲ Show 20 Lines • Show All 177 Lines • ▼ Show 20 Lines | if (*chainlen > 0) { | ||||
| (*chainlen)--; | (*chainlen)--; | ||||
| } | } | ||||
| else { | else { | ||||
| /* IK length did not change, skip updates. */ | /* IK length did not change, skip updates. */ | ||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| /* sanity checks (don't assume t->poseobj is set, or that it is an armature) */ | |||||
| if (ELEM(NULL, t->poseobj, t->poseobj->pose)) | |||||
| return; | |||||
| /* apply to all pose-channels */ | /* apply to all pose-channels */ | ||||
| bool changed = false; | bool changed = false; | ||||
| for (pchan = t->poseobj->pose->chanbase.first; pchan; pchan = pchan->next) { | |||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | |||||
| /* sanity checks (don't assume t->poseobj is set, or that it is an armature) */ | |||||
| if (ELEM(NULL, tc->poseobj, tc->poseobj->pose)) { | |||||
| continue; | |||||
| } | |||||
| for (pchan = tc->poseobj->pose->chanbase.first; pchan; pchan = pchan->next) { | |||||
| changed |= pchan_autoik_adjust(pchan, *chainlen); | changed |= pchan_autoik_adjust(pchan, *chainlen); | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| if (changed) { | if (changed) { | ||||
| /* TODO(sergey): Consider doing partial update only. */ | /* TODO(sergey): Consider doing partial update only. */ | ||||
| DEG_relations_tag_update(G.main); | DEG_relations_tag_update(G.main); | ||||
| } | } | ||||
| } | } | ||||
| /* frees temporal IKs */ | /* frees temporal IKs */ | ||||
| static void pose_grab_with_ik_clear(Object *ob) | static void pose_grab_with_ik_clear(Object *ob) | ||||
| ▲ Show 20 Lines • Show All 191 Lines • ▼ Show 20 Lines | if (tot_ik) { | ||||
| /* TODO(sergey): Consuder doing partial update only. */ | /* TODO(sergey): Consuder doing partial update only. */ | ||||
| DEG_relations_tag_update(G.main); | DEG_relations_tag_update(G.main); | ||||
| } | } | ||||
| return (tot_ik) ? 1 : 0; | return (tot_ik) ? 1 : 0; | ||||
| } | } | ||||
| /* only called with pose mode active object now */ | /** | ||||
| static void createTransPose(TransInfo *t, Object *ob) | * When objects array is NULL, use 't->data_container' as is. | ||||
| */ | |||||
| static void createTransPose(TransInfo *t, Object **objects, uint objects_len) | |||||
| { | { | ||||
| if (objects != NULL) { | |||||
| if (t->data_container) { | |||||
| MEM_freeN(t->data_container); | |||||
| } | |||||
| t->data_container = MEM_callocN(sizeof(*t->data_container) * objects_len, __func__); | |||||
| t->data_container_len = objects_len; | |||||
| int th_index; | |||||
| FOREACH_TRANS_DATA_CONTAINER_INDEX (t, tc, th_index) { | |||||
| tc->poseobj = objects[th_index]; | |||||
| } | |||||
| } | |||||
| t->data_len_all = 0; | |||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | |||||
| Object *ob = tc->poseobj; | |||||
| bArmature *arm; | bArmature *arm; | ||||
| bPoseChannel *pchan; | bPoseChannel *pchan; | ||||
| TransData *td; | TransData *td; | ||||
| TransDataExtension *tdx; | TransDataExtension *tdx; | ||||
| short ik_on = 0; | short ik_on = 0; | ||||
| int i; | int i; | ||||
| t->total = 0; | |||||
| /* check validity of state */ | /* check validity of state */ | ||||
| arm = BKE_armature_from_object(ob); | arm = BKE_armature_from_object(tc->poseobj); | ||||
| if ((arm == NULL) || (ob->pose == NULL)) return; | if ((arm == NULL) || (ob->pose == NULL)) { | ||||
| continue; | |||||
| } | |||||
| if (arm->flag & ARM_RESTPOS) { | if (arm->flag & ARM_RESTPOS) { | ||||
| if (ELEM(t->mode, TFM_DUMMY, TFM_BONESIZE) == 0) { | if (ELEM(t->mode, TFM_DUMMY, TFM_BONESIZE) == 0) { | ||||
| BKE_report(t->reports, RPT_ERROR, "Cannot change Pose when 'Rest Position' is enabled"); | BKE_report(t->reports, RPT_ERROR, "Cannot change Pose when 'Rest Position' is enabled"); | ||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| /* do we need to add temporal IK chains? */ | /* do we need to add temporal IK chains? */ | ||||
| if ((arm->flag & ARM_AUTO_IK) && t->mode == TFM_TRANSLATION) { | if ((arm->flag & ARM_AUTO_IK) && t->mode == TFM_TRANSLATION) { | ||||
| ik_on = pose_grab_with_ik(ob); | ik_on = pose_grab_with_ik(ob); | ||||
| if (ik_on) t->flag |= T_AUTOIK; | if (ik_on) t->flag |= T_AUTOIK; | ||||
| } | } | ||||
| /* set flags and count total (warning, can change transform to rotate) */ | /* set flags and count total (warning, can change transform to rotate) */ | ||||
| t->total = count_set_pose_transflags(&t->mode, t->around, ob); | tc->data_len = count_set_pose_transflags(&t->mode, t->around, ob); | ||||
| if (t->total == 0) return; | |||||
| t->flag |= T_POSE; | if (tc->data_len == 0) { | ||||
| t->poseobj = ob; /* we also allow non-active objects to be transformed, in weightpaint */ | continue; | ||||
| } | |||||
| /* disable PET, its not usable in pose mode yet [#32444] */ | tc->poseobj = ob; /* we also allow non-active objects to be transformed, in weightpaint */ | ||||
| t->flag &= ~T_PROP_EDIT_ALL; | |||||
| /* init trans data */ | /* init trans data */ | ||||
| td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransPoseBone"); | td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransPoseBone"); | ||||
| tdx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "TransPoseBoneExt"); | tdx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "TransPoseBoneExt"); | ||||
| for (i = 0; i < t->total; i++, td++, tdx++) { | for (i = 0; i < tc->data_len; i++, td++, tdx++) { | ||||
| td->ext = tdx; | td->ext = tdx; | ||||
| td->val = NULL; | td->val = NULL; | ||||
| } | } | ||||
| /* use pose channels to fill trans data */ | /* use pose channels to fill trans data */ | ||||
| td = t->data; | td = tc->data; | ||||
| for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { | for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { | ||||
| if (pchan->bone->flag & BONE_TRANSFORM) { | if (pchan->bone->flag & BONE_TRANSFORM) { | ||||
| add_pose_transdata(t, pchan, ob, td); | add_pose_transdata(t, pchan, ob, tc, td); | ||||
| td++; | td++; | ||||
| } | } | ||||
| } | } | ||||
| if (td != (t->data + t->total)) { | if (td != (tc->data + tc->data_len)) { | ||||
| BKE_report(t->reports, RPT_DEBUG, "Bone selection count error"); | BKE_report(t->reports, RPT_DEBUG, "Bone selection count error"); | ||||
| } | } | ||||
| /* initialize initial auto=ik chainlen's? */ | /* initialize initial auto=ik chainlen's? */ | ||||
| if (ik_on) transform_autoik_update(t, 0); | if (ik_on) transform_autoik_update(t, 0); | ||||
| } // FIXME(indent) | |||||
| t->flag |= T_POSE; | |||||
| /* disable PET, its not usable in pose mode yet [#32444] */ | |||||
| t->flag &= ~T_PROP_EDIT_ALL; | |||||
| } | } | ||||
| void restoreBones(TransInfo *t) | void restoreBones(TransDataContainer *tc) | ||||
| { | { | ||||
| bArmature *arm = t->obedit->data; | bArmature *arm = tc->obedit->data; | ||||
| BoneInitData *bid = t->custom.type.data; | BoneInitData *bid = tc->custom.type.data; | ||||
| EditBone *ebo; | EditBone *ebo; | ||||
| while (bid->bone) { | while (bid->bone) { | ||||
| ebo = bid->bone; | ebo = bid->bone; | ||||
| ebo->dist = bid->dist; | ebo->dist = bid->dist; | ||||
| ebo->rad_tail = bid->rad_tail; | ebo->rad_tail = bid->rad_tail; | ||||
| ebo->roll = bid->roll; | ebo->roll = bid->roll; | ||||
| Show All 24 Lines | while (bid->bone) { | ||||
| bid++; | bid++; | ||||
| } | } | ||||
| } | } | ||||
| /* ********************* armature ************** */ | /* ********************* armature ************** */ | ||||
| static void createTransArmatureVerts(TransInfo *t) | static void createTransArmatureVerts(TransInfo *t) | ||||
| { | { | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | |||||
| EditBone *ebo, *eboflip; | EditBone *ebo, *eboflip; | ||||
| bArmature *arm = t->obedit->data; | bArmature *arm = tc->obedit->data; | ||||
| ListBase *edbo = arm->edbo; | ListBase *edbo = arm->edbo; | ||||
| TransData *td, *td_old; | TransData *td, *td_old; | ||||
| float mtx[3][3], smtx[3][3], bonemat[3][3]; | float mtx[3][3], smtx[3][3], bonemat[3][3]; | ||||
| bool mirror = ((arm->flag & ARM_MIRROR_EDIT) != 0); | bool mirror = ((arm->flag & ARM_MIRROR_EDIT) != 0); | ||||
| int total_mirrored = 0, i; | int total_mirrored = 0, i; | ||||
| int oldtot; | int oldtot; | ||||
| BoneInitData *bid; | BoneInitData *bid; | ||||
| t->total = 0; | tc->data_len = 0; | ||||
| for (ebo = edbo->first; ebo; ebo = ebo->next) { | for (ebo = edbo->first; ebo; ebo = ebo->next) { | ||||
| oldtot = t->total; | oldtot = tc->data_len; | ||||
| if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) { | if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) { | ||||
| if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) { | if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) { | ||||
| if (ebo->flag & BONE_SELECTED) | if (ebo->flag & BONE_SELECTED) | ||||
| t->total++; | tc->data_len++; | ||||
| } | } | ||||
| else if (t->mode == TFM_BONE_ROLL) { | else if (t->mode == TFM_BONE_ROLL) { | ||||
| if (ebo->flag & BONE_SELECTED) | if (ebo->flag & BONE_SELECTED) | ||||
| t->total++; | tc->data_len++; | ||||
| } | } | ||||
| else { | else { | ||||
| if (ebo->flag & BONE_TIPSEL) | if (ebo->flag & BONE_TIPSEL) | ||||
| t->total++; | tc->data_len++; | ||||
| if (ebo->flag & BONE_ROOTSEL) | if (ebo->flag & BONE_ROOTSEL) | ||||
| t->total++; | tc->data_len++; | ||||
| } | } | ||||
| } | } | ||||
| if (mirror && (oldtot < t->total)) { | if (mirror && (oldtot < tc->data_len)) { | ||||
| eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo); | eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo); | ||||
| if (eboflip) | if (eboflip) | ||||
| total_mirrored++; | total_mirrored++; | ||||
| } | } | ||||
| } | } | ||||
| if (!t->total) return; | if (!tc->data_len) { | ||||
| continue; | |||||
| } | |||||
| transform_around_single_fallback(t); | transform_around_single_fallback(t); | ||||
| copy_m3_m4(mtx, t->obedit->obmat); | copy_m3_m4(mtx, tc->obedit->obmat); | ||||
| pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); | pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); | ||||
| td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransEditBone"); | td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransEditBone"); | ||||
| if (mirror) { | if (mirror) { | ||||
| t->custom.type.data = bid = MEM_mallocN((total_mirrored + 1) * sizeof(BoneInitData), "BoneInitData"); | tc->custom.type.data = bid = MEM_mallocN((total_mirrored + 1) * sizeof(BoneInitData), "BoneInitData"); | ||||
| t->custom.type.use_free = true; | tc->custom.type.use_free = true; | ||||
| } | } | ||||
| i = 0; | i = 0; | ||||
| for (ebo = edbo->first; ebo; ebo = ebo->next) { | for (ebo = edbo->first; ebo; ebo = ebo->next) { | ||||
| td_old = td; | td_old = td; | ||||
| ebo->oldlength = ebo->length; // length==0.0 on extrude, used for scaling radius of bone points | ebo->oldlength = ebo->length; // length==0.0 on extrude, used for scaling radius of bone points | ||||
| if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) { | if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) { | ||||
| if (t->mode == TFM_BONE_ENVELOPE) { | if (t->mode == TFM_BONE_ENVELOPE) { | ||||
| if (ebo->flag & BONE_ROOTSEL) { | if (ebo->flag & BONE_ROOTSEL) { | ||||
| td->val = &ebo->rad_head; | td->val = &ebo->rad_head; | ||||
| td->ival = *td->val; | td->ival = *td->val; | ||||
| copy_v3_v3(td->center, ebo->head); | copy_v3_v3(td->center, ebo->head); | ||||
| td->flag = TD_SELECTED; | td->flag = TD_SELECTED; | ||||
| copy_m3_m3(td->smtx, smtx); | copy_m3_m3(td->smtx, smtx); | ||||
| copy_m3_m3(td->mtx, mtx); | copy_m3_m3(td->mtx, mtx); | ||||
| td->loc = NULL; | td->loc = NULL; | ||||
| td->ext = NULL; | td->ext = NULL; | ||||
| td->ob = t->obedit; | td->ob = tc->obedit; | ||||
| td++; | td++; | ||||
| } | } | ||||
| if (ebo->flag & BONE_TIPSEL) { | if (ebo->flag & BONE_TIPSEL) { | ||||
| td->val = &ebo->rad_tail; | td->val = &ebo->rad_tail; | ||||
| td->ival = *td->val; | td->ival = *td->val; | ||||
| copy_v3_v3(td->center, ebo->tail); | copy_v3_v3(td->center, ebo->tail); | ||||
| td->flag = TD_SELECTED; | td->flag = TD_SELECTED; | ||||
| copy_m3_m3(td->smtx, smtx); | copy_m3_m3(td->smtx, smtx); | ||||
| copy_m3_m3(td->mtx, mtx); | copy_m3_m3(td->mtx, mtx); | ||||
| td->loc = NULL; | td->loc = NULL; | ||||
| td->ext = NULL; | td->ext = NULL; | ||||
| td->ob = t->obedit; | td->ob = tc->obedit; | ||||
| td++; | td++; | ||||
| } | } | ||||
| } | } | ||||
| else if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) { | else if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) { | ||||
| if (ebo->flag & BONE_SELECTED) { | if (ebo->flag & BONE_SELECTED) { | ||||
| if ((t->mode == TFM_BONE_ENVELOPE_DIST) || (arm->drawtype == ARM_ENVELOPE)) { | if ((t->mode == TFM_BONE_ENVELOPE_DIST) || (arm->drawtype == ARM_ENVELOPE)) { | ||||
| Show All 14 Lines | if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) { | ||||
| ED_armature_ebone_to_mat3(ebo, bonemat); | ED_armature_ebone_to_mat3(ebo, bonemat); | ||||
| mul_m3_m3m3(td->mtx, mtx, bonemat); | mul_m3_m3m3(td->mtx, mtx, bonemat); | ||||
| invert_m3_m3(td->smtx, td->mtx); | invert_m3_m3(td->smtx, td->mtx); | ||||
| copy_m3_m3(td->axismtx, td->mtx); | copy_m3_m3(td->axismtx, td->mtx); | ||||
| normalize_m3(td->axismtx); | normalize_m3(td->axismtx); | ||||
| td->ext = NULL; | td->ext = NULL; | ||||
| td->ob = t->obedit; | td->ob = tc->obedit; | ||||
| td++; | td++; | ||||
| } | } | ||||
| } | } | ||||
| else if (t->mode == TFM_BONE_ROLL) { | else if (t->mode == TFM_BONE_ROLL) { | ||||
| if (ebo->flag & BONE_SELECTED) { | if (ebo->flag & BONE_SELECTED) { | ||||
| td->loc = NULL; | td->loc = NULL; | ||||
| td->val = &(ebo->roll); | td->val = &(ebo->roll); | ||||
| td->ival = ebo->roll; | td->ival = ebo->roll; | ||||
| copy_v3_v3(td->center, ebo->head); | copy_v3_v3(td->center, ebo->head); | ||||
| td->flag = TD_SELECTED; | td->flag = TD_SELECTED; | ||||
| td->ext = NULL; | td->ext = NULL; | ||||
| td->ob = t->obedit; | td->ob = tc->obedit; | ||||
| td++; | td++; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (ebo->flag & BONE_TIPSEL) { | if (ebo->flag & BONE_TIPSEL) { | ||||
| copy_v3_v3(td->iloc, ebo->tail); | copy_v3_v3(td->iloc, ebo->tail); | ||||
| Show All 22 Lines | if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) { | ||||
| if ((ebo->flag & BONE_ROOTSEL) == 0) { | if ((ebo->flag & BONE_ROOTSEL) == 0) { | ||||
| td->extra = ebo; | td->extra = ebo; | ||||
| td->ival = ebo->roll; | td->ival = ebo->roll; | ||||
| } | } | ||||
| td->ext = NULL; | td->ext = NULL; | ||||
| td->val = NULL; | td->val = NULL; | ||||
| td->ob = t->obedit; | td->ob = tc->obedit; | ||||
| td++; | td++; | ||||
| } | } | ||||
| if (ebo->flag & BONE_ROOTSEL) { | if (ebo->flag & BONE_ROOTSEL) { | ||||
| copy_v3_v3(td->iloc, ebo->head); | copy_v3_v3(td->iloc, ebo->head); | ||||
| copy_v3_v3(td->center, td->iloc); | copy_v3_v3(td->center, td->iloc); | ||||
| td->loc = ebo->head; | td->loc = ebo->head; | ||||
| td->flag = TD_SELECTED; | td->flag = TD_SELECTED; | ||||
| if (ebo->flag & BONE_EDITMODE_LOCKED) | if (ebo->flag & BONE_EDITMODE_LOCKED) | ||||
| td->protectflag = OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE; | td->protectflag = OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE; | ||||
| copy_m3_m3(td->smtx, smtx); | copy_m3_m3(td->smtx, smtx); | ||||
| copy_m3_m3(td->mtx, mtx); | copy_m3_m3(td->mtx, mtx); | ||||
| ED_armature_ebone_to_mat3(ebo, td->axismtx); | ED_armature_ebone_to_mat3(ebo, td->axismtx); | ||||
| td->extra = ebo; /* to fix roll */ | td->extra = ebo; /* to fix roll */ | ||||
| td->ival = ebo->roll; | td->ival = ebo->roll; | ||||
| td->ext = NULL; | td->ext = NULL; | ||||
| td->val = NULL; | td->val = NULL; | ||||
| td->ob = t->obedit; | td->ob = tc->obedit; | ||||
| td++; | td++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (mirror && (td_old != td)) { | if (mirror && (td_old != td)) { | ||||
| eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo); | eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo); | ||||
| Show All 10 Lines | if (mirror && (td_old != td)) { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (mirror) { | if (mirror) { | ||||
| /* trick to terminate iteration */ | /* trick to terminate iteration */ | ||||
| bid[total_mirrored].bone = NULL; | bid[total_mirrored].bone = NULL; | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| /* ********************* meta elements ********* */ | /* ********************* meta elements ********* */ | ||||
| static void createTransMBallVerts(TransInfo *t) | static void createTransMBallVerts(TransInfo *t) | ||||
| { | { | ||||
| MetaBall *mb = (MetaBall *)t->obedit->data; | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| MetaBall *mb = (MetaBall *)tc->obedit->data; | |||||
| MetaElem *ml; | MetaElem *ml; | ||||
| TransData *td; | TransData *td; | ||||
| TransDataExtension *tx; | TransDataExtension *tx; | ||||
| 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; | ||||
| /* count totals */ | /* count totals */ | ||||
| for (ml = mb->editelems->first; ml; ml = ml->next) { | for (ml = mb->editelems->first; ml; ml = ml->next) { | ||||
| if (ml->flag & SELECT) countsel++; | if (ml->flag & SELECT) countsel++; | ||||
| if (is_prop_edit) count++; | if (is_prop_edit) count++; | ||||
| } | } | ||||
| /* note: in prop mode we need at least 1 selected */ | /* note: in prop mode we need at least 1 selected */ | ||||
| if (countsel == 0) return; | if (countsel == 0) { | ||||
| continue; | |||||
| } | |||||
| if (is_prop_edit) t->total = count; | if (is_prop_edit) tc->data_len = count; | ||||
| else t->total = countsel; | else tc->data_len = countsel; | ||||
| td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(MBall EditMode)"); | td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(MBall EditMode)"); | ||||
| tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "MetaElement_TransExtension"); | tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "MetaElement_TransExtension"); | ||||
| copy_m3_m4(mtx, t->obedit->obmat); | copy_m3_m4(mtx, tc->obedit->obmat); | ||||
| pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); | pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); | ||||
| for (ml = mb->editelems->first; ml; ml = ml->next) { | for (ml = mb->editelems->first; ml; ml = ml->next) { | ||||
| if (is_prop_edit || (ml->flag & SELECT)) { | if (is_prop_edit || (ml->flag & SELECT)) { | ||||
| td->loc = &ml->x; | td->loc = &ml->x; | ||||
| copy_v3_v3(td->iloc, td->loc); | copy_v3_v3(td->iloc, td->loc); | ||||
| copy_v3_v3(td->center, td->loc); | copy_v3_v3(td->center, td->loc); | ||||
| Show All 28 Lines | if (is_prop_edit || (ml->flag & SELECT)) { | ||||
| copy_qt_qt(tx->iquat, ml->quat); | copy_qt_qt(tx->iquat, ml->quat); | ||||
| tx->rot = NULL; | tx->rot = NULL; | ||||
| td++; | td++; | ||||
| tx++; | tx++; | ||||
| } | } | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| /* ********************* curve/surface ********* */ | /* ********************* curve/surface ********* */ | ||||
| static void calc_distanceCurveVerts(TransData *head, TransData *tail) | static void calc_distanceCurveVerts(TransData *head, TransData *tail) | ||||
| { | { | ||||
| TransData *td, *td_near = NULL; | TransData *td, *td_near = NULL; | ||||
| for (td = head; td <= tail; td++) { | for (td = head; td <= tail; td++) { | ||||
| ▲ Show 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | if ((flag != ((1 << 0) | (1 << 1) | (1 << 2))) && (flag & (1 << 1))) { | ||||
| } | } | ||||
| } | } | ||||
| return flag; | return flag; | ||||
| } | } | ||||
| static void createTransCurveVerts(TransInfo *t) | static void createTransCurveVerts(TransInfo *t) | ||||
| { | { | ||||
| Curve *cu = t->obedit->data; | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| Curve *cu = tc->obedit->data; | |||||
| TransData *td = NULL; | TransData *td = NULL; | ||||
| Nurb *nu; | Nurb *nu; | ||||
| BezTriple *bezt; | BezTriple *bezt; | ||||
| BPoint *bp; | BPoint *bp; | ||||
| float mtx[3][3], smtx[3][3]; | float mtx[3][3], smtx[3][3]; | ||||
| int a; | int a; | ||||
| 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; | ||||
| Show All 27 Lines | else { | ||||
| if (bp->hide == 0) { | if (bp->hide == 0) { | ||||
| if (is_prop_edit) count++; | if (is_prop_edit) count++; | ||||
| if (bp->f1 & SELECT) countsel++; | if (bp->f1 & SELECT) countsel++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* note: in prop mode we need at least 1 selected */ | /* note: in prop mode we need at least 1 selected */ | ||||
| if (countsel == 0) return; | if (countsel == 0) { | ||||
| tc->data_len = 0; | |||||
| continue; | |||||
| } | |||||
| if (is_prop_edit) t->total = count; | if (is_prop_edit) tc->data_len = count; | ||||
| else t->total = countsel; | else tc->data_len = countsel; | ||||
| t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Curve EditMode)"); | tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Curve EditMode)"); | ||||
| transform_around_single_fallback(t); | transform_around_single_fallback(t); | ||||
| copy_m3_m4(mtx, t->obedit->obmat); | copy_m3_m4(mtx, tc->obedit->obmat); | ||||
| pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); | pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); | ||||
| td = t->data; | td = tc->data; | ||||
| for (nu = nurbs->first; nu; nu = nu->next) { | for (nu = nurbs->first; nu; nu = nu->next) { | ||||
| if (nu->type == CU_BEZIER) { | if (nu->type == CU_BEZIER) { | ||||
| TransData *head, *tail; | TransData *head, *tail; | ||||
| head = tail = td; | head = tail = td; | ||||
| for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { | for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { | ||||
| if (bezt->hide == 0) { | if (bezt->hide == 0) { | ||||
| TransDataCurveHandleFlags *hdata = NULL; | TransDataCurveHandleFlags *hdata = NULL; | ||||
| float axismtx[3][3]; | float axismtx[3][3]; | ||||
| ▲ Show 20 Lines • Show All 193 Lines • ▼ Show 20 Lines | else { | ||||
| head = tail; | head = tail; | ||||
| } | } | ||||
| } | } | ||||
| if (is_prop_edit && head != tail) | if (is_prop_edit && head != tail) | ||||
| calc_distanceCurveVerts(head, tail - 1); | calc_distanceCurveVerts(head, tail - 1); | ||||
| } | } | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| #undef SEL_F1 | #undef SEL_F1 | ||||
| #undef SEL_F2 | #undef SEL_F2 | ||||
| #undef SEL_F3 | #undef SEL_F3 | ||||
| } | } | ||||
| /* ********************* lattice *************** */ | /* ********************* lattice *************** */ | ||||
| static void createTransLatticeVerts(TransInfo *t) | static void createTransLatticeVerts(TransInfo *t) | ||||
| { | { | ||||
| Lattice *latt = ((Lattice *)t->obedit->data)->editlatt->latt; | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| Lattice *latt = ((Lattice *)tc->obedit->data)->editlatt->latt; | |||||
| TransData *td = NULL; | TransData *td = NULL; | ||||
| BPoint *bp; | BPoint *bp; | ||||
| float mtx[3][3], smtx[3][3]; | float mtx[3][3], smtx[3][3]; | ||||
| int a; | int a; | ||||
| 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; | ||||
| bp = latt->def; | bp = latt->def; | ||||
| a = latt->pntsu * latt->pntsv * latt->pntsw; | a = latt->pntsu * latt->pntsv * latt->pntsw; | ||||
| while (a--) { | while (a--) { | ||||
| if (bp->hide == 0) { | if (bp->hide == 0) { | ||||
| if (bp->f1 & SELECT) countsel++; | if (bp->f1 & SELECT) countsel++; | ||||
| if (is_prop_edit) count++; | if (is_prop_edit) count++; | ||||
| } | } | ||||
| bp++; | bp++; | ||||
| } | } | ||||
| /* note: in prop mode we need at least 1 selected */ | /* note: in prop mode we need at least 1 selected */ | ||||
| if (countsel == 0) return; | if (countsel == 0) return; | ||||
| if (is_prop_edit) t->total = count; | if (is_prop_edit) tc->data_len = count; | ||||
| else t->total = countsel; | else tc->data_len = countsel; | ||||
| t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Lattice EditMode)"); | tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Lattice EditMode)"); | ||||
| copy_m3_m4(mtx, t->obedit->obmat); | copy_m3_m4(mtx, tc->obedit->obmat); | ||||
| pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); | pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); | ||||
| td = t->data; | td = tc->data; | ||||
| bp = latt->def; | bp = latt->def; | ||||
| a = latt->pntsu * latt->pntsv * latt->pntsw; | a = latt->pntsu * latt->pntsv * latt->pntsw; | ||||
| while (a--) { | while (a--) { | ||||
| if (is_prop_edit || (bp->f1 & SELECT)) { | if (is_prop_edit || (bp->f1 & SELECT)) { | ||||
| if (bp->hide == 0) { | if (bp->hide == 0) { | ||||
| copy_v3_v3(td->iloc, bp->vec); | copy_v3_v3(td->iloc, bp->vec); | ||||
| td->loc = bp->vec; | td->loc = bp->vec; | ||||
| copy_v3_v3(td->center, td->loc); | copy_v3_v3(td->center, td->loc); | ||||
| Show All 10 Lines | if (is_prop_edit || (bp->f1 & SELECT)) { | ||||
| td->val = NULL; | td->val = NULL; | ||||
| td++; | td++; | ||||
| count++; | count++; | ||||
| } | } | ||||
| } | } | ||||
| bp++; | bp++; | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| /* ******************* particle edit **************** */ | /* ******************* particle edit **************** */ | ||||
| static void createTransParticleVerts(bContext *C, TransInfo *t) | static void createTransParticleVerts(bContext *C, TransInfo *t) | ||||
| { | { | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | |||||
| TransData *td = NULL; | TransData *td = NULL; | ||||
| TransDataExtension *tx; | TransDataExtension *tx; | ||||
| Object *ob = CTX_data_active_object(C); | Object *ob = CTX_data_active_object(C); | ||||
| ParticleEditSettings *pset = PE_settings(t->scene); | ParticleEditSettings *pset = PE_settings(t->scene); | ||||
| PTCacheEdit *edit = PE_get_current(t->scene, ob); | PTCacheEdit *edit = PE_get_current(t->scene, ob); | ||||
| ParticleSystem *psys = NULL; | ParticleSystem *psys = NULL; | ||||
| ParticleSystemModifierData *psmd = NULL; | ParticleSystemModifierData *psmd = NULL; | ||||
| PTCacheEditPoint *point; | PTCacheEditPoint *point; | ||||
| Show All 31 Lines | if (transformparticle) { | ||||
| count += point->totkey; | count += point->totkey; | ||||
| point->flag |= PEP_TRANSFORM; | point->flag |= PEP_TRANSFORM; | ||||
| } | } | ||||
| } | } | ||||
| /* note: in prop mode we need at least 1 selected */ | /* note: in prop mode we need at least 1 selected */ | ||||
| if (hasselected == 0) return; | if (hasselected == 0) return; | ||||
| t->total = count; | tc->data_len = count; | ||||
| td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Particle Mode)"); | td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Particle Mode)"); | ||||
| if (t->mode == TFM_BAKE_TIME) | if (t->mode == TFM_BAKE_TIME) | ||||
| tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "Particle_TransExtension"); | tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "Particle_TransExtension"); | ||||
| else | else | ||||
| tx = t->ext = NULL; | tx = tc->data_ext = NULL; | ||||
| unit_m4(mat); | unit_m4(mat); | ||||
| invert_m4_m4(ob->imat, ob->obmat); | invert_m4_m4(ob->imat, ob->obmat); | ||||
| for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) { | for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) { | ||||
| TransData *head, *tail; | TransData *head, *tail; | ||||
| head = tail = td; | head = tail = td; | ||||
| ▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | for (k = 0, key = point->keys; k < point->totkey; k++, key++) { | ||||
| td++; | td++; | ||||
| if (tx) | if (tx) | ||||
| tx++; | tx++; | ||||
| tail++; | tail++; | ||||
| } | } | ||||
| if (is_prop_edit && head != tail) | if (is_prop_edit && head != tail) | ||||
| calc_distanceCurveVerts(head, tail - 1); | calc_distanceCurveVerts(head, tail - 1); | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| void flushTransParticles(TransInfo *t) | void flushTransParticles(TransInfo *t) | ||||
| { | { | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | |||||
| Scene *scene = t->scene; | Scene *scene = t->scene; | ||||
| ViewLayer *view_layer = t->view_layer; | ViewLayer *view_layer = t->view_layer; | ||||
| Object *ob = OBACT(view_layer); | Object *ob = OBACT(view_layer); | ||||
| PTCacheEdit *edit = PE_get_current(scene, ob); | PTCacheEdit *edit = PE_get_current(scene, ob); | ||||
| ParticleSystem *psys = edit->psys; | ParticleSystem *psys = edit->psys; | ||||
| ParticleSystemModifierData *psmd = NULL; | ParticleSystemModifierData *psmd = NULL; | ||||
| PTCacheEditPoint *point; | PTCacheEditPoint *point; | ||||
| PTCacheEditKey *key; | PTCacheEditKey *key; | ||||
| TransData *td; | TransData *td; | ||||
| float mat[4][4], imat[4][4], co[3]; | float mat[4][4], imat[4][4], co[3]; | ||||
| int i, k; | int i, k; | ||||
| const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0; | const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0; | ||||
| if (psys) | if (psys) | ||||
| psmd = psys_get_modifier(ob, psys); | psmd = psys_get_modifier(ob, psys); | ||||
| /* we do transform in world space, so flush world space position | /* we do transform in world space, so flush world space position | ||||
| * back to particle local space (only for hair particles) */ | * back to particle local space (only for hair particles) */ | ||||
| td = t->data; | td = tc->data; | ||||
| for (i = 0, point = edit->points; i < edit->totpoint; i++, point++, td++) { | for (i = 0, point = edit->points; i < edit->totpoint; i++, point++, td++) { | ||||
| if (!(point->flag & PEP_TRANSFORM)) continue; | if (!(point->flag & PEP_TRANSFORM)) continue; | ||||
| if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { | if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { | ||||
| psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + i, mat); | psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + i, mat); | ||||
| invert_m4_m4(imat, mat); | invert_m4_m4(imat, mat); | ||||
| for (k = 0, key = point->keys; k < point->totkey; k++, key++) { | for (k = 0, key = point->keys; k < point->totkey; k++, key++) { | ||||
| copy_v3_v3(co, key->world_co); | copy_v3_v3(co, key->world_co); | ||||
| mul_m4_v3(imat, co); | mul_m4_v3(imat, co); | ||||
| /* optimization for proportional edit */ | /* optimization for proportional edit */ | ||||
| if (!is_prop_edit || !compare_v3v3(key->co, co, 0.0001f)) { | if (!is_prop_edit || !compare_v3v3(key->co, co, 0.0001f)) { | ||||
| copy_v3_v3(key->co, co); | copy_v3_v3(key->co, co); | ||||
| point->flag |= PEP_EDIT_RECALC; | point->flag |= PEP_EDIT_RECALC; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| point->flag |= PEP_EDIT_RECALC; | point->flag |= PEP_EDIT_RECALC; | ||||
| } | } | ||||
| PE_update_object(&t->eval_ctx, scene, OBACT(view_layer), 1); | PE_update_object(&t->eval_ctx, scene, OBACT(view_layer), 1); | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| /* ********************* mesh ****************** */ | /* ********************* mesh ****************** */ | ||||
| static bool bmesh_test_dist_add( | static bool bmesh_test_dist_add( | ||||
| BMVert *v, BMVert *v_other, | BMVert *v, BMVert *v_other, | ||||
| float *dists, const float *dists_prev, | float *dists, const float *dists_prev, | ||||
| /* optionally track original index */ | /* optionally track original index */ | ||||
| ▲ Show 20 Lines • Show All 393 Lines • ▼ Show 20 Lines | static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx, | ||||
| else if (t->mode == TFM_SHRINKFATTEN) { | else if (t->mode == TFM_SHRINKFATTEN) { | ||||
| td->ext = tx; | td->ext = tx; | ||||
| tx->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); | ||||
| } | } | ||||
| } | } | ||||
| static void createTransEditVerts(TransInfo *t) | static void createTransEditVerts(TransInfo *t) | ||||
| { | { | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | |||||
| TransData *tob = NULL; | TransData *tob = NULL; | ||||
| TransDataExtension *tx = NULL; | TransDataExtension *tx = NULL; | ||||
| BMEditMesh *em = BKE_editmesh_from_object(t->obedit); | BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); | ||||
| Mesh *me = t->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; | ||||
| int a; | int a; | ||||
| const int prop_mode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0; | const int prop_mode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0; | ||||
| int mirror = 0; | int mirror = 0; | ||||
| int cd_vert_bweight_offset = -1; | int cd_vert_bweight_offset = -1; | ||||
| bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0; | bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0; | ||||
| struct TransIslandData *island_info = NULL; | struct TransIslandData *island_info = NULL; | ||||
| int island_info_tot; | int island_info_tot; | ||||
| int *island_vert_map = NULL; | int *island_vert_map = NULL; | ||||
| /* Even for translation this is needed because of island-orientation, see: T51651. */ | /* Even for translation this is needed because of island-orientation, see: T51651. */ | ||||
| const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS); | const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS); | ||||
| /* Original index of our connected vertex when connected distances are calculated. | /* Original index of our connected vertex when connected distances are calculated. | ||||
| * Optional, allocate if needed. */ | * Optional, allocate if needed. */ | ||||
| int *dists_index = NULL; | int *dists_index = NULL; | ||||
| if (t->flag & T_MIRROR) { | if (t->flag & T_MIRROR) { | ||||
| /* TODO(campbell): xform: We need support for many mirror objects at once! */ | |||||
| if (tc->is_active) { | |||||
| EDBM_verts_mirror_cache_begin(em, 0, false, (t->flag & T_PROP_EDIT) == 0, use_topology); | EDBM_verts_mirror_cache_begin(em, 0, false, (t->flag & T_PROP_EDIT) == 0, use_topology); | ||||
| mirror = 1; | mirror = 1; | ||||
| } | } | ||||
| } | |||||
| /** | /** | ||||
| * Quick check if we can transform. | * Quick check if we can transform. | ||||
| * | * | ||||
| * \note ignore modes here, even in edge/face modes, transform data is created by selected vertices. | * \note ignore modes here, even in edge/face modes, transform data is created by selected vertices. | ||||
| * \note in prop mode we need at least 1 selected. | * \note in prop mode we need at least 1 selected. | ||||
| */ | */ | ||||
| if (bm->totvertsel == 0) { | if (bm->totvertsel == 0) { | ||||
| goto cleanup; | goto cleanup; | ||||
| } | } | ||||
| if (t->mode == TFM_BWEIGHT) { | if (t->mode == TFM_BWEIGHT) { | ||||
| BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_VERT_BWEIGHT); | BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_VERT_BWEIGHT); | ||||
| cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); | cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); | ||||
| } | } | ||||
| if (prop_mode) { | if (prop_mode) { | ||||
| unsigned int count = 0; | unsigned int count = 0; | ||||
| BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { | BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { | ||||
| if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { | if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { | ||||
| count++; | count++; | ||||
| } | } | ||||
| } | } | ||||
| t->total = count; | tc->data_len = count; | ||||
| /* allocating scratch arrays */ | /* allocating scratch arrays */ | ||||
| if (prop_mode & T_PROP_CONNECTED) { | if (prop_mode & T_PROP_CONNECTED) { | ||||
| dists = MEM_mallocN(em->bm->totvert * sizeof(float), __func__); | dists = MEM_mallocN(em->bm->totvert * sizeof(float), __func__); | ||||
| if (is_island_center) { | if (is_island_center) { | ||||
| dists_index = MEM_mallocN(em->bm->totvert * sizeof(int), __func__); | dists_index = MEM_mallocN(em->bm->totvert * sizeof(int), __func__); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| t->total = bm->totvertsel; | tc->data_len = bm->totvertsel; | ||||
| } | } | ||||
| tob = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Mesh EditMode)"); | tob = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Mesh EditMode)"); | ||||
| if (ELEM(t->mode, TFM_SKIN_RESIZE, TFM_SHRINKFATTEN)) { | if (ELEM(t->mode, TFM_SKIN_RESIZE, TFM_SHRINKFATTEN)) { | ||||
| /* warning, this is overkill, we only need 2 extra floats, | /* warning, this 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 = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), | tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "TransObData ext"); | ||||
| "TransObData ext"); | |||||
| } | } | ||||
| copy_m3_m4(mtx, t->obedit->obmat); | copy_m3_m4(mtx, tc->obedit->obmat); | ||||
| /* we use a pseudoinverse so that when one of the axes is scaled to 0, | /* we use a pseudoinverse 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); | ||||
| } | } | ||||
| if (is_island_center) { | if (is_island_center) { | ||||
| /* In this specific case, near-by vertices will need to know the island of the nearest connected vertex. */ | /* In this specific case, near-by vertices will need to know the island of the nearest connected vertex. */ | ||||
| const bool calc_single_islands = ( | const bool calc_single_islands = ( | ||||
| (prop_mode & T_PROP_CONNECTED) && | (prop_mode & T_PROP_CONNECTED) && | ||||
| (t->around == V3D_AROUND_LOCAL_ORIGINS) && | (t->around == V3D_AROUND_LOCAL_ORIGINS) && | ||||
| (em->selectmode & SCE_SELECT_VERTEX)); | (em->selectmode & SCE_SELECT_VERTEX)); | ||||
| island_info = editmesh_islands_info_calc(em, &island_info_tot, &island_vert_map, calc_single_islands); | island_info = editmesh_islands_info_calc(em, &island_info_tot, &island_vert_map, calc_single_islands); | ||||
| } | } | ||||
| /* detect CrazySpace [tm] */ | /* detect CrazySpace [tm] */ | ||||
| if (modifiers_getCageIndex(t->scene, t->obedit, NULL, 1) != -1) { | if (modifiers_getCageIndex(t->scene, tc->obedit, NULL, 1) != -1) { | ||||
| int totleft = -1; | int totleft = -1; | ||||
| if (modifiers_isCorrectableDeformed(t->scene, t->obedit)) { | if (modifiers_isCorrectableDeformed(t->scene, tc->obedit)) { | ||||
| /* check if we can use deform matrices for modifier from the | /* check if we can use deform matrices for modifier from the | ||||
| * start up to stack, they are more accurate than quats */ | * start up to stack, they are more accurate than quats */ | ||||
| totleft = BKE_crazyspace_get_first_deform_matrices_editbmesh(&t->eval_ctx, t->scene, t->obedit, em, &defmats, &defcos); | totleft = BKE_crazyspace_get_first_deform_matrices_editbmesh(&t->eval_ctx, t->scene, tc->obedit, em, &defmats, &defcos); | ||||
| } | } | ||||
| /* if we still have more modifiers, also do crazyspace | /* if we still have more modifiers, also do crazyspace | ||||
| * correction with quats, relative to the coordinates after | * correction with quats, relative to the coordinates after | ||||
| * the modifiers that support deform matrices (defcos) */ | * the modifiers that support deform matrices (defcos) */ | ||||
| #if 0 /* TODO, fix crazyspace+extrude so it can be enabled for general use - campbell */ | #if 0 /* TODO, fix crazyspace+extrude so it can be enabled for general use - campbell */ | ||||
| if ((totleft > 0) || (totleft == -1)) | if ((totleft > 0) || (totleft == -1)) | ||||
| #else | #else | ||||
| if (totleft > 0) | if (totleft > 0) | ||||
| #endif | #endif | ||||
| { | { | ||||
| mappedcos = BKE_crazyspace_get_mapped_editverts(&t->eval_ctx, t->scene, t->obedit); | mappedcos = BKE_crazyspace_get_mapped_editverts(&t->eval_ctx, t->scene, tc->obedit); | ||||
| quats = MEM_mallocN(em->bm->totvert * sizeof(*quats), "crazy quats"); | quats = MEM_mallocN(em->bm->totvert * sizeof(*quats), "crazy quats"); | ||||
| BKE_crazyspace_set_quats_editmesh(em, defcos, mappedcos, quats, !prop_mode); | BKE_crazyspace_set_quats_editmesh(em, defcos, mappedcos, quats, !prop_mode); | ||||
| if (mappedcos) | if (mappedcos) | ||||
| MEM_freeN(mappedcos); | MEM_freeN(mappedcos); | ||||
| } | } | ||||
| if (defcos) { | if (defcos) { | ||||
| MEM_freeN(defcos); | MEM_freeN(defcos); | ||||
| ▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | #endif | ||||
| } | } | ||||
| if (island_info) { | if (island_info) { | ||||
| MEM_freeN(island_info); | MEM_freeN(island_info); | ||||
| MEM_freeN(island_vert_map); | MEM_freeN(island_vert_map); | ||||
| } | } | ||||
| if (mirror != 0) { | if (mirror != 0) { | ||||
| tob = t->data; | tob = tc->data; | ||||
| for (a = 0; a < t->total; a++, tob++) { | for (a = 0; a < tc->data_len; a++, tob++) { | ||||
| if (ABS(tob->loc[0]) <= 0.00001f) { | if (ABS(tob->loc[0]) <= 0.00001f) { | ||||
| tob->flag |= TD_MIRROR_EDGE; | tob->flag |= TD_MIRROR_EDGE; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| cleanup: | cleanup: | ||||
| /* crazy space free */ | /* crazy space free */ | ||||
| if (quats) | if (quats) | ||||
| MEM_freeN(quats); | MEM_freeN(quats); | ||||
| if (defmats) | if (defmats) | ||||
| MEM_freeN(defmats); | MEM_freeN(defmats); | ||||
| if (dists) | if (dists) | ||||
| MEM_freeN(dists); | MEM_freeN(dists); | ||||
| if (dists_index) | if (dists_index) | ||||
| MEM_freeN(dists_index); | MEM_freeN(dists_index); | ||||
| if (t->flag & T_MIRROR) { | if (t->flag & T_MIRROR) { | ||||
| EDBM_verts_mirror_cache_end(em); | EDBM_verts_mirror_cache_end(em); | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| /* *** NODE EDITOR *** */ | /* *** NODE EDITOR *** */ | ||||
| void flushTransNodes(TransInfo *t) | void flushTransNodes(TransInfo *t) | ||||
| { | { | ||||
| const float dpi_fac = UI_DPI_FAC; | const float dpi_fac = UI_DPI_FAC; | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | |||||
| int a; | int a; | ||||
| TransData *td; | TransData *td; | ||||
| TransData2D *td2d; | TransData2D *td2d; | ||||
| applyGridAbsolute(t); | applyGridAbsolute(t); | ||||
| /* flush to 2d vector from internally used 3d vector */ | /* flush to 2d vector from internally used 3d vector */ | ||||
| for (a = 0, td = t->data, td2d = t->data2d; a < t->total; a++, td++, td2d++) { | for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) { | ||||
| bNode *node = td->extra; | bNode *node = td->extra; | ||||
| float locx, locy; | float locx, locy; | ||||
| /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */ | /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */ | ||||
| #ifdef USE_NODE_CENTER | #ifdef USE_NODE_CENTER | ||||
| locx = (td2d->loc[0] - (BLI_rctf_size_x(&node->totr)) * +0.5f) / dpi_fac; | locx = (td2d->loc[0] - (BLI_rctf_size_x(&node->totr)) * +0.5f) / dpi_fac; | ||||
| locy = (td2d->loc[1] - (BLI_rctf_size_y(&node->totr)) * -0.5f) / dpi_fac; | locy = (td2d->loc[1] - (BLI_rctf_size_y(&node->totr)) * -0.5f) / dpi_fac; | ||||
| #else | #else | ||||
| locx = td2d->loc[0] / dpi_fac; | locx = td2d->loc[0] / dpi_fac; | ||||
| locy = td2d->loc[1] / dpi_fac; | locy = td2d->loc[1] / dpi_fac; | ||||
| #endif | #endif | ||||
| /* account for parents (nested nodes) */ | /* account for parents (nested nodes) */ | ||||
| if (node->parent) { | if (node->parent) { | ||||
| nodeFromView(node->parent, locx, locy, &node->locx, &node->locy); | nodeFromView(node->parent, locx, locy, &node->locx, &node->locy); | ||||
| } | } | ||||
| else { | else { | ||||
| node->locx = locx; | node->locx = locx; | ||||
| node->locy = locy; | node->locy = locy; | ||||
| } | } | ||||
| } | } | ||||
| /* handle intersection with noodles */ | /* handle intersection with noodles */ | ||||
| if (t->total == 1) { | if (tc->data_len == 1) { | ||||
| ED_node_link_intersect_test(t->sa, 1); | ED_node_link_intersect_test(t->sa, 1); | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| /* *** SEQUENCE EDITOR *** */ | /* *** SEQUENCE EDITOR *** */ | ||||
| /* commented _only_ because the meta may have animation data which | /* commented _only_ because the meta may have animation data which | ||||
| * needs moving too [#28158] */ | * needs moving too [#28158] */ | ||||
| #define SEQ_TX_NESTED_METAS | #define SEQ_TX_NESTED_METAS | ||||
| Show All 12 Lines | BLI_INLINE void trans_update_seq(Scene *sce, Sequence *seq, int old_start, int sel_flag) | ||||
| if (sel_flag == SELECT) | if (sel_flag == SELECT) | ||||
| BKE_sequencer_offset_animdata(sce, seq, seq->start - old_start); | BKE_sequencer_offset_animdata(sce, seq, seq->start - old_start); | ||||
| } | } | ||||
| void flushTransSeq(TransInfo *t) | void flushTransSeq(TransInfo *t) | ||||
| { | { | ||||
| ListBase *seqbasep = BKE_sequencer_editing_get(t->scene, false)->seqbasep; /* Editing null check already done */ | ListBase *seqbasep = BKE_sequencer_editing_get(t->scene, false)->seqbasep; /* Editing null check already done */ | ||||
| int a, new_frame; | int a, new_frame; | ||||
| TransData *td = NULL; | TransData *td = NULL; | ||||
| TransData2D *td2d = NULL; | TransData2D *td2d = NULL; | ||||
| TransDataSeq *tdsq = NULL; | TransDataSeq *tdsq = NULL; | ||||
| Sequence *seq; | Sequence *seq; | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | |||||
| /* prevent updating the same seq twice | /* prevent updating the same seq twice | ||||
| * if the transdata order is changed this will mess up | * if the transdata order is changed this will mess up | ||||
| * but so will TransDataSeq */ | * but so will TransDataSeq */ | ||||
| Sequence *seq_prev = NULL; | Sequence *seq_prev = NULL; | ||||
| int old_start_prev = 0, sel_flag_prev = 0; | int old_start_prev = 0, sel_flag_prev = 0; | ||||
| /* flush to 2d vector from internally used 3d vector */ | /* flush to 2d vector from internally used 3d vector */ | ||||
| for (a = 0, td = t->data, td2d = t->data2d; a < t->total; a++, td++, td2d++) { | for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) { | ||||
| int old_start; | int old_start; | ||||
| tdsq = (TransDataSeq *)td->extra; | tdsq = (TransDataSeq *)td->extra; | ||||
| seq = tdsq->seq; | seq = tdsq->seq; | ||||
| old_start = seq->start; | old_start = seq->start; | ||||
| new_frame = round_fl_to_int(td2d->loc[0]); | new_frame = round_fl_to_int(td2d->loc[0]); | ||||
| switch (tdsq->sel_flag) { | switch (tdsq->sel_flag) { | ||||
| case SELECT: | case SELECT: | ||||
| ▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | if (ELEM(t->mode, TFM_SEQ_SLIDE, TFM_TIME_TRANSLATE)) { /* originally TFM_TIME_EXTEND, transform changes */ | ||||
| } | } | ||||
| for (seq = seqbasep->first; seq; seq = seq->next) { | for (seq = seqbasep->first; seq; seq = seq->next) { | ||||
| if (seq->seq1 || seq->seq2 || seq->seq3) { | if (seq->seq1 || seq->seq2 || seq->seq3) { | ||||
| BKE_sequence_calc(t->scene, seq); | BKE_sequence_calc(t->scene, seq); | ||||
| } | } | ||||
| } | } | ||||
| /* update effects inside meta's */ | /* update effects inside meta's */ | ||||
| for (a = 0, seq_prev = NULL, td = t->data, td2d = t->data2d; | for (a = 0, seq_prev = NULL, td = tc->data, td2d = tc->data_2d; | ||||
| a < t->total; | a < tc->data_len; | ||||
| a++, td++, td2d++, seq_prev = seq) | a++, td++, td2d++, seq_prev = seq) | ||||
| { | { | ||||
| tdsq = (TransDataSeq *)td->extra; | tdsq = (TransDataSeq *)td->extra; | ||||
| seq = tdsq->seq; | seq = tdsq->seq; | ||||
| if ((seq != seq_prev) && (seq->depth != 0)) { | if ((seq != seq_prev) && (seq->depth != 0)) { | ||||
| if (seq->seq1 || seq->seq2 || seq->seq3) { | if (seq->seq1 || seq->seq2 || seq->seq3) { | ||||
| BKE_sequence_calc(t->scene, seq); | BKE_sequence_calc(t->scene, seq); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* need to do the overlap check in a new loop otherwise adjacent strips | /* need to do the overlap check in a new loop otherwise adjacent strips | ||||
| * will not be updated and we'll get false positives */ | * will not be updated and we'll get false positives */ | ||||
| seq_prev = NULL; | seq_prev = NULL; | ||||
| for (a = 0, td = t->data, td2d = t->data2d; a < t->total; a++, td++, td2d++) { | for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) { | ||||
| tdsq = (TransDataSeq *)td->extra; | tdsq = (TransDataSeq *)td->extra; | ||||
| seq = tdsq->seq; | seq = tdsq->seq; | ||||
| if (seq != seq_prev) { | if (seq != seq_prev) { | ||||
| if (seq->depth == 0) { | if (seq->depth == 0) { | ||||
| /* test overlap, displayes red outline */ | /* test overlap, displayes red outline */ | ||||
| seq->flag &= ~SEQ_OVERLAP; | seq->flag &= ~SEQ_OVERLAP; | ||||
| ▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| static void createTransUVs(bContext *C, TransInfo *t) | static void createTransUVs(bContext *C, TransInfo *t) | ||||
| { | { | ||||
| SpaceImage *sima = CTX_wm_space_image(C); | SpaceImage *sima = CTX_wm_space_image(C); | ||||
| Image *ima = CTX_data_edit_image(C); | Image *ima = CTX_data_edit_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_connected = (t->flag & T_PROP_CONNECTED) != 0; | |||||
| const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS); | |||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | |||||
| TransData *td = NULL; | TransData *td = NULL; | ||||
| TransData2D *td2d = NULL; | TransData2D *td2d = NULL; | ||||
| BMEditMesh *em = BKE_editmesh_from_object(t->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 { float co[2]; int co_num; } *island_center = NULL; | struct { float co[2]; int co_num; } *island_center = NULL; | ||||
| int count = 0, countsel = 0, count_rejected = 0; | int count = 0, countsel = 0, count_rejected = 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_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS); | |||||
| const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); | const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); | ||||
| if (!ED_space_image_show_uvedit(sima, t->obedit)) | if (!ED_space_image_show_uvedit(sima, tc->obedit)) { | ||||
| return; | continue; | ||||
| } | |||||
| /* count */ | /* count */ | ||||
| if (is_prop_connected || is_island_center) { | if (is_prop_connected || is_island_center) { | ||||
| /* create element map with island information */ | /* create element map with island information */ | ||||
| const bool use_facesel = (ts->uv_flag & UV_SYNC_SELECTION) == 0; | const bool use_facesel = (ts->uv_flag & UV_SYNC_SELECTION) == 0; | ||||
| elementmap = BM_uv_element_map_create(em->bm, use_facesel, false, true); | elementmap = BM_uv_element_map_create(em->bm, use_facesel, false, true); | ||||
| if (elementmap == NULL) { | if (elementmap == NULL) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (is_prop_connected) { | if (is_prop_connected) { | ||||
| island_enabled = BLI_BITMAP_NEW(elementmap->totalIslands, "TransIslandData(UV Editing)"); | island_enabled = BLI_BITMAP_NEW(elementmap->totalIslands, "TransIslandData(UV Editing)"); | ||||
| } | } | ||||
| if (is_island_center) { | if (is_island_center) { | ||||
| island_center = MEM_callocN(sizeof(*island_center) * elementmap->totalIslands, __func__); | island_center = MEM_callocN(sizeof(*island_center) * elementmap->totalIslands, __func__); | ||||
| } | } | ||||
| } | } | ||||
| 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 (!uvedit_face_visible_test(scene, t->obedit, ima, efa)) { | if (!uvedit_face_visible_test(scene, tc->obedit, ima, efa)) { | ||||
| BM_elem_flag_disable(efa, BM_ELEM_TAG); | BM_elem_flag_disable(efa, BM_ELEM_TAG); | ||||
| continue; | continue; | ||||
| } | } | ||||
| BM_elem_flag_enable(efa, BM_ELEM_TAG); | BM_elem_flag_enable(efa, BM_ELEM_TAG); | ||||
| BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { | BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { | ||||
| if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { | if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { | ||||
| countsel++; | countsel++; | ||||
| Show All 31 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); | ||||
| } | } | ||||
| } | } | ||||
| t->total = (is_prop_edit) ? count : countsel; | tc->data_len = (is_prop_edit) ? count : countsel; | ||||
| t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(UV Editing)"); | tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(UV Editing)"); | ||||
| /* 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 */ | ||||
| t->data2d = MEM_callocN(t->total * 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 = t->data; | td = tc->data; | ||||
| td2d = t->data2d; | 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 21 Lines | BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { | ||||
| 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++, td2d++, luv->uv, center, selected); | ||||
| } | } | ||||
| } | } | ||||
| if (is_prop_connected) { | if (is_prop_connected) { | ||||
| t->total -= count_rejected; | tc->data_len -= count_rejected; | ||||
| } | } | ||||
| if (sima->flag & SI_LIVE_UNWRAP) | if (sima->flag & SI_LIVE_UNWRAP) { | ||||
| ED_uvedit_live_unwrap_begin(t->scene, t->obedit); | /* TODO(campbell): xform: Only active object currently! | ||||
| * it uses a static variable. */ | |||||
| if (tc->is_active) { | |||||
| ED_uvedit_live_unwrap_begin(t->scene, tc->obedit); | |||||
| } | |||||
| } | |||||
| finally: | finally: | ||||
| if (is_prop_connected || is_island_center) { | if (is_prop_connected || is_island_center) { | ||||
| BM_uv_element_map_free(elementmap); | BM_uv_element_map_free(elementmap); | ||||
| if (is_prop_connected) { | if (is_prop_connected) { | ||||
| MEM_freeN(island_enabled); | MEM_freeN(island_enabled); | ||||
| } | } | ||||
| if (island_center) { | if (island_center) { | ||||
| MEM_freeN(island_center); | MEM_freeN(island_center); | ||||
| } | } | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| void flushTransUVs(TransInfo *t) | void flushTransUVs(TransInfo *t) | ||||
| { | { | ||||
| SpaceImage *sima = t->sa->spacedata.first; | SpaceImage *sima = t->sa->spacedata.first; | ||||
| const bool use_pixel_snap = ((sima->flag & SI_PIXELSNAP) && (t->state != TRANS_CANCEL)); | |||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | |||||
| TransData2D *td; | TransData2D *td; | ||||
| int a; | int a; | ||||
| float aspect_inv[2], size[2]; | float aspect_inv[2], size[2]; | ||||
| const bool use_pixel_snap = ((sima->flag & SI_PIXELSNAP) && (t->state != TRANS_CANCEL)); | |||||
| aspect_inv[0] = 1.0f / t->aspect[0]; | aspect_inv[0] = 1.0f / t->aspect[0]; | ||||
| aspect_inv[1] = 1.0f / t->aspect[1]; | aspect_inv[1] = 1.0f / t->aspect[1]; | ||||
| if (use_pixel_snap) { | if (use_pixel_snap) { | ||||
| int size_i[2]; | int size_i[2]; | ||||
| ED_space_image_get_size(sima, &size_i[0], &size_i[1]); | ED_space_image_get_size(sima, &size_i[0], &size_i[1]); | ||||
| size[0] = size_i[0]; | size[0] = size_i[0]; | ||||
| size[1] = size_i[1]; | size[1] = size_i[1]; | ||||
| } | } | ||||
| /* flush to 2d vector from internally used 3d vector */ | /* flush to 2d vector from internally used 3d vector */ | ||||
| for (a = 0, td = t->data2d; a < t->total; a++, td++) { | for (a = 0, td = tc->data_2d; a < tc->data_len; a++, td++) { | ||||
| td->loc2d[0] = td->loc[0] * aspect_inv[0]; | td->loc2d[0] = td->loc[0] * aspect_inv[0]; | ||||
| td->loc2d[1] = td->loc[1] * aspect_inv[1]; | td->loc2d[1] = td->loc[1] * aspect_inv[1]; | ||||
| if (use_pixel_snap) { | if (use_pixel_snap) { | ||||
| td->loc2d[0] = roundf(td->loc2d[0] * size[0]) / size[0]; | td->loc2d[0] = roundf(td->loc2d[0] * size[0]) / size[0]; | ||||
| td->loc2d[1] = roundf(td->loc2d[1] * size[1]) / size[1]; | td->loc2d[1] = roundf(td->loc2d[1] * size[1]) / size[1]; | ||||
| } | } | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| bool clipUVTransform(TransInfo *t, float vec[2], const bool resize) | bool clipUVTransform(TransInfo *t, float vec[2], const bool resize) | ||||
| { | { | ||||
| TransData *td; | |||||
| int a; | |||||
| bool clipx = true, clipy = true; | bool clipx = true, clipy = true; | ||||
| float min[2], max[2]; | float min[2], max[2]; | ||||
| min[0] = min[1] = 0.0f; | min[0] = min[1] = 0.0f; | ||||
| max[0] = t->aspect[0]; | max[0] = t->aspect[0]; | ||||
| max[1] = t->aspect[1]; | max[1] = t->aspect[1]; | ||||
| for (a = 0, td = t->data; a < t->total; a++, td++) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| TransData *td; | |||||
| int a; | |||||
| for (a = 0, td = tc->data; a < tc->data_len; a++, td++) { | |||||
| minmax_v2v2_v2(min, max, td->loc); | minmax_v2v2_v2(min, max, td->loc); | ||||
| } | } | ||||
| if (resize) { | if (resize) { | ||||
| if (min[0] < 0.0f && t->center[0] > 0.0f && t->center[0] < t->aspect[0] * 0.5f) | if (min[0] < 0.0f && t->center_global[0] > 0.0f && t->center_global[0] < t->aspect[0] * 0.5f) | ||||
| vec[0] *= t->center[0] / (t->center[0] - min[0]); | vec[0] *= t->center_global[0] / (t->center_global[0] - min[0]); | ||||
| else if (max[0] > t->aspect[0] && t->center[0] < t->aspect[0]) | else if (max[0] > t->aspect[0] && t->center_global[0] < t->aspect[0]) | ||||
| vec[0] *= (t->center[0] - t->aspect[0]) / (t->center[0] - max[0]); | vec[0] *= (t->center_global[0] - t->aspect[0]) / (t->center_global[0] - max[0]); | ||||
| else | else | ||||
| clipx = 0; | clipx = 0; | ||||
| if (min[1] < 0.0f && t->center[1] > 0.0f && t->center[1] < t->aspect[1] * 0.5f) | if (min[1] < 0.0f && t->center_global[1] > 0.0f && t->center_global[1] < t->aspect[1] * 0.5f) | ||||
| vec[1] *= t->center[1] / (t->center[1] - min[1]); | vec[1] *= t->center_global[1] / (t->center_global[1] - min[1]); | ||||
| else if (max[1] > t->aspect[1] && t->center[1] < t->aspect[1]) | else if (max[1] > t->aspect[1] && t->center_global[1] < t->aspect[1]) | ||||
| vec[1] *= (t->center[1] - t->aspect[1]) / (t->center[1] - max[1]); | vec[1] *= (t->center_global[1] - t->aspect[1]) / (t->center_global[1] - max[1]); | ||||
| else | else | ||||
| clipy = 0; | clipy = 0; | ||||
| } | } | ||||
| else { | else { | ||||
| if (min[0] < 0.0f) | if (min[0] < 0.0f) | ||||
| vec[0] -= min[0]; | vec[0] -= min[0]; | ||||
| else if (max[0] > t->aspect[0]) | else if (max[0] > t->aspect[0]) | ||||
| vec[0] -= max[0] - t->aspect[0]; | vec[0] -= max[0] - t->aspect[0]; | ||||
| else | else | ||||
| clipx = 0; | clipx = 0; | ||||
| if (min[1] < 0.0f) | if (min[1] < 0.0f) | ||||
| vec[1] -= min[1]; | vec[1] -= min[1]; | ||||
| else if (max[1] > t->aspect[1]) | else if (max[1] > t->aspect[1]) | ||||
| vec[1] -= max[1] - t->aspect[1]; | vec[1] -= max[1] - t->aspect[1]; | ||||
| else | else | ||||
| clipy = 0; | clipy = 0; | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| return (clipx || clipy); | return (clipx || clipy); | ||||
| } | } | ||||
| void clipUVData(TransInfo *t) | void clipUVData(TransInfo *t) | ||||
| { | { | ||||
| TransData *td = NULL; | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| int a; | TransData *td = tc->data; | ||||
| for (int a = 0; a < tc->data_len; a++, td++) { | |||||
| for (a = 0, td = t->data; a < t->total; a++, td++) { | |||||
| if (td->flag & TD_NOACTION) | if (td->flag & TD_NOACTION) | ||||
| break; | break; | ||||
| if ((td->flag & TD_SKIP) || (!td->loc)) | if ((td->flag & TD_SKIP) || (!td->loc)) | ||||
| continue; | continue; | ||||
| td->loc[0] = min_ff(max_ff(0.0f, td->loc[0]), t->aspect[0]); | td->loc[0] = min_ff(max_ff(0.0f, td->loc[0]), t->aspect[0]); | ||||
| td->loc[1] = min_ff(max_ff(0.0f, td->loc[1]), t->aspect[1]); | td->loc[1] = min_ff(max_ff(0.0f, td->loc[1]), t->aspect[1]); | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| /* ********************* ANIMATION EDITORS (GENERAL) ************************* */ | /* ********************* ANIMATION EDITORS (GENERAL) ************************* */ | ||||
| /* This function tests if a point is on the "mouse" side of the cursor/frame-marking */ | /* This function tests if a point is on the "mouse" side of the cursor/frame-marking */ | ||||
| static bool FrameOnMouseSide(char side, float frame, float cframe) | static bool FrameOnMouseSide(char side, float frame, float cframe) | ||||
| { | { | ||||
| /* both sides, so it doesn't matter */ | /* both sides, so it doesn't matter */ | ||||
| Show All 16 Lines | static void createTransNlaData(bContext *C, TransInfo *t) | ||||
| TransDataNla *tdn = NULL; | TransDataNla *tdn = NULL; | ||||
| bAnimContext ac; | bAnimContext ac; | ||||
| ListBase anim_data = {NULL, NULL}; | ListBase anim_data = {NULL, NULL}; | ||||
| bAnimListElem *ale; | bAnimListElem *ale; | ||||
| int filter; | int filter; | ||||
| int count = 0; | int count = 0; | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | |||||
| /* determine what type of data we are operating on */ | /* determine what type of data we are operating on */ | ||||
| if (ANIM_animdata_get_context(C, &ac) == 0) | if (ANIM_animdata_get_context(C, &ac) == 0) | ||||
| return; | return; | ||||
| snla = (SpaceNla *)ac.sl; | snla = (SpaceNla *)ac.sl; | ||||
| /* filter data */ | /* filter data */ | ||||
| filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT); | filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT); | ||||
| ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); | ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); | ||||
| ▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | if (count == 0) { | ||||
| } | } | ||||
| /* cleanup temp list */ | /* cleanup temp list */ | ||||
| ANIM_animdata_freelist(&anim_data); | ANIM_animdata_freelist(&anim_data); | ||||
| return; | return; | ||||
| } | } | ||||
| /* allocate memory for data */ | /* allocate memory for data */ | ||||
| t->total = count; | tc->data_len = count; | ||||
| t->data = MEM_callocN(t->total * sizeof(TransData), "TransData(NLA Editor)"); | tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransData(NLA Editor)"); | ||||
| td = t->data; | td = tc->data; | ||||
| t->custom.type.data = tdn = MEM_callocN(t->total * sizeof(TransDataNla), "TransDataNla (NLA Editor)"); | tc->custom.type.data = tdn = MEM_callocN(tc->data_len * sizeof(TransDataNla), "TransDataNla (NLA Editor)"); | ||||
| t->custom.type.use_free = true; | tc->custom.type.use_free = true; | ||||
| /* loop 2: build transdata array */ | /* loop 2: build transdata array */ | ||||
| for (ale = anim_data.first; ale; ale = ale->next) { | for (ale = anim_data.first; ale; ale = ale->next) { | ||||
| /* only if a real NLA-track */ | /* only if a real NLA-track */ | ||||
| if (ale->type == ANIMTYPE_NLATRACK) { | if (ale->type == ANIMTYPE_NLATRACK) { | ||||
| AnimData *adt = ale->adt; | AnimData *adt = ale->adt; | ||||
| NlaTrack *nlt = (NlaTrack *)ale->data; | NlaTrack *nlt = (NlaTrack *)ale->data; | ||||
| NlaStrip *strip; | NlaStrip *strip; | ||||
| ▲ Show 20 Lines • Show All 513 Lines • ▼ Show 20 Lines | |||||
| typedef struct tGPFtransdata { | typedef struct tGPFtransdata { | ||||
| float val; /* where transdata writes transform */ | float val; /* where transdata writes transform */ | ||||
| int *sdata; /* pointer to gpf->framenum */ | int *sdata; /* pointer to gpf->framenum */ | ||||
| } tGPFtransdata; | } tGPFtransdata; | ||||
| /* This function helps flush transdata written to tempdata into the gp-frames */ | /* This function helps flush transdata written to tempdata into the gp-frames */ | ||||
| void flushTransIntFrameActionData(TransInfo *t) | void flushTransIntFrameActionData(TransInfo *t) | ||||
| { | { | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | |||||
| tGPFtransdata *tfd = t->custom.type.data; | tGPFtransdata *tfd = t->custom.type.data; | ||||
| int i; | |||||
| /* flush data! */ | /* flush data! */ | ||||
| for (i = 0; i < t->total; i++, tfd++) { | for (int i = 0; i < tc->data_len; i++, tfd++) { | ||||
| *(tfd->sdata) = round_fl_to_int(tfd->val); | *(tfd->sdata) = round_fl_to_int(tfd->val); | ||||
| } | } | ||||
| } | } | ||||
| /* This function advances the address to which td points to, so it must return | /* This function advances the address to which td points to, so it must return | ||||
| * the new address so that the next time new transform data is added, it doesn't | * the new address so that the next time new transform data is added, it doesn't | ||||
| * overwrite the existing ones... i.e. td = GPLayerToTransData(td, ipo, ob, side, cfra); | * overwrite the existing ones... i.e. td = GPLayerToTransData(td, ipo, ob, side, cfra); | ||||
| * | * | ||||
| ▲ Show 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | static void createTransActionData(bContext *C, TransInfo *t) | ||||
| } | } | ||||
| /* stop if trying to build list if nothing selected */ | /* stop if trying to build list if nothing selected */ | ||||
| if (count == 0) { | if (count == 0) { | ||||
| /* cleanup temp list */ | /* cleanup temp list */ | ||||
| ANIM_animdata_freelist(&anim_data); | ANIM_animdata_freelist(&anim_data); | ||||
| return; | return; | ||||
| } | } | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | |||||
| /* allocate memory for data */ | /* allocate memory for data */ | ||||
| t->total = count; | tc->data_len = count; | ||||
| t->data = MEM_callocN(t->total * sizeof(TransData), "TransData(Action Editor)"); | tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransData(Action Editor)"); | ||||
| t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "transdata2d"); | tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "transdata2d"); | ||||
| td = t->data; | td = tc->data; | ||||
| td2d = t->data2d; | td2d = tc->data_2d; | ||||
| if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { | if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { | ||||
| t->custom.type.data = tfd = MEM_callocN(sizeof(tGPFtransdata) * count, "tGPFtransdata"); | tc->custom.type.data = tfd = MEM_callocN(sizeof(tGPFtransdata) * count, "tGPFtransdata"); | ||||
| t->custom.type.use_free = true; | tc->custom.type.use_free = true; | ||||
| } | } | ||||
| /* loop 2: build transdata array */ | /* loop 2: build transdata array */ | ||||
| for (ale = anim_data.first; ale; ale = ale->next) { | for (ale = anim_data.first; ale; ale = ale->next) { | ||||
| if (is_prop_edit && !ale->tag) | if (is_prop_edit && !ale->tag) | ||||
| continue; | continue; | ||||
| Show All 28 Lines | else { | ||||
| FCurve *fcu = (FCurve *)ale->key_data; | FCurve *fcu = (FCurve *)ale->key_data; | ||||
| td = ActionFCurveToTransData(td, &td2d, fcu, adt, t->frame_side, cfra, is_prop_edit, ypos); | td = ActionFCurveToTransData(td, &td2d, fcu, adt, t->frame_side, cfra, is_prop_edit, ypos); | ||||
| } | } | ||||
| } | } | ||||
| /* calculate distances for proportional editing */ | /* calculate distances for proportional editing */ | ||||
| if (is_prop_edit) { | if (is_prop_edit) { | ||||
| td = t->data; | td = tc->data; | ||||
| for (ale = anim_data.first; ale; ale = ale->next) { | for (ale = anim_data.first; ale; ale = ale->next) { | ||||
| AnimData *adt; | AnimData *adt; | ||||
| /* F-Curve may not have any keyframes */ | /* F-Curve may not have any keyframes */ | ||||
| if (!ale->tag) | if (!ale->tag) | ||||
| continue; | continue; | ||||
| ▲ Show 20 Lines • Show All 325 Lines • ▼ Show 20 Lines | static void createTransGraphEditData(bContext *C, TransInfo *t) | ||||
| } | } | ||||
| /* stop if trying to build list if nothing selected */ | /* stop if trying to build list if nothing selected */ | ||||
| if (count == 0) { | if (count == 0) { | ||||
| /* cleanup temp list */ | /* cleanup temp list */ | ||||
| ANIM_animdata_freelist(&anim_data); | ANIM_animdata_freelist(&anim_data); | ||||
| return; | return; | ||||
| } | } | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | |||||
| /* allocate memory for data */ | /* allocate memory for data */ | ||||
| t->total = count; | tc->data_len = count; | ||||
| t->data = MEM_callocN(t->total * sizeof(TransData), "TransData (Graph Editor)"); | tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransData (Graph Editor)"); | ||||
| /* for each 2d vert a 3d vector is allocated, so that they can be treated just as if they were 3d verts */ | /* for each 2d vert a 3d vector is allocated, so that they can be treated just as if they were 3d verts */ | ||||
| t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransData2D (Graph Editor)"); | tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransData2D (Graph Editor)"); | ||||
| t->custom.type.data = MEM_callocN(t->total * sizeof(TransDataGraph), "TransDataGraph"); | tc->custom.type.data = MEM_callocN(tc->data_len * sizeof(TransDataGraph), "TransDataGraph"); | ||||
| t->custom.type.use_free = true; | tc->custom.type.use_free = true; | ||||
| td = t->data; | td = tc->data; | ||||
| td2d = t->data2d; | td2d = tc->data_2d; | ||||
| tdg = t->custom.type.data; | tdg = tc->custom.type.data; | ||||
| /* precompute space-conversion matrices for dealing with non-uniform scaling of Graph Editor */ | /* precompute space-conversion matrices for dealing with non-uniform scaling of Graph Editor */ | ||||
| unit_m3(mtx); | unit_m3(mtx); | ||||
| unit_m3(smtx); | unit_m3(smtx); | ||||
| if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE)) { | if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE)) { | ||||
| float xscale, yscale; | float xscale, yscale; | ||||
| ▲ Show 20 Lines • Show All 110 Lines • ▼ Show 20 Lines | for (ale = anim_data.first; ale; ale = ale->next) { | ||||
| } | } | ||||
| /* Sets handles based on the selection */ | /* Sets handles based on the selection */ | ||||
| testhandles_fcurve(fcu, use_handle); | testhandles_fcurve(fcu, use_handle); | ||||
| } | } | ||||
| if (is_prop_edit) { | if (is_prop_edit) { | ||||
| /* loop 2: build transdata arrays */ | /* loop 2: build transdata arrays */ | ||||
| td = t->data; | td = tc->data; | ||||
| for (ale = anim_data.first; ale; ale = ale->next) { | for (ale = anim_data.first; ale; ale = ale->next) { | ||||
| AnimData *adt = ANIM_nla_mapping_get(&ac, ale); | AnimData *adt = ANIM_nla_mapping_get(&ac, ale); | ||||
| FCurve *fcu = (FCurve *)ale->key_data; | FCurve *fcu = (FCurve *)ale->key_data; | ||||
| TransData *td_start = td; | TransData *td_start = td; | ||||
| float cfra; | float cfra; | ||||
| /* F-Curve may not have any keyframes */ | /* F-Curve may not have any keyframes */ | ||||
| ▲ Show 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | |||||
| static void beztmap_to_data(TransInfo *t, FCurve *fcu, BeztMap *bezms, int totvert, const short UNUSED(use_handle)) | static void beztmap_to_data(TransInfo *t, FCurve *fcu, BeztMap *bezms, int totvert, const short UNUSED(use_handle)) | ||||
| { | { | ||||
| BezTriple *bezts = fcu->bezt; | BezTriple *bezts = fcu->bezt; | ||||
| BeztMap *bezm; | BeztMap *bezm; | ||||
| TransData2D *td2d; | TransData2D *td2d; | ||||
| TransData *td; | TransData *td; | ||||
| int i, j; | int i, j; | ||||
| char *adjusted; | char *adjusted; | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | |||||
| /* dynamically allocate an array of chars to mark whether an TransData's | /* dynamically allocate an array of chars to mark whether an TransData's | ||||
| * pointers have been fixed already, so that we don't override ones that are | * pointers have been fixed already, so that we don't override ones that are | ||||
| * already done | * already done | ||||
| */ | */ | ||||
| adjusted = MEM_callocN(t->total, "beztmap_adjusted_map"); | adjusted = MEM_callocN(tc->data_len, "beztmap_adjusted_map"); | ||||
| /* for each beztmap item, find if it is used anywhere */ | /* for each beztmap item, find if it is used anywhere */ | ||||
| bezm = bezms; | bezm = bezms; | ||||
| for (i = 0; i < totvert; i++, bezm++) { | for (i = 0; i < totvert; i++, bezm++) { | ||||
| /* loop through transdata, testing if we have a hit | /* loop through transdata, testing if we have a hit | ||||
| * for the handles (vec[0]/vec[2]), we must also check if they need to be swapped... | * for the handles (vec[0]/vec[2]), we must also check if they need to be swapped... | ||||
| */ | */ | ||||
| td2d = t->data2d; | td2d = tc->data_2d; | ||||
| td = t->data; | td = tc->data; | ||||
| for (j = 0; j < t->total; j++, td2d++, td++) { | for (j = 0; j < tc->data_len; j++, td2d++, td++) { | ||||
| /* skip item if already marked */ | /* skip item if already marked */ | ||||
| if (adjusted[j] != 0) continue; | if (adjusted[j] != 0) continue; | ||||
| /* update all transdata pointers, no need to check for selections etc, | /* update all transdata pointers, no need to check for selections etc, | ||||
| * since only points that are really needed were created as transdata | * since only points that are really needed were created as transdata | ||||
| */ | */ | ||||
| if (td2d->loc2d == bezm->bezt->vec[0]) { | if (td2d->loc2d == bezm->bezt->vec[0]) { | ||||
| if (bezm->swapHs == 1) | if (bezm->swapHs == 1) | ||||
| ▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | void flushTransGraphData(TransInfo *t) | ||||
| SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first; | SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first; | ||||
| TransData *td; | TransData *td; | ||||
| TransData2D *td2d; | TransData2D *td2d; | ||||
| TransDataGraph *tdg; | TransDataGraph *tdg; | ||||
| Scene *scene = t->scene; | Scene *scene = t->scene; | ||||
| double secf = FPS; | double secf = FPS; | ||||
| int a; | int a; | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | |||||
| /* flush to 2d vector from internally used 3d vector */ | /* flush to 2d vector from internally used 3d vector */ | ||||
| for (a = 0, td = t->data, td2d = t->data2d, tdg = t->custom.type.data; | for (a = 0, td = tc->data, td2d = tc->data_2d, tdg = tc->custom.type.data; | ||||
| a < t->total; | a < tc->data_len; | ||||
| a++, td++, td2d++, tdg++) | a++, td++, td2d++, tdg++) | ||||
| { | { | ||||
| AnimData *adt = (AnimData *)td->extra; /* pointers to relevant AnimData blocks are stored in the td->extra pointers */ | AnimData *adt = (AnimData *)td->extra; /* pointers to relevant AnimData blocks are stored in the td->extra pointers */ | ||||
| float inv_unit_scale = 1.0f / tdg->unit_scale; | float inv_unit_scale = 1.0f / tdg->unit_scale; | ||||
| /* handle snapping for time values | /* handle snapping for time values | ||||
| * - we should still be in NLA-mapping timespace | * - we should still be in NLA-mapping timespace | ||||
| * - only apply to keyframes (but never to handles) | * - only apply to keyframes (but never to handles) | ||||
| ▲ Show 20 Lines • Show All 345 Lines • ▼ Show 20 Lines | static void SeqTransDataBounds(TransInfo *t, ListBase *seqbase, TransSeq *ts) | ||||
| if (ts) { | if (ts) { | ||||
| ts->max = max; | ts->max = max; | ||||
| ts->min = min; | ts->min = min; | ||||
| } | } | ||||
| } | } | ||||
| static void freeSeqData(TransInfo *t, TransCustomData *custom_data) | static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data) | ||||
| { | { | ||||
| Editing *ed = BKE_sequencer_editing_get(t->scene, false); | Editing *ed = BKE_sequencer_editing_get(t->scene, false); | ||||
| if (ed != NULL) { | if (ed != NULL) { | ||||
| ListBase *seqbasep = ed->seqbasep; | ListBase *seqbasep = ed->seqbasep; | ||||
| TransData *td = t->data; | TransData *td = tc->data; | ||||
| int a; | int a; | ||||
| /* prevent updating the same seq twice | /* prevent updating the same seq twice | ||||
| * if the transdata order is changed this will mess up | * if the transdata order is changed this will mess up | ||||
| * but so will TransDataSeq */ | * but so will TransDataSeq */ | ||||
| Sequence *seq_prev = NULL; | Sequence *seq_prev = NULL; | ||||
| Sequence *seq; | Sequence *seq; | ||||
| Show All 11 Lines | #if 0 // default 2.4 behavior | ||||
| seq_prev = seq; | seq_prev = seq; | ||||
| } | } | ||||
| #else // durian hack | #else // durian hack | ||||
| { | { | ||||
| int overlap = 0; | int overlap = 0; | ||||
| for (a = 0, seq_prev = NULL; a < t->total; a++, td++, seq_prev = seq) { | for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) { | ||||
| seq = ((TransDataSeq *)td->extra)->seq; | seq = ((TransDataSeq *)td->extra)->seq; | ||||
| if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) { | if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) { | ||||
| overlap = 1; | overlap = 1; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| if (overlap) { | if (overlap) { | ||||
| bool has_effect_root = false, has_effect_any = false; | bool has_effect_root = false, has_effect_any = false; | ||||
| for (seq = seqbasep->first; seq; seq = seq->next) | for (seq = seqbasep->first; seq; seq = seq->next) | ||||
| seq->tmp = NULL; | seq->tmp = NULL; | ||||
| td = t->data; | td = tc->data; | ||||
| for (a = 0, seq_prev = NULL; a < t->total; a++, td++, seq_prev = seq) { | for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) { | ||||
| seq = ((TransDataSeq *)td->extra)->seq; | seq = ((TransDataSeq *)td->extra)->seq; | ||||
| if ((seq != seq_prev)) { | if ((seq != seq_prev)) { | ||||
| /* check effects strips, we cant change their time */ | /* check effects strips, we cant change their time */ | ||||
| if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) { | if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) { | ||||
| has_effect_any = true; | has_effect_any = true; | ||||
| if (seq->depth == 0) { | if (seq->depth == 0) { | ||||
| has_effect_root = true; | has_effect_root = true; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* Tag seq with a non zero value, | /* Tag seq with a non zero value, | ||||
| * used by BKE_sequence_base_shuffle_time to identify the ones to shuffle */ | * used by BKE_sequence_base_shuffle_time to identify the ones to shuffle */ | ||||
| if (seq->depth == 0) { | if (seq->depth == 0) { | ||||
| seq->tmp = (void *)1; | seq->tmp = (void *)1; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (t->flag & T_ALT_TRANSFORM) { | if (t->flag & T_ALT_TRANSFORM) { | ||||
| int minframe = MAXFRAME; | int minframe = MAXFRAME; | ||||
| td = t->data; | td = tc->data; | ||||
| for (a = 0, seq_prev = NULL; a < t->total; a++, td++, seq_prev = seq) { | for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) { | ||||
| seq = ((TransDataSeq *)td->extra)->seq; | seq = ((TransDataSeq *)td->extra)->seq; | ||||
| if ((seq != seq_prev) && (seq->depth == 0)) { | if ((seq != seq_prev) && (seq->depth == 0)) { | ||||
| minframe = min_ii(minframe, seq->startdisp); | minframe = min_ii(minframe, seq->startdisp); | ||||
| } | } | ||||
| } | } | ||||
| for (seq = seqbasep->first; seq; seq = seq->next) { | for (seq = seqbasep->first; seq; seq = seq->next) { | ||||
| Show All 19 Lines | #else // durian hack | ||||
| BKE_sequence_base_shuffle_time(seqbasep, t->scene); | BKE_sequence_base_shuffle_time(seqbasep, t->scene); | ||||
| } | } | ||||
| else { | else { | ||||
| BKE_sequence_base_shuffle_time(seqbasep, t->scene); | BKE_sequence_base_shuffle_time(seqbasep, t->scene); | ||||
| } | } | ||||
| if (has_effect_any) { | if (has_effect_any) { | ||||
| /* update effects strips based on strips just moved in time */ | /* update effects strips based on strips just moved in time */ | ||||
| td = t->data; | td = tc->data; | ||||
| for (a = 0, seq_prev = NULL; a < t->total; a++, td++, seq_prev = seq) { | for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) { | ||||
| seq = ((TransDataSeq *)td->extra)->seq; | seq = ((TransDataSeq *)td->extra)->seq; | ||||
| if ((seq != seq_prev)) { | if ((seq != seq_prev)) { | ||||
| if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) { | if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) { | ||||
| BKE_sequence_calc(t->scene, seq); | BKE_sequence_calc(t->scene, seq); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (has_effect_root) { | if (has_effect_root) { | ||||
| /* now if any effects _still_ overlap, we need to move them up */ | /* now if any effects _still_ overlap, we need to move them up */ | ||||
| td = t->data; | td = tc->data; | ||||
| for (a = 0, seq_prev = NULL; a < t->total; a++, td++, seq_prev = seq) { | for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) { | ||||
| seq = ((TransDataSeq *)td->extra)->seq; | seq = ((TransDataSeq *)td->extra)->seq; | ||||
| if ((seq != seq_prev) && (seq->depth == 0)) { | if ((seq != seq_prev) && (seq->depth == 0)) { | ||||
| if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) { | if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) { | ||||
| if (BKE_sequence_test_overlap(seqbasep, seq)) { | if (BKE_sequence_test_overlap(seqbasep, seq)) { | ||||
| BKE_sequence_base_shuffle(seqbasep, seq, t->scene); | BKE_sequence_base_shuffle(seqbasep, seq, t->scene); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| Show All 12 Lines | #endif | ||||
| else if (seq->seq3 && seq->seq3->flag & SELECT) BKE_sequence_calc(t->scene, seq); | else if (seq->seq3 && seq->seq3->flag & SELECT) BKE_sequence_calc(t->scene, seq); | ||||
| } | } | ||||
| } | } | ||||
| BKE_sequencer_sort(t->scene); | BKE_sequencer_sort(t->scene); | ||||
| } | } | ||||
| else { | else { | ||||
| /* Canceled, need to update the strips display */ | /* Canceled, need to update the strips display */ | ||||
| for (a = 0; a < t->total; a++, td++) { | for (a = 0; a < tc->data_len; a++, td++) { | ||||
| seq = ((TransDataSeq *)td->extra)->seq; | seq = ((TransDataSeq *)td->extra)->seq; | ||||
| if ((seq != seq_prev) && (seq->depth == 0)) { | if ((seq != seq_prev) && (seq->depth == 0)) { | ||||
| if (seq->flag & SEQ_OVERLAP) | if (seq->flag & SEQ_OVERLAP) | ||||
| BKE_sequence_base_shuffle(seqbasep, seq, t->scene); | BKE_sequence_base_shuffle(seqbasep, seq, t->scene); | ||||
| BKE_sequence_calc_disp(t->scene, seq); | BKE_sequence_calc_disp(t->scene, seq); | ||||
| } | } | ||||
| seq_prev = seq; | seq_prev = seq; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if ((custom_data->data != NULL) && custom_data->use_free) { | if ((custom_data->data != NULL) && custom_data->use_free) { | ||||
| TransSeq *ts = custom_data->data; | TransSeq *ts = custom_data->data; | ||||
| MEM_freeN(ts->tdseq); | MEM_freeN(ts->tdseq); | ||||
| MEM_freeN(custom_data->data); | MEM_freeN(custom_data->data); | ||||
| custom_data->data = NULL; | custom_data->data = NULL; | ||||
| } | } | ||||
| if (t->data) { | if (tc->data) { | ||||
| MEM_freeN(t->data); // XXX postTrans usually does this | MEM_freeN(tc->data); // XXX postTrans usually does this | ||||
| t->data = NULL; | tc->data = NULL; | ||||
| } | } | ||||
| } | } | ||||
| static void createTransSeqData(bContext *C, TransInfo *t) | static void createTransSeqData(bContext *C, TransInfo *t) | ||||
| { | { | ||||
| #define XXX_DURIAN_ANIM_TX_HACK | #define XXX_DURIAN_ANIM_TX_HACK | ||||
| View2D *v2d = UI_view2d_fromcontext(C); | View2D *v2d = UI_view2d_fromcontext(C); | ||||
| Scene *scene = t->scene; | Scene *scene = t->scene; | ||||
| Editing *ed = BKE_sequencer_editing_get(t->scene, false); | Editing *ed = BKE_sequencer_editing_get(t->scene, false); | ||||
| TransData *td = NULL; | TransData *td = NULL; | ||||
| TransData2D *td2d = NULL; | TransData2D *td2d = NULL; | ||||
| TransDataSeq *tdsq = NULL; | TransDataSeq *tdsq = NULL; | ||||
| TransSeq *ts = NULL; | TransSeq *ts = NULL; | ||||
| int xmouse; | int xmouse; | ||||
| int count = 0; | int count = 0; | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | |||||
| if (ed == NULL) { | if (ed == NULL) { | ||||
| t->total = 0; | tc->data_len = 0; | ||||
| return; | return; | ||||
| } | } | ||||
| t->custom.type.free_cb = freeSeqData; | tc->custom.type.free_cb = freeSeqData; | ||||
| xmouse = (int)UI_view2d_region_to_view_x(v2d, t->mouse.imval[0]); | xmouse = (int)UI_view2d_region_to_view_x(v2d, t->mouse.imval[0]); | ||||
| /* which side of the current frame should be allowed */ | /* which side of the current frame should be allowed */ | ||||
| if (t->mode == TFM_TIME_EXTEND) { | if (t->mode == TFM_TIME_EXTEND) { | ||||
| /* only side on which mouse is gets transformed */ | /* only side on which mouse is gets transformed */ | ||||
| t->frame_side = (xmouse > CFRA) ? 'R' : 'L'; | t->frame_side = (xmouse > CFRA) ? 'R' : 'L'; | ||||
| } | } | ||||
| Show All 22 Lines | for (seq = ed->seqbasep->first; seq; seq = seq->next) { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||
| count = SeqTransCount(t, NULL, ed->seqbasep, 0); | count = SeqTransCount(t, NULL, ed->seqbasep, 0); | ||||
| /* allocate memory for data */ | /* allocate memory for data */ | ||||
| t->total = count; | tc->data_len = count; | ||||
| /* stop if trying to build list if nothing selected */ | /* stop if trying to build list if nothing selected */ | ||||
| if (count == 0) { | if (count == 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| t->custom.type.data = ts = MEM_callocN(sizeof(TransSeq), "transseq"); | tc->custom.type.data = ts = MEM_callocN(sizeof(TransSeq), "transseq"); | ||||
| t->custom.type.use_free = true; | tc->custom.type.use_free = true; | ||||
| td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransSeq TransData"); | td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransSeq TransData"); | ||||
| td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransSeq TransData2D"); | td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransSeq TransData2D"); | ||||
| ts->tdseq = tdsq = MEM_callocN(t->total * sizeof(TransDataSeq), "TransSeq TransDataSeq"); | ts->tdseq = tdsq = MEM_callocN(tc->data_len * sizeof(TransDataSeq), "TransSeq TransDataSeq"); | ||||
| /* loop 2: build transdata array */ | /* loop 2: build transdata array */ | ||||
| SeqToTransData_Recursive(t, ed->seqbasep, td, td2d, tdsq); | SeqToTransData_Recursive(t, ed->seqbasep, td, td2d, tdsq); | ||||
| SeqTransDataBounds(t, ed->seqbasep, ts); | SeqTransDataBounds(t, ed->seqbasep, ts); | ||||
| /* set the snap mode based on how close the mouse is at the end/start points */ | /* set the snap mode based on how close the mouse is at the end/start points */ | ||||
| if (abs(xmouse - ts->max) > abs(xmouse - ts->min)) | if (abs(xmouse - ts->max) > abs(xmouse - ts->min)) | ||||
| ts->snap_left = true; | ts->snap_left = true; | ||||
| ▲ Show 20 Lines • Show All 713 Lines • ▼ Show 20 Lines | if (canceled && t->remove_on_cancel) { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t) | static void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t) | ||||
| { | { | ||||
| /* so automerge supports mirror */ | /* so automerge supports mirror */ | ||||
| if ((t->scene->toolsettings->automerge) && | if ((t->scene->toolsettings->automerge) && | ||||
| (t->obedit && t->obedit->type == OB_MESH)) | ((t->flag & T_EDIT) && t->obedit_type == OB_MESH)) | ||||
| { | { | ||||
| BMEditMesh *em = BKE_editmesh_from_object(t->obedit); | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); | |||||
| BMesh *bm = em->bm; | BMesh *bm = em->bm; | ||||
| char hflag; | char hflag; | ||||
| bool has_face_sel = (bm->totfacesel != 0); | bool has_face_sel = (bm->totfacesel != 0); | ||||
| if (t->flag & T_MIRROR) { | if (t->flag & T_MIRROR) { | ||||
| TransData *td; | TransData *td; | ||||
| int i; | int i; | ||||
| /* rather then adjusting the selection (which the user would notice) | /* rather then adjusting the selection (which the user would notice) | ||||
| * tag all mirrored verts, then automerge those */ | * tag all mirrored verts, then automerge those */ | ||||
| BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false); | BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false); | ||||
| for (i = 0, td = t->data; i < t->total; i++, td++) { | for (i = 0, td = tc->data; i < tc->data_len; i++, td++) { | ||||
| if (td->extra) { | if (td->extra) { | ||||
| BM_elem_flag_enable((BMVert *)td->extra, BM_ELEM_TAG); | BM_elem_flag_enable((BMVert *)td->extra, BM_ELEM_TAG); | ||||
| } | } | ||||
| } | } | ||||
| hflag = BM_ELEM_SELECT | BM_ELEM_TAG; | hflag = BM_ELEM_SELECT | BM_ELEM_TAG; | ||||
| } | } | ||||
| else { | else { | ||||
| hflag = BM_ELEM_SELECT; | hflag = BM_ELEM_SELECT; | ||||
| } | } | ||||
| EDBM_automerge(t->scene, t->obedit, true, hflag); | EDBM_automerge(t->scene, tc->obedit, true, hflag); | ||||
| /* Special case, this is needed or faces won't re-select. | /* Special case, this is needed or faces won't re-select. | ||||
| * Flush selected edges to faces. */ | * Flush selected edges to faces. */ | ||||
| if (has_face_sel && (em->selectmode == SCE_SELECT_FACE)) { | if (has_face_sel && (em->selectmode == SCE_SELECT_FACE)) { | ||||
| EDBM_selectmode_flush_ex(em, SCE_SELECT_EDGE); | EDBM_selectmode_flush_ex(em, SCE_SELECT_EDGE); | ||||
| } | } | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| /* inserting keys, pointcache, redraw events... */ | /* inserting keys, pointcache, redraw events... */ | ||||
| /* | /* | ||||
| * note: sequencer freeing has its own function now because of a conflict with transform's order of freeing (campbell) | * note: sequencer freeing has its own function now because of a conflict with transform's order of freeing (campbell) | ||||
| * Order changed, the sequencer stuff should go back in here | * Order changed, the sequencer stuff should go back in here | ||||
| * */ | * */ | ||||
| void special_aftertrans_update(bContext *C, TransInfo *t) | void special_aftertrans_update(bContext *C, TransInfo *t) | ||||
| { | { | ||||
| Object *ob; | Object *ob; | ||||
| // short redrawipo=0, resetslowpar=1; | // short redrawipo=0, resetslowpar=1; | ||||
| const bool canceled = (t->state == TRANS_CANCEL); | const bool canceled = (t->state == TRANS_CANCEL); | ||||
| const bool duplicate = (t->mode == TFM_TIME_DUPLICATE); | const bool duplicate = (t->mode == TFM_TIME_DUPLICATE); | ||||
| /* early out when nothing happened */ | /* early out when nothing happened */ | ||||
| if (t->total == 0 || t->mode == TFM_DUMMY) | if (t->data_len_all == 0 || t->mode == TFM_DUMMY) { | ||||
| return; | return; | ||||
| } | |||||
| if (t->spacetype == SPACE_VIEW3D) { | if (t->spacetype == SPACE_VIEW3D) { | ||||
| if (t->obedit) { | if (t->flag & T_EDIT) { | ||||
| /* Special Exception: | /* Special Exception: | ||||
| * We don't normally access 't->custom.mode' here, but its needed in this case. */ | * We don't normally access 't->custom.mode' here, but its needed in this case. */ | ||||
| if (canceled == 0) { | if (canceled == 0) { | ||||
| /* we need to delete the temporary faces before automerging */ | /* we need to delete the temporary faces before automerging */ | ||||
| if (t->mode == TFM_EDGE_SLIDE) { | if (t->mode == TFM_EDGE_SLIDE) { | ||||
| EdgeSlideData *sld = t->custom.mode.data; | |||||
| /* handle multires re-projection, done | /* handle multires re-projection, done | ||||
| * on transform completion since it's | * on transform completion since it's | ||||
| * really slow -joeedh */ | * really slow -joeedh */ | ||||
| projectEdgeSlideData(t, true); | projectEdgeSlideData(t, true); | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | |||||
| EdgeSlideData *sld = tc->custom.mode.data; | |||||
| /* free temporary faces to avoid automerging and deleting | /* free temporary faces to avoid automerging and deleting | ||||
| * during cleanup - psy-fi */ | * during cleanup - psy-fi */ | ||||
| freeEdgeSlideTempFaces(sld); | freeEdgeSlideTempFaces(sld); | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| else if (t->mode == TFM_VERT_SLIDE) { | else if (t->mode == TFM_VERT_SLIDE) { | ||||
| /* as above */ | /* as above */ | ||||
| VertSlideData *sld = t->custom.mode.data; | |||||
| projectVertSlideData(t, true); | projectVertSlideData(t, true); | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | |||||
| VertSlideData *sld = tc->custom.mode.data; | |||||
| freeVertSlideTempFaces(sld); | freeVertSlideTempFaces(sld); | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| if (t->obedit->type == OB_MESH) { | if (t->obedit_type == OB_MESH) { | ||||
| special_aftertrans_update__mesh(C, t); | special_aftertrans_update__mesh(C, t); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (t->mode == TFM_EDGE_SLIDE) { | if (t->mode == TFM_EDGE_SLIDE) { | ||||
| EdgeSlideData *sld = t->custom.mode.data; | EdgeSlideParams *slp = t->custom.mode.data; | ||||
| slp->perc = 0.0; | |||||
| sld->perc = 0.0; | |||||
| projectEdgeSlideData(t, false); | projectEdgeSlideData(t, false); | ||||
| } | } | ||||
| else if (t->mode == TFM_VERT_SLIDE) { | else if (t->mode == TFM_VERT_SLIDE) { | ||||
| VertSlideData *sld = t->custom.mode.data; | EdgeSlideParams *slp = t->custom.mode.data; | ||||
| slp->perc = 0.0; | |||||
| sld->perc = 0.0; | |||||
| projectVertSlideData(t, false); | projectVertSlideData(t, false); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (t->options & CTX_GPENCIL_STROKES) { | if (t->options & CTX_GPENCIL_STROKES) { | ||||
| ▲ Show 20 Lines • Show All 257 Lines • ▼ Show 20 Lines | if (ac.datatype) { | ||||
| /* free temp memory */ | /* free temp memory */ | ||||
| ANIM_animdata_freelist(&anim_data); | ANIM_animdata_freelist(&anim_data); | ||||
| /* perform after-transfrom validation */ | /* perform after-transfrom validation */ | ||||
| ED_nla_postop_refresh(&ac); | ED_nla_postop_refresh(&ac); | ||||
| } | } | ||||
| } | } | ||||
| else if (t->obedit) { | else if (t->flag & T_EDIT) { | ||||
| if (t->obedit->type == OB_MESH) { | if (t->obedit_type == OB_MESH) { | ||||
| BMEditMesh *em = BKE_editmesh_from_object(t->obedit); | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); | |||||
| /* table needs to be created for each edit command, since vertices can move etc */ | /* table needs to be created for each edit command, since vertices can move etc */ | ||||
| ED_mesh_mirror_spatial_table(t->obedit, em, NULL, NULL, 'e'); | ED_mesh_mirror_spatial_table(tc->obedit, em, NULL, NULL, 'e'); | ||||
| /* TODO(campbell): xform: We need support for many mirror objects at once! */ | |||||
| break; | |||||
| } | } | ||||
| } | } | ||||
| else if ((t->flag & T_POSE) && (t->poseobj)) { | } | ||||
| else if (t->flag & T_POSE) { | |||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | |||||
| bArmature *arm; | bArmature *arm; | ||||
| bPoseChannel *pchan; | bPoseChannel *pchan; | ||||
| short targetless_ik = 0; | short targetless_ik = 0; | ||||
| ob = t->poseobj; | ob = tc->poseobj; | ||||
| arm = ob->data; | arm = ob->data; | ||||
| if ((t->flag & T_AUTOIK) && (t->options & CTX_AUTOCONFIRM)) { | if ((t->flag & T_AUTOIK) && (t->options & CTX_AUTOCONFIRM)) { | ||||
| /* when running transform non-interactively (operator exec), | /* when running transform non-interactively (operator exec), | ||||
| * we need to update the pose otherwise no updates get called during | * we need to update the pose otherwise no updates get called during | ||||
| * transform and the auto-ik is not applied. see [#26164] */ | * transform and the auto-ik is not applied. see [#26164] */ | ||||
| struct Object *pose_ob = t->poseobj; | struct Object *pose_ob = tc->poseobj; | ||||
| BKE_pose_where_is(&t->eval_ctx, t->scene, pose_ob); | BKE_pose_where_is(&t->eval_ctx, t->scene, pose_ob); | ||||
| } | } | ||||
| /* set BONE_TRANSFORM flags for autokey, manipulator draw might have changed them */ | /* set BONE_TRANSFORM flags for autokey, manipulator draw might have changed them */ | ||||
| if (!canceled && (t->mode != TFM_DUMMY)) | if (!canceled && (t->mode != TFM_DUMMY)) | ||||
| count_set_pose_transflags(&t->mode, t->around, ob); | count_set_pose_transflags(&t->mode, t->around, ob); | ||||
| /* if target-less IK grabbing, we calculate the pchan transforms and clear flag */ | /* if target-less IK grabbing, we calculate the pchan transforms and clear flag */ | ||||
| Show All 21 Lines | else if (arm->flag & ARM_DELAYDEFORM) { | ||||
| * possible yet within new dependency graph, and also other contexts | * possible yet within new dependency graph, and also other contexts | ||||
| * might need to update their CoW copies. | * might need to update their CoW copies. | ||||
| */ | */ | ||||
| DEG_id_tag_update(&ob->id, OB_RECALC_DATA); | DEG_id_tag_update(&ob->id, OB_RECALC_DATA); | ||||
| } | } | ||||
| else { | else { | ||||
| DEG_id_tag_update(&ob->id, OB_RECALC_DATA); | DEG_id_tag_update(&ob->id, OB_RECALC_DATA); | ||||
| } | } | ||||
| } // FIXME(indent) | |||||
| } | } | ||||
| else if (t->options & CTX_PAINT_CURVE) { | else if (t->options & CTX_PAINT_CURVE) { | ||||
| /* pass */ | /* pass */ | ||||
| } | } | ||||
| else if ((t->view_layer->basact) && | else if ((t->view_layer->basact) && | ||||
| (ob = t->view_layer->basact->object) && | (ob = t->view_layer->basact->object) && | ||||
| (ob->mode & OB_MODE_PARTICLE_EDIT) && | (ob->mode & OB_MODE_PARTICLE_EDIT) && | ||||
| PE_get_current(t->scene, ob)) | PE_get_current(t->scene, ob)) | ||||
| { | { | ||||
| /* do nothing */ | /* do nothing */ | ||||
| } | } | ||||
| else { /* Objects */ | else { /* Objects */ | ||||
| int i; | int i; | ||||
| BLI_assert(t->flag & (T_OBJECT | T_TEXTURE)); | BLI_assert(t->flag & (T_OBJECT | T_TEXTURE)); | ||||
| for (i = 0; i < t->total; i++) { | TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | ||||
| TransData *td = t->data + i; | |||||
| for (i = 0; i < tc->data_len; i++) { | |||||
| TransData *td = tc->data + i; | |||||
| ListBase pidlist; | ListBase pidlist; | ||||
| PTCacheID *pid; | PTCacheID *pid; | ||||
| ob = td->ob; | ob = td->ob; | ||||
| if (td->flag & TD_NOACTION) | if (td->flag & TD_NOACTION) | ||||
| break; | break; | ||||
| if (td->flag & TD_SKIP) | if (td->flag & TD_SKIP) | ||||
| Show All 37 Lines | |||||
| int special_transform_moving(TransInfo *t) | int special_transform_moving(TransInfo *t) | ||||
| { | { | ||||
| if (t->spacetype == SPACE_SEQ) { | if (t->spacetype == SPACE_SEQ) { | ||||
| return G_TRANSFORM_SEQ; | return G_TRANSFORM_SEQ; | ||||
| } | } | ||||
| else if (t->spacetype == SPACE_IPO) { | else if (t->spacetype == SPACE_IPO) { | ||||
| return G_TRANSFORM_FCURVES; | return G_TRANSFORM_FCURVES; | ||||
| } | } | ||||
| else if (t->obedit || ((t->flag & T_POSE) && (t->poseobj))) { | else if ((t->flag & T_EDIT) || (t->flag & T_POSE)) { | ||||
| return G_TRANSFORM_EDIT; | return G_TRANSFORM_EDIT; | ||||
| } | } | ||||
| else if (t->flag & (T_OBJECT | T_TEXTURE)) { | else if (t->flag & (T_OBJECT | T_TEXTURE)) { | ||||
| return G_TRANSFORM_OBJ; | return G_TRANSFORM_OBJ; | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| static void createTransObject(bContext *C, TransInfo *t) | static void createTransObject(bContext *C, TransInfo *t) | ||||
| { | { | ||||
| TransData *td = NULL; | TransData *td = NULL; | ||||
| TransDataExtension *tx; | TransDataExtension *tx; | ||||
| const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0; | const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0; | ||||
| set_trans_object_base_flags(t); | set_trans_object_base_flags(t); | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | |||||
| /* count */ | /* count */ | ||||
| t->total = CTX_DATA_COUNT(C, selected_objects); | tc->data_len = CTX_DATA_COUNT(C, selected_objects); | ||||
| if (!t->total) { | if (!tc->data_len) { | ||||
| /* clear here, main transform function escapes too */ | /* clear here, main transform function escapes too */ | ||||
| clear_trans_object_base_flags(t); | clear_trans_object_base_flags(t); | ||||
| return; | return; | ||||
| } | } | ||||
| if (is_prop_edit) { | if (is_prop_edit) { | ||||
| t->total += count_proportional_objects(t); | tc->data_len += count_proportional_objects(t); | ||||
| } | } | ||||
| td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransOb"); | td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransOb"); | ||||
| tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "TransObExtension"); | tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "TransObExtension"); | ||||
| CTX_DATA_BEGIN(C, Base *, base, selected_bases) | CTX_DATA_BEGIN(C, Base *, base, selected_bases) | ||||
| { | { | ||||
| Object *ob = base->object; | Object *ob = base->object; | ||||
| td->flag = TD_SELECTED; | td->flag = TD_SELECTED; | ||||
| td->protectflag = ob->protectflag; | td->protectflag = ob->protectflag; | ||||
| td->ext = tx; | td->ext = tx; | ||||
| ▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | |||||
| static void createTransNodeData(bContext *UNUSED(C), TransInfo *t) | static void createTransNodeData(bContext *UNUSED(C), TransInfo *t) | ||||
| { | { | ||||
| const float dpi_fac = UI_DPI_FAC; | const float dpi_fac = UI_DPI_FAC; | ||||
| TransData *td; | TransData *td; | ||||
| TransData2D *td2d; | TransData2D *td2d; | ||||
| SpaceNode *snode = t->sa->spacedata.first; | SpaceNode *snode = t->sa->spacedata.first; | ||||
| bNode *node; | bNode *node; | ||||
| t->total = 0; | TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | ||||
| tc->data_len = 0; | |||||
| if (!snode->edittree) { | if (!snode->edittree) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* nodes dont support PET and probably never will */ | /* nodes dont support PET and probably never will */ | ||||
| t->flag &= ~T_PROP_EDIT_ALL; | t->flag &= ~T_PROP_EDIT_ALL; | ||||
| /* set transform flags on nodes */ | /* set transform flags on nodes */ | ||||
| for (node = snode->edittree->nodes.first; node; node = node->next) { | for (node = snode->edittree->nodes.first; node; node = node->next) { | ||||
| if (node->flag & NODE_SELECT && is_node_parent_select(node) == false) { | if (node->flag & NODE_SELECT && is_node_parent_select(node) == false) { | ||||
| node->flag |= NODE_TRANSFORM; | node->flag |= NODE_TRANSFORM; | ||||
| t->total++; | tc->data_len++; | ||||
| } | } | ||||
| else { | else { | ||||
| node->flag &= ~NODE_TRANSFORM; | node->flag &= ~NODE_TRANSFORM; | ||||
| } | } | ||||
| } | } | ||||
| td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransNode TransData"); | td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransNode TransData"); | ||||
| td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransNode TransData2D"); | td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransNode TransData2D"); | ||||
| for (node = snode->edittree->nodes.first; node; node = node->next) { | for (node = snode->edittree->nodes.first; node; node = node->next) { | ||||
| if (node->flag & NODE_TRANSFORM) { | if (node->flag & NODE_TRANSFORM) { | ||||
| NodeToTransData(td++, td2d++, node, dpi_fac); | NodeToTransData(td++, td2d++, node, dpi_fac); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 168 Lines • ▼ Show 20 Lines | static void planeTrackToTransData(const int framenr, TransData *td, TransData2D *td2d, | ||||
| tdt->flag = plane_marker->flag; | tdt->flag = plane_marker->flag; | ||||
| plane_marker->flag &= ~PLANE_MARKER_TRACKED; | plane_marker->flag &= ~PLANE_MARKER_TRACKED; | ||||
| for (i = 0; i < 4; i++) { | for (i = 0; i < 4; i++) { | ||||
| planeMarkerToTransDataInit(td++, td2d++, tdt++, plane_track, plane_marker->corners[i], aspect); | planeMarkerToTransDataInit(td++, td2d++, tdt++, plane_track, plane_marker->corners[i], aspect); | ||||
| } | } | ||||
| } | } | ||||
| static void transDataTrackingFree(TransInfo *UNUSED(t), TransCustomData *custom_data) | static void transDataTrackingFree(TransInfo *UNUSED(t), TransDataContainer *UNUSED(tc), TransCustomData *custom_data) | ||||
| { | { | ||||
| if (custom_data->data) { | if (custom_data->data) { | ||||
| TransDataTracking *tdt = custom_data->data; | TransDataTracking *tdt = custom_data->data; | ||||
| if (tdt->smarkers) | if (tdt->smarkers) | ||||
| MEM_freeN(tdt->smarkers); | MEM_freeN(tdt->smarkers); | ||||
| MEM_freeN(tdt); | MEM_freeN(tdt); | ||||
| custom_data->data = NULL; | custom_data->data = NULL; | ||||
| } | } | ||||
| } | } | ||||
| static void createTransTrackingTracksData(bContext *C, TransInfo *t) | static void createTransTrackingTracksData(bContext *C, TransInfo *t) | ||||
| { | { | ||||
| TransData *td; | TransData *td; | ||||
| TransData2D *td2d; | TransData2D *td2d; | ||||
| SpaceClip *sc = CTX_wm_space_clip(C); | SpaceClip *sc = CTX_wm_space_clip(C); | ||||
| MovieClip *clip = ED_space_clip_get_clip(sc); | MovieClip *clip = ED_space_clip_get_clip(sc); | ||||
| ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); | ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); | ||||
| ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking); | ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking); | ||||
| MovieTrackingTrack *track; | MovieTrackingTrack *track; | ||||
| MovieTrackingPlaneTrack *plane_track; | MovieTrackingPlaneTrack *plane_track; | ||||
| TransDataTracking *tdt; | TransDataTracking *tdt; | ||||
| int framenr = ED_space_clip_get_clip_frame_number(sc); | int framenr = ED_space_clip_get_clip_frame_number(sc); | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | |||||
| /* count */ | /* count */ | ||||
| t->total = 0; | tc->data_len = 0; | ||||
| track = tracksbase->first; | track = tracksbase->first; | ||||
| while (track) { | while (track) { | ||||
| if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { | if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { | ||||
| t->total++; /* offset */ | tc->data_len++; /* offset */ | ||||
| if (track->flag & SELECT) | if (track->flag & SELECT) | ||||
| t->total++; | tc->data_len++; | ||||
| if (track->pat_flag & SELECT) | if (track->pat_flag & SELECT) | ||||
| t->total += 4; | tc->data_len += 4; | ||||
| if (track->search_flag & SELECT) | if (track->search_flag & SELECT) | ||||
| t->total += 2; | tc->data_len += 2; | ||||
| } | } | ||||
| track = track->next; | track = track->next; | ||||
| } | } | ||||
| for (plane_track = plane_tracks_base->first; | for (plane_track = plane_tracks_base->first; | ||||
| plane_track; | plane_track; | ||||
| plane_track = plane_track->next) | plane_track = plane_track->next) | ||||
| { | { | ||||
| if (PLANE_TRACK_VIEW_SELECTED(plane_track)) { | if (PLANE_TRACK_VIEW_SELECTED(plane_track)) { | ||||
| t->total += 4; | tc->data_len += 4; | ||||
| } | } | ||||
| } | } | ||||
| if (t->total == 0) | if (tc->data_len == 0) | ||||
| return; | return; | ||||
| td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransTracking TransData"); | td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransTracking TransData"); | ||||
| td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransTracking TransData2D"); | td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransTracking TransData2D"); | ||||
| tdt = t->custom.type.data = MEM_callocN(t->total * sizeof(TransDataTracking), "TransTracking TransDataTracking"); | tdt = tc->custom.type.data = MEM_callocN(tc->data_len * sizeof(TransDataTracking), "TransTracking TransDataTracking"); | ||||
| t->custom.type.free_cb = transDataTrackingFree; | tc->custom.type.free_cb = transDataTrackingFree; | ||||
| /* create actual data */ | /* create actual data */ | ||||
| track = tracksbase->first; | track = tracksbase->first; | ||||
| while (track) { | while (track) { | ||||
| if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { | if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { | ||||
| trackToTransData(framenr, td, td2d, tdt, track, t->aspect); | trackToTransData(framenr, td, td2d, tdt, track, t->aspect); | ||||
| /* offset */ | /* offset */ | ||||
| ▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | static void createTransTrackingCurvesData(bContext *C, TransInfo *t) | ||||
| ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); | ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); | ||||
| MovieTrackingTrack *track; | MovieTrackingTrack *track; | ||||
| MovieTrackingMarker *marker, *prev_marker; | MovieTrackingMarker *marker, *prev_marker; | ||||
| TransDataTracking *tdt; | TransDataTracking *tdt; | ||||
| int i, width, height; | int i, width, height; | ||||
| BKE_movieclip_get_size(clip, &sc->user, &width, &height); | BKE_movieclip_get_size(clip, &sc->user, &width, &height); | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | |||||
| /* count */ | /* count */ | ||||
| t->total = 0; | tc->data_len = 0; | ||||
| if ((sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION) == 0) { | if ((sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION) == 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| track = tracksbase->first; | track = tracksbase->first; | ||||
| while (track) { | while (track) { | ||||
| if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { | if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { | ||||
| for (i = 1; i < track->markersnr; i++) { | for (i = 1; i < track->markersnr; i++) { | ||||
| marker = &track->markers[i]; | marker = &track->markers[i]; | ||||
| prev_marker = &track->markers[i - 1]; | prev_marker = &track->markers[i - 1]; | ||||
| if ((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED)) | if ((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED)) | ||||
| continue; | continue; | ||||
| if (marker->flag & MARKER_GRAPH_SEL_X) | if (marker->flag & MARKER_GRAPH_SEL_X) | ||||
| t->total += 1; | tc->data_len += 1; | ||||
| if (marker->flag & MARKER_GRAPH_SEL_Y) | if (marker->flag & MARKER_GRAPH_SEL_Y) | ||||
| t->total += 1; | tc->data_len += 1; | ||||
| } | } | ||||
| } | } | ||||
| track = track->next; | track = track->next; | ||||
| } | } | ||||
| if (t->total == 0) | if (tc->data_len == 0) | ||||
| return; | return; | ||||
| td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransTracking TransData"); | td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransTracking TransData"); | ||||
| td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransTracking TransData2D"); | td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransTracking TransData2D"); | ||||
| t->custom.type.data = tdt = MEM_callocN(t->total * sizeof(TransDataTracking), "TransTracking TransDataTracking"); | tc->custom.type.data = tdt = MEM_callocN(tc->data_len * sizeof(TransDataTracking), "TransTracking TransDataTracking"); | ||||
| t->custom.type.free_cb = transDataTrackingFree; | tc->custom.type.free_cb = transDataTrackingFree; | ||||
| /* create actual data */ | /* create actual data */ | ||||
| track = tracksbase->first; | track = tracksbase->first; | ||||
| while (track) { | while (track) { | ||||
| if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { | if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { | ||||
| for (i = 1; i < track->markersnr; i++) { | for (i = 1; i < track->markersnr; i++) { | ||||
| marker = &track->markers[i]; | marker = &track->markers[i]; | ||||
| prev_marker = &track->markers[i - 1]; | prev_marker = &track->markers[i - 1]; | ||||
| Show All 24 Lines | |||||
| static void createTransTrackingData(bContext *C, TransInfo *t) | static void createTransTrackingData(bContext *C, TransInfo *t) | ||||
| { | { | ||||
| ARegion *ar = CTX_wm_region(C); | ARegion *ar = CTX_wm_region(C); | ||||
| SpaceClip *sc = CTX_wm_space_clip(C); | SpaceClip *sc = CTX_wm_space_clip(C); | ||||
| MovieClip *clip = ED_space_clip_get_clip(sc); | MovieClip *clip = ED_space_clip_get_clip(sc); | ||||
| int width, height; | int width, height; | ||||
| t->total = 0; | TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | ||||
| tc->data_len = 0; | |||||
| if (!clip) | if (!clip) | ||||
| return; | return; | ||||
| BKE_movieclip_get_size(clip, &sc->user, &width, &height); | BKE_movieclip_get_size(clip, &sc->user, &width, &height); | ||||
| if (width == 0 || height == 0) | if (width == 0 || height == 0) | ||||
| return; | return; | ||||
| if (ar->regiontype == RGN_TYPE_PREVIEW) { | if (ar->regiontype == RGN_TYPE_PREVIEW) { | ||||
| /* transformation was called from graph editor */ | /* transformation was called from graph editor */ | ||||
| createTransTrackingCurvesData(C, t); | createTransTrackingCurvesData(C, t); | ||||
| } | } | ||||
| else { | else { | ||||
| createTransTrackingTracksData(C, t); | createTransTrackingTracksData(C, t); | ||||
| } | } | ||||
| } | } | ||||
| static void cancelTransTracking(TransInfo *t) | static void cancelTransTracking(TransInfo *t) | ||||
| { | { | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | |||||
| SpaceClip *sc = t->sa->spacedata.first; | SpaceClip *sc = t->sa->spacedata.first; | ||||
| int i, framenr = ED_space_clip_get_clip_frame_number(sc); | int i, framenr = ED_space_clip_get_clip_frame_number(sc); | ||||
| TransDataTracking *tdt_array = t->custom.type.data; | TransDataTracking *tdt_array = tc->custom.type.data; | ||||
| i = 0; | i = 0; | ||||
| while (i < t->total) { | while (i < tc->data_len) { | ||||
| TransDataTracking *tdt = &tdt_array[i]; | TransDataTracking *tdt = &tdt_array[i]; | ||||
| if (tdt->mode == transDataTracking_ModeTracks) { | if (tdt->mode == transDataTracking_ModeTracks) { | ||||
| MovieTrackingTrack *track = tdt->track; | MovieTrackingTrack *track = tdt->track; | ||||
| MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); | MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); | ||||
| marker->flag = tdt->flag; | marker->flag = tdt->flag; | ||||
| Show All 40 Lines | void flushTransTracking(TransInfo *t) | ||||
| TransData *td; | TransData *td; | ||||
| TransData2D *td2d; | TransData2D *td2d; | ||||
| TransDataTracking *tdt; | TransDataTracking *tdt; | ||||
| int a; | int a; | ||||
| if (t->state == TRANS_CANCEL) | if (t->state == TRANS_CANCEL) | ||||
| cancelTransTracking(t); | cancelTransTracking(t); | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | |||||
| /* flush to 2d vector from internally used 3d vector */ | /* flush to 2d vector from internally used 3d vector */ | ||||
| for (a = 0, td = t->data, td2d = t->data2d, tdt = t->custom.type.data; a < t->total; a++, td2d++, td++, tdt++) { | for (a = 0, td = tc->data, td2d = tc->data_2d, tdt = tc->custom.type.data; a < tc->data_len; a++, td2d++, td++, tdt++) { | ||||
| if (tdt->mode == transDataTracking_ModeTracks) { | if (tdt->mode == transDataTracking_ModeTracks) { | ||||
| float loc2d[2]; | float loc2d[2]; | ||||
| if (t->mode == TFM_ROTATION && tdt->area == TRACK_AREA_SEARCH) { | if (t->mode == TFM_ROTATION && tdt->area == TRACK_AREA_SEARCH) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| loc2d[0] = td2d->loc[0] / t->aspect[0]; | loc2d[0] = td2d->loc[0] / t->aspect[0]; | ||||
| ▲ Show 20 Lines • Show All 249 Lines • ▼ Show 20 Lines | static void createTransMaskingData(bContext *C, TransInfo *t) | ||||
| MaskLayer *masklay; | MaskLayer *masklay; | ||||
| TransData *td = NULL; | TransData *td = NULL; | ||||
| TransData2D *td2d = NULL; | TransData2D *td2d = NULL; | ||||
| TransDataMasking *tdm = NULL; | TransDataMasking *tdm = NULL; | ||||
| int count = 0, countsel = 0; | int count = 0, countsel = 0; | ||||
| const bool is_prop_edit = (t->flag & T_PROP_EDIT); | const bool is_prop_edit = (t->flag & T_PROP_EDIT); | ||||
| float asp[2]; | float asp[2]; | ||||
| t->total = 0; | TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | ||||
| tc->data_len = 0; | |||||
| if (!mask) | if (!mask) | ||||
| return; | return; | ||||
| if (t->spacetype == SPACE_CLIP) { | if (t->spacetype == SPACE_CLIP) { | ||||
| SpaceClip *sc = t->sa->spacedata.first; | SpaceClip *sc = t->sa->spacedata.first; | ||||
| MovieClip *clip = ED_space_clip_get_clip(sc); | MovieClip *clip = ED_space_clip_get_clip(sc); | ||||
| if (!clip) { | if (!clip) { | ||||
| ▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | static void createTransMaskingData(bContext *C, TransInfo *t) | ||||
| /* note: in prop mode we need at least 1 selected */ | /* note: in prop mode we need at least 1 selected */ | ||||
| if (countsel == 0) { | if (countsel == 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| ED_mask_get_aspect(t->sa, t->ar, &asp[0], &asp[1]); | ED_mask_get_aspect(t->sa, t->ar, &asp[0], &asp[1]); | ||||
| t->total = (is_prop_edit) ? count : countsel; | tc->data_len = (is_prop_edit) ? count : countsel; | ||||
| td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Mask Editing)"); | td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Mask Editing)"); | ||||
| /* 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 */ | ||||
| td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransObData2D(Mask Editing)"); | td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransObData2D(Mask Editing)"); | ||||
| t->custom.type.data = tdm = MEM_callocN(t->total * sizeof(TransDataMasking), "TransDataMasking(Mask Editing)"); | tc->custom.type.data = tdm = MEM_callocN(tc->data_len * sizeof(TransDataMasking), "TransDataMasking(Mask Editing)"); | ||||
| t->custom.type.use_free = true; | tc->custom.type.use_free = true; | ||||
| /* create data */ | /* create data */ | ||||
| for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { | for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { | ||||
| MaskSpline *spline; | MaskSpline *spline; | ||||
| if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { | if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| Show All 40 Lines | |||||
| void flushTransMasking(TransInfo *t) | void flushTransMasking(TransInfo *t) | ||||
| { | { | ||||
| TransData2D *td; | TransData2D *td; | ||||
| TransDataMasking *tdm; | TransDataMasking *tdm; | ||||
| int a; | int a; | ||||
| float asp[2], inv[2]; | float asp[2], inv[2]; | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | |||||
| ED_mask_get_aspect(t->sa, t->ar, &asp[0], &asp[1]); | ED_mask_get_aspect(t->sa, t->ar, &asp[0], &asp[1]); | ||||
| inv[0] = 1.0f / asp[0]; | inv[0] = 1.0f / asp[0]; | ||||
| inv[1] = 1.0f / asp[1]; | inv[1] = 1.0f / asp[1]; | ||||
| /* flush to 2d vector from internally used 3d vector */ | /* flush to 2d vector from internally used 3d vector */ | ||||
| for (a = 0, td = t->data2d, tdm = t->custom.type.data; a < t->total; a++, td++, tdm++) { | for (a = 0, td = tc->data_2d, tdm = tc->custom.type.data; a < tc->data_len; a++, td++, tdm++) { | ||||
| td->loc2d[0] = td->loc[0] * inv[0]; | td->loc2d[0] = td->loc[0] * inv[0]; | ||||
| td->loc2d[1] = td->loc[1] * inv[1]; | td->loc2d[1] = td->loc[1] * inv[1]; | ||||
| mul_m3_v2(tdm->parent_inverse_matrix, td->loc2d); | mul_m3_v2(tdm->parent_inverse_matrix, td->loc2d); | ||||
| if (tdm->is_handle) { | if (tdm->is_handle) { | ||||
| BKE_mask_point_set_handle(tdm->point, tdm->which_handle, | BKE_mask_point_set_handle(tdm->point, tdm->which_handle, | ||||
| td->loc2d, | td->loc2d, | ||||
| (t->flag & T_ALT_TRANSFORM) != 0, | (t->flag & T_ALT_TRANSFORM) != 0, | ||||
| ▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | static void createTransPaintCurveVerts(bContext *C, TransInfo *t) | ||||
| PaintCurvePoint *pcp; | PaintCurvePoint *pcp; | ||||
| Brush *br; | Brush *br; | ||||
| TransData *td = NULL; | TransData *td = NULL; | ||||
| TransData2D *td2d = NULL; | TransData2D *td2d = NULL; | ||||
| TransDataPaintCurve *tdpc = NULL; | TransDataPaintCurve *tdpc = NULL; | ||||
| int i; | int i; | ||||
| int total = 0; | int total = 0; | ||||
| t->total = 0; | TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | ||||
| tc->data_len = 0; | |||||
| if (!paint || !paint->brush || !paint->brush->paint_curve) | if (!paint || !paint->brush || !paint->brush->paint_curve) | ||||
| return; | return; | ||||
| br = paint->brush; | br = paint->brush; | ||||
| pc = br->paint_curve; | pc = br->paint_curve; | ||||
| for (pcp = pc->points, i = 0; i < pc->tot_points; i++, pcp++) { | for (pcp = pc->points, i = 0; i < pc->tot_points; i++, pcp++) { | ||||
| Show All 9 Lines | if (PC_IS_ANY_SEL(pcp)) { | ||||
| total++; | total++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (!total) | if (!total) | ||||
| return; | return; | ||||
| t->total = total; | tc->data_len = total; | ||||
| td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransData2D"); | td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransData2D"); | ||||
| td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransData"); | td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransData"); | ||||
| t->custom.type.data = tdpc = MEM_callocN(t->total * sizeof(TransDataPaintCurve), "TransDataPaintCurve"); | tc->custom.type.data = tdpc = MEM_callocN(tc->data_len * sizeof(TransDataPaintCurve), "TransDataPaintCurve"); | ||||
| t->custom.type.use_free = true; | tc->custom.type.use_free = true; | ||||
| for (pcp = pc->points, i = 0; i < pc->tot_points; i++, pcp++) { | for (pcp = pc->points, i = 0; i < pc->tot_points; i++, pcp++) { | ||||
| if (PC_IS_ANY_SEL(pcp)) { | if (PC_IS_ANY_SEL(pcp)) { | ||||
| PaintCurvePointToTransData(pcp, td, td2d, tdpc); | PaintCurvePointToTransData(pcp, td, td2d, tdpc); | ||||
| if (pcp->bez.f2 & SELECT) { | if (pcp->bez.f2 & SELECT) { | ||||
| td += 3; | td += 3; | ||||
| td2d += 3; | td2d += 3; | ||||
| Show All 14 Lines | for (pcp = pc->points, i = 0; i < pc->tot_points; i++, pcp++) { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void flushTransPaintCurve(TransInfo *t) | void flushTransPaintCurve(TransInfo *t) | ||||
| { | { | ||||
| int i; | int i; | ||||
| TransData2D *td2d = t->data2d; | |||||
| TransDataPaintCurve *tdpc = t->custom.type.data; | |||||
| for (i = 0; i < t->total; i++, tdpc++, td2d++) { | TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | ||||
| TransData2D *td2d = tc->data_2d; | |||||
| TransDataPaintCurve *tdpc = tc->custom.type.data; | |||||
| for (i = 0; i < tc->data_len; i++, tdpc++, td2d++) { | |||||
| PaintCurvePoint *pcp = tdpc->pcp; | PaintCurvePoint *pcp = tdpc->pcp; | ||||
| copy_v2_v2(pcp->bez.vec[tdpc->id], td2d->loc); | copy_v2_v2(pcp->bez.vec[tdpc->id], td2d->loc); | ||||
| } | } | ||||
| } | } | ||||
| static void createTransGPencil(bContext *C, TransInfo *t) | static void createTransGPencil(bContext *C, TransInfo *t) | ||||
| { | { | ||||
| bGPdata *gpd = ED_gpencil_data_get_active(C); | bGPdata *gpd = ED_gpencil_data_get_active(C); | ||||
| bGPDlayer *gpl; | bGPDlayer *gpl; | ||||
| TransData *td = NULL; | TransData *td = NULL; | ||||
| float mtx[3][3], smtx[3][3]; | float mtx[3][3], smtx[3][3]; | ||||
| const Scene *scene = CTX_data_scene(C); | const Scene *scene = CTX_data_scene(C); | ||||
| const int cfra_scene = CFRA; | const int cfra_scene = CFRA; | ||||
| 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_edit_connected = (t->flag & T_PROP_CONNECTED) != 0; | const bool is_prop_edit_connected = (t->flag & T_PROP_CONNECTED) != 0; | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | |||||
| /* == Grease Pencil Strokes to Transform Data == | /* == Grease Pencil Strokes to Transform Data == | ||||
| * Grease Pencil stroke points can be a mixture of 2D (screen-space), | * Grease Pencil stroke points can be a mixture of 2D (screen-space), | ||||
| * or 3D coordinates. However, they're always saved as 3D points. | * or 3D coordinates. However, they're always saved as 3D points. | ||||
| * For now, we just do these without creating TransData2D for the 2D | * For now, we just do these without creating TransData2D for the 2D | ||||
| * strokes. This may cause issues in future though. | * strokes. This may cause issues in future though. | ||||
| */ | */ | ||||
| t->total = 0; | tc->data_len = 0; | ||||
| if (gpd == NULL) | if (gpd == NULL) | ||||
| return; | return; | ||||
| /* First Pass: Count the number of datapoints required for the strokes, | /* First Pass: Count the number of datapoints required for the strokes, | ||||
| * (and additional info about the configuration - e.g. 2D/3D?) | * (and additional info about the configuration - e.g. 2D/3D?) | ||||
| */ | */ | ||||
| for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { | for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { | ||||
| Show All 12 Lines | if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (is_prop_edit) { | if (is_prop_edit) { | ||||
| /* Proportional Editing... */ | /* Proportional Editing... */ | ||||
| if (is_prop_edit_connected) { | if (is_prop_edit_connected) { | ||||
| /* connected only - so only if selected */ | /* connected only - so only if selected */ | ||||
| if (gps->flag & GP_STROKE_SELECT) | if (gps->flag & GP_STROKE_SELECT) | ||||
| t->total += gps->totpoints; | tc->data_len += gps->totpoints; | ||||
| } | } | ||||
| else { | else { | ||||
| /* everything goes - connection status doesn't matter */ | /* everything goes - connection status doesn't matter */ | ||||
| t->total += gps->totpoints; | tc->data_len += gps->totpoints; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* only selected stroke points are considered */ | /* only selected stroke points are considered */ | ||||
| if (gps->flag & GP_STROKE_SELECT) { | if (gps->flag & GP_STROKE_SELECT) { | ||||
| bGPDspoint *pt; | bGPDspoint *pt; | ||||
| int i; | int i; | ||||
| // TODO: 2D vs 3D? | // TODO: 2D vs 3D? | ||||
| for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { | for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { | ||||
| if (pt->flag & GP_SPOINT_SELECT) | if (pt->flag & GP_SPOINT_SELECT) | ||||
| t->total++; | tc->data_len++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Stop trying if nothing selected */ | /* Stop trying if nothing selected */ | ||||
| if (t->total == 0) { | if (tc->data_len == 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* Allocate memory for data */ | /* Allocate memory for data */ | ||||
| t->data = MEM_callocN(t->total * sizeof(TransData), "TransData(GPencil)"); | tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransData(GPencil)"); | ||||
| td = t->data; | td = tc->data; | ||||
| unit_m3(smtx); | unit_m3(smtx); | ||||
| unit_m3(mtx); | unit_m3(mtx); | ||||
| /* Second Pass: Build transdata array */ | /* Second Pass: Build transdata array */ | ||||
| for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { | for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { | ||||
| /* only editable and visible layers are considered */ | /* only editable and visible layers are considered */ | ||||
| if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) { | if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) { | ||||
| ▲ Show 20 Lines • Show All 151 Lines • ▼ Show 20 Lines | #endif | ||||
| calc_distanceCurveVerts(head, tail - 1); | calc_distanceCurveVerts(head, tail - 1); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static int countAndCleanTransDataContainer(TransInfo *t) | |||||
| { | |||||
| BLI_assert(ELEM(t->data_len_all, 0, -1)); | |||||
| t->data_len_all = 0; | |||||
| uint data_container_len_orig = t->data_container_len; | |||||
| for (TransDataContainer *th_end = t->data_container - 1, *tc = t->data_container + (t->data_container_len - 1); tc != th_end; tc--) { | |||||
| if (tc->data_len == 0) { | |||||
| uint index = tc - t->data_container; | |||||
| if (index + 1 != t->data_container_len) { | |||||
| SWAP(TransDataContainer, t->data_container[index], t->data_container[t->data_container_len - 1]); | |||||
| } | |||||
| t->data_container_len -= 1; | |||||
| } | |||||
| else { | |||||
| t->data_len_all += tc->data_len; | |||||
| } | |||||
| } | |||||
| if (data_container_len_orig != t->data_container_len) { | |||||
| t->data_container = MEM_reallocN(t->data_container, sizeof(*t->data_container) * t->data_container_len); | |||||
| } | |||||
| return t->data_len_all; | |||||
| } | |||||
| void createTransData(bContext *C, TransInfo *t) | void createTransData(bContext *C, TransInfo *t) | ||||
| { | { | ||||
| Scene *scene = t->scene; | Scene *scene = t->scene; | ||||
| ViewLayer *view_layer = t->view_layer; | ViewLayer *view_layer = t->view_layer; | ||||
| Object *ob = OBACT(view_layer); | Object *ob = OBACT(view_layer); | ||||
| t->data_len_all = -1; | |||||
| /* if tests must match recalcData for correct updates */ | /* if tests must match recalcData for correct updates */ | ||||
| if (t->options & CTX_TEXTURE) { | if (t->options & CTX_TEXTURE) { | ||||
| t->flag |= T_TEXTURE; | t->flag |= T_TEXTURE; | ||||
| createTransTexspace(t); | createTransTexspace(t); | ||||
| countAndCleanTransDataContainer(t); | |||||
| } | } | ||||
| else if (t->options & CTX_EDGE) { | else if (t->options & CTX_EDGE) { | ||||
| t->ext = NULL; | /* Multi object editing. */ | ||||
| initTransDataContainers_FromObjectData(t); | |||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | |||||
| tc->data_ext = NULL; | |||||
| } | |||||
| t->flag |= T_EDIT; | t->flag |= T_EDIT; | ||||
| createTransEdge(t); | createTransEdge(t); | ||||
| if (t->data && t->flag & T_PROP_EDIT) { | countAndCleanTransDataContainer(t); | ||||
| if (t->data_len_all && t->flag & T_PROP_EDIT) { | |||||
| sort_trans_data(t); // makes selected become first in array | sort_trans_data(t); // makes selected become first in array | ||||
| set_prop_dist(t, 1); | set_prop_dist(t, 1); | ||||
| sort_trans_data_dist(t); | sort_trans_data_dist(t); | ||||
| } | } | ||||
| } | } | ||||
| else if (t->options & CTX_GPENCIL_STROKES) { | else if (t->options & CTX_GPENCIL_STROKES) { | ||||
| t->options |= CTX_GPENCIL_STROKES; | t->options |= CTX_GPENCIL_STROKES; | ||||
| t->flag |= T_POINTS; | t->flag |= T_POINTS; | ||||
| createTransGPencil(C, t); | createTransGPencil(C, t); | ||||
| countAndCleanTransDataContainer(t); | |||||
| if (t->data && (t->flag & T_PROP_EDIT)) { | if (t->data_len_all && (t->flag & T_PROP_EDIT)) { | ||||
| sort_trans_data(t); // makes selected become first in array | sort_trans_data(t); // makes selected become first in array | ||||
| set_prop_dist(t, 1); | set_prop_dist(t, 1); | ||||
| sort_trans_data_dist(t); | sort_trans_data_dist(t); | ||||
| } | } | ||||
| } | } | ||||
| else if (t->spacetype == SPACE_IMAGE) { | else if (t->spacetype == SPACE_IMAGE) { | ||||
| t->flag |= T_POINTS | T_2D_EDIT; | t->flag |= T_POINTS | T_2D_EDIT; | ||||
| if (t->options & CTX_MASK) { | if (t->options & CTX_MASK) { | ||||
| /* copied from below */ | /* copied from below */ | ||||
| createTransMaskingData(C, t); | createTransMaskingData(C, t); | ||||
| countAndCleanTransDataContainer(t); | |||||
| if (t->data && (t->flag & T_PROP_EDIT)) { | if (t->data_len_all && (t->flag & T_PROP_EDIT)) { | ||||
| sort_trans_data(t); // makes selected become first in array | sort_trans_data(t); // makes selected become first in array | ||||
| set_prop_dist(t, true); | set_prop_dist(t, true); | ||||
| sort_trans_data_dist(t); | sort_trans_data_dist(t); | ||||
| } | } | ||||
| } | } | ||||
| else if (t->options & CTX_PAINT_CURVE) { | else if (t->options & CTX_PAINT_CURVE) { | ||||
| if (!ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) | if (!ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) { | ||||
| createTransPaintCurveVerts(C, t); | createTransPaintCurveVerts(C, t); | ||||
| countAndCleanTransDataContainer(t); | |||||
| } | } | ||||
| else if (t->obedit) { | } | ||||
| else if (t->obedit_type == OB_MESH) { | |||||
| initTransDataContainers_FromObjectData(t); | |||||
| createTransUVs(C, t); | createTransUVs(C, t); | ||||
| if (t->data && (t->flag & T_PROP_EDIT)) { | countAndCleanTransDataContainer(t); | ||||
| t->flag |= T_EDIT; | |||||
| if (t->data_len_all && (t->flag & T_PROP_EDIT)) { | |||||
| sort_trans_data(t); // makes selected become first in array | sort_trans_data(t); // makes selected become first in array | ||||
| set_prop_dist(t, 1); | set_prop_dist(t, 1); | ||||
| sort_trans_data_dist(t); | sort_trans_data_dist(t); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (t->spacetype == SPACE_ACTION) { | else if (t->spacetype == SPACE_ACTION) { | ||||
| t->flag |= T_POINTS | T_2D_EDIT; | t->flag |= T_POINTS | T_2D_EDIT; | ||||
| createTransActionData(C, t); | createTransActionData(C, t); | ||||
| countAndCleanTransDataContainer(t); | |||||
| if (t->data && (t->flag & T_PROP_EDIT)) { | if (t->data_len_all && (t->flag & T_PROP_EDIT)) { | ||||
| sort_trans_data(t); // makes selected become first in array | sort_trans_data(t); // makes selected become first in array | ||||
| //set_prop_dist(t, false); /* don't do that, distance has been set in createTransActionData already */ | //set_prop_dist(t, false); /* don't do that, distance has been set in createTransActionData already */ | ||||
| sort_trans_data_dist(t); | sort_trans_data_dist(t); | ||||
| } | } | ||||
| } | } | ||||
| else if (t->spacetype == SPACE_NLA) { | else if (t->spacetype == SPACE_NLA) { | ||||
| t->flag |= T_POINTS | T_2D_EDIT; | t->flag |= T_POINTS | T_2D_EDIT; | ||||
| createTransNlaData(C, t); | createTransNlaData(C, t); | ||||
| countAndCleanTransDataContainer(t); | |||||
| } | } | ||||
| else if (t->spacetype == SPACE_SEQ) { | else if (t->spacetype == SPACE_SEQ) { | ||||
| t->flag |= T_POINTS | T_2D_EDIT; | t->flag |= T_POINTS | T_2D_EDIT; | ||||
| t->num.flag |= NUM_NO_FRACTION; /* sequencer has no use for floating point transformations */ | t->num.flag |= NUM_NO_FRACTION; /* sequencer has no use for floating point transformations */ | ||||
| createTransSeqData(C, t); | createTransSeqData(C, t); | ||||
| countAndCleanTransDataContainer(t); | |||||
| } | } | ||||
| else if (t->spacetype == SPACE_IPO) { | else if (t->spacetype == SPACE_IPO) { | ||||
| t->flag |= T_POINTS | T_2D_EDIT; | t->flag |= T_POINTS | T_2D_EDIT; | ||||
| createTransGraphEditData(C, t); | createTransGraphEditData(C, t); | ||||
| countAndCleanTransDataContainer(t); | |||||
| if (t->data && (t->flag & T_PROP_EDIT)) { | if (t->data_len_all && (t->flag & T_PROP_EDIT)) { | ||||
| sort_trans_data(t); // makes selected become first in array | sort_trans_data(t); // makes selected become first in array | ||||
| set_prop_dist(t, false); /* don't do that, distance has been set in createTransGraphEditData already */ | set_prop_dist(t, false); /* don't do that, distance has been set in createTransGraphEditData already */ | ||||
| sort_trans_data_dist(t); | sort_trans_data_dist(t); | ||||
| } | } | ||||
| } | } | ||||
| else if (t->spacetype == SPACE_NODE) { | else if (t->spacetype == SPACE_NODE) { | ||||
| t->flag |= T_POINTS | T_2D_EDIT; | t->flag |= T_POINTS | T_2D_EDIT; | ||||
| createTransNodeData(C, t); | createTransNodeData(C, t); | ||||
| if (t->data && (t->flag & T_PROP_EDIT)) { | countAndCleanTransDataContainer(t); | ||||
| if (t->data_len_all && (t->flag & T_PROP_EDIT)) { | |||||
| sort_trans_data(t); // makes selected become first in array | sort_trans_data(t); // makes selected become first in array | ||||
| set_prop_dist(t, 1); | set_prop_dist(t, 1); | ||||
| sort_trans_data_dist(t); | sort_trans_data_dist(t); | ||||
| } | } | ||||
| } | } | ||||
| else if (t->spacetype == SPACE_CLIP) { | else if (t->spacetype == SPACE_CLIP) { | ||||
| t->flag |= T_POINTS | T_2D_EDIT; | t->flag |= T_POINTS | T_2D_EDIT; | ||||
| if (t->options & CTX_MOVIECLIP) | if (t->options & CTX_MOVIECLIP) { | ||||
| createTransTrackingData(C, t); | createTransTrackingData(C, t); | ||||
| countAndCleanTransDataContainer(t); | |||||
| } | |||||
| else if (t->options & CTX_MASK) { | else if (t->options & CTX_MASK) { | ||||
| /* copied from above */ | /* copied from above */ | ||||
| createTransMaskingData(C, t); | createTransMaskingData(C, t); | ||||
| countAndCleanTransDataContainer(t); | |||||
| if (t->data && (t->flag & T_PROP_EDIT)) { | if (t->data_len_all && (t->flag & T_PROP_EDIT)) { | ||||
| sort_trans_data(t); // makes selected become first in array | sort_trans_data(t); // makes selected become first in array | ||||
| set_prop_dist(t, true); | set_prop_dist(t, true); | ||||
| sort_trans_data_dist(t); | sort_trans_data_dist(t); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (t->obedit) { | else if (t->obedit_type != -1) { | ||||
| t->ext = NULL; | /* Multi object editing. */ | ||||
| if (t->obedit->type == OB_MESH) { | initTransDataContainers_FromObjectData(t); | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | |||||
| tc->data_ext = NULL; | |||||
| } | |||||
| if (t->obedit_type == OB_MESH) { | |||||
| createTransEditVerts(t); | createTransEditVerts(t); | ||||
| } | } | ||||
| else if (ELEM(t->obedit->type, OB_CURVE, OB_SURF)) { | else if (ELEM(t->obedit_type, OB_CURVE, OB_SURF)) { | ||||
| createTransCurveVerts(t); | createTransCurveVerts(t); | ||||
| } | } | ||||
| else if (t->obedit->type == OB_LATTICE) { | else if (t->obedit_type == OB_LATTICE) { | ||||
| createTransLatticeVerts(t); | createTransLatticeVerts(t); | ||||
| } | } | ||||
| else if (t->obedit->type == OB_MBALL) { | else if (t->obedit_type == OB_MBALL) { | ||||
| createTransMBallVerts(t); | createTransMBallVerts(t); | ||||
| } | } | ||||
| else if (t->obedit->type == OB_ARMATURE) { | else if (t->obedit_type == OB_ARMATURE) { | ||||
| t->flag &= ~T_PROP_EDIT; | t->flag &= ~T_PROP_EDIT; | ||||
| createTransArmatureVerts(t); | createTransArmatureVerts(t); | ||||
| } | } | ||||
| else { | else { | ||||
| printf("edit type not implemented!\n"); | printf("edit type not implemented!\n"); | ||||
| } | } | ||||
| countAndCleanTransDataContainer(t); | |||||
| t->flag |= T_EDIT | T_POINTS; | t->flag |= T_EDIT | T_POINTS; | ||||
| if (t->data && t->flag & T_PROP_EDIT) { | if (t->data_len_all && t->flag & T_PROP_EDIT) { | ||||
| if (ELEM(t->obedit->type, OB_CURVE, OB_MESH)) { | if (ELEM(t->obedit_type, OB_CURVE, OB_MESH)) { | ||||
| sort_trans_data(t); // makes selected become first in array | sort_trans_data(t); // makes selected become first in array | ||||
| if ((t->obedit->type == OB_MESH) && (t->flag & T_PROP_CONNECTED)) { | if ((t->obedit_type == OB_MESH) && (t->flag & T_PROP_CONNECTED)) { | ||||
| /* already calculated by editmesh_set_connectivity_distance */ | /* already calculated by editmesh_set_connectivity_distance */ | ||||
| } | } | ||||
| else { | else { | ||||
| set_prop_dist(t, 0); | set_prop_dist(t, 0); | ||||
| } | } | ||||
| sort_trans_data_dist(t); | sort_trans_data_dist(t); | ||||
| } | } | ||||
| else { | else { | ||||
| sort_trans_data(t); // makes selected become first in array | sort_trans_data(t); // makes selected become first in array | ||||
| set_prop_dist(t, 1); | set_prop_dist(t, 1); | ||||
| sort_trans_data_dist(t); | sort_trans_data_dist(t); | ||||
| } | } | ||||
| } | } | ||||
| /* exception... hackish, we want bonesize to use bone orientation matrix (ton) */ | /* exception... hackish, we want bonesize to use bone orientation matrix (ton) */ | ||||
| if (t->mode == TFM_BONESIZE) { | if (t->mode == TFM_BONESIZE) { | ||||
| t->flag &= ~(T_EDIT | T_POINTS); | t->flag &= ~(T_EDIT | T_POINTS); | ||||
| t->flag |= T_POSE; | t->flag |= T_POSE; | ||||
| t->poseobj = ob; /* <- tsk tsk, this is going to give issues one day */ | |||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | |||||
| tc->poseobj = tc->obedit; | |||||
| tc->obedit = NULL; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| else if (ob && (ob->mode & OB_MODE_POSE)) { | else if (ob && (ob->mode & OB_MODE_POSE)) { | ||||
| // XXX this is currently limited to active armature only... | // XXX this is currently limited to active armature only... | ||||
| // XXX active-layer checking isn't done as that should probably be checked through context instead | // XXX active-layer checking isn't done as that should probably be checked through context instead | ||||
| createTransPose(t, ob); | |||||
| /* Multi object editing. */ | |||||
| initTransDataContainers_FromObjectData(t); | |||||
| createTransPose(t, NULL, 0); | |||||
| countAndCleanTransDataContainer(t); | |||||
| } | } | ||||
| else if (ob && (ob->mode & OB_MODE_WEIGHT_PAINT) && !(t->options & CTX_PAINT_CURVE)) { | else if (ob && (ob->mode & OB_MODE_WEIGHT_PAINT) && !(t->options & CTX_PAINT_CURVE)) { | ||||
| /* important that ob_armature can be set even when its not selected [#23412] | /* important that ob_armature can be set even when its not selected [#23412] | ||||
| * lines below just check is also visible */ | * lines below just check is also visible */ | ||||
| Object *ob_armature = modifiers_isDeformedByArmature(ob); | Object *ob_armature = modifiers_isDeformedByArmature(ob); | ||||
| if (ob_armature && ob_armature->mode & OB_MODE_POSE) { | if (ob_armature && ob_armature->mode & OB_MODE_POSE) { | ||||
| Base *base_arm = BKE_view_layer_base_find(t->view_layer, ob_armature); | Base *base_arm = BKE_view_layer_base_find(t->view_layer, ob_armature); | ||||
| if (base_arm) { | if (base_arm) { | ||||
| if (BASE_VISIBLE(base_arm)) { | if (BASE_VISIBLE(base_arm)) { | ||||
| createTransPose(t, ob_armature); | Object *objects[1]; | ||||
| objects[0] = ob_armature; | |||||
| uint objects_len = 1; | |||||
| createTransPose(t, objects, objects_len); | |||||
| countAndCleanTransDataContainer(t); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) && PE_start_edit(PE_get_current(scene, ob))) { | else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) && PE_start_edit(PE_get_current(scene, ob))) { | ||||
| createTransParticleVerts(C, t); | createTransParticleVerts(C, t); | ||||
| countAndCleanTransDataContainer(t); | |||||
| t->flag |= T_POINTS; | t->flag |= T_POINTS; | ||||
| if (t->data && t->flag & T_PROP_EDIT) { | if (t->data_len_all && t->flag & T_PROP_EDIT) { | ||||
| sort_trans_data(t); // makes selected become first in array | sort_trans_data(t); // makes selected become first in array | ||||
| set_prop_dist(t, 1); | set_prop_dist(t, 1); | ||||
| sort_trans_data_dist(t); | sort_trans_data_dist(t); | ||||
| } | } | ||||
| } | } | ||||
| else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) { | else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) { | ||||
| if ((t->options & CTX_PAINT_CURVE) && !ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) { | if ((t->options & CTX_PAINT_CURVE) && !ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) { | ||||
| t->flag |= T_POINTS | T_2D_EDIT; | t->flag |= T_POINTS | T_2D_EDIT; | ||||
| createTransPaintCurveVerts(C, t); | createTransPaintCurveVerts(C, t); | ||||
| countAndCleanTransDataContainer(t); | |||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| createTransObject(C, t); | createTransObject(C, t); | ||||
| countAndCleanTransDataContainer(t); | |||||
| t->flag |= T_OBJECT; | t->flag |= T_OBJECT; | ||||
| if (t->data && t->flag & T_PROP_EDIT) { | if (t->data_len_all && t->flag & T_PROP_EDIT) { | ||||
| // selected objects are already first, no need to presort | // selected objects are already first, no need to presort | ||||
| set_prop_dist(t, 1); | set_prop_dist(t, 1); | ||||
| sort_trans_data_dist(t); | sort_trans_data_dist(t); | ||||
| } | } | ||||
| /* Check if we're transforming the camera from the camera */ | /* Check if we're transforming the camera from the camera */ | ||||
| if ((t->spacetype == SPACE_VIEW3D) && (t->ar->regiontype == RGN_TYPE_WINDOW)) { | if ((t->spacetype == SPACE_VIEW3D) && (t->ar->regiontype == RGN_TYPE_WINDOW)) { | ||||
| View3D *v3d = t->view; | View3D *v3d = t->view; | ||||
| RegionView3D *rv3d = t->ar->regiondata; | RegionView3D *rv3d = t->ar->regiondata; | ||||
| if ((rv3d->persp == RV3D_CAMOB) && v3d->camera) { | if ((rv3d->persp == RV3D_CAMOB) && v3d->camera) { | ||||
| /* we could have a flag to easily check an object is being transformed */ | /* we could have a flag to easily check an object is being transformed */ | ||||
| if (v3d->camera->id.tag & LIB_TAG_DOIT) { | if (v3d->camera->id.tag & LIB_TAG_DOIT) { | ||||
| t->flag |= T_CAMERA; | t->flag |= T_CAMERA; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Check that 'countAndCleanTransDataContainer' ran. */ | |||||
| BLI_assert(t->data_len_all != -1); | |||||
| } | } | ||||