=bmesh= merge from trunk at r36529
[blender.git] / source / blender / blenkernel / intern / displist.c
index 4ef868616857c2bc71f35d419a145a1c9a3a639d..48192546b0f58013802f9d044efdcccd4a2410fe 100644 (file)
@@ -17,7 +17,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  * All rights reserved.
  * ***** END GPL LICENSE BLOCK *****
  */
 
+/** \file blender/blenkernel/intern/displist.c
+ *  \ingroup bke
+ */
+
+
 #include <math.h>
 #include <stdio.h>
 #include <string.h>
 
 #include "MEM_guardedalloc.h"
 
-#include "IMB_imbuf_types.h"
-
-#include "DNA_texture_types.h"
-#include "DNA_meta_types.h"
 #include "DNA_curve_types.h"
-#include "DNA_effect_types.h"
-#include "DNA_listBase.h"
-#include "DNA_lamp_types.h"
-#include "DNA_object_types.h"
-#include "DNA_object_force.h"
-#include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
 #include "DNA_scene_types.h"
-#include "DNA_image_types.h"
+#include "DNA_object_types.h"
 #include "DNA_material_types.h"
-#include "DNA_view3d_types.h"
-#include "DNA_lattice_types.h"
-#include "DNA_key_types.h"
 
 #include "BLI_blenlib.h"
-#include "BLI_arithb.h"
+#include "BLI_math.h"
 #include "BLI_editVert.h"
-#include "BLI_edgehash.h"
+#include "BLI_scanfill.h"
+#include "BLI_utildefines.h"
 
-#include "BKE_utildefines.h"
 #include "BKE_global.h"
 #include "BKE_displist.h"
-#include "BKE_deform.h"
-#include "BKE_DerivedMesh.h"
+#include "BKE_cdderivedmesh.h"
 #include "BKE_object.h"
-#include "BKE_world.h"
-#include "BKE_mesh.h"
-#include "BKE_effect.h"
 #include "BKE_mball.h"
 #include "BKE_material.h"
 #include "BKE_curve.h"
 #include "BKE_key.h"
 #include "BKE_anim.h"
-#include "BKE_screen.h"
-#include "BKE_texture.h"
-#include "BKE_library.h"
 #include "BKE_font.h"
 #include "BKE_lattice.h"
-#include "BKE_scene.h"
-#include "BKE_subsurf.h"
 #include "BKE_modifier.h"
-#include "BKE_customdata.h"
 
 #include "RE_pipeline.h"
 #include "RE_shader_ext.h"
 
 #include "BLO_sys_types.h" // for intptr_t support
 
+#include "ED_curve.h" /* for BKE_curve_nurbs */
 
 static void boundbox_displist(Object *ob);
 
@@ -144,7 +126,7 @@ DispList *find_displist(ListBase *lb, int type)
                dl= dl->next;
        }
 
-       return 0;
+       return NULL;
 }
 
 int displist_has_faces(ListBase *lb)
@@ -161,7 +143,7 @@ void copy_displist(ListBase *lbn, ListBase *lb)
 {
        DispList *dln, *dl;
        
-       lbn->first= lbn->last= 0;
+       freedisplist(lbn);
        
        dl= lb->first;
        while(dl) {
@@ -173,12 +155,15 @@ void copy_displist(ListBase *lbn, ListBase *lb)
                dln->index= MEM_dupallocN(dl->index);
                dln->col1= MEM_dupallocN(dl->col1);
                dln->col2= MEM_dupallocN(dl->col2);
-               
+
+               if(dl->bevelSplitFlag)
+                       dln->bevelSplitFlag= MEM_dupallocN(dl->bevelSplitFlag);
+
                dl= dl->next;
        }
 }
 
