Curve: extend BKE_nurb_bezt_handle_test & BKE_nurb_handles_test
Replace use_handles with an enum that optionally uses handles except when the vertex (knot) is selected in which case it behaves as if both handles are selected. Needed for nurb curves not to change handle type when only the center point is selected (as is done in the graph editor). No functional changes.
This commit is contained in:
parent
ccaafa318d
commit
78b6ed19f3
|
@ -50,6 +50,21 @@ typedef struct CVKeyIndex {
|
|||
bool switched;
|
||||
} CVKeyIndex;
|
||||
|
||||
typedef enum eNurbHandleTest_Mode {
|
||||
/** Read the selection from each handle. */
|
||||
NURB_HANDLE_TEST_EACH = 1,
|
||||
/**
|
||||
* When the knot (center point) is selected treat the handles as selected too.
|
||||
* Otherwise use the same behavior as #NURB_HANDLE_TEST_EACH.
|
||||
*/
|
||||
NURB_HANDLE_TEST_KNOT_OR_EACH = 2,
|
||||
/**
|
||||
* When the knot is selected, treat all handles as selected, otherwise none.
|
||||
* \note Typically used when handles are hidden.
|
||||
*/
|
||||
NURB_HANDLE_TEST_KNOT_ONLY = 3,
|
||||
} eNurbHandleTest_Mode;
|
||||
|
||||
#define KNOTSU(nu) \
|
||||
((nu)->orderu + (nu)->pntsu + (((nu)->flagu & CU_NURB_CYCLIC) ? ((nu)->orderu - 1) : 0))
|
||||
#define KNOTSV(nu) \
|
||||
|
@ -340,6 +355,15 @@ void BKE_nurb_handle_smooth_fcurve(struct BezTriple *bezt, int total, bool cycli
|
|||
|
||||
void BKE_nurb_handles_calc(struct Nurb *nu);
|
||||
void BKE_nurb_handles_autocalc(struct Nurb *nu, uint8_t flag);
|
||||
|
||||
/**
|
||||
* Return a flag for the handles to treat as "selected":
|
||||
* `1 << 0`, `1 << 1`, `1 << 2` map to handles 1 2 & 3.
|
||||
*/
|
||||
short BKE_nurb_bezt_handle_test_calc_flag(const BezTriple *bezt,
|
||||
const eBezTriple_Flag__Alias sel_flag,
|
||||
const eNurbHandleTest_Mode handle_mode);
|
||||
|
||||
/**
|
||||
* Update selected handle types to ensure valid state, e.g. deduce "Auto" types to concrete ones.
|
||||
* Thereby \a sel_flag defines what qualifies as selected.
|
||||
|
@ -349,14 +373,15 @@ void BKE_nurb_handles_autocalc(struct Nurb *nu, uint8_t flag);
|
|||
*
|
||||
* \param sel_flag: The flag (bezt.f1/2/3) value to use to determine selection. Usually `SELECT`,
|
||||
* but may want to use a different one at times (if caller does not operate on * selection).
|
||||
* \param use_handle: Check selection state of individual handles, otherwise always update both
|
||||
* handles if the key is selected.
|
||||
* \param handle_mode: Interpret the selection base on modes in #eNurbHandleTest_Mode.
|
||||
*/
|
||||
void BKE_nurb_bezt_handle_test(struct BezTriple *bezt,
|
||||
eBezTriple_Flag__Alias sel_flag,
|
||||
bool use_handle,
|
||||
const eNurbHandleTest_Mode handle_mode,
|
||||
bool use_around_local);
|
||||
void BKE_nurb_handles_test(struct Nurb *nu, bool use_handles, bool use_around_local);
|
||||
void BKE_nurb_handles_test(struct Nurb *nu,
|
||||
eNurbHandleTest_Mode handle_mode,
|
||||
bool use_around_local);
|
||||
|
||||
/* **** Depsgraph evaluation **** */
|
||||
|
||||
|
|
|
@ -4032,32 +4032,49 @@ void BKE_nurb_handle_calc_simple_auto(Nurb *nu, BezTriple *bezt)
|
|||
}
|
||||
}
|
||||
|
||||
void BKE_nurb_bezt_handle_test(BezTriple *bezt,
|
||||
const eBezTriple_Flag__Alias sel_flag,
|
||||
const bool use_handle,
|
||||
const bool use_around_local)
|
||||
{
|
||||
short flag = 0;
|
||||
|
||||
#define SEL_F1 (1 << 0)
|
||||
#define SEL_F2 (1 << 1)
|
||||
#define SEL_F3 (1 << 2)
|
||||
|
||||
if (use_handle) {
|
||||
if (bezt->f1 & sel_flag) {
|
||||
flag |= SEL_F1;
|
||||
}
|
||||
if (bezt->f2 & sel_flag) {
|
||||
flag |= SEL_F2;
|
||||
}
|
||||
if (bezt->f3 & sel_flag) {
|
||||
flag |= SEL_F3;
|
||||
}
|
||||
}
|
||||
else {
|
||||
flag = (bezt->f2 & sel_flag) ? (SEL_F1 | SEL_F2 | SEL_F3) : 0;
|
||||
}
|
||||
short BKE_nurb_bezt_handle_test_calc_flag(const BezTriple *bezt,
|
||||
const eBezTriple_Flag__Alias sel_flag,
|
||||
const eNurbHandleTest_Mode handle_mode)
|
||||
{
|
||||
short flag = 0;
|
||||
|
||||
switch (handle_mode) {
|
||||
case NURB_HANDLE_TEST_KNOT_ONLY: {
|
||||
flag = (bezt->f2 & sel_flag) ? (SEL_F1 | SEL_F2 | SEL_F3) : 0;
|
||||
break;
|
||||
}
|
||||
case NURB_HANDLE_TEST_KNOT_OR_EACH:
|
||||
if (bezt->f2 & sel_flag) {
|
||||
flag = (bezt->f2 & sel_flag) ? (SEL_F1 | SEL_F2 | SEL_F3) : 0;
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
case NURB_HANDLE_TEST_EACH: {
|
||||
if (bezt->f1 & sel_flag) {
|
||||
flag |= SEL_F1;
|
||||
}
|
||||
if (bezt->f2 & sel_flag) {
|
||||
flag |= SEL_F2;
|
||||
}
|
||||
if (bezt->f3 & sel_flag) {
|
||||
flag |= SEL_F3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
void BKE_nurb_bezt_handle_test(BezTriple *bezt,
|
||||
const eBezTriple_Flag__Alias sel_flag,
|
||||
const eNurbHandleTest_Mode handle_mode,
|
||||
const bool use_around_local)
|
||||
{
|
||||
short flag = BKE_nurb_bezt_handle_test_calc_flag(bezt, sel_flag, handle_mode);
|
||||
if (use_around_local) {
|
||||
flag &= ~SEL_F2;
|
||||
}
|
||||
|
@ -4082,13 +4099,15 @@ void BKE_nurb_bezt_handle_test(BezTriple *bezt,
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef SEL_F1
|
||||
#undef SEL_F2
|
||||
#undef SEL_F3
|
||||
}
|
||||
|
||||
void BKE_nurb_handles_test(Nurb *nu, const bool use_handle, const bool use_around_local)
|
||||
void BKE_nurb_handles_test(Nurb *nu,
|
||||
const eNurbHandleTest_Mode handle_mode,
|
||||
const bool use_around_local)
|
||||
{
|
||||
BezTriple *bezt;
|
||||
int a;
|
||||
|
@ -4100,7 +4119,7 @@ void BKE_nurb_handles_test(Nurb *nu, const bool use_handle, const bool use_aroun
|
|||
bezt = nu->bezt;
|
||||
a = nu->pntsu;
|
||||
while (a--) {
|
||||
BKE_nurb_bezt_handle_test(bezt, SELECT, use_handle, use_around_local);
|
||||
BKE_nurb_bezt_handle_test(bezt, SELECT, handle_mode, use_around_local);
|
||||
bezt++;
|
||||
}
|
||||
|
||||
|
|
|
@ -1314,7 +1314,8 @@ void testhandles_fcurve(FCurve *fcu, eBezTriple_Flag sel_flag, const bool use_ha
|
|||
BezTriple *bezt;
|
||||
uint a;
|
||||
for (a = 0, bezt = fcu->bezt; a < fcu->totvert; a++, bezt++) {
|
||||
BKE_nurb_bezt_handle_test(bezt, sel_flag, use_handle, false);
|
||||
BKE_nurb_bezt_handle_test(
|
||||
bezt, sel_flag, use_handle ? NURB_HANDLE_TEST_EACH : NURB_HANDLE_TEST_KNOT_ONLY, false);
|
||||
}
|
||||
|
||||
/* Recalculate handles. */
|
||||
|
|
|
@ -289,7 +289,7 @@ static void graphedit_activekey_handles_cb(bContext *C, void *fcu_ptr, void *bez
|
|||
bezt->h2 = HD_ALIGN;
|
||||
}
|
||||
else {
|
||||
BKE_nurb_bezt_handle_test(bezt, SELECT, true, false);
|
||||
BKE_nurb_bezt_handle_test(bezt, SELECT, NURB_HANDLE_TEST_EACH, false);
|
||||
}
|
||||
|
||||
/* now call standard updates */
|
||||
|
|
|
@ -1194,7 +1194,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
|
|||
if (CU_IS_2D(cu)) {
|
||||
BKE_nurb_project_2d(nu);
|
||||
}
|
||||
BKE_nurb_handles_test(nu, true, false); /* test for bezier too */
|
||||
BKE_nurb_handles_test(nu, NURB_HANDLE_TEST_EACH, false); /* test for bezier too */
|
||||
}
|
||||
}
|
||||
else if ((ob->type == OB_LATTICE) && (apply_vcos || median_basis.lattice.weight)) {
|
||||
|
|
|
@ -33,19 +33,10 @@
|
|||
* For the purpose of transform code we need to behave as if handles are selected,
|
||||
* even when they aren't (see special case below).
|
||||
*/
|
||||
static int bezt_select_to_transform_triple_flag(const BezTriple *bezt, const bool hide_handles)
|
||||
static int bezt_select_to_transform_triple_flag(const BezTriple *bezt,
|
||||
const eNurbHandleTest_Mode handle_mode)
|
||||
{
|
||||
int flag = 0;
|
||||
|
||||
if (hide_handles) {
|
||||
if (bezt->f2 & SELECT) {
|
||||
flag = (1 << 0) | (1 << 1) | (1 << 2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
flag = (((bezt->f1 & SELECT) ? (1 << 0) : 0) | ((bezt->f2 & SELECT) ? (1 << 1) : 0) |
|
||||
((bezt->f3 & SELECT) ? (1 << 2) : 0));
|
||||
}
|
||||
int flag = BKE_nurb_bezt_handle_test_calc_flag(bezt, SELECT, handle_mode);
|
||||
|
||||
/* Special case for auto & aligned handles:
|
||||
* When a center point is being moved without the handles,
|
||||
|
@ -83,6 +74,8 @@ static void createTransCurveVerts(bContext * /*C*/, TransInfo *t)
|
|||
View3D *v3d = static_cast<View3D *>(t->view);
|
||||
short hide_handles = (v3d != nullptr) ? (v3d->overlay.handle_display == CURVE_HANDLE_NONE) :
|
||||
false;
|
||||
const eNurbHandleTest_Mode handle_mode = hide_handles ? NURB_HANDLE_TEST_KNOT_ONLY :
|
||||
NURB_HANDLE_TEST_EACH;
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
Curve *cu = static_cast<Curve *>(tc->obedit->data);
|
||||
|
@ -99,7 +92,7 @@ static void createTransCurveVerts(bContext * /*C*/, TransInfo *t)
|
|||
if (nu->type == CU_BEZIER) {
|
||||
for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
|
||||
if (bezt->hide == 0) {
|
||||
const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles);
|
||||
const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, handle_mode);
|
||||
if (bezt_tx & (SEL_F1 | SEL_F2 | SEL_F3)) {
|
||||
if (bezt_tx & SEL_F1) {
|
||||
countsel++;
|
||||
|
@ -208,7 +201,7 @@ static void createTransCurveVerts(bContext * /*C*/, TransInfo *t)
|
|||
}
|
||||
|
||||
/* 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, handle_mode);
|
||||
has_any_selected |= bezt_tx != 0;
|
||||
|
||||
if (is_prop_edit || bezt_tx & SEL_F1) {
|
||||
|
@ -410,7 +403,7 @@ static void createTransCurveVerts(bContext * /*C*/, TransInfo *t)
|
|||
ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT, TFM_DUMMY) == 0) {
|
||||
/* sets the handles based on their selection,
|
||||
* 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, handle_mode, use_around_origins_for_handles_test);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -357,8 +357,11 @@ static void createTransGPencil_curves(bContext *C,
|
|||
|
||||
/* Update the handle types so transformation is possible */
|
||||
if (bezt_use && !ELEM(t->mode, TFM_GPENCIL_OPACITY, TFM_GPENCIL_SHRINKFATTEN)) {
|
||||
BKE_nurb_bezt_handle_test(
|
||||
bezt, SELECT, !hide_handles, use_around_origins_for_handles_test);
|
||||
BKE_nurb_bezt_handle_test(bezt,
|
||||
SELECT,
|
||||
hide_handles ? NURB_HANDLE_TEST_KNOT_ONLY :
|
||||
NURB_HANDLE_TEST_EACH,
|
||||
use_around_origins_for_handles_test);
|
||||
need_handle_recalc = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ void ED_transverts_update_obedit(TransVertStore *tvs, Object *obedit)
|
|||
if (CU_IS_2D(cu)) {
|
||||
BKE_nurb_project_2d(nu);
|
||||
}
|
||||
BKE_nurb_handles_test(nu, true, false); /* test for bezier too */
|
||||
BKE_nurb_handles_test(nu, NURB_HANDLE_TEST_EACH, false); /* test for bezier too */
|
||||
nu = nu->next;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue