diff options
25 files changed, 197 insertions, 129 deletions
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index baa90e7a856..b1020464728 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -42,6 +42,13 @@ struct Main; struct Nurb; struct Object; struct Scene; +struct Path; + +typedef struct CurveCache { + ListBase disp; + ListBase bev; + struct Path *path; +} CurveCache; #define KNOTSU(nu) ( (nu)->orderu + (nu)->pntsu + (((nu)->flagu & CU_NURB_CYCLIC) ? ((nu)->orderu - 1) : 0) ) #define KNOTSV(nu) ( (nu)->orderv + (nu)->pntsv + (((nu)->flagv & CU_NURB_CYCLIC) ? ((nu)->orderv - 1) : 0) ) diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 992792dcb99..dbd2263cfc9 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -60,6 +60,7 @@ void BKE_object_copy_softbody(struct Object *obn, struct Object *ob); void BKE_object_free_particlesystems(struct Object *ob); void BKE_object_free_softbody(struct Object *ob); void BKE_object_free_bulletsoftbody(struct Object *ob); +void BKE_object_free_curve_cache(struct Object *ob); void BKE_object_update_base_layer(struct Scene *scene, struct Object *ob); void BKE_object_free(struct Object *ob); diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index ba680147201..f3e2b118f2e 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -509,11 +509,11 @@ void calc_curvepath(Object *ob) } cu = ob->data; - if (cu->path) free_path(cu->path); - cu->path = NULL; + if (ob->curve_cache->path) free_path(ob->curve_cache->path); + ob->curve_cache->path = NULL; /* weak! can only use first curve */ - bl = cu->bev.first; + bl = ob->curve_cache->bev.first; if (bl == NULL || !bl->nr) { return; } @@ -521,7 +521,7 @@ void calc_curvepath(Object *ob) nurbs = BKE_curve_nurbs_get(cu); nu = nurbs->first; - cu->path = path = MEM_callocN(sizeof(Path), "calc_curvepath"); + ob->curve_cache->path = path = MEM_callocN(sizeof(Path), "calc_curvepath"); /* if POLY: last vertice != first vertice */ cycl = (bl->poly != -1); @@ -630,15 +630,15 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua if (ob == NULL || ob->type != OB_CURVE) return 0; cu = ob->data; - if (cu->path == NULL || cu->path->data == NULL) { + if (ob->curve_cache == NULL || ob->curve_cache->path == NULL || ob->curve_cache->path->data == NULL) { printf("no path!\n"); return 0; } - path = cu->path; + path = ob->curve_cache->path; pp = path->data; /* test for cyclic */ - bl = cu->bev.first; + bl = ob->curve_cache->bev.first; if (!bl) return 0; if (!bl->nr) return 0; if (bl->poly > -1) cycl = 1; diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index f006710dc21..dbe3c39af97 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1826,18 +1826,16 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos * - this is a workaround for a depsgraph bug... */ if (ikData->tar) { - Curve *cu = ikData->tar->data; - /* note: when creating constraints that follow path, the curve gets the CU_PATH set now, * currently for paths to work it needs to go through the bevlist/displist system (ton) */ /* only happens on reload file, but violates depsgraph still... fix! */ - if (ELEM(NULL, cu->path, cu->path->data)) { + if (ELEM3(NULL, ikData->tar->curve_cache, ikData->tar->curve_cache->path, ikData->tar->curve_cache->path->data)) { BKE_displist_make_curveTypes(scene, ikData->tar, 0); /* path building may fail in EditMode after removing verts [#33268]*/ - if (ELEM(NULL, cu->path, cu->path->data)) { + if (ELEM(NULL, ikData->tar->curve_cache->path, ikData->tar->curve_cache->path->data)) { /* BLI_assert(cu->path != NULL); */ return; } @@ -1901,7 +1899,6 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos * since it's easier to determine the positions of all the joints beforehand this way */ if ((ikData->flag & CONSTRAINT_SPLINEIK_SCALE_LIMITED) && (totLength != 0.0f)) { - Curve *cu = (Curve *)ikData->tar->data; float splineLen, maxScale; int i; @@ -1914,7 +1911,7 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos /* get the current length of the curve */ /* NOTE: this is assumed to be correct even after the curve was resized */ - splineLen = cu->path->totdist; + splineLen = ikData->tar->curve_cache->path->totdist; /* calculate the scale factor to multiply all the path values by so that the * bone chain retains its current length, such that diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 6205c8016b6..5ab618c4001 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1814,7 +1814,13 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob)) DerivedMesh *CDDM_from_curve(Object *ob) { - return CDDM_from_curve_displist(ob, &ob->disp); + ListBase disp = {NULL}; + + if (ob->curve_cache) { + disp = ob->curve_cache->disp; + } + + return CDDM_from_curve_displist(ob, &disp); } DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index eda770ddf30..a1cb360e0a4 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -69,6 +69,7 @@ #include "BKE_bvhutils.h" #include "BKE_camera.h" #include "BKE_constraint.h" +#include "BKE_curve.h" #include "BKE_displist.h" #include "BKE_deform.h" #include "BKE_DerivedMesh.h" /* for geometry targets */ @@ -448,7 +449,7 @@ static void contarget_get_lattice_mat(Object *ob, const char *substring, float m { Lattice *lt = (Lattice *)ob->data; - DispList *dl = BKE_displist_find(&ob->disp, DL_VERTS); + DispList *dl = ob->curve_cache ? BKE_displist_find(&ob->curve_cache->disp, DL_VERTS) : NULL; float *co = dl ? dl->verts : NULL; BPoint *bp = lt->def; @@ -1163,10 +1164,10 @@ static void followpath_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra */ /* only happens on reload file, but violates depsgraph still... fix! */ - if (cu->path == NULL || cu->path->data == NULL) + if (ct->tar->curve_cache == NULL || ct->tar->curve_cache->path == NULL || ct->tar->curve_cache->path->data == NULL) BKE_displist_make_curveTypes(cob->scene, ct->tar, 0); - if (cu->path && cu->path->data) { + if (ct->tar->curve_cache->path && ct->tar->curve_cache->path->data) { float quat[4]; if ((data->followflag & FOLLOWPATH_STATIC) == 0) { /* animated position along curve depending on time */ @@ -1933,10 +1934,8 @@ static void pycon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTa if (VALID_CONS_TARGET(ct)) { /* special exception for curves - depsgraph issues */ if (ct->tar->type == OB_CURVE) { - Curve *cu = ct->tar->data; - /* this check is to make sure curve objects get updated on file load correctly.*/ - if (cu->path == NULL || cu->path->data == NULL) /* only happens on reload file, but violates depsgraph still... fix! */ + if (ct->tar->curve_cache == NULL || ct->tar->curve_cache->path == NULL || ct->tar->curve_cache->path->data == NULL) /* only happens on reload file, but violates depsgraph still... fix! */ BKE_displist_make_curveTypes(cob->scene, ct->tar, 0); } @@ -3009,14 +3008,12 @@ static void clampto_flush_tars(bConstraint *con, ListBase *list, short nocopy) static void clampto_get_tarmat(bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime)) { if (VALID_CONS_TARGET(ct)) { - Curve *cu = ct->tar->data; - /* note: when creating constraints that follow path, the curve gets the CU_PATH set now, * currently for paths to work it needs to go through the bevlist/displist system (ton) */ /* only happens on reload file, but violates depsgraph still... fix! */ - if (cu->path == NULL || cu->path->data == NULL) + if (ct->tar->curve_cache == NULL || ct->tar->curve_cache->path == NULL || ct->tar->curve_cache->path->data == NULL) BKE_displist_make_curveTypes(cob->scene, ct->tar, 0); } @@ -3034,7 +3031,6 @@ static void clampto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar /* only evaluate if there is a target and it is a curve */ if (VALID_CONS_TARGET(ct) && (ct->tar->type == OB_CURVE)) { - Curve *cu = data->tar->data; float obmat[4][4], ownLoc[3]; float curveMin[3], curveMax[3]; float targetMatrix[4][4] = MAT4_UNITY; @@ -3047,7 +3043,7 @@ static void clampto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar BKE_object_minmax(ct->tar, curveMin, curveMax, TRUE); /* get targetmatrix */ - if (cu->path && cu->path->data) { + if (data->tar->curve_cache && data->tar->curve_cache->path && data->tar->curve_cache->path->data) { float vec[4], dir[3], totmat[4][4]; float curvetime; short clamp_axis; @@ -3650,14 +3646,12 @@ static void splineik_flush_tars(bConstraint *con, ListBase *list, short nocopy) static void splineik_get_tarmat(bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime)) { if (VALID_CONS_TARGET(ct)) { - Curve *cu = ct->tar->data; - /* note: when creating constraints that follow path, the curve gets the CU_PATH set now, * currently for paths to work it needs to go through the bevlist/displist system (ton) */ /* only happens on reload file, but violates depsgraph still... fix! */ - if (cu->path == NULL || cu->path->data == NULL) + if (ct->tar->curve_cache == NULL || ct->tar->curve_cache->path == NULL || ct->tar->curve_cache->path->data == NULL) BKE_displist_make_curveTypes(cob->scene, ct->tar, 0); } diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 7377a48a87e..8fa24ecbbe5 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -145,7 +145,6 @@ void BKE_curve_editNurb_free(Curve *cu) void BKE_curve_free(Curve *cu) { BKE_nurbList_free(&cu->nurb); - BLI_freelistN(&cu->bev); BKE_curve_editfont_free(cu); BKE_curve_editNurb_free(cu); @@ -160,8 +159,6 @@ void BKE_curve_free(Curve *cu) MEM_freeN(cu->strinfo); if (cu->bb) MEM_freeN(cu->bb); - if (cu->path) - free_path(cu->path); if (cu->tb) MEM_freeN(cu->tb); } @@ -227,9 +224,6 @@ Curve *BKE_curve_copy(Curve *cu) cun->key = BKE_key_copy(cu->key); if (cun->key) cun->key->from = (ID *)cun; - cun->bev.first = cun->bev.last = NULL; - cun->path = NULL; - cun->editnurb = NULL; cun->editfont = NULL; cun->selboxes = NULL; @@ -1562,10 +1556,10 @@ void BKE_curve_bevel_make(Scene *scene, Object *ob, ListBase *disp, int forRende dl = bevdisp.first; } else { - dl = cu->bevobj->disp.first; + dl = cu->bevobj->curve_cache ? cu->bevobj->curve_cache->disp.first : NULL; if (dl == NULL) { BKE_displist_make_curveTypes(scene, cu->bevobj, 0); - dl = cu->bevobj->disp.first; + dl = cu->bevobj->curve_cache->disp.first; } } @@ -2442,16 +2436,19 @@ void BKE_curve_bevelList_make(Object *ob) int a, b, nr, poly, resolu = 0, len = 0; int do_tilt, do_radius, do_weight; int is_editmode = 0; + ListBase *bev; /* this function needs an object, because of tflag and upflag */ cu = ob->data; + bev = &ob->curve_cache->bev; + /* do we need to calculate the radius for each point? */ /* do_radius = (cu->bevobj || cu->taperobj || (cu->flag & CU_FRONT) || (cu->flag & CU_BACK)) ? 0 : 1; */ /* STEP 1: MAKE POLYS */ - BLI_freelistN(&(cu->bev)); + BLI_freelistN(&(ob->curve_cache->bev)); if (cu->editnurb && ob->type != OB_FONT) { ListBase *nurbs = BKE_curve_editNurbs_get(cu); nu = nurbs->first; @@ -2475,7 +2472,7 @@ void BKE_curve_bevelList_make(Object *ob) * enforced in the UI but can go wrong possibly */ if (!BKE_nurb_check_valid_u(nu)) { bl = MEM_callocN(sizeof(BevList) + 1 * sizeof(BevPoint), "makeBevelList1"); - BLI_addtail(&(cu->bev), bl); + BLI_addtail(bev, bl); bl->nr = 0; bl->charidx = nu->charidx; } @@ -2488,7 +2485,7 @@ void BKE_curve_bevelList_make(Object *ob) if (nu->type == CU_POLY) { len = nu->pntsu; bl = MEM_callocN(sizeof(BevList) + len * sizeof(BevPoint), "makeBevelList2"); - BLI_addtail(&(cu->bev), bl); + BLI_addtail(bev, bl); bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1; bl->nr = len; @@ -2515,7 +2512,7 @@ void BKE_curve_bevelList_make(Object *ob) /* in case last point is not cyclic */ len = resolu * (nu->pntsu + (nu->flagu & CU_NURB_CYCLIC) - 1) + 1; bl = MEM_callocN(sizeof(BevList) + len * sizeof(BevPoint), "makeBevelBPoints"); - BLI_addtail(&(cu->bev), bl); + BLI_addtail(bev, bl); bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1; bl->charidx = nu->charidx; @@ -2608,7 +2605,7 @@ void BKE_curve_bevelList_make(Object *ob) len = (resolu * SEGMENTSU(nu)); bl = MEM_callocN(sizeof(BevList) + len * sizeof(BevPoint), "makeBevelList3"); - BLI_addtail(&(cu->bev), bl); + BLI_addtail(bev, bl); bl->nr = len; bl->dupe_nr = 0; bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1; @@ -2630,7 +2627,7 @@ void BKE_curve_bevelList_make(Object *ob) } /* STEP 2: DOUBLE POINTS AND AUTOMATIC RESOLUTION, REDUCE DATABLOCKS */ - bl = cu->bev.first; + bl = bev->first; while (bl) { if (bl->nr) { /* null bevel items come from single points */ nr = bl->nr; @@ -2652,7 +2649,7 @@ void BKE_curve_bevelList_make(Object *ob) } bl = bl->next; } - bl = cu->bev.first; + bl = bev->first; while (bl) { blnext = bl->next; if (bl->nr && bl->dupe_nr) { @@ -2660,8 +2657,8 @@ void BKE_curve_bevelList_make(Object *ob) blnew = MEM_mallocN(sizeof(BevList) + nr * sizeof(BevPoint), "makeBevelList4"); memcpy(blnew, bl, sizeof(BevList)); blnew->nr = 0; - BLI_remlink(&(cu->bev), bl); - BLI_insertlinkbefore(&(cu->bev), blnext, blnew); /* to make sure bevlijst is tuned with nurblist */ + BLI_remlink(bev, bl); + BLI_insertlinkbefore(bev, blnext, blnew); /* to make sure bevlijst is tuned with nurblist */ bevp0 = (BevPoint *)(bl + 1); bevp1 = (BevPoint *)(blnew + 1); nr = bl->nr; @@ -2680,7 +2677,7 @@ void BKE_curve_bevelList_make(Object *ob) } /* STEP 3: POLYS COUNT AND AUTOHOLE */ - bl = cu->bev.first; + bl = bev->first; poly = 0; while (bl) { if (bl->nr && bl->poly >= 0) { @@ -2694,7 +2691,7 @@ void BKE_curve_bevelList_make(Object *ob) /* find extreme left points, also test (turning) direction */ if (poly > 0) { sd = sortdata = MEM_mallocN(sizeof(struct bevelsort) * poly, "makeBevelList5"); - bl = cu->bev.first; + bl = bev->first; while (bl) { if (bl->poly > 0) { @@ -2774,7 +2771,7 @@ void BKE_curve_bevelList_make(Object *ob) /* STEP 4: 2D-COSINES or 3D ORIENTATION */ if ((cu->flag & CU_3D) == 0) { /* 2D Curves */ - for (bl = cu->bev.first; bl; bl = bl->next) { + for (bl = bev->first; bl; bl = bl->next) { if (bl->nr < 2) { /* do nothing */ } @@ -2788,7 +2785,7 @@ void BKE_curve_bevelList_make(Object *ob) } else { /* 3D Curves */ - for (bl = cu->bev.first; bl; bl = bl->next) { + for (bl = bev->first; bl; bl = bl->next) { if (bl->nr < 2) { /* do nothing */ } diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 4ce06623bae..f786f842be3 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -29,6 +29,7 @@ #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <math.h> diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index cfd89e91fdd..3fb86c904bb 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -667,10 +667,10 @@ static float displist_calc_taper(Scene *scene, Object *taperobj, float fac) if (taperobj == NULL || taperobj->type != OB_CURVE) return 1.0; - dl = taperobj->disp.first; + dl = taperobj->curve_cache ? taperobj->curve_cache->disp.first : NULL; if (dl == NULL) { BKE_displist_make_curveTypes(scene, taperobj, 0); - dl = taperobj->disp.first; + dl = taperobj->curve_cache->disp.first; } if (dl) { float minx, dx, *fp; @@ -718,14 +718,19 @@ void BKE_displist_make_mball(Scene *scene, Object *ob) if (G.is_rendering) return; - BKE_displist_free(&(ob->disp)); + if (ob->curve_cache) { + BKE_displist_free(&(ob->curve_cache->disp)); + } + else { + ob->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for MBall"); + } if (ob->type == OB_MBALL) { if (ob == BKE_mball_basis_find(scene, ob)) { - BKE_mball_polygonize(scene, ob, &ob->disp); + BKE_mball_polygonize(scene, ob, &ob->curve_cache->disp); BKE_mball_texspace_calc(ob); - object_deform_mball(ob, &ob->disp); + object_deform_mball(ob, &ob->curve_cache->disp); } boundbox_displist_object(ob); @@ -1400,10 +1405,10 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba nubase = BKE_curve_nurbs_get(cu); - BLI_freelistN(&(cu->bev)); + BLI_freelistN(&(ob->curve_cache->bev)); - if (cu->path) free_path(cu->path); - cu->path = NULL; + if (ob->curve_cache->path) free_path(ob->curve_cache->path); + ob->curve_cache->path = NULL; if (ob->type == OB_FONT) BKE_vfont_to_curve(G.main, scene, ob, 0); @@ -1422,7 +1427,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba } else { float widfac = cu->width - 1.0f; - BevList *bl = cu->bev.first; + BevList *bl = ob->curve_cache->bev.first; Nurb *nu = nubase->first; for (; bl && nu; bl = bl->next, nu = nu->next) { @@ -1625,9 +1630,14 @@ void BKE_displist_make_curveTypes(Scene *scene, Object *ob, int forOrco) if (!ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return; - BKE_displist_free(&(ob->disp)); - dispbase = &(ob->disp); - BKE_displist_free(dispbase); + if (ob->curve_cache) { + BKE_displist_free(&(ob->curve_cache->disp)); + } + else { + ob->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for curve types"); + } + + dispbase = &(ob->curve_cache->disp); do_makeDispListCurveTypes(scene, ob, dispbase, &ob->derivedFinal, 0, forOrco, 0); @@ -1710,7 +1720,7 @@ static void boundbox_displist_object(Object *ob) DM_set_object_boundbox(ob, ob->derivedFinal); } else { - boundbox_dispbase(ob->bb, &ob->disp); + boundbox_dispbase(ob->bb, &ob->curve_cache->disp); } } } diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 0df8684044a..81b0de9fd32 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -67,6 +67,7 @@ #include "BKE_blender.h" #include "BKE_collision.h" #include "BKE_constraint.h" +#include "BKE_curve.h" #include "BKE_deform.h" #include "BKE_depsgraph.h" #include "BKE_displist.h" @@ -176,10 +177,10 @@ static void precalculate_effector(EffectorCache *eff) if (eff->pd->forcefield == PFIELD_GUIDE && eff->ob->type==OB_CURVE) { Curve *cu= eff->ob->data; if (cu->flag & CU_PATH) { - if (cu->path==NULL || cu->path->data==NULL) + if (eff->ob->curve_cache == NULL || eff->ob->curve_cache->path==NULL || eff->ob->curve_cache->path->data==NULL) BKE_displist_make_curveTypes(eff->scene, eff->ob, 0); - if (cu->path && cu->path->data) { + if (eff->ob->curve_cache->path && eff->ob->curve_cache->path->data) { where_on_path(eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius, NULL); mul_m4_v3(eff->ob->obmat, eff->guide_loc); mul_mat3_m4_v3(eff->ob->obmat, eff->guide_dir); diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 7c23438f93d..9700066be94 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -819,8 +819,10 @@ makebreak: cucu->flag |= (CU_PATH + CU_FOLLOW); - if (cucu->path == NULL) BKE_displist_make_curveTypes(scene, cu->textoncurve, 0); - if (cucu->path) { + if (cu->textoncurve->curve_cache == NULL || cu->textoncurve->curve_cache->path == NULL) { + BKE_displist_make_curveTypes(scene, cu->textoncurve, 0); + } + if (cu->textoncurve->curve_cache->path) { float distfac, imat[4][4], imat3[3][3], cmat[3][3]; float minx, maxx, miny, maxy; float timeofs, sizefac; @@ -845,7 +847,7 @@ makebreak: /* we put the x-coordinaat exact at the curve, the y is rotated */ /* length correction */ - distfac = sizefac * cucu->path->totdist / (maxx - minx); + distfac = sizefac * cu->textoncurve->curve_cache->path->totdist / (maxx - minx); timeofs = 0.0f; if (distfac > 1.0f) { diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 069c3ab8ea2..b6baeea51b1 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -51,6 +51,7 @@ #include "BKE_animsys.h" #include "BKE_anim.h" #include "BKE_cdderivedmesh.h" +#include "BKE_curve.h" #include "BKE_displist.h" #include "BKE_global.h" #include "BKE_key.h" @@ -164,7 +165,7 @@ void BKE_lattice_resize(Lattice *lt, int uNew, int vNew, int wNew, Object *ltOb) lt->typeu = lt->typev = lt->typew = KEY_LINEAR; /* prevent using deformed locations */ - BKE_displist_free(<Ob->disp); + BKE_displist_free(<Ob->curve_cache->disp); copy_m4_m4(mat, ltOb->obmat); unit_m4(ltOb->obmat); @@ -311,7 +312,7 @@ void init_latt_deform(Object *oblatt, Object *ob) /* we make an array with all differences */ Lattice *lt = oblatt->data; BPoint *bp; - DispList *dl = BKE_displist_find(&oblatt->disp, DL_VERTS); + DispList *dl = oblatt->curve_cache ? BKE_displist_find(&oblatt->curve_cache->disp, DL_VERTS) : NULL; float *co = dl ? dl->verts : NULL; float *fp, imat[4][4]; float fu, fv, fw; @@ -506,13 +507,12 @@ static void init_curve_deform(Object *par, Object *ob, CurveDeform *cd) */ static int where_on_path_deform(Object *ob, float ctime, float vec[4], float dir[3], float quat[4], float *radius) { - Curve *cu = ob->data; BevList *bl; float ctime1; int cycl = 0; /* test for cyclic */ - bl = cu->bev.first; + bl = ob->curve_cache->bev.first; if (!bl->nr) return 0; if (bl->poly > -1) cycl = 1; @@ -527,7 +527,7 @@ static int where_on_path_deform(Object *ob, float ctime, float vec[4], float dir if (where_on_path(ob, ctime1, vec, dir, quat, radius, NULL)) { if (cycl == 0) { - Path *path = cu->path; + Path *path = ob->curve_cache->path; float dvec[3]; if (ctime < 0.0f) { @@ -565,9 +565,9 @@ static int calc_curve_deform(Scene *scene, Object *par, float co[3], const int is_neg_axis = (axis > 2); /* to be sure, mostly after file load */ - if (cu->path == NULL) { + if (ELEM(NULL, par->curve_cache, par->curve_cache->path)) { BKE_displist_make_curveTypes(scene, par, 0); - if (cu->path == NULL) return 0; // happens on append... + if (par->curve_cache->path == NULL) return 0; // happens on append... } /* options */ @@ -576,14 +576,14 @@ static int calc_curve_deform(Scene *scene, Object *par, float co[3], if (cu->flag & CU_STRETCH) fac = (-co[index] - cd->dmax[index]) / (cd->dmax[index] - cd->dmin[index]); else - fac = -(co[index] - cd->dmax[index]) / (cu->path->totdist); + fac = -(co[index] - cd->dmax[index]) / (par->curve_cache->path->totdist); } else { index = axis; if (cu->flag & CU_STRETCH) fac = (co[index] - cd->dmin[index]) / (cd->dmax[index] - cd->dmin[index]); else - fac = +(co[index] - cd->dmin[index]) / (cu->path->totdist); + fac = +(co[index] - cd->dmin[index]) / (par->curve_cache->path->totdist); } if (where_on_path_deform(par, fac, loc, dir, new_quat, &radius)) { /* returns OK */ @@ -996,7 +996,12 @@ void BKE_lattice_modifiers_calc(Scene *scene, Object *ob) float (*vertexCos)[3] = NULL; int numVerts, editmode = (lt->editlatt != NULL); - BKE_displist_free(&ob->disp); + if (ob->curve_cache) { + BKE_displist_free(&ob->curve_cache->disp); + } + else { + ob->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for lattice"); + } for (; md; md = md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); @@ -1022,7 +1027,7 @@ void BKE_lattice_modifiers_calc(Scene *scene, Object *ob) dl->nr = numVerts; dl->verts = (float *) vertexCos; - BLI_addtail(&ob->disp, dl); + BLI_addtail(&ob->curve_cache->disp, dl); } } diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index c23b4ac4408..f3dc64a7279 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -1291,7 +1291,9 @@ int object_remove_material_slot(Object *ob) /* check indices from mesh */ if (ELEM4(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) { material_data_index_remove_id((ID *)ob->data, actcol - 1); - BKE_displist_free(&ob->disp); + if (ob->curve_cache) { + BKE_displist_free(&ob->curve_cache->disp); + } } return TRUE; diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 173b193b752..934ccc90199 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -56,6 +56,7 @@ /* #include "BKE_object.h" */ #include "BKE_animsys.h" +#include "BKE_curve.h" #include "BKE_scene.h" #include "BKE_library.h" #include "BKE_displist.h" @@ -366,7 +367,7 @@ void BKE_mball_texspace_calc(Object *ob) (min)[0] = (min)[1] = (min)[2] = 1.0e30f; (max)[0] = (max)[1] = (max)[2] = -1.0e30f; - dl = ob->disp.first; + dl = ob->curve_cache->disp.first; while (dl) { tot = dl->nr; if (tot) do_it = TRUE; diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 0db1f92f70f..ada1dfa2a69 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -1307,7 +1307,13 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert, MEdge **alledge, int *totedge, MLoop **allloop, MPoly **allpoly, int *totloop, int *totpoly) { - return BKE_mesh_nurbs_displist_to_mdata(ob, &ob->disp, + ListBase disp = {NULL}; + + if (ob->curve_cache) { + disp = ob->curve_cache->disp; + } + + return BKE_mesh_nurbs_displist_to_mdata(ob, &disp, allvert, totvert, alledge, totedge, allloop, allpoly, NULL, @@ -1653,8 +1659,13 @@ void BKE_mesh_from_nurbs(Object *ob) { Curve *cu = (Curve *) ob->data; bool use_orco_uv = (cu->flag & CU_UV_ORCO) != 0; + ListBase disp = {NULL}; + + if (ob->curve_cache) { + disp = ob->curve_cache->disp; + } - BKE_mesh_from_nurbs_displist(ob, &ob->disp, use_orco_uv); + BKE_mesh_from_nurbs_displist(ob, &disp, use_orco_uv); } typedef struct EdgeLink { diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index d1d755bd697..c3da7aef4b4 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -167,6 +167,19 @@ void BKE_object_free_bulletsoftbody(Object *ob) } } +void BKE_object_free_curve_cache(Object *ob) +{ + if (ob->curve_cache) { + BKE_displist_free(&ob->curve_cache->disp); + BLI_freelistN(&ob->curve_cache->bev); + if (ob->curve_cache->path) { + free_path(ob->curve_cache->path); + } + MEM_freeN(ob->curve_cache); + ob->curve_cache = NULL; + } +} + void BKE_object_free_modifiers(Object *ob) { while (ob->modifiers.first) { @@ -267,7 +280,9 @@ void BKE_object_free_derived_caches(Object *ob) ob->derivedDeform = NULL; } - BKE_displist_free(&ob->disp); + if (ob->curve_cache) { + BKE_displist_free(&ob->curve_cache->disp); + } } /* do not free object itself */ @@ -337,6 +352,14 @@ void BKE_object_free(Object *ob) free_sculptsession(ob); if (ob->pc_ids.first) BLI_freelistN(&ob->pc_ids); + + /* Free runtime curves data. */ + if (ob->curve_cache) { + BLI_freelistN(&ob->curve_cache->bev); + if (ob->curve_cache->path) + free_path(ob->curve_cache->path); + MEM_freeN(ob->curve_cache); + } } static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Object **obpoin) @@ -1256,8 +1279,6 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, int copy_caches) for (a = 0; a < obn->totcol; a++) id_us_plus((ID *)obn->mat[a]); - obn->disp.first = obn->disp.last = NULL; - if (ob->pd) { obn->pd = MEM_dupallocN(ob->pd); if (obn->pd->tex) @@ -1279,7 +1300,10 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, int copy_caches) obn->pc_ids.first = obn->pc_ids.last = NULL; obn->mpath = NULL; - + + /* Copy runtime surve data. */ + obn->curve_cache = NULL; + return obn; } @@ -1772,9 +1796,9 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[4][4]) unit_m4(mat); cu = par->data; - if (cu->path == NULL || cu->path->data == NULL) /* only happens on reload file, but violates depsgraph still... fix! */ + if (ELEM3(NULL, par->curve_cache, par->curve_cache->path, par->curve_cache->path->data)) /* only happens on reload file, but violates depsgraph still... fix! */ BKE_displist_make_curveTypes(scene, par, 0); - if (cu->path == NULL) return; + if (par->curve_cache->path == NULL) return; /* catch exceptions: feature for nla stride editing */ if (ob->ipoflag & OB_DISABLE_PATH) { @@ -1805,7 +1829,7 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[4][4]) /* time calculus is correct, now apply distance offset */ if (cu->flag & CU_OFFS_PATHDIST) { - ctime += timeoffs / cu->path->totdist; + ctime += timeoffs / par->curve_cache->path->totdist; /* restore */ SWAP(float, sf_orig, ob->sf); @@ -1962,7 +1986,7 @@ static void give_parvert(Object *par, int nr, float vec[3]) } else if (par->type == OB_LATTICE) { Lattice *latt = par->data; - DispList *dl = BKE_displist_find(&par->disp, DL_VERTS); + DispList *dl = par->curve_cache ? BKE_displist_find(&par->curve_cache->disp, DL_VERTS) : NULL; float (*co)[3] = dl ? (float (*)[3])dl->verts : NULL; int tot; @@ -2519,10 +2543,10 @@ void BKE_object_foreach_display_point( func_cb(co, user_data); } } - else if (ob->disp.first) { + else if (ob->curve_cache && ob->curve_cache->disp.first) { DispList *dl; - for (dl = ob->disp.first; dl; dl = dl->next) { + for (dl = ob->curve_cache->disp.first; dl; dl = dl->next) { float *v3 = dl->verts; int totvert = dl->nr; int i; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 96a6913e6e9..15e3aab2e00 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3399,10 +3399,8 @@ static void direct_link_curve(FileData *fd, Curve *cu) if (cu->wordspace == 0.0f) cu->wordspace = 1.0f; } - cu->bev.first = cu->bev.last = NULL; cu->editnurb = NULL; cu->lastsel = NULL; - cu->path = NULL; cu->editfont = NULL; for (nu = cu->nurb.first; nu; nu = nu->next) { @@ -4828,8 +4826,6 @@ static void direct_link_object(FileData *fd, Object *ob) ob->mode &= ~(OB_MODE_EDIT | OB_MODE_PARTICLE_EDIT); } - ob->disp.first = ob->disp.last = NULL; - ob->adt = newdataadr(fd, ob->adt); direct_link_animdata(fd, ob->adt); @@ -5024,6 +5020,9 @@ static void direct_link_object(FileData *fd, Object *ob) ob->gpulamp.first= ob->gpulamp.last = NULL; link_list(fd, &ob->pc_ids); + /* Runtime curve data */ + ob->curve_cache = NULL; + /* in case this value changes in future, clamp else we get undefined behavior */ CLAMP(ob->rotmode, ROT_MODE_MIN, ROT_MODE_MAX); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index ce61b4fce50..b907cba33e2 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1243,7 +1243,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, ob->parent = NULL; ob->constraints.first = ob->constraints.last = NULL; - ob->disp.first = ob->disp.last = NULL; + ob->curve_cache = NULL; ob->transflag &= ~OB_DUPLI; ob->lay = base->lay; @@ -1385,7 +1385,7 @@ static EnumPropertyItem convert_target_items[] = { static void curvetomesh(Scene *scene, Object *ob) { - if (ob->disp.first == NULL) + if (ELEM(NULL, ob->curve_cache, ob->curve_cache->disp.first)) BKE_displist_make_curveTypes(scene, ob, 0); /* force creation */ BKE_mesh_from_nurbs(ob); /* also does users */ @@ -1553,7 +1553,7 @@ static int convert_exec(bContext *C, wmOperator *op) cu = newob->data; - if (!newob->disp.first) + if ( !newob->curve_cache || !newob->curve_cache->disp.first) BKE_displist_make_curveTypes(scene, newob, 0); newob->type = OB_CURVE; @@ -1595,7 +1595,7 @@ static int convert_exec(bContext *C, wmOperator *op) curvetomesh(scene, newob); /* meshes doesn't use displist */ - BKE_displist_free(&newob->disp); + BKE_object_free_curve_cache(newob); } } else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { @@ -1616,7 +1616,7 @@ static int convert_exec(bContext *C, wmOperator *op) newob = ob; /* meshes doesn't use displist */ - BKE_displist_free(&newob->disp); + BKE_object_free_curve_cache(newob); } curvetomesh(scene, newob); @@ -1635,7 +1635,7 @@ static int convert_exec(bContext *C, wmOperator *op) ob->flag |= OB_DONE; } - if (!baseob->disp.first) { + if (!baseob->curve_cache || !baseob->curve_cache->disp.first) { BKE_displist_make_mball(scene, baseob); } @@ -1658,7 +1658,7 @@ static int convert_exec(bContext *C, wmOperator *op) for (a = 0; a < newob->totcol; a++) id_us_plus((ID *)me->mat[a]); } - BKE_mesh_from_metaball(&baseob->disp, newob->data); + BKE_mesh_from_metaball(&baseob->curve_cache->disp, newob->data); if (obact->type == OB_MBALL) { basact = basen; diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c index 98c9c8d15fe..c1cddf092aa 100644 --- a/source/blender/editors/space_info/info_stats.c +++ b/source/blender/editors/space_info/info_stats.c @@ -115,8 +115,8 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats) { int totv = 0, totf = 0, tottri = 0; - if (ob->disp.first) - BKE_displist_count(&ob->disp, &totv, &totf, &tottri); + if (ob->curve_cache && ob->curve_cache->disp.first) + BKE_displist_count(&ob->curve_cache->disp, &totv, &totf, &tottri); totv *= totob; totf *= totob; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 5dfc0f48676..fcea6929531 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1900,9 +1900,9 @@ static void drawlattice(Scene *scene, View3D *v3d, Object *ob) const bool is_edit = (lt->editlatt != NULL); /* now we default make displist, this will modifiers work for non animated case */ - if (ob->disp.first == NULL) + if (ELEM(NULL, ob->curve_cache, ob->curve_cache->disp.first)) BKE_lattice_modifiers_calc(scene, ob); - dl = BKE_displist_find(&ob->disp, DL_VERTS); + dl = BKE_displist_find(&ob->curve_cache->disp, DL_VERTS); if (is_edit) { lt = lt->editlatt->latt; @@ -3971,7 +3971,7 @@ static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3 case OB_CURVE: cu = ob->data; - lb = &ob->disp; + lb = &ob->curve_cache->disp; if (solid) { dl = lb->first; @@ -4021,7 +4021,7 @@ static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3 break; case OB_SURF: - lb = &ob->disp; + lb = &ob->curve_cache->disp; if (solid) { dl = lb->first; @@ -4049,8 +4049,11 @@ static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3 case OB_MBALL: if (BKE_mball_is_basis(ob)) { - lb = &ob->disp; - if (lb->first == NULL) BKE_displist_make_mball(scene, ob); + lb = ob->curve_cache ? &ob->curve_cache->disp : NULL; + if (lb->first == NULL) { + BKE_displist_make_mball(scene, ob); + lb = &ob->curve_cache->disp; + } if (lb->first == NULL) { return true; } @@ -5642,7 +5645,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, if ((cu->flag & CU_3D) && (ts->normalsize > 0.0015f) && (cu->drawflag & CU_HIDE_NORMALS) == 0) { UI_ThemeColor(TH_WIRE_EDIT); - for (bl = cu->bev.first, nu = nurb; nu && bl; bl = bl->next, nu = nu->next) { + for (bl = ob->curve_cache->bev.first, nu = nurb; nu && bl; bl = bl->next, nu = nu->next) { BevPoint *bevp = (BevPoint *)(bl + 1); int nr = bl->nr; int skip = nu->resolu / 16; @@ -6065,7 +6068,7 @@ static void draw_forcefield(Object *ob, RegionView3D *rv3d, } else if (pd->forcefield == PFIELD_GUIDE && ob->type == OB_CURVE) { Curve *cu = ob->data; - if ((cu->flag & CU_PATH) && cu->path && cu->path->data) { + if ((cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) { float mindist, guidevec1[4], guidevec2[3]; //if (has_ipo_code(ob->ipo, OB_PD_FSTR)) @@ -6330,7 +6333,7 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base, has_faces = dm->getNumTessFaces(dm); } else { - has_faces = BKE_displist_has_faces(&ob->disp); + has_faces = BKE_displist_has_faces(&ob->curve_cache->disp); } if (has_faces && ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb)) { @@ -6339,7 +6342,7 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base, draw_mesh_object_outline(v3d, ob, dm); } else { - drawDispListwire(&ob->disp); + drawDispListwire(&ob->curve_cache->disp); } draw_index_wire = true; } @@ -6347,7 +6350,7 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base, else if (ob->type == OB_MBALL) { if (BKE_mball_is_basis(ob)) { if ((base->flag & OB_FROMDUPLI) == 0) - drawDispListwire(&ob->disp); + drawDispListwire(&ob->curve_cache->disp); } } else if (ob->type == OB_ARMATURE) { @@ -6382,7 +6385,7 @@ static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, unsign drawCurveDMWired(ob); } else { - drawDispListwire(&ob->disp); + drawDispListwire(&ob->curve_cache->disp); } if (ob->type == OB_CURVE) @@ -6391,7 +6394,7 @@ static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, unsign } else if (ob->type == OB_MBALL) { if (BKE_mball_is_basis(ob)) { - drawDispListwire(&ob->disp); + drawDispListwire(&ob->curve_cache->disp); } } @@ -6701,7 +6704,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short /* bad exception, solve this! otherwise outline shows too late */ if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { /* still needed for curves hidden in other layers. depgraph doesnt handle that yet */ - if (ob->disp.first == NULL) BKE_displist_make_curveTypes(scene, ob, 0); + if (ELEM(NULL, ob->curve_cache, ob->curve_cache->disp.first)) { + BKE_displist_make_curveTypes(scene, ob, 0); + } } /* draw outline for selected objects, mesh does itself */ diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c index d13ab15d837..2023513ad92 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.c +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -368,7 +368,7 @@ void lattice_foreachScreenVert( Object *obedit = vc->obedit; Lattice *lt = obedit->data; BPoint *bp = lt->editlatt->latt->def; - DispList *dl = BKE_displist_find(&obedit->disp, DL_VERTS); + DispList *dl = obedit->curve_cache ? BKE_displist_find(&obedit->curve_cache->disp, DL_VERTS) : NULL; float *co = dl ? dl->verts : NULL; int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index a66919329df..1c99f9ac827 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -183,12 +183,9 @@ typedef struct Curve { struct Object *bevobj, *taperobj, *textoncurve; struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */ - Path *path; struct Key *key; struct Material **mat; - ListBase bev; - /* texture space, copied as one block in editobject.c */ float loc[3]; float size[3]; diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index de34f101c31..1e844d2a6fb 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -130,7 +130,6 @@ typedef struct Object { ListBase constraintChannels DNA_DEPRECATED; // XXX deprecated... old animation system ListBase effect DNA_DEPRECATED; // XXX deprecated... keep for readfile - ListBase disp; /* list of DispList, used by lattice, metaballs curve & surfaces */ ListBase defbase; /* list of bDeformGroup (vertex groups) names and flag only */ ListBase modifiers; /* list of ModifierData structures */ @@ -276,6 +275,9 @@ typedef struct Object { struct RigidBodyCon *rigidbody_constraint; /* settings for Bullet constraint */ float ima_ofs[2]; /* offset for image empties */ + + /* Runtime valuated curve-specific data, not stored in the file */ + struct CurveCache *curve_cache; } Object; /* Warning, this is not used anymore because hooks are now modifiers */ diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index fd931262904..8104fc169f6 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -361,8 +361,13 @@ Mesh *rna_Main_meshes_new_from_object( BKE_mesh_from_metaball(&disp, tmpmesh); BKE_displist_free(&disp); } - else - BKE_mesh_from_metaball(&ob->disp, tmpmesh); + else { + ListBase disp = {NULL, NULL}; + if (ob->curve_cache) { + disp = ob->curve_cache->disp; + } + BKE_mesh_from_metaball(&disp, tmpmesh); + } BKE_mesh_texspace_copy_from_object(tmpmesh, ob); diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index e09fa18ffc5..3478ec6e3b4 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -50,6 +50,7 @@ #include "BKE_cdderivedmesh.h" #include "BKE_displist.h" +#include "BKE_curve.h" #include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_object.h" @@ -387,12 +388,12 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, BKE_object_to_mat3(amd->curve_ob, tmp_mat); scale = mat3_to_scale(tmp_mat); - if (!cu->path) { + if (!amd->curve_ob->curve_cache || !amd->curve_ob->curve_cache->path) { cu->flag |= CU_PATH; // needed for path & bevlist BKE_displist_make_curveTypes(scene, amd->curve_ob, 0); } - if (cu->path) - length = scale * cu->path->totdist; + if (amd->curve_ob->curve_cache->path) + length = scale * amd->curve_ob->curve_cache->path->totdist; } } |