-void addnormalsDispList(Object *ob, ListBase *lb)
+void addnormalsDispList(ListBase *lb)
 {
        DispList *dl = NULL;
        float *vdata, *ndata, nor[3];
@@ -193,8 +178,8 @@ void addnormalsDispList(Object *ob, ListBase *lb)
                if(dl->type==DL_INDEX3) {
                        if(dl->nors==NULL) {
                                dl->nors= MEM_callocN(sizeof(float)*3, "dlnors");
-                               if(dl->verts[2]<0.0) dl->nors[2]= -1.0;
-                               else dl->nors[2]= 1.0;
+                               if(dl->verts[2] < 0.0f) dl->nors[2]= -1.0f;
+                               else dl->nors[2]= 1.0f;
                        }
                }
                else if(dl->type==DL_SURF) {
@@ -220,12 +205,12 @@ void addnormalsDispList(Object *ob, ListBase *lb)
                                        
                                        for(; b<dl->nr; b++) {
        
-                                               CalcNormFloat4(v1, v3, v4, v2, nor);
+                                               normal_quad_v3( nor,v1, v3, v4, v2);
        
-                                               VecAddf(n1, n1, nor);
-                                               VecAddf(n2, n2, nor);
-                                               VecAddf(n3, n3, nor);
-                                               VecAddf(n4, n4, nor);
+                                               add_v3_v3(n1, nor);
+                                               add_v3_v3(n2, nor);
+                                               add_v3_v3(n3, nor);
+                                               add_v3_v3(n4, nor);
        
                                                v2= v1; v1+= 3;
                                                v4= v3; v3+= 3;
@@ -236,7 +221,7 @@ void addnormalsDispList(Object *ob, ListBase *lb)
                                a= dl->parts*dl->nr;
                                v1= ndata;
                                while(a--) {
-                                       Normalize(v1);
+                                       normalize_v3(v1);
                                        v1+= 3;
                                }
                        }
@@ -313,7 +298,7 @@ static void init_fastshade_shadeinput(Render *re)
        shi.combinedflag= -1;
 }
 
-static Render *fastshade_get_render(Scene *scene)
+static Render *fastshade_get_render(Scene *UNUSED(scene))
 {
        // XXX 2.5: this crashes combined with previewrender
        // due to global R so disabled for now
@@ -428,10 +413,10 @@ static void fastshade(float *co, float *nor, float *orco, Material *ma, char *co
                        VECCOPY(shi.orn, shi.vn);
                }
                if(ma->texco & TEXCO_REFL) {
-                       float inp= 2.0*(shi.vn[2]);
+                       float inp= 2.0f * (shi.vn[2]);
                        shi.ref[0]= (inp*shi.vn[0]);
                        shi.ref[1]= (inp*shi.vn[1]);
-                       shi.ref[2]= (-1.0+inp*shi.vn[2]);
+                       shi.ref[2]= (-1.0f + inp*shi.vn[2]);
                }
        }
        
@@ -475,11 +460,11 @@ static void init_fastshade_for_ob(Render *re, Object *ob, int *need_orco_r, floa
        init_fastshade_shadeinput(re);
        
        RE_DataBase_GetView(re, tmat);
-       Mat4MulMat4(mat, ob->obmat, tmat);
+       mul_m4_m4m4(mat, ob->obmat, tmat);
        
-       Mat4Invert(tmat, mat);
-       Mat3CpyMat4(imat, tmat);
-       if(ob->transflag & OB_NEG_SCALE) Mat3MulFloat((float *)imat, -1.0);
+       invert_m4_m4(tmat, mat);
+       copy_m3_m4(imat, tmat);
+       if(ob->transflag & OB_NEG_SCALE) mul_m3_fl(imat, -1.0);
        
        if (need_orco_r) *need_orco_r= 0;
        for(a=0; a<ob->totcol; a++) {
@@ -516,7 +501,7 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
        float *orco, *vnors, *nors, imat[3][3], mat[4][4], vec[3];
        int a, i, need_orco, totface, totvert;
        CustomDataMask dataMask = CD_MASK_BAREMESH | CD_MASK_MCOL
-                                 | CD_MASK_MTFACE | CD_MASK_NORMAL;
+                                                         | CD_MASK_MTFACE | CD_MASK_NORMAL;
 
 
        init_fastshade_for_ob(re, ob, &need_orco, mat, imat);
@@ -563,7 +548,7 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
                vn[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
                vn[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
                vn[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
-               Normalize(vn);
+               normalize_v3(vn);
        }               
 
        for (i=0; i<totface; i++) {
@@ -586,27 +571,25 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
                        VECCOPY(nor, &nors[i*3]);
                } else {
                        if (mf->v4)
-                               CalcNormFloat4(mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co, nor);
+                               normal_quad_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
                        else
-                               CalcNormFloat(mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, nor);
+                               normal_tri_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
                }
 
                n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
                n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
                n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
-               Normalize(n1);
+               normalize_v3(n1);
 
                for (j=0; j<nverts; j++) {
                        MVert *mv= &mvert[vidx[j]];
                        char *col1= (char*)&col1base[j*4];
                        char *col2= (char*)(col2base?&col2base[j*4]:NULL);
                        float *vn = (mf->flag & ME_SMOOTH)?&vnors[3*vidx[j]]:n1;
-                       
-                       VECCOPY(vec, mv->co);
-                       Mat4MulVecfl(mat, vec);
-                       vec[0]+= 0.001*vn[0];
-                       vec[1]+= 0.001*vn[1];
-                       vec[2]+= 0.001*vn[2];
+
+                       mul_v3_m4v3(vec, mat, mv->co);
+
+                       mul_v3_v3fl(vec, vn, 0.001f);
 
                        fastshade_customdata(&dm->faceData, i, j, ma);
                        fastshade(vec, vn, orco?&orco[vidx[j]*3]:mv->co, ma, col1, col2);
@@ -645,7 +628,6 @@ void shadeDispList(Scene *scene, Base *base)
        Object *ob= base->object;
        DispList *dl, *dlob;
        Material *ma = NULL;
-       Curve *cu;
        Render *re;
        float imat[3][3], mat[4][4], vec[3];
        float *fp, *nor, n1[3];
@@ -679,8 +661,7 @@ void shadeDispList(Scene *scene, Base *base)
                if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
                
                        /* now we need the normals */
-                       cu= ob->data;
-                       dl= cu->disp.first;
+                       dl= ob->disp.first;
                        
                        while(dl) {
                                extern Material defmaterial;    /* material.c */
@@ -708,14 +689,13 @@ void shadeDispList(Scene *scene, Base *base)
                                                n1[0]= imat[0][0]*dl->nors[0]+imat[0][1]*dl->nors[1]+imat[0][2]*dl->nors[2];
                                                n1[1]= imat[1][0]*dl->nors[0]+imat[1][1]*dl->nors[1]+imat[1][2]*dl->nors[2];
                                                n1[2]= imat[2][0]*dl->nors[0]+imat[2][1]*dl->nors[1]+imat[2][2]*dl->nors[2];
-                                               Normalize(n1);
+                                               normalize_v3(n1);
                                                
                                                fp= dl->verts;
                                                
                                                a= dl->nr;              
                                                while(a--) {
-                                                       VECCOPY(vec, fp);
-                                                       Mat4MulVecfl(mat, vec);
+                                                       mul_v3_m4v3(vec, mat, fp);
                                                        
                                                        fastshade(vec, n1, fp, ma, (char *)col1, NULL);
                                                        
@@ -730,13 +710,12 @@ void shadeDispList(Scene *scene, Base *base)
                                                nor= dl->nors;
                                                
                                                while(a--) {
-                                                       VECCOPY(vec, fp);
-                                                       Mat4MulVecfl(mat, vec);
+                                                       mul_v3_m4v3(vec, mat, fp);
                                                        
                                                        n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
                                                        n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
                                                        n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
-                                                       Normalize(n1);
+                                                       normalize_v3(n1);
                                
                                                        fastshade(vec, n1, fp, ma, (char *)col1, NULL);
                                                        
@@ -768,14 +747,13 @@ void shadeDispList(Scene *scene, Base *base)
                                                
                                                a= dl->nr;              
                                                while(a--) {
-                                                       VECCOPY(vec, fp);
-                                                       Mat4MulVecfl(mat, vec);
+                                                       mul_v3_m4v3(vec, mat, fp);
                                                        
                                                        /* transpose ! */
                                                        n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
                                                        n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
                                                        n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
-                                                       Normalize(n1);
+                                                       normalize_v3(n1);
                                                
                                                        fastshade(vec, n1, fp, ma, (char *)col1, NULL);
                                                        
@@ -815,7 +793,7 @@ void reshadeall_displist(Scene *scene)
 
 /* ****************** make displists ********************* */
 
-static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
+static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, int forRender)
 {
        Nurb *nu;
        DispList *dl;
@@ -828,7 +806,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
        while(nu) {
                if(nu->hide==0) {
                        
-                       if(G.rendering && cu->resolu_ren!=0) 
+                       if(forRender && cu->resolu_ren!=0)
                                resolu= cu->resolu_ren;
                        else
                                resolu= nu->resolu;
@@ -839,17 +817,17 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
                                /* count */
                                len= 0;
                                a= nu->pntsu-1;
-                               if(nu->flagu & CU_CYCLIC) a++;
+                               if(nu->flagu & CU_NURB_CYCLIC) a++;
 
                                prevbezt= nu->bezt;
                                bezt= prevbezt+1;
                                while(a--) {
-                                       if(a==0 && (nu->flagu & CU_CYCLIC)) bezt= nu->bezt;
+                                       if(a==0 && (nu->flagu & CU_NURB_CYCLIC)) bezt= nu->bezt;
                                        
                                        if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) len++;
                                        else len+= resolu;
                                        
-                                       if(a==0 && (nu->flagu & CU_CYCLIC)==0) len++;
+                                       if(a==0 && (nu->flagu & CU_NURB_CYCLIC)==0) len++;
                                        
                                        prevbezt= bezt;
                                        bezt++;
@@ -866,7 +844,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
 
                                data= dl->verts;
 
-                               if(nu->flagu & CU_CYCLIC) {
+                               if(nu->flagu & CU_NURB_CYCLIC) {
                                        dl->type= DL_POLY;
                                        a= nu->pntsu;
                                }
@@ -919,9 +897,9 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
                                dl->charidx = nu->charidx;
 
                                data= dl->verts;
-                               if(nu->flagu & CU_CYCLIC) dl->type= DL_POLY;
+                               if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
                                else dl->type= DL_SEGM;
-                               makeNurbcurve(nu, data, NULL, NULL, resolu, 3*sizeof(float));
+                               makeNurbcurve(nu, data, NULL, NULL, NULL, resolu, 3*sizeof(float));
                        }
                        else if(nu->type == CU_POLY) {
                                len= nu->pntsu;
@@ -934,7 +912,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
                                dl->charidx = nu->charidx;
 
                                data= dl->verts;
-                               if(nu->flagu & CU_CYCLIC) dl->type= DL_POLY;
+                               if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
                                else dl->type= DL_SEGM;
                                
                                a= len;
@@ -951,59 +929,64 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
 }
 
 
-void filldisplist(ListBase *dispbase, ListBase *to)
+void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal)
 {
        EditVert *eve, *v1, *vlast;
        EditFace *efa;
-       DispList *dlnew=0, *dl;
+       DispList *dlnew=NULL, *dl;
        float *f1;
-       int colnr=0, charidx=0, cont=1, tot, a, *index;
+       int colnr=0, charidx=0, cont=1, tot, a, *index, nextcol= 0;
        intptr_t totvert;
        
-       if(dispbase==0) return;
-       if(dispbase->first==0) return;
+       if(dispbase==NULL) return;
+       if(dispbase->first==NULL) return;
 
        while(cont) {
                cont= 0;
-               totvert=0;
+               totvert= 0;
+               nextcol= 0;
+               
+               BLI_begin_edgefill();
                
                dl= dispbase->first;
                while(dl) {
        
                        if(dl->type==DL_POLY) {
                                if(charidx<dl->charidx) cont= 1;
-                               else if(charidx==dl->charidx) {
-                       
-                                       colnr= dl->col;
-                                       charidx= dl->charidx;
-               
-                                       /* make editverts and edges */
-                                       f1= dl->verts;
-                                       a= dl->nr;
-                                       eve= v1= 0;
-                                       
-                                       while(a--) {
-                                               vlast= eve;
-                                               
-                                               eve= BLI_addfillvert(f1);
-                                               totvert++;
+                               else if(charidx==dl->charidx) { /* character with needed index */
+                                       if(colnr==dl->col) {
+                                               /* make editverts and edges */
+                                               f1= dl->verts;
+                                               a= dl->nr;
+                                               eve= v1= NULL;
                                                
-                                               if(vlast==0) v1= eve;
-                                               else {
-                                                       BLI_addfilledge(vlast, eve);
+                                               while(a--) {
+                                                       vlast= eve;
+
+                                                       eve= BLI_addfillvert(f1);
+                                                       totvert++;
+
+                                                       if(vlast==NULL) v1= eve;
+                                                       else {
+                                                               BLI_addfilledge(vlast, eve);
+                                                       }
+                                                       f1+=3;
                                                }
-                                               f1+=3;
-                                       }
-                               
-                                       if(eve!=0 && v1!=0) {
-                                               BLI_addfilledge(eve, v1);
+
+                                               if(eve!=NULL && v1!=NULL) {
+                                                       BLI_addfilledge(eve, v1);
+                                               }
+                                       } else if (colnr<dl->col) {
+                                               /* got poly with next material at current char */
+                                               cont= 1;
+                                               nextcol= 1;
                                        }
                                }
                        }
                        dl= dl->next;
                }
                
-               if(totvert && BLI_edgefill(0, 0)) { // XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) {
+               if(totvert && BLI_edgefill(0)) { // XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) {
 
                        /* count faces  */
                        tot= 0;
@@ -1045,6 +1028,9 @@ void filldisplist(ListBase *dispbase, ListBase *to)
                                        index[0]= (intptr_t)efa->v1->tmp.l;
                                        index[1]= (intptr_t)efa->v2->tmp.l;
                                        index[2]= (intptr_t)efa->v3->tmp.l;
+
+                                       if(flipnormal)
+                                               SWAP(int, index[0], index[2]);
                                        
                                        index+= 3;
                                        efa= efa->next;
@@ -1056,7 +1042,14 @@ void filldisplist(ListBase *dispbase, ListBase *to)
                }
                BLI_end_edgefill();
 
-               charidx++;
+               if(nextcol) {
+                       /* stay at current char but fill polys with next material */
+                       colnr++;
+               } else {
+                       /* switch to next char and start filling from first material */
+                       charidx++;
+                       colnr= 0;
+               }
        }
        
        /* do not free polys, needed for wireframe display */
@@ -1070,7 +1063,7 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
        float *fp, *fp1;
        int a, dpoly;
        
-       front.first= front.last= back.first= back.last= 0;
+       front.first= front.last= back.first= back.last= NULL;
        
        dl= dispbase->first;
        while(dl) {
@@ -1121,17 +1114,17 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
                dl= dl->next;
        }
 
-       filldisplist(&front, dispbase);
-       filldisplist(&back, dispbase);
+       filldisplist(&front, dispbase, 1);
+       filldisplist(&back, dispbase, 0);
        
        freedisplist(&front);
        freedisplist(&back);
 
-       filldisplist(dispbase, dispbase);
+       filldisplist(dispbase, dispbase, 0);
        
 }
 
-static void curve_to_filledpoly(Curve *cu, ListBase *nurb, ListBase *dispbase)
+static void curve_to_filledpoly(Curve *cu, ListBase *UNUSED(nurb), ListBase *dispbase)
 {
        if(cu->flag & CU_3D) return;
 
@@ -1139,7 +1132,7 @@ static void curve_to_filledpoly(Curve *cu, ListBase *nurb, ListBase *dispbase)
                bevels_to_filledpoly(cu, dispbase);
        }
        else {
-               filldisplist(dispbase, dispbase);
+               filldisplist(dispbase, dispbase, 0);
        }
 }
 
@@ -1150,16 +1143,14 @@ static void curve_to_filledpoly(Curve *cu, ListBase *nurb, ListBase *dispbase)
 */
 float calc_taper(Scene *scene, Object *taperobj, int cur, int tot)
 {
-       Curve *cu;
        DispList *dl;
        
-       if(taperobj==NULL) return 1.0;
+       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);
@@ -1169,7 +1160,7 @@ float calc_taper(Scene *scene, Object *taperobj, int cur, int tot)
                /* horizontal size */
                minx= dl->verts[0];
                dx= dl->verts[3*(dl->nr-1)] - minx;
-               if(dx>0.0) {
+               if(dx > 0.0f) {
                
                        fp= dl->verts;
                        for(a=0; a<dl->nr; a++, fp+=3) {
@@ -1195,21 +1186,33 @@ void makeDispListMBall(Scene *scene, Object *ob)
 {
        if(!ob || ob->type!=OB_MBALL) return;
 
+       // XXX: mball stuff uses plenty of global variables
+       //      while this is unchanged updating during render is unsafe
+       if(G.rendering) return;
+
        freedisplist(&(ob->disp));
-       
+
        if(ob->type==OB_MBALL) {
                if(ob==find_basis_mball(scene, ob)) {
-                       metaball_polygonize(scene, ob);
+                       metaball_polygonize(scene, ob, &ob->disp);
                        tex_space_mball(ob);
 
-                       object_deform_mball(ob);
+                       object_deform_mball(ob, &ob->disp);
                }
        }
        
        boundbox_displist(ob);
 }
 
-static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int editmode)
+void makeDispListMBall_forRender(Scene *scene, Object *ob, ListBase *dispbase)
+{
+       metaball_polygonize(scene, ob, dispbase);
+       tex_space_mball(ob);
+       
+       object_deform_mball(ob, dispbase);
+}
+
+static ModifierData *curve_get_tesselate_point(Scene *scene, Object *ob, int forRender, int editmode)
 {
        ModifierData *md = modifiers_getVirtualModifierList(ob);
        ModifierData *preTesselatePoint;
@@ -1224,11 +1227,18 @@ static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int ed
        for (; md; md=md->next) {
                ModifierTypeInfo *mti = modifierType_getInfo(md->type);
 
-               if ((md->mode & required_mode) != required_mode) continue;
-               if (mti->isDisabled && mti->isDisabled(md)) continue;
+               if (!modifier_isEnabled(scene, md, required_mode)) continue;
+               if (mti->type == eModifierTypeType_Constructive) return preTesselatePoint;
 
                if (ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
-                       preTesselatePoint  = md;
+                       preTesselatePoint = md;
+
+                       /* this modifiers are moving point of tesselation automatically
+                          (some of them even can't be applied on tesselated curve), set flag
+                          for incformation button in modifier's header */
+                       md->mode |= eModifierMode_ApplyOnSpline;
+               } else if(md->mode&eModifierMode_ApplyOnSpline) {
+                       preTesselatePoint = md;
                }
        }
 
@@ -1240,7 +1250,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
        ModifierData *md = modifiers_getVirtualModifierList(ob);
        ModifierData *preTesselatePoint;
        Curve *cu= ob->data;
-       ListBase *nurb= cu->editnurb?cu->editnurb:&cu->nurb;
+       ListBase *nurb= BKE_curve_nurbs(cu);
        int numVerts = 0;
        int editmode = (!forRender && cu->editnurb);
        float (*originalVerts)[3] = NULL;
@@ -1251,7 +1261,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
        if(forRender) required_mode = eModifierMode_Render;
        else required_mode = eModifierMode_Realtime;
 
-       preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode);
+       preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
        
        if(editmode) required_mode |= eModifierMode_Editmode;
 
@@ -1275,14 +1285,14 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
                        md->scene= scene;
                        
                        if ((md->mode & required_mode) != required_mode) continue;
-                       if (mti->isDisabled && mti->isDisabled(md)) continue;
+                       if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
                        if (mti->type!=eModifierTypeType_OnlyDeform) continue;
 
                        if (!deformedVerts) {
                                deformedVerts = curve_getVertexCos(cu, nurb, &numVerts);
                                originalVerts = MEM_dupallocN(deformedVerts);
                        }
-                       
+
                        mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, forRender, editmode);
 
                        if (md==preTesselatePoint)
@@ -1294,7 +1304,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
                curve_applyVertexCos(cu, nurb, deformedVerts);
        if (keyVerts) /* these are not passed through modifier stack */
                curve_applyKeyVertexTilts(cu, nurb, keyVerts);
-       
+
        if(keyVerts)
                MEM_freeN(keyVerts);
 
@@ -1303,20 +1313,56 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
        *numVerts_r = numVerts;
 }
 
-static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispbase, int forRender, float (*originalVerts)[3], float (*deformedVerts)[3])
+static float (*displist_get_allverts (ListBase *dispbase, int *totvert))[3]
+{
+       DispList *dl;
+       float (*allverts)[3], *fp;
+
+       *totvert= 0;
+
+       for (dl=dispbase->first; dl; dl=dl->next)
+               *totvert+= (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr;
+
+       allverts= MEM_mallocN((*totvert)*sizeof(float)*3, "displist_get_allverts allverts");
+       fp= (float*)allverts;
+       for (dl=dispbase->first; dl; dl=dl->next) {
+               int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
+               memcpy(fp, dl->verts, sizeof(float) * offs);
+               fp+= offs;
+       }
+
+       return allverts;
+}
+
+static void displist_apply_allverts(ListBase *dispbase, float (*allverts)[3])
+{
+       DispList *dl;
+       float *fp;
+
+       fp= (float*)allverts;
+       for (dl=dispbase->first; dl; dl=dl->next) {
+               int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
+               memcpy(dl->verts, fp, sizeof(float) * offs);
+               fp+= offs;
+       }
+}
+
+static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispbase,
+       DerivedMesh **derivedFinal, int forRender, float (*originalVerts)[3], float (*deformedVerts)[3])
 {
        ModifierData *md = modifiers_getVirtualModifierList(ob);
        ModifierData *preTesselatePoint;
        Curve *cu= ob->data;
-       ListBase *nurb= cu->editnurb?cu->editnurb:&cu->nurb;
-       DispList *dl;
-       int required_mode;
+       ListBase *nurb= BKE_curve_nurbs(cu);
+       int required_mode = 0, totvert = 0;
        int editmode = (!forRender && cu->editnurb);
+       DerivedMesh *dm= NULL, *ndm;
+       float (*vertCos)[3] = NULL;
 
        if(forRender) required_mode = eModifierMode_Render;
        else required_mode = eModifierMode_Realtime;
 
-       preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode);
+       preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
        
        if(editmode) required_mode |= eModifierMode_Editmode;
 
@@ -1324,47 +1370,104 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
                md = preTesselatePoint->next;
        }
 
+       if (derivedFinal && *derivedFinal) {
+               (*derivedFinal)->release (*derivedFinal);
+       }
+
        for (; md; md=md->next) {
                ModifierTypeInfo *mti = modifierType_getInfo(md->type);
-               
+
                md->scene= scene;
-               
+
                if ((md->mode & required_mode) != required_mode) continue;
-               if (mti->isDisabled && mti->isDisabled(md)) continue;
-               if (mti->type!=eModifierTypeType_OnlyDeform && mti->type!=eModifierTypeType_DeformOrConstruct) continue;
+               if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
+
+               if (mti->type == eModifierTypeType_OnlyDeform ||
+                               (mti->type == eModifierTypeType_DeformOrConstruct && !dm)) {
+                       if (dm) {
+                               if (!vertCos) {
+                                       totvert = dm->getNumVerts(dm);
+                                       vertCos = MEM_mallocN(sizeof(*vertCos) * totvert, "dfmv");
+                                       dm->getVertCos(dm, vertCos);
+                               }
 
-               /* need to put all verts in 1 block for curve deform */
-               if(md->type==eModifierType_Curve) {
-                       float *allverts, *fp;
-                       int totvert= 0;
-                       
-                       for (dl=dispbase->first; dl; dl=dl->next)
-                               totvert+= (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr;
-                       
-                       fp= allverts= MEM_mallocN(totvert*sizeof(float)*3, "temp vert");
-                       for (dl=dispbase->first; dl; dl=dl->next) {
-                               int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
-                               memcpy(fp, dl->verts, sizeof(float) * offs);
-                               fp+= offs;
+                               mti->deformVerts(md, ob, dm, vertCos, totvert, forRender, editmode);
+                       } else {
+                               if (!vertCos) {
+                                       vertCos= displist_get_allverts(dispbase, &totvert);
+                               }
+
+                               mti->deformVerts(md, ob, NULL, vertCos, totvert, forRender, editmode);
                        }
-                       
-                       mti->deformVerts(md, ob, NULL, (float(*)[3]) allverts, totvert, forRender, editmode);
-                       
-                       fp= allverts;
-                       for (dl=dispbase->first; dl; dl=dl->next) {
-                               int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
-                               memcpy(dl->verts, fp, sizeof(float) * offs);
-                               fp+= offs;
+               } else {
+                       if (!derivedFinal) {
+                               /* makeDisplistCurveTypes could be used for beveling, where derived mesh */
+                               /* is totally unnecessary, so we could stop modifiers applying */
+                               /* when we found constructive modifier but derived mesh is unwanted result */
+                               break;
                        }
-                       MEM_freeN(allverts);
-               }
-               else {
-                       for (dl=dispbase->first; dl; dl=dl->next) {
-                               mti->deformVerts(md, ob, NULL, (float(*)[3]) dl->verts, (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr, forRender, editmode);
+
+                       if (dm) {
+                               if (vertCos) {
+                                       DerivedMesh *tdm = CDDM_copy(dm, 0);
+                                       dm->release(dm);
+                                       dm = tdm;
+
+                                       CDDM_apply_vert_coords(dm, vertCos);
+                                       CDDM_calc_normals(dm);
+                               }
+                       } else {
+                               if (vertCos) {
+                                       displist_apply_allverts(dispbase, vertCos);
+                               }
+
+                               if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) {
+                                       curve_to_filledpoly(cu, nurb, dispbase);
+                               }
+
+                               dm= CDDM_from_curve_customDB(ob, dispbase);
+
+                               CDDM_calc_normals(dm);
                        }
+
+                       if (vertCos) {
+                               /* Vertex coordinates were applied to necessary data, could free it */
+                               MEM_freeN(vertCos);
+                               vertCos= NULL;
+                       }
+
+                       ndm = mti->applyModifier(md, ob, dm, forRender, editmode);
+
+                       if (ndm) {
+                               /* Modifier returned a new derived mesh */
+
+                               if (dm && dm != ndm) /* Modifier  */
+                                       dm->release (dm);
+                               dm = ndm;
+                       }
+               }
+       }
+
+       if (vertCos) {
+               if (dm) {
+                       DerivedMesh *tdm = CDDM_copy(dm, 0);
+                       dm->release(dm);
+                       dm = tdm;
+
+                       CDDM_apply_vert_coords(dm, vertCos);
+                       CDDM_calc_normals(dm);
+                       MEM_freeN(vertCos);
+               } else {
+                       displist_apply_allverts(dispbase, vertCos);
+                       MEM_freeN(vertCos);
+                       vertCos= NULL;
                }
        }
 
+       if (derivedFinal) {
+               (*derivedFinal) = dm;
+       }
+
        if (deformedVerts) {
                curve_applyVertexCos(ob->data, nurb, originalVerts);
                MEM_freeN(originalVerts);
@@ -1402,7 +1505,110 @@ static void displist_surf_indices(DispList *dl)
        
 }
 
-void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRender, int forOrco)
+static DerivedMesh *create_orco_dm(Scene *scene, Object *ob)
+{
+       DerivedMesh *dm;
+       ListBase disp= {NULL, NULL};
+
+       /* OrcoDM should be created from underformed disp lists */
+       makeDispListCurveTypes_forOrco(scene, ob, &disp);
+       dm= CDDM_from_curve_customDB(ob, &disp);
+
+       freedisplist(&disp);
+
+       return dm;
+}
+
+static void add_orco_dm(Scene *scene, Object *ob, DerivedMesh *dm, DerivedMesh *orcodm)
+{
+       float (*orco)[3], (*layerorco)[3];
+       int totvert, a;
+       Curve *cu= ob->data;
+
+       totvert= dm->getNumVerts(dm);
+
+       if(orcodm) {
+               orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco");
+
+               if(orcodm->getNumVerts(orcodm) == totvert)
+                       orcodm->getVertCos(orcodm, orco);
+               else
+                       dm->getVertCos(dm, orco);
+       }
+       else {
+               orco= (float(*)[3])make_orco_curve(scene, ob);
+       }
+
+       for(a=0; a<totvert; a++) {
+               float *co = orco[a];
+               co[0] = (co[0]-cu->loc[0])/cu->size[0];
+               co[1] = (co[1]-cu->loc[1])/cu->size[1];
+               co[2] = (co[2]-cu->loc[2])/cu->size[2];
+       }
+
+       if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) {
+               memcpy(layerorco, orco, sizeof(float)*totvert);
+               MEM_freeN(orco);
+       }
+       else
+               DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
+}
+
+static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender)
+{
+       /* this function represents logic of mesh's orcodm calculation */
+       /* for displist-based objects */
+
+       ModifierData *md = modifiers_getVirtualModifierList(ob);
+       ModifierData *preTesselatePoint;
+       Curve *cu= ob->data;
+       int required_mode;
+       int editmode = (!forRender && cu->editnurb);
+       DerivedMesh *ndm, *orcodm= NULL;
+
+       if(forRender) required_mode = eModifierMode_Render;
+       else required_mode = eModifierMode_Realtime;
+
+       preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
+
+       if(editmode) required_mode |= eModifierMode_Editmode;
+
+       if (preTesselatePoint) {
+               md = preTesselatePoint->next;
+       }
+
+       for (; md; md=md->next) {
+               ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+
+               md->scene= scene;
+
+               if ((md->mode & required_mode) != required_mode) continue;
+               if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
+               if (mti->type!=eModifierTypeType_Constructive) continue;
+
+               if(!orcodm)
+                       orcodm= create_orco_dm(scene, ob);
+
+               ndm = mti->applyModifier(md, ob, orcodm, forRender, 0);
+
+               if(ndm) {
+                       /* if the modifier returned a new dm, release the old one */
+                       if(orcodm && orcodm != ndm) {
+                               orcodm->release(orcodm);
+                       }
+                       orcodm = ndm;
+               }
+       }
+
+       /* add an orco layer if needed */
+       add_orco_dm(scene, ob, derivedFinal, orcodm);
+
+       if(orcodm)
+               orcodm->release(orcodm);
+}
+
+void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase,
+       DerivedMesh **derivedFinal, int forRender, int forOrco)
 {
        ListBase *nubase;
        Nurb *nu;
@@ -1413,9 +1619,9 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRende
        int numVerts;
        float (*originalVerts)[3];
        float (*deformedVerts)[3];
-               
+
        if(!forRender && cu->editnurb)
-               nubase= cu->editnurb;
+               nubase= ED_curve_editnurbs(cu);
        else
                nubase= &cu->nurb;
 
@@ -1424,27 +1630,37 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRende
 
        for (nu=nubase->first; nu; nu=nu->next) {
                if(forRender || nu->hide==0) {
+                       int resolu= nu->resolu, resolv= nu->resolv;
+
+                       if(forRender){
+                               if(cu->resolu_ren) resolu= cu->resolu_ren;
+                               if(cu->resolv_ren) resolv= cu->resolv_ren;
+                       }
+
                        if(nu->pntsv==1) {
-                               len= SEGMENTSU(nu)*nu->resolu;
-                               
+                               len= SEGMENTSU(nu)*resolu;
+
                                dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
                                dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
-                               
+
                                BLI_addtail(dispbase, dl);
                                dl->parts= 1;
                                dl->nr= len;
                                dl->col= nu->mat_nr;
                                dl->charidx= nu->charidx;
-                               dl->rt= nu->flag;
-                               
+
+                               /* dl->rt will be used as flag for render face and */
+                               /* CU_2D conflicts with R_NOPUNOFLIP */
+                               dl->rt= nu->flag & ~CU_2D;
+
                                data= dl->verts;
-                               if(nu->flagu & CU_CYCLIC) dl->type= DL_POLY;
+                               if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
                                else dl->type= DL_SEGM;
-                               
-                               makeNurbcurve(nu, data, NULL, NULL, nu->resolu, 3*sizeof(float));
+
+                               makeNurbcurve(nu, data, NULL, NULL, NULL, resolu, 3*sizeof(float));
                        }
                        else {
-                               len= (nu->pntsu*nu->resolu) * (nu->pntsv*nu->resolv);
+                               len= (nu->pntsu*resolu) * (nu->pntsv*resolv);
                                
                                dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
                                dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
@@ -1452,17 +1668,20 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRende
 
                                dl->col= nu->mat_nr;
                                dl->charidx= nu->charidx;
-                               dl->rt= nu->flag;
-                               
+
+                               /* dl->rt will be used as flag for render face and */
+                               /* CU_2D conflicts with R_NOPUNOFLIP */
+                               dl->rt= nu->flag & ~CU_2D;
+
                                data= dl->verts;
                                dl->type= DL_SURF;
-                               
-                               dl->parts= (nu->pntsu*nu->resolu);      /* in reverse, because makeNurbfaces works that way */
-                               dl->nr= (nu->pntsv*nu->resolv);
-                               if(nu->flagv & CU_CYCLIC) dl->flag|= DL_CYCL_U; /* reverse too! */
-                               if(nu->flagu & CU_CYCLIC) dl->flag|= DL_CYCL_V;
 
-                               makeNurbfaces(nu, data, 0);
+                               dl->parts= (nu->pntsu*resolu);  /* in reverse, because makeNurbfaces works that way */
+                               dl->nr= (nu->pntsv*resolv);
+                               if(nu->flagv & CU_NURB_CYCLIC) dl->flag|= DL_CYCL_U;    /* reverse too! */
+                               if(nu->flagu & CU_NURB_CYCLIC) dl->flag|= DL_CYCL_V;
+
+                               makeNurbfaces(nu, data, 0, resolu, resolv);
                                
                                /* gl array drawing: using indices */
                                displist_surf_indices(dl);
@@ -1470,28 +1689,30 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRende
                }
        }
 
+       /* 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);
        }
 
        if(!forOrco)
-               curve_calc_modifiers_post(scene, ob, dispbase, forRender, originalVerts, deformedVerts);
+               curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal,
+                       forRender, originalVerts, deformedVerts);
 }
 
-void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
+static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispbase,
+       DerivedMesh **derivedFinal, int forRender, int forOrco)
 {
        Curve *cu = ob->data;
-       ListBase *dispbase;
-       
+
        /* we do allow duplis... this is only displist on curve level */
        if(!ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return;
 
-       freedisplist(&(ob->disp));
-       dispbase= &(cu->disp);
-       freedisplist(dispbase);
-       
        if(ob->type==OB_SURF) {
-               makeDispListSurf(scene, ob, dispbase, 0, forOrco);
+               makeDispListSurf(scene, ob, dispbase, derivedFinal, forRender, forOrco);
        }
        else if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
                ListBase dlbev;
@@ -1500,30 +1721,27 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
                float (*deformedVerts)[3];
                int numVerts;
 
-               if(cu->editnurb)
-                       nubase= cu->editnurb;
-               else
-                       nubase= &cu->nurb;
-               
+               nubase= BKE_curve_nurbs(cu);
+
                BLI_freelistN(&(cu->bev));
-               
+
                if(cu->path) free_path(cu->path);
                cu->path= NULL;
-               
+
                if(ob->type==OB_FONT) BKE_text_to_curve(scene, ob, 0);
-               
-               if(!forOrco) curve_calc_modifiers_pre(scene, ob, 0, &originalVerts, &deformedVerts, &numVerts);
+
+               if(!forOrco) curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts);
 
                makeBevelList(ob);
 
                /* If curve has no bevel will return nothing */
-               makebevelcurve(scene, ob, &dlbev);
+               makebevelcurve(scene, ob, &dlbev, forRender);
 
                /* no bevel or extrude, and no width correction? */
                if (!dlbev.first && cu->width==1.0f) {
-                       curve_to_displist(cu, nubase, dispbase);
+                       curve_to_displist(cu, nubase, dispbase, forRender);
                } else {
-                       float widfac= cu->width-1.0;
+                       float widfac= cu->width - 1.0f;
                        BevList *bl= cu->bev.first;
                        Nurb *nu= nubase->first;
 
@@ -1532,26 +1750,29 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
                                float *fp1, *data;
                                BevPoint *bevp;
                                int a,b;
-                               
+
                                if (bl->nr) { /* blank bevel lists can happen */
-                                       
+
                                        /* exception handling; curve without bevel or extrude, with width correction */
                                        if(dlbev.first==NULL) {
                                                dl= MEM_callocN(sizeof(DispList), "makeDispListbev");
                                                dl->verts= MEM_callocN(3*sizeof(float)*bl->nr, "dlverts");
                                                BLI_addtail(dispbase, dl);
-                                               
+
                                                if(bl->poly!= -1) dl->type= DL_POLY;
                                                else dl->type= DL_SEGM;
-                                               
+
                                                if(dl->type==DL_SEGM) dl->flag = (DL_FRONT_CURVE|DL_BACK_CURVE);
-                                               
+
                                                dl->parts= 1;
                                                dl->nr= bl->nr;
                                                dl->col= nu->mat_nr;
                                                dl->charidx= nu->charidx;
-                                               dl->rt= nu->flag;
-                                               
+
+                                               /* dl->rt will be used as flag for render face and */
+                                               /* CU_2D conflicts with R_NOPUNOFLIP */
+                                               dl->rt= nu->flag & ~CU_2D;
+
                                                a= dl->nr;
                                                bevp= (BevPoint *)(bl+1);
                                                data= dl->verts;
@@ -1565,10 +1786,10 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
                                        }
                                        else {
                                                DispList *dlb;
-                                               
+
                                                for (dlb=dlbev.first; dlb; dlb=dlb->next) {
        
-                                                               /* for each part of the bevel use a separate displblock */
+                                                       /* for each part of the bevel use a separate displblock */
                                                        dl= MEM_callocN(sizeof(DispList), "makeDispListbev1");
                                                        dl->verts= data= MEM_callocN(3*sizeof(float)*dlb->nr*bl->nr, "dlverts");
                                                        BLI_addtail(dispbase, dl);
@@ -1583,11 +1804,14 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
                                                        dl->nr= dlb->nr;
                                                        dl->col= nu->mat_nr;
                                                        dl->charidx= nu->charidx;
-                                                       dl->rt= nu->flag;
-                                                       dl->bevelSplitFlag= MEM_callocN(sizeof(*dl->col2)*((bl->nr+0x1F)>>5), "col2");
-                                                       bevp= (BevPoint *)(bl+1);
+
+                                                       /* dl->rt will be used as flag for render face and */
+                                                       /* CU_2D conflicts with R_NOPUNOFLIP */
+                                                       dl->rt= nu->flag & ~CU_2D;
+
+                                                       dl->bevelSplitFlag= MEM_callocN(sizeof(*dl->col2)*((bl->nr+0x1F)>>5), "bevelSplitFlag");
        
-                                                               /* for each point of poly make a bevel piece */
+                                                       /* for each point of poly make a bevel piece */
                                                        bevp= (BevPoint *)(bl+1);
                                                        for(a=0; a<bl->nr; a++,bevp++) {
                                                                float fac=1.0;
@@ -1597,7 +1821,7 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
                                                                } else {
                                                                        fac = calc_taper(scene, cu->taperobj, a, bl->nr);
                                                                }
-                                                               
+
                                                                if (bevp->split_tag) {
                                                                        dl->bevelSplitFlag[a>>5] |= 1<<(a&0x1F);
                                                                }
@@ -1611,9 +1835,9 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
                                                                                vec[0]= fp1[1]+widfac;
                                                                                vec[1]= fp1[2];
                                                                                vec[2]= 0.0;
-                                                                               
-                                                                               QuatMulVecf(bevp->quat, vec);
-                                                                               
+
+                                                                               mul_qt_v3(bevp->quat, vec);
+
                                                                                data[0]= bevp->vec[0] + fac*vec[0];
                                                                                data[1]= bevp->vec[1] + fac*vec[1];
                                                                                data[2]= bevp->vec[2] + fac*vec[2];
@@ -1636,26 +1860,91 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
                        freedisplist(&dlbev);
                }
 
-               curve_to_filledpoly(cu, nubase, dispbase);
+               if (!(cu->flag & CU_DEFORM_FILL)) {
+                       curve_to_filledpoly(cu, nubase, dispbase);
+               }
 
                if(cu->flag & CU_PATH) calc_curvepath(ob);
 
-               if(!forOrco) curve_calc_modifiers_post(scene, ob, &cu->disp, 0, originalVerts, deformedVerts);
-               tex_space_curve(cu);
+               /* 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);
+               }
+
+               if(!forOrco) curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal, forRender, originalVerts, deformedVerts);
+
+               if (cu->flag & CU_DEFORM_FILL && !ob->derivedFinal) {
+                       curve_to_filledpoly(cu, nubase, dispbase);
+               }
        }
-       
-       boundbox_displist(ob);
 }
 
-void imagestodisplist(void)
+void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
 {
-       /* removed */
+       Curve *cu= ob->data;
+       ListBase *dispbase;
+
+       freedisplist(&(ob->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) {
+               DM_set_object_boundbox (ob, ob->derivedFinal);
+       } else {
+               boundbox_displist (ob);
+
+               /* if there is no derivedMesh, object's boundbox is unneeded */
+               if (ob->bb) {
+                       MEM_freeN(ob->bb);
+                       ob->bb= NULL;
+               }
+       }
+}
+
+void makeDispListCurveTypes_forRender(Scene *scene, Object *ob, ListBase *dispbase,
+       DerivedMesh **derivedFinal, int forOrco)
+{
+       do_makeDispListCurveTypes(scene, ob, dispbase, derivedFinal, 1, forOrco);
+}
+
+void makeDispListCurveTypes_forOrco(struct Scene *scene, struct Object *ob, struct ListBase *dispbase)
+{
+       do_makeDispListCurveTypes(scene, ob, dispbase, NULL, 1, 1);
+}
+
+/* add Orco layer to the displist object which has got derived mesh and return orco */
+float *makeOrcoDispList(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender) {
+       float *orco;
+
+       if (derivedFinal == NULL)
+               derivedFinal= ob->derivedFinal;
+
+       if (!derivedFinal->getVertDataArray(derivedFinal, CD_ORCO)) {
+               curve_calc_orcodm(scene, ob, derivedFinal, forRender);
+       }
+
+       orco= derivedFinal->getVertDataArray(derivedFinal, CD_ORCO);
+
+       if(orco) {
+               orco= MEM_dupallocN(orco);
+       }
+
+       return orco;
 }
 
 /* this is confusing, there's also min_max_object, appplying the obmat... */
 static void boundbox_displist(Object *ob)
 {
-       BoundBox *bb=0;
+       BoundBox *bb=NULL;
        float min[3], max[3];
        DispList *dl;
        float *vert;
@@ -1667,10 +1956,10 @@ static void boundbox_displist(Object *ob)
                Curve *cu= ob->data;
                int doit= 0;
 
-               if(cu->bb==0) cu->bb= MEM_callocN(sizeof(BoundBox), "boundbox");        
+               if(cu->bb==NULL) 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;