Move bevel list and path from Curve to Object datablock
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 2 Jul 2013 19:23:19 +0000 (19:23 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 2 Jul 2013 19:23:19 +0000 (19:23 +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 dtaa 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.

16 files changed:
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/armature.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/object.c
source/blender/blenkernel/intern/scene.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/space_view3d/drawobject.c
source/blender/makesdna/DNA_curve_types.h
source/blender/makesdna/DNA_object_types.h
source/blender/modifiers/intern/MOD_array.c

index 9fea3d2e13f507d7dbfa8053844c80b3a4c05db8..8a1eaa66664cd153695e20f697f4e09b65abceb9 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->path) free_path(ob->path);
+       ob->path = NULL;
        
        /* weak! can only use first curve */
-       bl = cu->bev.first;
+       bl = ob->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->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->path == NULL || ob->path->data == NULL) {
                printf("no path!\n");
                return 0;
        }
-       path = cu->path;
+       path = ob->path;
        pp = path->data;
        
        /* test for cyclic */
-       bl = cu->bev.first;
+       bl = ob->bev.first;
        if (!bl) return 0;
        if (!bl->nr) return 0;
        if (bl->poly > -1) cycl = 1;
index 8fae35864390a21d3324c789f3a5d6c4f17535e9..fe62127dff50ab5116eb13f09905e237459b57bc 100644 (file)
@@ -1816,18 +1816,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 (ELEM(NULL, ikData->tar->path, ikData->tar->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->path, ikData->tar->path->data)) {
                                /* BLI_assert(cu->path != NULL); */
                                return;
                        }
@@ -1891,7 +1889,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;
 
@@ -1904,7 +1901,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->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 0cd13d528d559fba45a2364f33da23aadd1ede93..6b8cd19639ec8ba32a4604c8fbfb1359f2521b2c 100644 (file)
@@ -1164,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->path == NULL || ct->tar->path->data == NULL)
                        BKE_displist_make_curveTypes(cob->scene, ct->tar, 0);
                
-               if (cu->path && cu->path->data) {
+               if (ct->tar->path && ct->tar->path->data) {
                        float quat[4];
                        if ((data->followflag & FOLLOWPATH_STATIC) == 0) {
                                /* animated position along curve depending on time */
@@ -1934,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->path == NULL || ct->tar->path->data == NULL) /* only happens on reload file, but violates depsgraph still... fix! */
                                BKE_displist_make_curveTypes(cob->scene, ct->tar, 0);
                }
                
@@ -3008,14 +3006,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->path == NULL || ct->tar->path->data == NULL)
                        BKE_displist_make_curveTypes(cob->scene, ct->tar, 0);
        }
        
@@ -3033,7 +3029,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;
@@ -3046,7 +3041,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->path && data->tar->path->data) {
                        float vec[4], dir[3], totmat[4][4];
                        float curvetime;
                        short clamp_axis;
@@ -3649,14 +3644,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->path == NULL || ct->tar->path->data == NULL)
                        BKE_displist_make_curveTypes(cob->scene, ct->tar, 0);
        }
        
index 9a59c48667f0bba5cbee71dc6f57a66da98b6ab0..ea8f49a319963ba0789639a3dd8fed20e63d615a 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;
@@ -2264,16 +2258,19 @@ void BKE_curve_bevelList_make(Object *ob, bool for_render)
        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->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->bev));
        if (cu->editnurb && ob->type != OB_FONT) {
                ListBase *nurbs = BKE_curve_editNurbs_get(cu);
                nu = nurbs->first;
@@ -2297,7 +2294,7 @@ void BKE_curve_bevelList_make(Object *ob, bool for_render)
                 * 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;
                }
                else {
@@ -2309,7 +2306,7 @@ void BKE_curve_bevelList_make(Object *ob, bool for_render)
                        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);
 
                                if (nu->flagu & CU_NURB_CYCLIC) bl->poly = 0;
                                else bl->poly = -1;
