Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/transform/transform_generics.c
| Show First 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | |||||
| #include "RE_engine.h" | #include "RE_engine.h" | ||||
| #include "UI_resources.h" | #include "UI_resources.h" | ||||
| #include "UI_view2d.h" | #include "UI_view2d.h" | ||||
| #include "transform.h" | #include "transform.h" | ||||
| #include "transform_convert.h" | #include "transform_convert.h" | ||||
| #include "transform_data.h" | |||||
| #include "transform_mode.h" | #include "transform_mode.h" | ||||
| #include "transform_snap.h" | #include "transform_snap.h" | ||||
| /* ************************** Functions *************************** */ | /* ************************** Functions *************************** */ | ||||
| void getViewVector(const TransInfo *t, const float coord[3], float vec[3]) | void getViewVector(const TransInfo *t, const float coord[3], float vec[3]) | ||||
| { | { | ||||
| if (t->persp != RV3D_ORTHO) { | if (t->persp != RV3D_ORTHO) { | ||||
| Show All 30 Lines | for (; md; md = md->next) { | ||||
| tolerance[1] = mmd->tolerance; | tolerance[1] = mmd->tolerance; | ||||
| } | } | ||||
| if (mmd->flag & MOD_MIR_AXIS_Z) { | if (mmd->flag & MOD_MIR_AXIS_Z) { | ||||
| axis |= 4; | axis |= 4; | ||||
| tolerance[2] = mmd->tolerance; | tolerance[2] = mmd->tolerance; | ||||
| } | } | ||||
| if (axis) { | if (axis) { | ||||
| float mtx[4][4], imtx[4][4]; | float mtx[4][4], imtx[4][4]; | ||||
| int i; | |||||
| if (mmd->mirror_ob) { | if (mmd->mirror_ob) { | ||||
| float obinv[4][4]; | float obinv[4][4]; | ||||
| invert_m4_m4(obinv, mmd->mirror_ob->obmat); | invert_m4_m4(obinv, mmd->mirror_ob->obmat); | ||||
| mul_m4_m4m4(mtx, obinv, ob->obmat); | mul_m4_m4m4(mtx, obinv, ob->obmat); | ||||
| invert_m4_m4(imtx, mtx); | invert_m4_m4(imtx, mtx); | ||||
| } | } | ||||
| TransData *td = tc->data; | TransData *td = tc->data; | ||||
| for (i = 0; i < tc->data_len; i++, td++) { | for (int tdi = 0; tdi < tc->data_len; tdi++) { | ||||
| int clip; | int clip; | ||||
| float loc[3], iloc[3]; | float loc[3], iloc[3]; | ||||
| if (td->loc == NULL) { | if (td->basic[tdi].loc == NULL) { | ||||
| break; | break; | ||||
| } | } | ||||
| if (td->flag & TD_SKIP) { | if (td->basic[tdi].flag & TD_SKIP) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| copy_v3_v3(loc, td->loc); | copy_v3_v3(loc, td->basic[tdi].loc); | ||||
| copy_v3_v3(iloc, td->iloc); | copy_v3_v3(iloc, td->basic[tdi].iloc); | ||||
| if (mmd->mirror_ob) { | if (mmd->mirror_ob) { | ||||
| mul_m4_v3(mtx, loc); | mul_m4_v3(mtx, loc); | ||||
| mul_m4_v3(mtx, iloc); | mul_m4_v3(mtx, iloc); | ||||
| } | } | ||||
| clip = 0; | clip = 0; | ||||
| if (axis & 1) { | if (axis & 1) { | ||||
| Show All 14 Lines | for (; md; md = md->next) { | ||||
| loc[2] = 0.0f; | loc[2] = 0.0f; | ||||
| clip = 1; | clip = 1; | ||||
| } | } | ||||
| } | } | ||||
| if (clip) { | if (clip) { | ||||
| if (mmd->mirror_ob) { | if (mmd->mirror_ob) { | ||||
| mul_m4_v3(imtx, loc); | mul_m4_v3(imtx, loc); | ||||
| } | } | ||||
| copy_v3_v3(td->loc, loc); | copy_v3_v3(td->basic[tdi].loc, loc); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* assumes obedit set to mesh object */ | /* assumes obedit set to mesh object */ | ||||
| static void transform_apply_to_mirror(TransInfo *t) | static void transform_apply_to_mirror(TransInfo *t) | ||||
| { | { | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| if (tc->mirror.use_mirror_any) { | if (tc->mirror.use_mirror_any) { | ||||
| int i; | int i; | ||||
| TransData *td; | TransData *td = tc->data; | ||||
| for (i = 0, td = tc->data; i < tc->data_len; i++, td++) { | for (int tdi = 0; tdi < tc->data_len; tdi++) { | ||||
| if (td->flag & (TD_MIRROR_EDGE_X | TD_MIRROR_EDGE_Y | TD_MIRROR_EDGE_Z)) { | if (td->basic[tdi].flag & (TD_MIRROR_EDGE_X | TD_MIRROR_EDGE_Y | TD_MIRROR_EDGE_Z)) { | ||||
| if (td->flag & TD_MIRROR_EDGE_X) { | if (td->basic[tdi].flag & TD_MIRROR_EDGE_X) { | ||||
| td->loc[0] = 0.0f; | td->basic[tdi].loc[0] = 0.0f; | ||||
| } | } | ||||
| if (td->flag & TD_MIRROR_EDGE_Y) { | if (td->basic[tdi].flag & TD_MIRROR_EDGE_Y) { | ||||
| td->loc[1] = 0.0f; | td->basic[tdi].loc[1] = 0.0f; | ||||
| } | } | ||||
| if (td->flag & TD_MIRROR_EDGE_Z) { | if (td->basic[tdi].flag & TD_MIRROR_EDGE_Z) { | ||||
| td->loc[2] = 0.0f; | td->basic[tdi].loc[2] = 0.0f; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| TransDataMirror *tdm; | TransDataMirror *tdm; | ||||
| for (i = 0, tdm = tc->mirror.data; i < tc->mirror.data_len; i++, tdm++) { | for (i = 0, tdm = tc->mirror.data; i < tc->mirror.data_len; i++, tdm++) { | ||||
| tdm->loc_dst[0] = tdm->loc_src[0] * tdm->sign_x; | tdm->loc_dst[0] = tdm->loc_src[0] * tdm->sign_x; | ||||
| tdm->loc_dst[1] = tdm->loc_src[1] * tdm->sign_y; | tdm->loc_dst[1] = tdm->loc_src[1] * tdm->sign_y; | ||||
| ▲ Show 20 Lines • Show All 610 Lines • ▼ Show 20 Lines | else if (t->obedit_type == OB_ARMATURE) { /* no recalc flag, does pose */ | ||||
| if (t->state != TRANS_CANCEL) { | if (t->state != TRANS_CANCEL) { | ||||
| applyProject(t); | applyProject(t); | ||||
| } | } | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| bArmature *arm = tc->obedit->data; | bArmature *arm = tc->obedit->data; | ||||
| ListBase *edbo = arm->edbo; | ListBase *edbo = arm->edbo; | ||||
| EditBone *ebo, *ebo_parent; | EditBone *ebo, *ebo_parent; | ||||
| TransData *td = tc->data; | int tdi; | ||||
| int i; | |||||
| /* Ensure all bones are correctly adjusted */ | /* Ensure all bones are correctly adjusted */ | ||||
| TransData *td = tc->data; | |||||
| for (ebo = edbo->first; ebo; ebo = ebo->next) { | for (ebo = edbo->first; ebo; ebo = ebo->next) { | ||||
| ebo_parent = (ebo->flag & BONE_CONNECTED) ? ebo->parent : NULL; | ebo_parent = (ebo->flag & BONE_CONNECTED) ? ebo->parent : NULL; | ||||
| if (ebo_parent) { | if (ebo_parent) { | ||||
| /* If this bone has a parent tip that has been moved */ | /* If this bone has a parent tip that has been moved */ | ||||
| if (ebo_parent->flag & BONE_TIPSEL) { | if (ebo_parent->flag & BONE_TIPSEL) { | ||||
| copy_v3_v3(ebo->head, ebo_parent->tail); | copy_v3_v3(ebo->head, ebo_parent->tail); | ||||
| if (t->mode == TFM_BONE_ENVELOPE) { | if (t->mode == TFM_BONE_ENVELOPE) { | ||||
| Show All 32 Lines | else if (t->obedit_type == OB_ARMATURE) { /* no recalc flag, does pose */ | ||||
| ebo_parent->rad_tail = ebo->rad_head; | ebo_parent->rad_tail = ebo->rad_head; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (!ELEM( | if (!ELEM( | ||||
| t->mode, TFM_BONE_ROLL, TFM_BONE_ENVELOPE, TFM_BONE_ENVELOPE_DIST, TFM_BONESIZE)) { | t->mode, TFM_BONE_ROLL, TFM_BONE_ENVELOPE, TFM_BONE_ENVELOPE_DIST, TFM_BONESIZE)) { | ||||
| /* fix roll */ | /* fix roll */ | ||||
| for (i = 0; i < tc->data_len; i++, td++) { | for (tdi = 0; tdi < tc->data_len; tdi++) { | ||||
| if (td->extra) { | if (td->basic[tdi].extra) { | ||||
| float vec[3], up_axis[3]; | float vec[3], up_axis[3]; | ||||
| float qrot[4]; | float qrot[4]; | ||||
| float roll; | float roll; | ||||
| ebo = td->extra; | ebo = td->basic[tdi].extra; | ||||
| if (t->state == TRANS_CANCEL) { | if (t->state == TRANS_CANCEL) { | ||||
| /* restore roll */ | /* restore roll */ | ||||
| ebo->roll = td->ival; | ebo->roll = td->special[tdi].ival; | ||||
| } | } | ||||
| else { | else { | ||||
| copy_v3_v3(up_axis, td->axismtx[2]); | copy_v3_v3(up_axis, td->space[tdi].axismtx[2]); | ||||
| sub_v3_v3v3(vec, ebo->tail, ebo->head); | sub_v3_v3v3(vec, ebo->tail, ebo->head); | ||||
| normalize_v3(vec); | normalize_v3(vec); | ||||
| rotation_between_vecs_to_quat(qrot, td->axismtx[1], vec); | rotation_between_vecs_to_quat(qrot, td->space[tdi].axismtx[1], vec); | ||||
| mul_qt_v3(qrot, up_axis); | mul_qt_v3(qrot, up_axis); | ||||
| /* roll has a tendency to flip in certain orientations - [#34283], [#33974] */ | /* roll has a tendency to flip in certain orientations - [#34283], [#33974] */ | ||||
| roll = ED_armature_ebone_roll_to_vector(ebo, up_axis, false); | roll = ED_armature_ebone_roll_to_vector(ebo, up_axis, false); | ||||
| ebo->roll = angle_compat_rad(roll, td->ival); | ebo->roll = angle_compat_rad(roll, td->special[tdi].ival); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (arm->flag & ARM_MIRROR_EDIT) { | if (arm->flag & ARM_MIRROR_EDIT) { | ||||
| if (t->state != TRANS_CANCEL) { | if (t->state != TRANS_CANCEL) { | ||||
| ED_armature_edit_transform_mirror_update(tc->obedit); | ED_armature_edit_transform_mirror_update(tc->obedit); | ||||
| ▲ Show 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | else { | ||||
| bool motionpath_update = false; | bool motionpath_update = false; | ||||
| if (t->state != TRANS_CANCEL) { | if (t->state != TRANS_CANCEL) { | ||||
| applyProject(t); | applyProject(t); | ||||
| } | } | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| TransData *td = tc->data; | TransData *td = tc->data; | ||||
| for (int tdi = 0; tdi < tc->data_len; tdi++) { | |||||
| for (int i = 0; i < tc->data_len; i++, td++) { | Object *ob = td->object[tdi].ob; | ||||
| Object *ob = td->ob; | if (td->basic[tdi].flag & TD_SKIP) { | ||||
| if (td->flag & TD_SKIP) { | |||||
| continue; | continue; | ||||
| } | } | ||||
| /* if animtimer is running, and the object already has animation data, | /* if animtimer is running, and the object already has animation data, | ||||
| * check if the auto-record feature means that we should record 'samples' | * check if the auto-record feature means that we should record 'samples' | ||||
| * (i.e. uneditable animation values) | * (i.e. uneditable animation values) | ||||
| */ | */ | ||||
| /* TODO: autokeyframe calls need some setting to specify to add samples | /* TODO: autokeyframe calls need some setting to specify to add samples | ||||
| Show All 34 Lines | |||||
| static void recalcData_cursor(TransInfo *t) | static void recalcData_cursor(TransInfo *t) | ||||
| { | { | ||||
| DEG_id_tag_update(&t->scene->id, ID_RECALC_COPY_ON_WRITE); | DEG_id_tag_update(&t->scene->id, ID_RECALC_COPY_ON_WRITE); | ||||
| } | } | ||||
| /* helper for recalcData() - for sequencer transforms */ | /* helper for recalcData() - for sequencer transforms */ | ||||
| static void recalcData_sequencer(TransInfo *t) | static void recalcData_sequencer(TransInfo *t) | ||||
| { | { | ||||
| TransData *td; | |||||
| int a; | |||||
| Sequence *seq_prev = NULL; | Sequence *seq_prev = NULL; | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | ||||
| TransData *td = tc->data; | |||||
| for (a = 0, td = tc->data; a < tc->data_len; a++, td++) { | for (int tdi = 0; tdi < tc->data_len; tdi++) { | ||||
| TransDataSeq *tdsq = (TransDataSeq *)td->extra; | TransDataSeq *tdsq = (TransDataSeq *)td->basic[tdi].extra; | ||||
| Sequence *seq = tdsq->seq; | Sequence *seq = tdsq->seq; | ||||
| if (seq != seq_prev) { | if (seq != seq_prev) { | ||||
| BKE_sequence_invalidate_cache_composite(t->scene, seq); | BKE_sequence_invalidate_cache_composite(t->scene, seq); | ||||
| } | } | ||||
| seq_prev = seq; | seq_prev = seq; | ||||
| } | } | ||||
| DEG_id_tag_update(&t->scene->id, ID_RECALC_SEQUENCER_STRIPS); | DEG_id_tag_update(&t->scene->id, ID_RECALC_SEQUENCER_STRIPS); | ||||
| flushTransSeq(t); | flushTransSeq(t); | ||||
| } | } | ||||
| /* force recalculation of triangles during transformation */ | /* force recalculation of triangles during transformation */ | ||||
| static void recalcData_gpencil_strokes(TransInfo *t) | static void recalcData_gpencil_strokes(TransInfo *t) | ||||
| { | { | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | ||||
| GHash *strokes = BLI_ghash_ptr_new(__func__); | GHash *strokes = BLI_ghash_ptr_new(__func__); | ||||
| TransData *td = tc->data; | TransData *td = tc->data; | ||||
| for (int i = 0; i < tc->data_len; i++, td++) { | for (int tdi = 0; tdi < tc->data_len; tdi++) { | ||||
| bGPDstroke *gps = td->extra; | bGPDstroke *gps = td->basic[tdi].extra; | ||||
| if ((gps != NULL) && (!BLI_ghash_haskey(strokes, gps))) { | if ((gps != NULL) && (!BLI_ghash_haskey(strokes, gps))) { | ||||
| BLI_ghash_insert(strokes, gps, gps); | BLI_ghash_insert(strokes, gps, gps); | ||||
| /* Calc geometry data. */ | /* Calc geometry data. */ | ||||
| BKE_gpencil_stroke_geometry_update(gps); | BKE_gpencil_stroke_geometry_update(gps); | ||||
| } | } | ||||
| } | } | ||||
| BLI_ghash_free(strokes, NULL, NULL); | BLI_ghash_free(strokes, NULL, NULL); | ||||
| ▲ Show 20 Lines • Show All 782 Lines • ▼ Show 20 Lines | void postTrans(bContext *C, TransInfo *t) | ||||
| } | } | ||||
| /* postTrans can be called when nothing is selected, so data is NULL already */ | /* postTrans can be called when nothing is selected, so data is NULL already */ | ||||
| if (t->data_len_all != 0) { | if (t->data_len_all != 0) { | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| /* free data malloced per trans-data */ | /* free data malloced per trans-data */ | ||||
| if (ELEM(t->obedit_type, OB_CURVE, OB_SURF) || (t->spacetype == SPACE_GRAPH)) { | if (ELEM(t->obedit_type, OB_CURVE, OB_SURF) || (t->spacetype == SPACE_GRAPH)) { | ||||
| TransData *td = tc->data; | TransData *td = tc->data; | ||||
| for (int a = 0; a < tc->data_len; a++, td++) { | for (int tdi = 0; tdi < tc->data_len; tdi++) { | ||||
| if (td->flag & TD_BEZTRIPLE) { | if (td->basic[tdi].flag & TD_BEZTRIPLE) { | ||||
| MEM_freeN(td->hdata); | BLI_assert(td->curve && td->curve[tdi].hdata); | ||||
| MEM_freeN(td->curve[tdi].hdata); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| MEM_freeN(tc->data); | transform_data_free(tc->data); | ||||
| MEM_SAFE_FREE(tc->data_ext); | |||||
| MEM_SAFE_FREE(tc->data_2d); | MEM_SAFE_FREE(tc->data_2d); | ||||
| MEM_SAFE_FREE(tc->mirror.data); | MEM_SAFE_FREE(tc->mirror.data); | ||||
| } | } | ||||
| } | } | ||||
| MEM_SAFE_FREE(t->data_container); | MEM_SAFE_FREE(t->data_container); | ||||
| t->data_container = NULL; | t->data_container = NULL; | ||||
| Show All 28 Lines | void postTrans(bContext *C, TransInfo *t) | ||||
| freeSnapping(t); | freeSnapping(t); | ||||
| } | } | ||||
| void applyTransObjects(TransInfo *t) | void applyTransObjects(TransInfo *t) | ||||
| { | { | ||||
| TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); | ||||
| TransData *td; | TransData *td = tc->data; | ||||
| int tdi = 0; | |||||
| for (td = tc->data; td < tc->data + tc->data_len; td++) { | int tdi_last = tc->data_len - 1; | ||||
| copy_v3_v3(td->iloc, td->loc); | for (; tdi <= tdi_last; tdi++) { | ||||
| if (td->ext->rot) { | copy_v3_v3(td->basic[tdi].iloc, td->basic[tdi].loc); | ||||
| copy_v3_v3(td->ext->irot, td->ext->rot); | if (td->ext[tdi].rot) { | ||||
| copy_v3_v3(td->ext[tdi].irot, td->ext[tdi].rot); | |||||
| } | } | ||||
| if (td->ext->size) { | if (td->ext[tdi].size) { | ||||
| copy_v3_v3(td->ext->isize, td->ext->size); | copy_v3_v3(td->ext[tdi].isize, td->ext[tdi].size); | ||||
| } | } | ||||
| } | } | ||||
| recalcData(t); | recalcData(t); | ||||
| } | } | ||||
| static void restoreElement(TransData *td) | static void restoreElement(const TransData *td, const int tdi) | ||||
| { | { | ||||
| /* TransData for crease has no loc */ | /* TransData for crease has no loc */ | ||||
| if (td->loc) { | if (td->basic[tdi].loc) { | ||||
| copy_v3_v3(td->loc, td->iloc); | copy_v3_v3(td->basic[tdi].loc, td->basic[tdi].iloc); | ||||
| } | } | ||||
| if (td->val) { | if (td->special[tdi].val) { | ||||
| *td->val = td->ival; | *td->special[tdi].val = td->special[tdi].ival; | ||||
| } | } | ||||
| if (td->ext && (td->flag & TD_NO_EXT) == 0) { | if (td->ext && (td->basic[tdi].flag & TD_NO_EXT) == 0) { | ||||
| if (td->ext->rot) { | if (td->ext[tdi].rot) { | ||||
| copy_v3_v3(td->ext->rot, td->ext->irot); | copy_v3_v3(td->ext[tdi].rot, td->ext[tdi].irot); | ||||
| } | } | ||||
| if (td->ext->rotAngle) { | if (td->ext[tdi].rotAngle) { | ||||
| *td->ext->rotAngle = td->ext->irotAngle; | *td->ext[tdi].rotAngle = td->ext[tdi].irotAngle; | ||||
| } | } | ||||
| if (td->ext->rotAxis) { | if (td->ext[tdi].rotAxis) { | ||||
| copy_v3_v3(td->ext->rotAxis, td->ext->irotAxis); | copy_v3_v3(td->ext[tdi].rotAxis, td->ext[tdi].irotAxis); | ||||
| } | } | ||||
| /* XXX, drotAngle & drotAxis not used yet */ | /* XXX, drotAngle & drotAxis not used yet */ | ||||
| if (td->ext->size) { | if (td->ext[tdi].size) { | ||||
| copy_v3_v3(td->ext->size, td->ext->isize); | copy_v3_v3(td->ext[tdi].size, td->ext[tdi].isize); | ||||
| } | } | ||||
| if (td->ext->quat) { | if (td->ext[tdi].quat) { | ||||
| copy_qt_qt(td->ext->quat, td->ext->iquat); | copy_qt_qt(td->ext[tdi].quat, td->ext[tdi].iquat); | ||||
| } | } | ||||
| } | } | ||||
| if (td->flag & TD_BEZTRIPLE) { | if (td->basic[tdi].flag & TD_BEZTRIPLE) { | ||||
| *(td->hdata->h1) = td->hdata->ih1; | *(td->curve[tdi].hdata->h1) = td->curve[tdi].hdata->ih1; | ||||
| *(td->hdata->h2) = td->hdata->ih2; | *(td->curve[tdi].hdata->h2) = td->curve[tdi].hdata->ih2; | ||||
| } | } | ||||
| } | } | ||||
| void restoreTransObjects(TransInfo *t) | void restoreTransObjects(TransInfo *t) | ||||
| { | { | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| TransData *td; | |||||
| TransData2D *td2d; | TransData2D *td2d; | ||||
| for (td = tc->data; td < tc->data + tc->data_len; td++) { | TransData *td = tc->data; | ||||
| restoreElement(td); | int tdi = 0; | ||||
| int tdi_last = tc->data_len - 1; | |||||
| for (; tdi <= tdi_last; tdi++) { | |||||
| restoreElement(td, tdi); | |||||
| } | } | ||||
| for (td2d = tc->data_2d; tc->data_2d && td2d < tc->data_2d + tc->data_len; td2d++) { | for (td2d = tc->data_2d; tc->data_2d && td2d < tc->data_2d + tc->data_len; td2d++) { | ||||
| if (td2d->h1) { | if (td2d->h1) { | ||||
| td2d->h1[0] = td2d->ih1[0]; | td2d->h1[0] = td2d->ih1[0]; | ||||
| td2d->h1[1] = td2d->ih1[1]; | td2d->h1[1] = td2d->ih1[1]; | ||||
| } | } | ||||
| if (td2d->h2) { | if (td2d->h2) { | ||||
| ▲ Show 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| void calculateCenterMedian(TransInfo *t, float r_center[3]) | void calculateCenterMedian(TransInfo *t, float r_center[3]) | ||||
| { | { | ||||
| float partial[3] = {0.0f, 0.0f, 0.0f}; | float partial[3] = {0.0f, 0.0f, 0.0f}; | ||||
| int total = 0; | int total = 0; | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| for (int i = 0; i < tc->data_len; i++) { | TransData *td = tc->data; | ||||
| if (tc->data[i].flag & TD_SELECTED) { | for (int tdi = 0; tdi < tc->data_len; tdi++) { | ||||
| if (!(tc->data[i].flag & TD_NOCENTER)) { | if (td->basic[tdi].flag & TD_SELECTED) { | ||||
| if (!(td->basic[tdi].flag & TD_NOCENTER)) { | |||||
| if (tc->use_local_mat) { | if (tc->use_local_mat) { | ||||
| float v[3]; | float v[3]; | ||||
| mul_v3_m4v3(v, tc->mat, tc->data[i].center); | mul_v3_m4v3(v, tc->mat, td->center[tdi]); | ||||
| add_v3_v3(partial, v); | add_v3_v3(partial, v); | ||||
| } | } | ||||
| else { | else { | ||||
| add_v3_v3(partial, tc->data[i].center); | add_v3_v3(partial, td->center[tdi]); | ||||
| } | } | ||||
| total++; | total++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (total) { | if (total) { | ||||
| mul_v3_fl(partial, 1.0f / (float)total); | mul_v3_fl(partial, 1.0f / (float)total); | ||||
| } | } | ||||
| copy_v3_v3(r_center, partial); | copy_v3_v3(r_center, partial); | ||||
| } | } | ||||
| void calculateCenterBound(TransInfo *t, float r_center[3]) | void calculateCenterBound(TransInfo *t, float r_center[3]) | ||||
| { | { | ||||
| float max[3], min[3]; | float max[3], min[3]; | ||||
| bool changed = false; | bool changed = false; | ||||
| INIT_MINMAX(min, max); | INIT_MINMAX(min, max); | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| for (int i = 0; i < tc->data_len; i++) { | TransData *td = tc->data; | ||||
| if (tc->data[i].flag & TD_SELECTED) { | for (int tdi = 0; tdi < tc->data_len; tdi++) { | ||||
| if (!(tc->data[i].flag & TD_NOCENTER)) { | if (td->basic[tdi].flag & TD_SELECTED) { | ||||
| if (!(td->basic[tdi].flag & TD_NOCENTER)) { | |||||
| if (tc->use_local_mat) { | if (tc->use_local_mat) { | ||||
| float v[3]; | float v[3]; | ||||
| mul_v3_m4v3(v, tc->mat, tc->data[i].center); | mul_v3_m4v3(v, tc->mat, td->center[tdi]); | ||||
| minmax_v3v3_v3(min, max, v); | minmax_v3v3_v3(min, max, v); | ||||
| } | } | ||||
| else { | else { | ||||
| minmax_v3v3_v3(min, max, tc->data[i].center); | minmax_v3v3_v3(min, max, td->center[tdi]); | ||||
| } | } | ||||
| changed = true; | changed = true; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (changed) { | if (changed) { | ||||
| mid_v3_v3v3(r_center, min, max); | mid_v3_v3v3(r_center, min, max); | ||||
| ▲ Show 20 Lines • Show All 157 Lines • ▼ Show 20 Lines | if (cd->is_set == false) { | ||||
| calculateCenter_FromAround(t, around, cd->global); | calculateCenter_FromAround(t, around, cd->global); | ||||
| cd->is_set = true; | cd->is_set = true; | ||||
| } | } | ||||
| return cd; | return cd; | ||||
| } | } | ||||
| void calculatePropRatio(TransInfo *t) | void calculatePropRatio(TransInfo *t) | ||||
| { | { | ||||
| int i; | |||||
| float dist; | float dist; | ||||
| const bool connected = (t->flag & T_PROP_CONNECTED) != 0; | const bool connected = (t->flag & T_PROP_CONNECTED) != 0; | ||||
| t->proptext[0] = '\0'; | t->proptext[0] = '\0'; | ||||
| if (t->flag & T_PROP_EDIT) { | if (t->flag & T_PROP_EDIT) { | ||||
| const char *pet_id = NULL; | const char *pet_id = NULL; | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| TransData *td = tc->data; | TransData *td = tc->data; | ||||
| for (i = 0; i < tc->data_len; i++, td++) { | for (int tdi = 0; tdi < tc->data_len; tdi++) { | ||||
| if (td->flag & TD_SELECTED) { | if (td->basic[tdi].flag & TD_SELECTED) { | ||||
| td->factor = 1.0f; | td->prop[tdi].factor = 1.0f; | ||||
| } | } | ||||
| else if ((connected && (td->flag & TD_NOTCONNECTED || td->dist > t->prop_size)) || | else if ((connected && | ||||
| (connected == 0 && td->rdist > t->prop_size)) { | (td->basic[tdi].flag & TD_NOTCONNECTED || td->prop[tdi].dist > t->prop_size)) || | ||||
| td->factor = 0.0f; | (connected == 0 && td->prop[tdi].rdist > t->prop_size)) { | ||||
| restoreElement(td); | td->prop[tdi].factor = 0.0f; | ||||
| restoreElement(td, tdi); | |||||
| } | } | ||||
| else { | else { | ||||
| /* Use rdist for falloff calculations, it is the real distance */ | /* Use rdist for falloff calculations, it is the real distance */ | ||||
| if (connected) { | if (connected) { | ||||
| dist = (t->prop_size - td->dist) / t->prop_size; | dist = (t->prop_size - td->prop[tdi].dist) / t->prop_size; | ||||
| } | } | ||||
| else { | else { | ||||
| dist = (t->prop_size - td->rdist) / t->prop_size; | dist = (t->prop_size - td->prop[tdi].rdist) / t->prop_size; | ||||
| } | } | ||||
| /* | /* | ||||
| * Clamp to positive numbers. | * Clamp to positive numbers. | ||||
| * Certain corner cases with connectivity and individual centers | * Certain corner cases with connectivity and individual centers | ||||
| * can give values of rdist larger than propsize. | * can give values of rdist larger than propsize. | ||||
| */ | */ | ||||
| if (dist < 0.0f) { | if (dist < 0.0f) { | ||||
| dist = 0.0f; | dist = 0.0f; | ||||
| } | } | ||||
| switch (t->prop_mode) { | switch (t->prop_mode) { | ||||
| case PROP_SHARP: | case PROP_SHARP: | ||||
| td->factor = dist * dist; | td->prop[tdi].factor = dist * dist; | ||||
| break; | break; | ||||
| case PROP_SMOOTH: | case PROP_SMOOTH: | ||||
| td->factor = 3.0f * dist * dist - 2.0f * dist * dist * dist; | td->prop[tdi].factor = 3.0f * dist * dist - 2.0f * dist * dist * dist; | ||||
| break; | break; | ||||
| case PROP_ROOT: | case PROP_ROOT: | ||||
| td->factor = sqrtf(dist); | td->prop[tdi].factor = sqrtf(dist); | ||||
| break; | break; | ||||
| case PROP_LIN: | case PROP_LIN: | ||||
| td->factor = dist; | td->prop[tdi].factor = dist; | ||||
| break; | break; | ||||
| case PROP_CONST: | case PROP_CONST: | ||||
| td->factor = 1.0f; | td->prop[tdi].factor = 1.0f; | ||||
| break; | break; | ||||
| case PROP_SPHERE: | case PROP_SPHERE: | ||||
| td->factor = sqrtf(2 * dist - dist * dist); | td->prop[tdi].factor = sqrtf(2 * dist - dist * dist); | ||||
| break; | break; | ||||
| case PROP_RANDOM: | case PROP_RANDOM: | ||||
| if (t->rng == NULL) { | if (t->rng == NULL) { | ||||
| /* Lazy initialization. */ | /* Lazy initialization. */ | ||||
| uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX); | uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX); | ||||
| t->rng = BLI_rng_new(rng_seed); | t->rng = BLI_rng_new(rng_seed); | ||||
| } | } | ||||
| td->factor = BLI_rng_get_float(t->rng) * dist; | td->prop[tdi].factor = BLI_rng_get_float(t->rng) * dist; | ||||
| break; | break; | ||||
| case PROP_INVSQUARE: | case PROP_INVSQUARE: | ||||
| td->factor = dist * (2.0f - dist); | td->prop[tdi].factor = dist * (2.0f - dist); | ||||
| break; | break; | ||||
| default: | default: | ||||
| td->factor = 1; | td->prop[tdi].factor = 1; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| switch (t->prop_mode) { | switch (t->prop_mode) { | ||||
| case PROP_SHARP: | case PROP_SHARP: | ||||
| Show All 26 Lines | if (t->flag & T_PROP_EDIT) { | ||||
| if (pet_id) { | if (pet_id) { | ||||
| BLI_strncpy(t->proptext, IFACE_(pet_id), sizeof(t->proptext)); | BLI_strncpy(t->proptext, IFACE_(pet_id), sizeof(t->proptext)); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| TransData *td = tc->data; | TransData *td = tc->data; | ||||
| for (i = 0; i < tc->data_len; i++, td++) { | for (int tdi = 0; tdi < tc->data_len; tdi++) { | ||||
| td->factor = 1.0; | td->prop[tdi].factor = 1.0; | ||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Rotate an element, low level code, ignore protected channels. | |||||
| * (use for objects or pose-bones) | |||||
| * Similar to #ElementRotation. | |||||
| */ | |||||
| void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot) | |||||
| { | |||||
| float totmat[3][3]; | |||||
| float smat[3][3]; | |||||
| float fmat[3][3]; | |||||
| float obmat[3][3]; | |||||
| float dmat[3][3]; /* delta rotation */ | |||||
| float dmat_inv[3][3]; | |||||
| mul_m3_m3m3(totmat, mat, td->mtx); | |||||
| mul_m3_m3m3(smat, td->smtx, mat); | |||||
| /* logic from BKE_object_rot_to_mat3 */ | |||||
| if (use_drot) { | |||||
| if (td->ext->rotOrder > 0) { | |||||
| eulO_to_mat3(dmat, td->ext->drot, td->ext->rotOrder); | |||||
| } | |||||
| else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) { | |||||
| #if 0 | |||||
| axis_angle_to_mat3(dmat, td->ext->drotAxis, td->ext->drotAngle); | |||||
| #else | |||||
| unit_m3(dmat); | |||||
| #endif | |||||
| } | |||||
| else { | |||||
| float tquat[4]; | |||||
| normalize_qt_qt(tquat, td->ext->dquat); | |||||
| quat_to_mat3(dmat, tquat); | |||||
| } | |||||
| invert_m3_m3(dmat_inv, dmat); | |||||
| } | |||||
| if (td->ext->rotOrder == ROT_MODE_QUAT) { | |||||
| float quat[4]; | |||||
| /* calculate the total rotatation */ | |||||
| quat_to_mat3(obmat, td->ext->iquat); | |||||
| if (use_drot) { | |||||
| mul_m3_m3m3(obmat, dmat, obmat); | |||||
| } | } | ||||
| /* mat = transform, obmat = object rotation */ | |||||
| mul_m3_m3m3(fmat, smat, obmat); | |||||
| if (use_drot) { | |||||
| mul_m3_m3m3(fmat, dmat_inv, fmat); | |||||
| } | |||||
| mat3_to_quat(quat, fmat); | |||||
| /* apply */ | |||||
| copy_qt_qt(td->ext->quat, quat); | |||||
| } | |||||
| else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) { | |||||
| float axis[3], angle; | |||||
| /* calculate the total rotatation */ | |||||
| axis_angle_to_mat3(obmat, td->ext->irotAxis, td->ext->irotAngle); | |||||
| if (use_drot) { | |||||
| mul_m3_m3m3(obmat, dmat, obmat); | |||||
| } | } | ||||
| /* mat = transform, obmat = object rotation */ | |||||
| mul_m3_m3m3(fmat, smat, obmat); | |||||
| if (use_drot) { | |||||
| mul_m3_m3m3(fmat, dmat_inv, fmat); | |||||
| } | |||||
| mat3_to_axis_angle(axis, &angle, fmat); | |||||
| /* apply */ | |||||
| copy_v3_v3(td->ext->rotAxis, axis); | |||||
| *td->ext->rotAngle = angle; | |||||
| } | |||||
| else { | |||||
| float eul[3]; | |||||
| /* calculate the total rotatation */ | |||||
| eulO_to_mat3(obmat, td->ext->irot, td->ext->rotOrder); | |||||
| if (use_drot) { | |||||
| mul_m3_m3m3(obmat, dmat, obmat); | |||||
| } | |||||
| /* mat = transform, obmat = object rotation */ | |||||
| mul_m3_m3m3(fmat, smat, obmat); | |||||
| if (use_drot) { | |||||
| mul_m3_m3m3(fmat, dmat_inv, fmat); | |||||
| } | |||||
| mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat); | |||||
| /* apply */ | |||||
| copy_v3_v3(td->ext->rot, eul); | |||||
| } | } | ||||
| } | } | ||||