Todo item: linked curve objects behaves incorrect with modifiers
authorSergey Sharybin <sergey.vfx@gmail.com>
Wed, 5 Jan 2011 10:40:38 +0000 (10:40 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Wed, 5 Jan 2011 10:40:38 +0000 (10:40 +0000)
Use object's displists for storing deformed tesselated curve. Was unable to
totally get rid of curve's displist because of how texture space is calculating.

source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/mesh.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/makesdna/DNA_curve_types.h

index 8030a36..efdfdbc 100644 (file)
@@ -1644,7 +1644,7 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *UNUSED(me))
 
 DerivedMesh *CDDM_from_curve(Object *ob)
 {
-       return CDDM_from_curve_customDB(ob, &((Curve *)ob->data)->disp);
+       return CDDM_from_curve_customDB(ob, &ob->disp);
 }
 
 DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase)
index 6368c13..6dd3eb4 100644 (file)
@@ -1266,10 +1266,10 @@ void makebevelcurve(Scene *scene, Object *ob, ListBase *disp, int forRender)
                                makeDispListCurveTypes_forRender(scene, cu->bevobj, &bevdisp, NULL, 0);
                                dl= bevdisp.first;
                        } else {
-                               dl= bevcu->disp.first;
+                               dl= cu->bevobj->disp.first;
                                if(dl==0) {
                                        makeDispListCurveTypes(scene, cu->bevobj, 0);
-                                       dl= bevcu->disp.first;
+                                       dl= cu->bevobj->disp.first;
                                }
                        }
 
index 81a6b4a..2429c09 100644 (file)
@@ -2330,23 +2330,10 @@ static void dag_id_flush_update(Scene *sce, ID *id)
                idtype= GS(id->name);
 
                if(ELEM7(idtype, ID_ME, ID_CU, ID_MB, ID_LA, ID_LT, ID_CA, ID_AR)) {
-                       int first_ob= 1;
                        for(obt=bmain->object.first; obt; obt= obt->id.next) {
                                if(!(ob && obt == ob) && obt->data == id) {
-
-                                       /* try to avoid displist recalculation for linked curves */
-                                       if (!first_ob && ELEM(obt->type, OB_CURVE, OB_SURF)) {
-                                               /* if curve object has got derivedFinal it means this
-                                                  object has got constructive modifiers and object
-                                                  should be recalculated anyhow */
-                                               if (!obt->derivedFinal)
-                                                       continue;
-                                       }
-
                                        obt->recalc |= OB_RECALC_DATA;
                                        BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
-
-                                       first_ob= 0;
                                }
                        }
                }
index 0ee8562..612d0d4 100644 (file)
@@ -660,7 +660,7 @@ void shadeDispList(Scene *scene, Base *base)
                
                        /* now we need the normals */
                        cu= ob->data;
-                       dl= cu->disp.first;
+                       dl= ob->disp.first;
                        
                        while(dl) {
                                extern Material defmaterial;    /* material.c */
@@ -1140,16 +1140,14 @@ static void curve_to_filledpoly(Curve *cu, ListBase *UNUSED(nurb), ListBase *dis
 */
 float calc_taper(Scene *scene, Object *taperobj, int cur, int tot)
 {
-       Curve *cu;
        DispList *dl;
        
        if(taperobj==NULL || taperobj->type!=OB_CURVE) return 1.0;
        
-       cu= taperobj->data;
-       dl= cu->disp.first;
+       dl= taperobj->disp.first;
        if(dl==NULL) {
                makeDispListCurveTypes(scene, taperobj, 0);
-               dl= cu->disp.first;
+               dl= taperobj->disp.first;
        }
        if(dl) {
                float fac= ((float)cur)/(float)(tot-1);
@@ -1678,6 +1676,11 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase,
                }
        }
 
+       /* make copy of 'undeformed" displist for texture space calculation
+          actually, it's not totally undeformed -- pre-tesselation modifiers are
+          already applied, thats how it worked for years, so keep for compatibility (sergey) */
+       copy_displist(&cu->disp, dispbase);
+
        if (!forRender) {
                tex_space_curve(cu);
        }
@@ -1851,6 +1854,11 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
 
                if(cu->flag & CU_PATH) calc_curvepath(ob);
 
+               /* make copy of 'undeformed" displist for texture space calculation
+                  actually, it's not totally undeformed -- pre-tesselation modifiers are
+                  already applied, thats how it worked for years, so keep for compatibility (sergey) */
+               copy_displist(&cu->disp, dispbase);
+
                 if (!forRender) {
                         tex_space_curve(cu);
                 }
@@ -1865,13 +1873,16 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
 
 void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
 {
-       Curve *cu = ob->data;
+       Curve *cu= ob->data;
        ListBase *dispbase;
 
        freedisplist(&(ob->disp));
-       dispbase= &(cu->disp);
+       dispbase= &(ob->disp);
        freedisplist(dispbase);
 
+       /* free displist used for textspace */
+       freedisplist(&cu->disp);
+
        do_makeDispListCurveTypes(scene, ob, dispbase, &ob->derivedFinal, 0, forOrco);
 
        if (ob->derivedFinal) {
@@ -1941,7 +1952,7 @@ static void boundbox_displist(Object *ob)
                if(cu->bb==0) cu->bb= MEM_callocN(sizeof(BoundBox), "boundbox");
                bb= cu->bb;
                
-               dl= cu->disp.first;
+               dl= ob->disp.first;
 
                while (dl) {
                        if(dl->type==DL_INDEX3) tot= dl->nr;
index 7a72207..03fab07 100644 (file)
@@ -735,7 +735,7 @@ void mball_to_mesh(ListBase *lb, Mesh *me)
 int nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert,
        MEdge **alledge, int *totedge, MFace **allface, int *totface)
 {
-       return nurbs_to_mdata_customdb(ob, &((Curve *)ob->data)->disp,
+       return nurbs_to_mdata_customdb(ob, &ob->disp,
                allvert, totvert, alledge, totedge, allface, totface);
 }
 
index fdf46ea..696d8bc 100644 (file)
@@ -1036,9 +1036,7 @@ static EnumPropertyItem convert_target_items[]= {
 
 static void curvetomesh(Scene *scene, Object *ob) 
 {
-       Curve *cu= ob->data;
-       
-       if(cu->disp.first==0)
+       if(ob->disp.first==0)
                makeDispListCurveTypes(scene, ob, 0); /* force creation */
 
        nurbs_to_mesh(ob); /* also does users */
@@ -1188,7 +1186,7 @@ static int convert_exec(bContext *C, wmOperator *op)
 
                        cu= newob->data;
 
-                       if (!cu->disp.first)
+                       if (!newob->disp.first)
                                makeDispListCurveTypes(scene, newob, 0);
 
                        newob->type= OB_CURVE;
@@ -1225,8 +1223,12 @@ static int convert_exec(bContext *C, wmOperator *op)
                        for(nu=cu->nurb.first; nu; nu=nu->next)
                                nu->charidx= 0;
 
-                       if(target == OB_MESH)
+                       if(target == OB_MESH) {
                                curvetomesh(scene, newob);
+
+                               /* meshes doesn't use displist */
+                               freedisplist(&newob->disp);
+                       }
                }
                else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
                        ob->flag |= OB_DONE;
@@ -1243,6 +1245,9 @@ static int convert_exec(bContext *C, wmOperator *op)
                                        newob->data= copy_curve(ob->data);
                                } else {
                                        newob= ob;
+
+                                       /* meshes doesn't use displist */
+                                       freedisplist(&newob->disp);
                                }
 
                                curvetomesh(scene, newob);
index 7a6e5da..b4185d1 100644 (file)
@@ -91,13 +91,12 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
        case OB_SURF:
        case OB_CURVE:
        case OB_FONT: {
-               Curve *cu= ob->data;
                int tot= 0, totf= 0;
 
                stats->totcurve += totob;
 
-               if(cu->disp.first)
-                       count_displist(&cu->disp, &tot, &totf);
+               if(ob->disp.first)
+                       count_displist(&ob->disp, &tot, &totf);
 
                tot *= totob;
                totf *= totob;
index e62b3c6..d17657f 100644 (file)
@@ -3146,7 +3146,7 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
        case OB_CURVE:
                cu= ob->data;
                
-               lb= &cu->disp;
+               lb= &ob->disp;
                
                if(solid) {
                        dl= lb->first;
@@ -3193,7 +3193,7 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
                break;
        case OB_SURF:
 
-               lb= &((Curve *)ob->data)->disp;
+               lb= &ob->disp;
                
                if(solid) {
                        dl= lb->first;
@@ -5436,7 +5436,7 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
                if (dm) {
                        hasfaces= dm->getNumFaces(dm);
                } else {
-                       hasfaces= displist_has_faces(&cu->disp);
+                       hasfaces= displist_has_faces(&ob->disp);
                }
 
                if (hasfaces && boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb)) {
@@ -5444,7 +5444,7 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
                        if (dm) {
                                draw_mesh_object_outline(v3d, ob, dm);
                        } else {
-                               drawDispListwire(&cu->disp);
+                               drawDispListwire(&ob->disp);
                        }
                        draw_index_wire= 1;
                }
@@ -5499,7 +5499,7 @@ static void drawWireExtra(Scene *scene, RegionView3D *rv3d, Object *ob)
                        if (ob->derivedFinal) {
                                drawCurveDMWired(ob);
                        } else {
-                               drawDispListwire(&cu->disp);
+                               drawDispListwire(&ob->disp);
                        }
 
                        if (ob->type==OB_CURVE)
@@ -5820,9 +5820,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
 
        /* bad exception, solve this! otherwise outline shows too late */
        if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
-               cu= ob->data;
                /* still needed for curves hidden in other layers. depgraph doesnt handle that yet */
-               if (cu->disp.first==NULL) makeDispListCurveTypes(scene, ob, 0);
+               if (ob->disp.first==NULL) makeDispListCurveTypes(scene, ob, 0);
        }
        
        /* draw outline for selected objects, mesh does itself */
index de6416e..08d5258 100644 (file)
@@ -171,7 +171,7 @@ typedef struct Curve {
        struct BoundBox *bb;
        
        ListBase nurb;          /* actual data, called splines in rna */
-       ListBase disp;
+       ListBase disp;          /* undeformed display list, used mostly for texture space calculation */
        
        EditNurb *editnurb;     /* edited data, not in file, use pointer so we can check for it */