Curve: Remove 'CU_2D' flag used for nurbs

This fixes T86440

As the CU_2D flag is set for nurbs, a Curve can have 2D nurbs mixed with 3D.

But the UI does not allow this mixing. It updates all nurbs to 2D or 3D when set.

So remove this specific flag for nurbs.

This may break old files, since 2D curves with mixed 3D are now set as 3D.

Differential Revision: https://developer.blender.org/D10738
This commit is contained in:
Germano Cavalcante 2021-04-01 10:41:12 -03:00 committed by Germano Cavalcante
parent 7a757662bc
commit f674976edd
Notes: blender-bot 2023-02-14 09:21:21 +01:00
Referenced by commit b7b1b2325c, Fix T87274: Curve 2D resets to 3D on reload
Referenced by issue #87274, Curve 2D resets to 3D on reload
Referenced by issue #86440, transforming 2d curve sa 3d curve (rotation+depth)
19 changed files with 86 additions and 84 deletions

View File

@ -69,16 +69,16 @@ typedef struct CVKeyIndex {
#define SEGMENTSU(nu) (((nu)->flagu & CU_NURB_CYCLIC) ? (nu)->pntsu : (nu)->pntsu - 1)
#define SEGMENTSV(nu) (((nu)->flagv & CU_NURB_CYCLIC) ? (nu)->pntsv : (nu)->pntsv - 1)
#define CU_DO_TILT(cu, nu) ((((nu)->flag & CU_2D) && ((cu)->flag & CU_3D) == 0) ? 0 : 1)
#define CU_DO_RADIUS(cu, nu) \
((CU_DO_TILT(cu, nu) || ((cu)->flag & CU_PATH_RADIUS) || (cu)->bevobj || (cu)->ext1 != 0.0f || \
((((cu)->flag & (CU_PATH_RADIUS | CU_3D)) || (cu)->bevobj || (cu)->ext1 != 0.0f || \
(cu)->ext2 != 0.0f) ? \
1 : \
0)
#define CU_IS_2D(cu) (((cu)->flag & CU_3D) == 0)
/* not 3d and not unfilled */
#define CU_DO_2DFILL(cu) \
((((cu)->flag & CU_3D) == 0) && (((cu)->flag & (CU_FRONT | CU_BACK)) != 0))
#define CU_DO_2DFILL(cu) (CU_IS_2D(cu) && (((cu)->flag & (CU_FRONT | CU_BACK)) != 0))
/* ** Curve ** */
void BKE_curve_editfont_free(struct Curve *cu);
@ -86,7 +86,7 @@ void BKE_curve_init(struct Curve *cu, const short curve_type);
struct Curve *BKE_curve_add(struct Main *bmain, const char *name, int type);
short BKE_curve_type_get(const struct Curve *cu);
void BKE_curve_type_test(struct Object *ob);
void BKE_curve_curve_dimension_update(struct Curve *cu);
void BKE_curve_dimension_update(struct Curve *cu);
struct BoundBox *BKE_curve_boundbox_get(struct Object *ob);
@ -186,7 +186,7 @@ void BKE_nurb_free(struct Nurb *nu);
struct Nurb *BKE_nurb_duplicate(const struct Nurb *nu);
struct Nurb *BKE_nurb_copy(struct Nurb *src, int pntsu, int pntsv);
void BKE_nurb_test_2d(struct Nurb *nu);
void BKE_nurb_project_2d(struct Nurb *nu);
void BKE_nurb_minmax(const struct Nurb *nu, bool use_radius, float min[3], float max[3]);
float BKE_nurb_calc_length(const struct Nurb *nu, int resolution);

View File

@ -462,24 +462,19 @@ short BKE_curve_type_get(const Curve *cu)
return type;
}
void BKE_curve_curve_dimension_update(Curve *cu)
void BKE_curve_dimension_update(Curve *cu)
{
ListBase *nurbs = BKE_curve_nurbs_get(cu);
bool is_2d = CU_IS_2D(cu);
if (cu->flag & CU_3D) {
LISTBASE_FOREACH (Nurb *, nu, nurbs) {
nu->flag &= ~CU_2D;
LISTBASE_FOREACH (Nurb *, nu, nurbs) {
if (is_2d) {
BKE_nurb_project_2d(nu);
}
}
else {
LISTBASE_FOREACH (Nurb *, nu, nurbs) {
nu->flag |= CU_2D;
BKE_nurb_test_2d(nu);
/* since the handles are moved they need to be auto-located again */
if (nu->type == CU_BEZIER) {
BKE_nurb_handles_calc(nu);
}
/* since the handles are moved they need to be auto-located again */
if (nu->type == CU_BEZIER) {
BKE_nurb_handles_calc(nu);
}
}
}
@ -489,7 +484,10 @@ void BKE_curve_type_test(Object *ob)
ob->type = BKE_curve_type_get(ob->data);
if (ob->type == OB_CURVE) {
BKE_curve_curve_dimension_update((Curve *)ob->data);
Curve *cu = ob->data;
if (CU_IS_2D(cu)) {
BKE_curve_dimension_update(cu);
}
}
}
@ -745,16 +743,12 @@ void BKE_nurbList_duplicate(ListBase *lb1, const ListBase *lb2)
}
}
void BKE_nurb_test_2d(Nurb *nu)
void BKE_nurb_project_2d(Nurb *nu)
{
BezTriple *bezt;
BPoint *bp;
int a;
if ((nu->flag & CU_2D) == 0) {
return;
}
if (nu->type == CU_BEZIER) {
a = nu->pntsu;
bezt = nu->bezt;
@ -2712,8 +2706,9 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
continue;
}
/* check if we will calculate tilt data */
do_tilt = CU_DO_TILT(cu, nu);
/* Tilt, as the rotation angle of curve control points, is only calculated for 3D curves,
* (since this transformation affects the 3D space). */
do_tilt = (cu->flag & CU_3D) != 0;
/* Normal display uses the radius, better just to calculate them. */
do_radius = CU_DO_RADIUS(cu, nu);
@ -3125,7 +3120,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
}
/* turning direction */
if ((cu->flag & CU_3D) == 0) {
if (CU_IS_2D(cu)) {
sd = sortdata;
for (a = 0; a < poly; a++, sd++) {
if (sd->bl->hole == sd->dir) {
@ -3145,7 +3140,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
}
/* STEP 4: 2D-COSINES or 3D ORIENTATION */
if ((cu->flag & CU_3D) == 0) {
if (CU_IS_2D(cu)) {
/* 2D Curves */
LISTBASE_FOREACH (BevList *, bl, bev) {
if (bl->nr < 2) {
@ -4730,9 +4725,7 @@ void BKE_curve_nurbs_vert_coords_apply_with_mat4(ListBase *lb,
}
if (constrain_2d) {
if (nu->flag & CU_2D) {
BKE_nurb_test_2d(nu);
}
BKE_nurb_project_2d(nu);
}
calchandlesNurb_intern(nu, SELECT, true);
@ -4768,9 +4761,7 @@ void BKE_curve_nurbs_vert_coords_apply(ListBase *lb,
}
if (constrain_2d) {
if (nu->flag & CU_2D) {
BKE_nurb_test_2d(nu);
}
BKE_nurb_project_2d(nu);
}
calchandlesNurb_intern(nu, SELECT, true);

View File

@ -44,7 +44,7 @@ static Curve *curve_from_font_object(Object *object, Depsgraph *depsgraph)
new_curve->type = OB_CURVE;
new_curve->flag &= ~CU_3D;
BKE_curve_curve_dimension_update(new_curve);
BKE_curve_dimension_update(new_curve);
return new_curve;
}

View File

@ -1185,7 +1185,7 @@ void BKE_displist_make_surf(Depsgraph *depsgraph,
/* dl->rt will be used as flag for render face and */
/* CU_2D conflicts with R_NOPUNOFLIP */
dl->rt = nu->flag & ~CU_2D;
dl->rt = nu->flag;
data = dl->verts;
if (nu->flagu & CU_NURB_CYCLIC) {
@ -1209,7 +1209,7 @@ void BKE_displist_make_surf(Depsgraph *depsgraph,
/* dl->rt will be used as flag for render face and */
/* CU_2D conflicts with R_NOPUNOFLIP */
dl->rt = nu->flag & ~CU_2D;
dl->rt = nu->flag;
data = dl->verts;
dl->type = DL_SURF;
@ -1320,7 +1320,7 @@ static void fillBevelCap(const Nurb *nu,
/* dl->rt will be used as flag for render face and */
/* CU_2D conflicts with R_NOPUNOFLIP */
dl->rt = nu->flag & ~CU_2D;
dl->rt = nu->flag;
BLI_addtail(dispbase, dl);
}
@ -1551,7 +1551,7 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph,
/* dl->rt will be used as flag for render face and */
/* CU_2D conflicts with R_NOPUNOFLIP */
dl->rt = nu->flag & ~CU_2D;
dl->rt = nu->flag;
int a = dl->nr;
BevPoint *bevp = bl->bevpoints;
@ -1606,7 +1606,7 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph,
/* dl->rt will be used as flag for render face and */
/* CU_2D conflicts with R_NOPUNOFLIP */
dl->rt = nu->flag & ~CU_2D;
dl->rt = nu->flag;
/* for each point of poly make a bevel piece */
BevPoint *bevp_first = bl->bevpoints;

View File

@ -447,7 +447,6 @@ static void build_underline(Curve *cu,
nu2->resolu = cu->resolu;
nu2->bezt = NULL;
nu2->knotsu = nu2->knotsv = NULL;
nu2->flag = CU_2D;
nu2->charidx = charidx + 1000;
if (mat_nr > 0) {
nu2->mat_nr = mat_nr - 1;

View File

@ -135,7 +135,6 @@ static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *
nu->type = CU_BEZIER;
nu->pntsu = onpoints[j];
nu->resolu = 8;
nu->flag = CU_2D;
nu->flagu = CU_NURB_CYCLIC;
nu->bezt = bezt;

View File

@ -779,7 +779,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
Nurb *nu;
for (nu = cu->nurb.first; nu; nu = nu->next) {
nu->flag |= (nu->type & CU_2D);
nu->type &= CU_TYPE;
}
}

View File

@ -57,6 +57,7 @@
#include "BKE_collection.h"
#include "BKE_colortools.h"
#include "BKE_cryptomatte.h"
#include "BKE_curve.h"
#include "BKE_fcurve.h"
#include "BKE_gpencil.h"
#include "BKE_lib_id.h"
@ -1983,5 +1984,25 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
/* The CU_2D flag has been removed. */
LISTBASE_FOREACH (Curve *, cu, &bmain->curves) {
#define CU_2D (1 << 3)
ListBase *nurbs = BKE_curve_nurbs_get(cu);
bool is_2d = true;
LISTBASE_FOREACH (Nurb *, nu, nurbs) {
if (nu->flag & CU_2D) {
nu->flag &= ~CU_2D;
}
else {
is_2d = false;
}
}
#undef CU_2D
if (!is_2d && CU_IS_2D(cu)) {
cu->flag |= CU_3D;
}
}
}
}

View File

@ -142,7 +142,10 @@ struct GHash *ED_curve_keyindex_hash_duplicate(struct GHash *keyindex);
void ED_curve_keyindex_update_nurb(struct EditNurb *editnurb, struct Nurb *nu, struct Nurb *newnu);
/* helper functions */
void ed_editnurb_translate_flag(struct ListBase *editnurb, uint8_t flag, const float vec[3]);
void ed_editnurb_translate_flag(struct ListBase *editnurb,
uint8_t flag,
const float vec[3],
bool is_2d);
bool ed_editnurb_extrude_flag(struct EditNurb *editnurb, const uint8_t flag);
bool ed_editnurb_spin(float viewmat[4][4],
struct View3D *v3d,

View File

@ -1314,7 +1314,6 @@ void ED_curve_editnurb_make(Object *obedit)
LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
Nurb *newnu = BKE_nurb_duplicate(nu);
BKE_nurb_test_2d(newnu); /* after join, or any other creation of curve */
BLI_addtail(&editnurb->nurbs, newnu);
}
@ -1706,7 +1705,7 @@ static void rotateflagNurb(ListBase *editnurb,
}
}
void ed_editnurb_translate_flag(ListBase *editnurb, uint8_t flag, const float vec[3])
void ed_editnurb_translate_flag(ListBase *editnurb, uint8_t flag, const float vec[3], bool is_2d)
{
/* all verts with ('flag' & flag) translate */
BezTriple *bezt;
@ -1741,7 +1740,9 @@ void ed_editnurb_translate_flag(ListBase *editnurb, uint8_t flag, const float ve
}
}
BKE_nurb_test_2d(nu);
if (is_2d) {
BKE_nurb_project_2d(nu);
}
}
}
@ -5401,7 +5402,7 @@ static int ed_editcurve_addvert(Curve *cu,
mul_v3_fl(center, 1.0f / (float)verts_len);
sub_v3_v3v3(ofs, location_init, center);
if ((cu->flag & CU_3D) == 0) {
if (CU_IS_2D(cu)) {
ofs[2] = 0.0f;
}
@ -5439,7 +5440,7 @@ static int ed_editcurve_addvert(Curve *cu,
copy_v3_v3(location, location_init);
if ((cu->flag & CU_3D) == 0) {
if (CU_IS_2D(cu)) {
location[2] = 0.0f;
}
@ -5455,10 +5456,6 @@ static int ed_editcurve_addvert(Curve *cu,
nurb_new->orderu = 4;
nurb_new->flag |= CU_SMOOTH;
BKE_nurb_bezierPoints_add(nurb_new, 1);
if ((cu->flag & CU_3D) == 0) {
nurb_new->flag |= CU_2D;
}
}
else {
/* Copy the active nurb settings. */
@ -5590,7 +5587,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ED_transform_snap_object_context_destroy(snap_context);
}
if ((cu->flag & CU_3D) == 0) {
if (CU_IS_2D(cu)) {
const float eps = 1e-6f;
/* get the view vector to 'location' */
@ -6922,9 +6919,9 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op)
cu = ob_active->data;
BLI_movelisttolist(&cu->nurb, &tempbase);
if (ob_active->type == OB_CURVE) {
if (ob_active->type == OB_CURVE && CU_IS_2D(cu)) {
/* Account for mixed 2D/3D curves when joining */
BKE_curve_curve_dimension_update(cu);
BKE_curve_dimension_update(cu);
}
DEG_relations_tag_update(bmain); /* because we removed object(s), call before editmode! */

View File

@ -380,10 +380,10 @@ Nurb *ED_curve_add_nurbs_primitive(
mul_mat3_m4_v3(mat, vec);
ed_editnurb_translate_flag(editnurb, SELECT, vec);
ed_editnurb_translate_flag(editnurb, SELECT, vec, CU_IS_2D(cu));
ed_editnurb_extrude_flag(cu->editnurb, SELECT);
mul_v3_fl(vec, -2.0f);
ed_editnurb_translate_flag(editnurb, SELECT, vec);
ed_editnurb_translate_flag(editnurb, SELECT, vec, CU_IS_2D(cu));
BLI_remlink(editnurb, nu);
@ -492,15 +492,13 @@ Nurb *ED_curve_add_nurbs_primitive(
BLI_assert(nu != NULL);
if (nu) { /* should always be set */
if ((obedit->type != OB_SURF) && ((cu->flag & CU_3D) == 0)) {
nu->flag |= CU_2D;
}
nu->flag |= CU_SMOOTH;
cu->actnu = BLI_listbase_count(editnurb);
cu->actvert = CU_ACT_NONE;
BKE_nurb_test_2d(nu);
if (CU_IS_2D(cu)) {
BKE_nurb_project_2d(nu);
}
}
return nu;

View File

@ -1072,7 +1072,7 @@ static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const float *plane_no = NULL;
const float *plane_co = NULL;
if ((cu->flag & CU_3D) == 0) {
if (CU_IS_2D(cu)) {
/* 2D overrides other options */
plane_co = obedit->obmat[3];
plane_no = obedit->obmat[2];

View File

@ -2897,7 +2897,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
}
cu->flag &= ~CU_3D;
BKE_curve_curve_dimension_update(cu);
BKE_curve_dimension_update(cu);
if (target == OB_MESH) {
/* No assumption should be made that the resulting objects is a mesh, as conversion can

View File

@ -593,13 +593,14 @@ void ED_object_data_xform_by_mat4(struct XFormObjectData *xod_base, const float
if (xod_base->is_edit_mode) {
EditNurb *editnurb = cu->editnurb;
nurb = &editnurb->nurbs;
BKE_curve_nurbs_vert_coords_apply_with_mat4(&editnurb->nurbs, xod->elem_array, mat, true);
BKE_curve_nurbs_vert_coords_apply_with_mat4(
&editnurb->nurbs, xod->elem_array, mat, CU_IS_2D(cu));
/* Always operate on all keys for the moment. */
// key_index = editnurb->shapenr - 1;
}
else {
nurb = &cu->nurb;
BKE_curve_nurbs_vert_coords_apply_with_mat4(&cu->nurb, xod->elem_array, mat, true);
BKE_curve_nurbs_vert_coords_apply_with_mat4(&cu->nurb, xod->elem_array, mat, CU_IS_2D(cu));
}
if ((key != NULL) && (xod->key_data != NULL)) {
@ -694,12 +695,12 @@ void ED_object_data_xform_restore(struct XFormObjectData *xod_base)
struct XFormObjectData_Curve *xod = (struct XFormObjectData_Curve *)xod_base;
if (xod_base->is_edit_mode) {
EditNurb *editnurb = cu->editnurb;
BKE_curve_nurbs_vert_coords_apply(&editnurb->nurbs, xod->elem_array, true);
BKE_curve_nurbs_vert_coords_apply(&editnurb->nurbs, xod->elem_array, CU_IS_2D(cu));
/* Always operate on all keys for the moment. */
// key_index = editnurb->shapenr - 1;
}
else {
BKE_curve_nurbs_vert_coords_apply(&cu->nurb, xod->elem_array, true);
BKE_curve_nurbs_vert_coords_apply(&cu->nurb, xod->elem_array, CU_IS_2D(cu));
}
if ((key != NULL) && (xod->key_data != NULL)) {

View File

@ -1031,7 +1031,9 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
}
}
BKE_nurb_test_2d(nu);
if (CU_IS_2D(cu)) {
BKE_nurb_project_2d(nu);
}
BKE_nurb_handles_test(nu, true, false); /* test for bezier too */
}
}

View File

@ -461,11 +461,7 @@ void recalcData_curve(TransInfo *t)
}
else {
/* Normal updating */
while (nu) {
BKE_nurb_test_2d(nu);
BKE_nurb_handles_calc(nu);
nu = nu->next;
}
BKE_curve_dimension_update(cu);
}
}
}

View File

@ -111,7 +111,9 @@ void ED_transverts_update_obedit(TransVertStore *tvs, Object *obedit)
}
}
BKE_nurb_test_2d(nu);
if (CU_IS_2D(cu)) {
BKE_nurb_project_2d(nu);
}
BKE_nurb_handles_test(nu, true, false); /* test for bezier too */
nu = nu->next;
}

View File

@ -425,7 +425,6 @@ enum {
/* Nurb.flag */
enum {
CU_SMOOTH = 1 << 0,
CU_2D = 1 << 3, /* moved from type since 2.4x */
};
/* Nurb.type */

View File

@ -357,9 +357,8 @@ static void rna_Curve_dimension_set(PointerRNA *ptr, int value)
}
else {
cu->flag &= ~CU_3D;
BKE_curve_dimension_update(cu);
}
BKE_curve_curve_dimension_update(cu);
}
static const EnumPropertyItem *rna_Curve_fill_mode_itemf(bContext *UNUSED(C),
@ -721,10 +720,6 @@ static Nurb *rna_Curve_spline_new(Curve *cu, int type)
nu->resolv = cu->resolv;
nu->flag = CU_SMOOTH;
if ((cu->flag & CU_3D) == 0) {
nu->flag |= CU_2D;
}
BLI_addtail(BKE_curve_nurbs_get(cu), nu);
return nu;