@@ -2332,7 +2329,7 @@ void BKE_curve_bevelList_make(Object *ob, bool for_render)
                                /* 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);
 
                                if (nu->flagu & CU_NURB_CYCLIC) bl->poly = 0;
                                else bl->poly = -1;
@@ -2418,7 +2415,7 @@ void BKE_curve_bevelList_make(Object *ob, bool for_render)
                                        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;
                                        if (nu->flagu & CU_NURB_CYCLIC) bl->poly = 0;
@@ -2436,7 +2433,7 @@ void BKE_curve_bevelList_make(Object *ob, bool for_render)
        }
 
        /* 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;
@@ -2458,7 +2455,7 @@ void BKE_curve_bevelList_make(Object *ob, bool for_render)
                }
                bl = bl->next;
        }
-       bl = cu->bev.first;
+       bl = bev->first;
        while (bl) {
                blnext = bl->next;
                if (bl->nr && bl->dupe_nr) {
@@ -2466,8 +2463,8 @@ void BKE_curve_bevelList_make(Object *ob, bool for_render)
                        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;
@@ -2486,7 +2483,7 @@ void BKE_curve_bevelList_make(Object *ob, bool for_render)
        }
 
        /* STEP 3: POLYS COUNT AND AUTOHOLE */
-       bl = cu->bev.first;
+       bl = bev->first;
        poly = 0;
        while (bl) {
                if (bl->nr && bl->poly >= 0) {
@@ -2500,7 +2497,7 @@ void BKE_curve_bevelList_make(Object *ob, bool for_render)
        /* 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) {
 
@@ -2578,7 +2575,7 @@ void BKE_curve_bevelList_make(Object *ob, bool for_render)
        /* 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 */
                        }
@@ -2592,7 +2589,7 @@ void BKE_curve_bevelList_make(Object *ob, bool for_render)
        }
        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 309eb6d8bf79b57ee69f46898b59cbf5429ae726..ce2047cb7af7aedb9bf342018a17338ffa3b51da 100644 (file)
@@ -29,6 +29,7 @@
 
  
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <math.h>
 
index 3289e6cddcf4ee20acd1bbb38909c3f765e977f4..058122c21aa6d8adb53a73527211e4c64e422cab 100644 (file)
@@ -1398,10 +1398,10 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
                /* XXX: Temp workaround for depsgraph_mt branch. */
                BLI_lock_thread(LOCK_CUSTOM1);
 
-               BLI_freelistN(&(cu->bev));
+               BLI_freelistN(&(ob->bev));
 
-               if (cu->path) free_path(cu->path);
-               cu->path = NULL;
+               if (ob->path) free_path(ob->path);
+               ob->path = NULL;
 
                if (ob->type == OB_FONT)
                        BKE_vfont_to_curve(G.main, scene, ob, 0);
@@ -1420,7 +1420,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->bev.first;
                        Nurb *nu = nubase->first;
 
                        for (; bl && nu; bl = bl->next, nu = nu->next) {
index 02d1621e408b0fe547fe9de1e6c178e9fee99bb7..1a2c368a7d46f72d20ed0668733d824a66dbce7d 100644 (file)
@@ -176,10 +176,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->path==NULL || eff->ob->path->data==NULL)
                                BKE_displist_make_curveTypes(eff->scene, eff->ob, 0);
 
-                       if (cu->path && cu->path->data) {
+                       if (eff->ob->path && eff->ob->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 b3edeb67928355faa610ad118e8bb3c0598243d3..24cbe1e19ab44b0bdac9816df80da119b216e61e 100644 (file)
@@ -819,8 +819,8 @@ 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->path == NULL) BKE_displist_make_curveTypes(scene, cu->textoncurve, 0);
+               if (cu->textoncurve->path) {
                        float distfac, imat[4][4], imat3[3][3], cmat[3][3];
                        float minx, maxx, miny, maxy;
                        float timeofs, sizefac;
@@ -845,7 +845,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->path->totdist / (maxx - minx);
                        timeofs = 0.0f;
                        
                        if (distfac > 1.0f) {
index b07923ff8ef33422371ddfffe49f677f84a23839..abe5a153b9e9e52137a87c4df2ae395d26846a94 100644 (file)
@@ -506,13 +506,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->bev.first;
        if (!bl->nr) return 0;
        if (bl->poly > -1) cycl = 1;
 
@@ -527,7 +526,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->path;
                        float dvec[3];
                        
                        if (ctime < 0.0f) {
@@ -565,9 +564,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 (par->path == NULL) {
                BKE_displist_make_curveTypes(scene, par, 0);
-               if (cu->path == NULL) return 0;  // happens on append...
+               if (par->path == NULL) return 0;  // happens on append...
        }
        
        /* options */
@@ -576,14 +575,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->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->path->totdist);
        }
        
        if (where_on_path_deform(par, fac, loc, dir, new_quat, &radius)) {  /* returns OK */
index 02a9dfe48417ac3b1fd64e7d2d3171749ffde6f4..875217e94dd3a655be4013a9e216450d388dc15f 100644 (file)
@@ -340,6 +340,11 @@ void BKE_object_free(Object *ob)
        free_sculptsession(ob);
 
        if (ob->pc_ids.first) BLI_freelistN(&ob->pc_ids);
+
+       /* Free runtime curves data. */
+       BLI_freelistN(&ob->bev);
+       if (ob->path)
+               free_path(ob->path);
 }
 
 static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Object **obpoin)
@@ -1273,7 +1278,11 @@ 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->bev.first = obn->bev.last = NULL;
+       obn->path = NULL;
+
        return obn;
 }
 
