Move bevel list and path from Curve to Object datablock
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 19 Aug 2013 09:25:24 +0000 (09:25 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 19 Aug 2013 09:25:24 +0000 (09:25 +0000)
I know this is not so much nice to have this guys hanging
around in a general Object datablock and ideally they better
be wrapped around into a structure like DerivedMesh or
something like this. But this is pure runtime only stuff and
we could re-wrap them around later.

Main purpose of this is making curves more thread safe,
so no separate threads will ever start freeing the same path
or the same bevel list.

It also makes sense because path and bevel shall include
deformation coming from modifiers which are applying on
pre-tesselation point and different objects could have
different set of modifiers. This used to be really confusing
in the past and now data which depends on object is stored
in an object, making things clear for understanding even.

This doesn't make curve code fully thread-safe due to
pre-tesselation modifiers still modifies actual nurbs and
lock is still needed in makeDispListsCurveTypes, but this
change makes usage of paths safe for threading.

Once modifiers will stop modifying actual nurbs, curves
will be fully safe for threading.

Actually, this commit also contains wrapping runtime curve
members into own structure

This allows easier assignment on file loading, keeps curve-
specific runtime data grouped and saves couple of bytes in
Object for non-curve types.

--
svn merge -r57938:57939 ^/branches/soc-2013-depsgraph_mt
svn merge -r57957:57958^/branches/soc-2013-depsgraph_mt

25 files changed:
source/blender/blenkernel/BKE_curve.h
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/effect.c
source/blender/blenkernel/intern/font.c
source/blender/blenkernel/intern/lattice.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/mball.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenkernel/intern/object.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/object/object_add.c
source/blender/editors/space_info/info_stats.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_iterators.c
source/blender/makesdna/DNA_curve_types.h
source/blender/makesdna/DNA_object_types.h
source/blender/makesrna/intern/rna_main_api.c
source/blender/modifiers/intern/MOD_array.c

index baa90e7a856752be9f9f7ad9d59336da011f4be4..b1020464728e0edd8041739353c68d2835153f46 100644 (file)
@@ -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) )
index 992792dcb999b90ff256ef2e9fd8730b3ed8e833..dbd2263cfc9887587cb04d2e587597b6bc75f712 100644 (file)
@@ -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);
index ba680147201487fd2aa95b25c44fc52a666d0e56..f3e2b118f2e92c99407e61b6b9f02b9c5e7f143c 100644 (file)
@@ -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;
index f006710dc21e70b20ebd6fb85e25329bdb4bfa5d..dbe3c39af973bfa3fd82c13a86ee4f9f49605fff 100644 (file)
@@ -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
index 6205c8016b6ac86763db7c42ca19246c1b94a82a..5ab618c4001554ba97c72e4a2b7bb17b604d7908 100644 (file)
@@ -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)
index eda770ddf30ffe04611477d7153901010be3d0ce..a1cb360e0a45b3862d39678bb3a3f367d7f796f6 100644 (file)
@@ -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);
        }
        
index 7377a48a87e08c19c3b502450ed51d2920bd4876..8fa24ecbbe5a5873e58f79c80e0378b640564333 100644 (file)
@@ -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 */
                        }
index 4ce06623baec8f31dbac01188934478ec66c7c2d..f786f842be37f65e938fd104eac9844fa165d913 100644 (file)
@@ -29,6 +29,7 @@
 
  
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <math.h>
 
index cfd89e91fdddec959a247804d8b1688a44b363de..3fb86c904bbb97f870ee3a00d1a5548c87ba4d4c 100644 (file)
@@ -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);
                }
        }
 }
index 0df8684044a082efb64133faedfa810eb6a50b20..81b0de9fd32c59bd0ed63b6ef058161388c91a93 100644 (file)
@@ -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);
index 7c23438f93d1f7186d7123e2afb3ea4ad5298750..9700066be94204688ab97e79d70be648dcf1a53b 100644 (file)
@@ -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) {
index 069c3ab8ea2edf065d2463b52ea081eabaacb86a..b6baeea51b181c7f73044d3361d36d5b0df57093 100644 (file)
@@ -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(&ltOb->disp);
+               BKE_displist_free(&ltOb->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);
        }
 }
 
index c23b4ac4408bf79dd4409983c42bafa6fa41215b..f3dc64a72796f1fdc6051a40db87c3f954107919 100644 (file)
@@ -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;
index 173b193b7527ff542c6e5f28fb8b11f5c2128f0c..934ccc901991e9f780be824105d6c5607953385f 100644 (file)
@@ -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;
index 0db1f92f70f86c168981672215faf370b1dc4fac..ada1dfa2a6904fcc06c2851f41ee3e2f73e471db 100644 (file)
@@ -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 {
index d1d755bd6973157b110ef7addeb5e95392ece952..c3da7aef4b45b36431eab6865f0964ab6286215f 100644 (file)
@@ -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;
index 96a6913e6e94e9d549d60e4e89c692642801199e..15e3aab2e00eb1b4f749bd3910e324d41c087d97 100644 (file)
@@ -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);
 
index ce61b4fce502f4c3accf9dfcd475a10db32a304f..b907cba33e2ef4e566411b95d9444bc887ff7b8e 100644 (file)
@@ -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;
index 98c9c8d15fe3a2a459bec6dea1b5cd8b3836ff16..c1cddf092aa0429a577f3b3119a70c748667414d 100644 (file)
@@ -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;
index 5dfc0f486762b65db9cd8c70950fabe152846fa5..fcea69295319850a40b83eb2f5c8b635b88936d4 100644 (file)
@@ -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 */
index d13ab15d8371cd142fa4fb403bf0ce99d18dab92..2023513ad920fc78f11fdffd3623daab6ff2df93 100644 (file)
@@ -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;
 
index a66919329df1b9d6424de0c3823b2248914dd558..1c99f9ac827bb5c9de742dc988ce5aa476a22a6c 100644 (file)
@@ -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];
index de34f101c3155c11a1eb44c0632f95314371560a..1e844d2a6fb9b0e46739adc5a113582e2deb4cd6 100644 (file)
@@ -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 */
index fd9312629040ad9a405b995c3e78de99dcdf92ca..8104fc169f606b85be32a3b871a14de2cc943861 100644 (file)
@@ -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);
 
index e09fa18ffc5ff85a53d24f676a78475264788031..3478ec6e3b4221c4914147a5d468e2fd0a8e1b79 100644 (file)
@@ -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;
                }
        }