Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/transform/transform_convert_curve.c
| Show All 27 Lines | |||||
| #include "BLI_listbase.h" | #include "BLI_listbase.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_curve.h" | #include "BKE_curve.h" | ||||
| #include "transform.h" | #include "transform.h" | ||||
| #include "transform_convert.h" | #include "transform_convert.h" | ||||
| #include "transform_data.h" | |||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Curve/Surfaces Transform Creation | /** \name Curve/Surfaces Transform Creation | ||||
| * | * | ||||
| * \{ */ | * \{ */ | ||||
| /** | /** | ||||
| * For the purpose of transform code we need to behave as if handles are selected, | * For the purpose of transform code we need to behave as if handles are selected, | ||||
| ▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| } | } | ||||
| if (is_prop_edit) { | if (is_prop_edit) { | ||||
| tc->data_len = count; | tc->data_len = count; | ||||
| } | } | ||||
| else { | else { | ||||
| tc->data_len = countsel; | tc->data_len = countsel; | ||||
| } | } | ||||
| tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Curve EditMode)"); | |||||
| tc->data = transform_data_alloc(tc->data_len, TD_BASIC_COMP); | |||||
| t->data_len_all += tc->data_len; | t->data_len_all += tc->data_len; | ||||
| } | } | ||||
| transform_around_single_fallback(t); | transform_around_single_fallback(t); | ||||
| t->data_len_all = -1; | t->data_len_all = -1; | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| if (tc->data_len == 0) { | if (tc->data_len == 0) { | ||||
| Show All 12 Lines | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| bool use_around_origins_for_handles_test = ((t->around == V3D_AROUND_LOCAL_ORIGINS) && | bool use_around_origins_for_handles_test = ((t->around == V3D_AROUND_LOCAL_ORIGINS) && | ||||
| transform_mode_use_local_origins(t)); | transform_mode_use_local_origins(t)); | ||||
| float mtx[3][3], smtx[3][3]; | float mtx[3][3], smtx[3][3]; | ||||
| copy_m3_m4(mtx, tc->obedit->obmat); | copy_m3_m4(mtx, tc->obedit->obmat); | ||||
| pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); | pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); | ||||
| TransData *td = tc->data; | TransData *td = tc->data; | ||||
| int tdi = 0; | |||||
| ListBase *nurbs = BKE_curve_editNurbs_get(cu); | ListBase *nurbs = BKE_curve_editNurbs_get(cu); | ||||
| LISTBASE_FOREACH (Nurb *, nu, nurbs) { | LISTBASE_FOREACH (Nurb *, nu, nurbs) { | ||||
| if (nu->type == CU_BEZIER) { | if (nu->type == CU_BEZIER) { | ||||
| TransData *head, *tail; | int head, tail; | ||||
| head = tail = td; | head = tail = tdi; | ||||
| 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]; | ||||
| if (t->around == V3D_AROUND_LOCAL_ORIGINS) { | if (t->around == V3D_AROUND_LOCAL_ORIGINS) { | ||||
| float normal[3], plane[3]; | float normal[3], plane[3]; | ||||
| Show All 9 Lines | LISTBASE_FOREACH (Nurb *, nu, nurbs) { | ||||
| invert_m3(axismtx); | invert_m3(axismtx); | ||||
| } | } | ||||
| } | } | ||||
| /* Elements that will be transform (not always a match to selection). */ | /* Elements that will be transform (not always a match to selection). */ | ||||
| const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles); | const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles); | ||||
| if (is_prop_edit || bezt_tx & SEL_F1) { | if (is_prop_edit || bezt_tx & SEL_F1) { | ||||
| copy_v3_v3(td->iloc, bezt->vec[0]); | copy_v3_v3(td->basic[tdi].iloc, bezt->vec[0]); | ||||
| td->loc = bezt->vec[0]; | td->basic[tdi].loc = bezt->vec[0]; | ||||
| copy_v3_v3(td->center, | copy_v3_v3(td->center[tdi], | ||||
| bezt->vec[(hide_handles || (t->around == V3D_AROUND_LOCAL_ORIGINS) || | bezt->vec[(hide_handles || (t->around == V3D_AROUND_LOCAL_ORIGINS) || | ||||
| (bezt->f2 & SELECT)) ? | (bezt->f2 & SELECT)) ? | ||||
| 1 : | 1 : | ||||
| 0]); | 0]); | ||||
| if (hide_handles) { | if (hide_handles) { | ||||
| if (bezt->f2 & SELECT) { | if (bezt->f2 & SELECT) { | ||||
| td->flag = TD_SELECTED; | td->basic[tdi].flag = TD_SELECTED; | ||||
| } | } | ||||
| else { | else { | ||||
| td->flag = 0; | td->basic[tdi].flag = 0; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (bezt->f1 & SELECT) { | if (bezt->f1 & SELECT) { | ||||
| td->flag = TD_SELECTED; | td->basic[tdi].flag = TD_SELECTED; | ||||
| } | } | ||||
| else { | else { | ||||
| td->flag = 0; | td->basic[tdi].flag = 0; | ||||
| } | } | ||||
| } | } | ||||
| td->ext = NULL; | td->special[tdi].val = NULL; | ||||
| td->val = NULL; | |||||
| hdata = initTransDataCurveHandles(td, bezt); | hdata = initTransDataCurveHandles(td, tdi, bezt); | ||||
| copy_m3_m3(td->smtx, smtx); | copy_m3_m3(td->space[tdi].smtx, smtx); | ||||
| copy_m3_m3(td->mtx, mtx); | copy_m3_m3(td->space[tdi].mtx, mtx); | ||||
| if (t->around == V3D_AROUND_LOCAL_ORIGINS) { | if (t->around == V3D_AROUND_LOCAL_ORIGINS) { | ||||
| copy_m3_m3(td->axismtx, axismtx); | copy_m3_m3(td->space[tdi].axismtx, axismtx); | ||||
| } | } | ||||
| td++; | tdi++; | ||||
| tail++; | tail++; | ||||
| } | } | ||||
| /* This is the Curve Point, the other two are handles */ | /* This is the Curve Point, the other two are handles */ | ||||
| if (is_prop_edit || bezt_tx & SEL_F2) { | if (is_prop_edit || bezt_tx & SEL_F2) { | ||||
| copy_v3_v3(td->iloc, bezt->vec[1]); | copy_v3_v3(td->basic[tdi].iloc, bezt->vec[1]); | ||||
| td->loc = bezt->vec[1]; | td->basic[tdi].loc = bezt->vec[1]; | ||||
| copy_v3_v3(td->center, td->loc); | copy_v3_v3(td->center[tdi], bezt->vec[1]); | ||||
| if (bezt->f2 & SELECT) { | if (bezt->f2 & SELECT) { | ||||
| td->flag = TD_SELECTED; | td->basic[tdi].flag = TD_SELECTED; | ||||
| } | } | ||||
| else { | else { | ||||
| td->flag = 0; | td->basic[tdi].flag = 0; | ||||
| } | } | ||||
| td->ext = NULL; | |||||
| /* TODO - make points scale */ | /* TODO - make points scale */ | ||||
| if (t->mode == TFM_CURVE_SHRINKFATTEN) { /* || t->mode==TFM_RESIZE) {*/ | if (t->mode == TFM_CURVE_SHRINKFATTEN) { /* || t->mode==TFM_RESIZE) {*/ | ||||
| td->val = &(bezt->radius); | td->special[tdi].val = &(bezt->radius); | ||||
| td->ival = bezt->radius; | td->special[tdi].ival = bezt->radius; | ||||
| } | } | ||||
| else if (t->mode == TFM_TILT) { | else if (t->mode == TFM_TILT) { | ||||
| td->val = &(bezt->tilt); | td->special[tdi].val = &(bezt->tilt); | ||||
| td->ival = bezt->tilt; | td->special[tdi].ival = bezt->tilt; | ||||
| } | } | ||||
| else { | else { | ||||
| td->val = NULL; | td->special[tdi].val = NULL; | ||||
| } | } | ||||
| copy_m3_m3(td->smtx, smtx); | copy_m3_m3(td->space[tdi].smtx, smtx); | ||||
| copy_m3_m3(td->mtx, mtx); | copy_m3_m3(td->space[tdi].mtx, mtx); | ||||
| if (t->around == V3D_AROUND_LOCAL_ORIGINS) { | if (t->around == V3D_AROUND_LOCAL_ORIGINS) { | ||||
| copy_m3_m3(td->axismtx, axismtx); | copy_m3_m3(td->space[tdi].axismtx, axismtx); | ||||
| } | } | ||||
| if ((bezt_tx & SEL_F1) == 0 && (bezt_tx & SEL_F3) == 0) { | if ((bezt_tx & SEL_F1) == 0 && (bezt_tx & SEL_F3) == 0) { | ||||
| /* If the middle is selected but the sides arnt, this is needed */ | /* If the middle is selected but the sides arnt, this is needed */ | ||||
| if (hdata == NULL) { | if (hdata == NULL) { | ||||
| /* if the handle was not saved by the previous handle */ | /* if the handle was not saved by the previous handle */ | ||||
| hdata = initTransDataCurveHandles(td, bezt); | hdata = initTransDataCurveHandles(td, tdi, bezt); | ||||
| } | } | ||||
| } | } | ||||
| td++; | tdi++; | ||||
| tail++; | tail++; | ||||
| } | } | ||||
| if (is_prop_edit || bezt_tx & SEL_F3) { | if (is_prop_edit || bezt_tx & SEL_F3) { | ||||
| copy_v3_v3(td->iloc, bezt->vec[2]); | copy_v3_v3(td->basic[tdi].iloc, bezt->vec[2]); | ||||
| td->loc = bezt->vec[2]; | td->basic[tdi].loc = bezt->vec[2]; | ||||
| copy_v3_v3(td->center, | copy_v3_v3(td->center[tdi], | ||||
| bezt->vec[(hide_handles || (t->around == V3D_AROUND_LOCAL_ORIGINS) || | bezt->vec[(hide_handles || (t->around == V3D_AROUND_LOCAL_ORIGINS) || | ||||
| (bezt->f2 & SELECT)) ? | (bezt->f2 & SELECT)) ? | ||||
| 1 : | 1 : | ||||
| 2]); | 2]); | ||||
| if (hide_handles) { | if (hide_handles) { | ||||
| if (bezt->f2 & SELECT) { | if (bezt->f2 & SELECT) { | ||||
| td->flag = TD_SELECTED; | td->basic[tdi].flag = TD_SELECTED; | ||||
| } | } | ||||
| else { | else { | ||||
| td->flag = 0; | td->basic[tdi].flag = 0; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (bezt->f3 & SELECT) { | if (bezt->f3 & SELECT) { | ||||
| td->flag = TD_SELECTED; | td->basic[tdi].flag = TD_SELECTED; | ||||
| } | } | ||||
| else { | else { | ||||
| td->flag = 0; | td->basic[tdi].flag = 0; | ||||
| } | } | ||||
| } | } | ||||
| td->ext = NULL; | td->special[tdi].val = NULL; | ||||
| td->val = NULL; | |||||
| if (hdata == NULL) { | if (hdata == NULL) { | ||||
| /* if the handle was not saved by the previous handle */ | /* if the handle was not saved by the previous handle */ | ||||
| hdata = initTransDataCurveHandles(td, bezt); | hdata = initTransDataCurveHandles(td, tdi, bezt); | ||||
| } | } | ||||
| copy_m3_m3(td->smtx, smtx); | copy_m3_m3(td->space[tdi].smtx, smtx); | ||||
| copy_m3_m3(td->mtx, mtx); | copy_m3_m3(td->space[tdi].mtx, mtx); | ||||
| if (t->around == V3D_AROUND_LOCAL_ORIGINS) { | if (t->around == V3D_AROUND_LOCAL_ORIGINS) { | ||||
| copy_m3_m3(td->axismtx, axismtx); | copy_m3_m3(td->space[tdi].axismtx, axismtx); | ||||
| } | } | ||||
| td++; | tdi++; | ||||
| tail++; | tail++; | ||||
| } | } | ||||
| (void)hdata; /* quiet warning */ | (void)hdata; /* quiet warning */ | ||||
| } | } | ||||
| else if (is_prop_edit && head != tail) { | else if (is_prop_edit && head != tail) { | ||||
| calc_distanceCurveVerts(head, tail - 1); | calc_distanceCurveVerts(tc->data, head, tail - 1); | ||||
| head = tail; | head = tail; | ||||
| } | } | ||||
| } | } | ||||
| if (is_prop_edit && head != tail) { | if (is_prop_edit && head != tail) { | ||||
| calc_distanceCurveVerts(head, tail - 1); | calc_distanceCurveVerts(td, head, tail - 1); | ||||
| } | } | ||||
| /* TODO - in the case of tilt and radius we can also avoid allocating the | /* TODO - in the case of tilt and radius we can also avoid allocating the | ||||
| * initTransDataCurveHandles but for now just don't change handle types */ | * initTransDataCurveHandles but for now just don't change handle types */ | ||||
| if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT, TFM_DUMMY) == 0) { | if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT, TFM_DUMMY) == 0) { | ||||
| /* sets the handles based on their selection, | /* sets the handles based on their selection, | ||||
| * do this after the data is copied to the TransData */ | * do this after the data is copied to the TransData */ | ||||
| BKE_nurb_handles_test(nu, !hide_handles, use_around_origins_for_handles_test); | BKE_nurb_handles_test(nu, !hide_handles, use_around_origins_for_handles_test); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| TransData *head, *tail; | int head, tail; | ||||
| head = tail = td; | head = tail = tdi; | ||||
| for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) { | for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) { | ||||
| if (bp->hide == 0) { | if (bp->hide == 0) { | ||||
| if (is_prop_edit || (bp->f1 & SELECT)) { | if (is_prop_edit || (bp->f1 & SELECT)) { | ||||
| float axismtx[3][3]; | float axismtx[3][3]; | ||||
| if (t->around == V3D_AROUND_LOCAL_ORIGINS) { | if (t->around == V3D_AROUND_LOCAL_ORIGINS) { | ||||
| if (nu->pntsv == 1) { | if (nu->pntsv == 1) { | ||||
| float normal[3], plane[3]; | float normal[3], plane[3]; | ||||
| BKE_nurb_bpoint_calc_normal(nu, bp, normal); | BKE_nurb_bpoint_calc_normal(nu, bp, normal); | ||||
| BKE_nurb_bpoint_calc_plane(nu, bp, plane); | BKE_nurb_bpoint_calc_plane(nu, bp, plane); | ||||
| if (createSpaceNormalTangent(axismtx, normal, plane)) { | if (createSpaceNormalTangent(axismtx, normal, plane)) { | ||||
| /* pass */ | /* pass */ | ||||
| } | } | ||||
| else { | else { | ||||
| normalize_v3(normal); | normalize_v3(normal); | ||||
| axis_dominant_v3_to_m3(axismtx, normal); | axis_dominant_v3_to_m3(axismtx, normal); | ||||
| invert_m3(axismtx); | invert_m3(axismtx); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| copy_v3_v3(td->iloc, bp->vec); | copy_v3_v3(td->basic[tdi].iloc, bp->vec); | ||||
| td->loc = bp->vec; | td->basic[tdi].loc = bp->vec; | ||||
| copy_v3_v3(td->center, td->loc); | copy_v3_v3(td->center[tdi], bp->vec); | ||||
| if (bp->f1 & SELECT) { | if (bp->f1 & SELECT) { | ||||
| td->flag = TD_SELECTED; | td->basic[tdi].flag = TD_SELECTED; | ||||
| } | } | ||||
| else { | else { | ||||
| td->flag = 0; | td->basic[tdi].flag = 0; | ||||
| } | } | ||||
| td->ext = NULL; | |||||
| if (t->mode == TFM_CURVE_SHRINKFATTEN || t->mode == TFM_RESIZE) { | if (t->mode == TFM_CURVE_SHRINKFATTEN || t->mode == TFM_RESIZE) { | ||||
| td->val = &(bp->radius); | td->special[tdi].val = &(bp->radius); | ||||
| td->ival = bp->radius; | td->special[tdi].ival = bp->radius; | ||||
| } | } | ||||
| else { | else { | ||||
| td->val = &(bp->tilt); | td->special[tdi].val = &(bp->tilt); | ||||
| td->ival = bp->tilt; | td->special[tdi].ival = bp->tilt; | ||||
| } | } | ||||
| copy_m3_m3(td->smtx, smtx); | copy_m3_m3(td->space[tdi].smtx, smtx); | ||||
| copy_m3_m3(td->mtx, mtx); | copy_m3_m3(td->space[tdi].mtx, mtx); | ||||
| if (t->around == V3D_AROUND_LOCAL_ORIGINS) { | if (t->around == V3D_AROUND_LOCAL_ORIGINS) { | ||||
| if (nu->pntsv == 1) { | if (nu->pntsv == 1) { | ||||
| copy_m3_m3(td->axismtx, axismtx); | copy_m3_m3(td->space[tdi].axismtx, axismtx); | ||||
| } | } | ||||
| } | } | ||||
| td++; | tdi++; | ||||
| tail++; | tail++; | ||||
| } | } | ||||
| } | } | ||||
| else if (is_prop_edit && head != tail) { | else if (is_prop_edit && head != tail) { | ||||
| calc_distanceCurveVerts(head, tail - 1); | calc_distanceCurveVerts(tc->data, head, tail - 1); | ||||
| head = tail; | head = tail; | ||||
| } | } | ||||
| } | } | ||||
| if (is_prop_edit && head != tail) { | if (is_prop_edit && head != tail) { | ||||
| calc_distanceCurveVerts(head, tail - 1); | calc_distanceCurveVerts(tc->data, head, tail - 1); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| #undef SEL_F1 | #undef SEL_F1 | ||||
| #undef SEL_F2 | #undef SEL_F2 | ||||
| #undef SEL_F3 | #undef SEL_F3 | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||