@@ -1751,9 +1760,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 (par->path == NULL || par->path->data == NULL) /* only happens on reload file, but violates depsgraph still... fix! */
                BKE_displist_make_curveTypes(scene, par, 0);
-       if (cu->path == NULL) return;
+       if (par->path == NULL) return;
        
        /* catch exceptions: feature for nla stride editing */
        if (ob->ipoflag & OB_DISABLE_PATH) {
@@ -1784,7 +1793,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->path->totdist;
 
                /* restore */
                SWAP(float, sf_orig, ob->sf);
index d56dcae2368a1aa11c57ad5901413d3b9e536298..e83d848f9de8ce6f4dddc6fb6b6806ad306759bc 100644 (file)
@@ -1207,9 +1207,7 @@ static void scene_update_object_func(TaskPool *pool, void *taskdata, int threadi
 
        ThreadedObjectUpdateState *state = (ThreadedObjectUpdateState *) BLI_task_pool_userdata(pool);
        void *node = taskdata;
-       Object *object;
-
-       object = DAG_threaded_update_get_node_object(node);
+       Object *object = DAG_threaded_update_get_node_object(node);
 
        if (object) {
                PRINT("Thread %d: update object %s\n", threadid, object->id.name);
index 111d6c852842972915bb76feaf08fe2595585c8a..d78edc80654a9a241880bc99d4031d00db50a0f6 100644 (file)
@@ -3391,10 +3391,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) {
@@ -5016,6 +5014,10 @@ 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->bev.first = ob->bev.last = NULL;
+       ob->path = NULL;
+
        /* in case this value changes in future, clamp else we get undefined behavior */
        CLAMP(ob->rotmode, ROT_MODE_MIN, ROT_MODE_MAX);
 
index 4af271b6ba1766e64dc30ecf15fef2da17b48d33..512651e91fbee8a403847b4ba0c756a7169d33fa 100644 (file)
@@ -5554,7 +5554,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->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;
@@ -5977,7 +5977,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->path && ob->path->data) {
                        float mindist, guidevec1[4], guidevec2[3];
 
                        //if (has_ipo_code(ob->ipo, OB_PD_FSTR))
index d6d8ffa0cf9d4924cb51fad1705dfbbb7e2dcd1f..437229d63a85de02b3181b25f6911f29439b508a 100644 (file)
@@ -182,12 +182,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..4544e0332c4b4ca4d7d7967f5d333838f989bbb9 100644 (file)
@@ -276,6 +276,9 @@ typedef struct Object {
        struct RigidBodyCon *rigidbody_constraint;      /* settings for Bullet constraint */
 
        float ima_ofs[2];               /* offset for image empties */
+
+       struct Path *path;
+       ListBase bev;
 } Object;
 
 /* Warning, this is not used anymore because hooks are now modifiers */
index e09fa18ffc5ff85a53d24f676a78475264788031..0a61777ee672fe7a8b40372583305bd4246af93a 100644 (file)
@@ -387,12 +387,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->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->path)
+                               length = scale * amd->curve_ob->path->totdist;
                }
        }