svn merge -r36900:37028 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender-staging.git] / source / blender / blenkernel / intern / curve.c
index 5015e0cef6cf5764bc63c64d3f5712cd211d20eb..dfc615f4489f6281338b4440e8c62f2fdee1a723 100644 (file)
  * ***** END GPL LICENSE BLOCK *****
  */
 
+/** \file blender/blenkernel/intern/curve.c
+ *  \ingroup bke
+ */
+
+
 #include <math.h>  // floor
 #include <string.h>
 #include <stdlib.h>  
 
 #include "MEM_guardedalloc.h"
+
 #include "BLI_blenlib.h"  
 #include "BLI_math.h"  
+#include "BLI_utildefines.h"
 
 #include "DNA_curve_types.h"  
 #include "DNA_material_types.h"  
@@ -45,6 +52,8 @@
 #include "DNA_key_types.h"  
 #include "DNA_scene_types.h"  
 #include "DNA_vfont_types.h"  
+#include "DNA_meshdata_types.h"  
+#include "DNA_object_types.h"
 
 #include "BKE_animsys.h"
 #include "BKE_anim.h"  
 #include "BKE_key.h"  
 #include "BKE_library.h"  
 #include "BKE_main.h"  
-#include "BKE_object.h"  
-#include "BKE_utildefines.h"  // VECCOPY
+#include "BKE_object.h"
+#include "BKE_material.h"
+
+
+#include "ED_curve.h"
 
 /* globals */
 
@@ -71,12 +83,22 @@ void unlink_curve(Curve *cu)
        
        for(a=0; a<cu->totcol; a++) {
                if(cu->mat[a]) cu->mat[a]->id.us--;
-               cu->mat[a]= 0;
+               cu->mat[a]= NULL;
        }
        if(cu->vfont) cu->vfont->id.us--; 
-       cu->vfont= 0;
+       cu->vfont= NULL;
+
+       if(cu->vfontb) cu->vfontb->id.us--; 
+       cu->vfontb= NULL;
+
+       if(cu->vfonti) cu->vfonti->id.us--; 
+       cu->vfonti= NULL;
+
+       if(cu->vfontbi) cu->vfontbi->id.us--; 
+       cu->vfontbi= NULL;
+       
        if(cu->key) cu->key->id.us--;
-       cu->key= 0;
+       cu->key= NULL;
 }
 
 /* frees editcurve entirely */
@@ -104,13 +126,8 @@ void free_curve(Curve *cu)
        BLI_freelistN(&cu->bev);
        freedisplist(&cu->disp);
        BKE_free_editfont(cu);
-       
-       if(cu->editnurb) {
-               freeNurblist(cu->editnurb);
-               MEM_freeN(cu->editnurb);
-               cu->editnurb= NULL;
-       }
 
+       free_curve_editNurb(cu);
        unlink_curve(cu);
        BKE_free_animdata((ID *)cu);
        
@@ -122,16 +139,16 @@ void free_curve(Curve *cu)
        if(cu->tb) MEM_freeN(cu->tb);
 }
 
-Curve *add_curve(char *name, int type)
+Curve *add_curve(const char *name, int type)
 {
        Curve *cu;
 
        cu= alloc_libblock(&G.main->curve, ID_CU, name);
        
        cu->size[0]= cu->size[1]= cu->size[2]= 1.0;
-       cu->flag= CU_FRONT|CU_BACK|CU_PATH_RADIUS;
+       cu->flag= CU_FRONT|CU_BACK|CU_DEFORM_BOUNDS_OFF|CU_PATH_RADIUS;
        cu->pathlen= 100;
-       cu->resolu= cu->resolv= 12;
+       cu->resolu= cu->resolv= (type == OB_SURF) ? 4 : 12;
        cu->width= 1.0;
        cu->wordspace = 1.0;
        cu->spacing= cu->linedist= 1.0;
@@ -147,8 +164,8 @@ Curve *add_curve(char *name, int type)
                cu->vfont= cu->vfontb= cu->vfonti= cu->vfontbi= get_builtin_font();
                cu->vfont->id.us+=4;
                cu->str= MEM_mallocN(12, "str");
-               strcpy(cu->str, "Text");
-               cu->pos= 4;
+               BLI_strncpy(cu->str, "Text", 12);
+               cu->len= cu->pos= 4;
                cu->strinfo= MEM_callocN(12*sizeof(CharInfo), "strinfo new");
                cu->totbox= cu->actbox= 1;
                cu->tb= MEM_callocN(MAXTEXTBOX*sizeof(TextBox), "textbox");
@@ -164,7 +181,7 @@ Curve *copy_curve(Curve *cu)
        int a;
        
        cun= copy_libblock(cu);
-       cun->nurb.first= cun->nurb.last= 0;
+       cun->nurb.first= cun->nurb.last= NULL;
        duplicateNurblist( &(cun->nurb), &(cu->nurb));
 
        cun->mat= MEM_dupallocN(cu->mat);
@@ -180,12 +197,13 @@ Curve *copy_curve(Curve *cu)
        cun->key= copy_key(cu->key);
        if(cun->key) cun->key->from= (ID *)cun;
        
-       cun->disp.first= cun->disp.last= 0;
-       cun->bev.first= cun->bev.last= 0;
-       cun->path= 0;
+       cun->disp.first= cun->disp.last= NULL;
+       cun->bev.first= cun->bev.last= NULL;
+       cun->path= NULL;
 
        cun->editnurb= NULL;
        cun->editfont= NULL;
+       cun->selboxes= NULL;
 
 #if 0  // XXX old animation system
        /* single user ipo too */
@@ -200,10 +218,22 @@ Curve *copy_curve(Curve *cu)
        return cun;
 }
 
+static void extern_local_curve(Curve *cu)
+{      
+       id_lib_extern((ID *)cu->vfont);
+       id_lib_extern((ID *)cu->vfontb);        
+       id_lib_extern((ID *)cu->vfonti);
+       id_lib_extern((ID *)cu->vfontbi);
+       
+       if(cu->mat) {
+               extern_local_matarar(cu->mat, cu->totcol);
+       }
+}
+
 void make_local_curve(Curve *cu)
 {
-       Object *ob = 0;
-       Curve *cun;
+       Main *bmain= G.main;
+       Object *ob;
        int local=0, lib=0;
        
        /* - when there are only lib users: don't do
@@ -211,46 +241,43 @@ void make_local_curve(Curve *cu)
         * - mixed: do a copy
         */
        
-       if(cu->id.lib==0) return;
-       
-       if(cu->vfont) cu->vfont->id.lib= 0;
-       
+       if(cu->id.lib==NULL) return;
+
        if(cu->id.us==1) {
-               cu->id.lib= 0;
+               cu->id.lib= NULL;
                cu->id.flag= LIB_LOCAL;
-               new_id(0, (ID *)cu, 0);
+
+               new_id(&bmain->curve, (ID *)cu, NULL);
+               extern_local_curve(cu);
                return;
        }
-       
-       ob= G.main->object.first;
-       while(ob) {
-               if(ob->data==cu) {
+
+       for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) {
+               if(ob->data == cu) {
                        if(ob->id.lib) lib= 1;
                        else local= 1;
                }
-               ob= ob->id.next;
        }
-       
+
        if(local && lib==0) {
-               cu->id.lib= 0;
+               cu->id.lib= NULL;
                cu->id.flag= LIB_LOCAL;
-               new_id(0, (ID *)cu, 0);
+
+               new_id(&bmain->curve, (ID *)cu, NULL);
+               extern_local_curve(cu);
        }
        else if(local && lib) {
-               cun= copy_curve(cu);
+               Curve *cun= copy_curve(cu);
                cun->id.us= 0;
-               
-               ob= G.main->object.first;
-               while(ob) {
+
+               for(ob= bmain->object.first; ob; ob= ob->id.next) {
                        if(ob->data==cu) {
-                               
-                               if(ob->id.lib==0) {
+                               if(ob->id.lib==NULL) {
                                        ob->data= cun;
                                        cun->id.us++;
                                        cu->id.us--;
                                }
                        }
-                       ob= ob->id.next;
                }
        }
 }
@@ -279,7 +306,7 @@ void tex_space_curve(Curve *cu)
 {
        DispList *dl;
        BoundBox *bb;
-       float *fp, min[3], max[3], loc[3], size[3];
+       float *fp, min[3], max[3];
        int tot, doit= 0;
        
        if(cu->bb==NULL) cu->bb= MEM_callocN(sizeof(BoundBox), "boundbox");
@@ -306,33 +333,28 @@ void tex_space_curve(Curve *cu)
                min[0] = min[1] = min[2] = -1.0f;
                max[0] = max[1] = max[2] = 1.0f;
        }
-       
-       loc[0]= (min[0]+max[0])/2.0f;
-       loc[1]= (min[1]+max[1])/2.0f;
-       loc[2]= (min[2]+max[2])/2.0f;
-       
-       size[0]= (max[0]-min[0])/2.0f;
-       size[1]= (max[1]-min[1])/2.0f;
-       size[2]= (max[2]-min[2])/2.0f;
 
        boundbox_set_from_min_max(bb, min, max);
 
        if(cu->texflag & CU_AUTOSPACE) {
-               VECCOPY(cu->loc, loc);
-               VECCOPY(cu->size, size);
-               cu->rot[0]= cu->rot[1]= cu->rot[2]= 0.0;
+               mid_v3_v3v3(cu->loc, min, max);
+               cu->size[0]= (max[0]-min[0])/2.0f;
+               cu->size[1]= (max[1]-min[1])/2.0f;
+               cu->size[2]= (max[2]-min[2])/2.0f;
 
-               if(cu->size[0]==0.0) cu->size[0]= 1.0;
-               else if(cu->size[0]>0.0 && cu->size[0]<0.00001) cu->size[0]= 0.00001;
-               else if(cu->size[0]<0.0 && cu->size[0]> -0.00001) cu->size[0]= -0.00001;
+               cu->rot[0]= cu->rot[1]= cu->rot[2]= 0.0f;
+
+               if(cu->size[0]==0.0f) cu->size[0]= 1.0f;
+               else if(cu->size[0]>0.0f && cu->size[0]<0.00001f) cu->size[0]= 0.00001f;
+               else if(cu->size[0]<0.0f && cu->size[0]> -0.00001f) cu->size[0]= -0.00001f;
        
-               if(cu->size[1]==0.0) cu->size[1]= 1.0;
-               else if(cu->size[1]>0.0 && cu->size[1]<0.00001) cu->size[1]= 0.00001;
-               else if(cu->size[1]<0.0 && cu->size[1]> -0.00001) cu->size[1]= -0.00001;
+               if(cu->size[1]==0.0f) cu->size[1]= 1.0f;
+               else if(cu->size[1]>0.0f && cu->size[1]<0.00001f) cu->size[1]= 0.00001f;
+               else if(cu->size[1]<0.0f && cu->size[1]> -0.00001f) cu->size[1]= -0.00001f;
        
-               if(cu->size[2]==0.0) cu->size[2]= 1.0;
-               else if(cu->size[2]>0.0 && cu->size[2]<0.00001) cu->size[2]= 0.00001;
-               else if(cu->size[2]<0.0 && cu->size[2]> -0.00001) cu->size[2]= -0.00001;
+               if(cu->size[2]==0.0f) cu->size[2]= 1.0f;
+               else if(cu->size[2]>0.0f && cu->size[2]<0.00001f) cu->size[2]= 0.00001f;
+               else if(cu->size[2]<0.0f && cu->size[2]> -0.00001f) cu->size[2]= -0.00001f;
 
        }
 }
@@ -373,12 +395,12 @@ int count_curveverts_without_handles(ListBase *nurb)
 void freeNurb(Nurb *nu)
 {
 
-       if(nu==0) return;
+       if(nu==NULL) return;
 
        if(nu->bezt) MEM_freeN(nu->bezt);
-       nu->bezt= 0;
+       nu->bezt= NULL;
        if(nu->bp) MEM_freeN(nu->bp);
-       nu->bp= 0;
+       nu->bp= NULL;
        if(nu->knotsu) MEM_freeN(nu->knotsu);
        nu->knotsu= NULL;
        if(nu->knotsv) MEM_freeN(nu->knotsv);
@@ -394,7 +416,7 @@ void freeNurblist(ListBase *lb)
 {
        Nurb *nu, *next;
 
-       if(lb==0) return;
+       if(lb==NULL) return;
 
        nu= lb->first;
        while(nu) {
@@ -402,7 +424,7 @@ void freeNurblist(ListBase *lb)
                freeNurb(nu);
                nu= next;
        }
-       lb->first= lb->last= 0;
+       lb->first= lb->last= NULL;
 }
 
 Nurb *duplicateNurb(Nurb *nu)
@@ -411,7 +433,7 @@ Nurb *duplicateNurb(Nurb *nu)
        int len;
 
        newnu= (Nurb*)MEM_mallocN(sizeof(Nurb),"duplicateNurb");
-       if(newnu==0) return 0;
+       if(newnu==NULL) return NULL;
        memcpy(newnu, nu, sizeof(Nurb));
 
        if(nu->bezt) {
@@ -577,7 +599,7 @@ static void calcknots(float *knots, short aantal, short order, short type)
                k= 0.0;
                for(a=1;a<=t;a++) {
                        knots[a-1]= k;
-                       if(a>=order && a<=aantal) k+= 1.0;
+                       if(a>=order && a<=aantal) k+= 1.0f;
                }
        }
        else if(type==2) {
@@ -585,15 +607,15 @@ static void calcknots(float *knots, short aantal, short order, short type)
                if(order==4) {
                        k= 0.34;
                        for(a=0;a<t;a++) {
-                               knots[a]= (float)floor(k);
-                               k+= (1.0/3.0);
+                               knots[a]= floorf(k);
+                               k+= (1.0f/3.0f);
                        }
                }
                else if(order==3) {
-                       k= 0.6;
+                       k= 0.6f;
                        for(a=0;a<t;a++) {
-                               if(a>=order && a<=aantal) k+= (0.5);
-                               knots[a]= (float)floor(k);
+                               if(a>=order && a<=aantal) k+= 0.5f;
+                               knots[a]= floorf(k);
                        }
                }
                else {
@@ -607,7 +629,7 @@ static void makecyclicknots(float *knots, short pnts, short order)
 {
        int a, b, order2, c;
 
-       if(knots==0) return;
+       if(knots==NULL) return;
 
        order2=order-1;
 
@@ -617,7 +639,7 @@ static void makecyclicknots(float *knots, short pnts, short order)
                for(a=1; a<order2; a++) {
                        if(knots[b]!= knots[b-a]) break;
                }
-               if(a==order2) knots[pnts+order-2]+= 1.0;
+               if(a==order2) knots[pnts+order-2]+= 1.0f;
        }
 
        b= order;
@@ -630,7 +652,7 @@ static void makecyclicknots(float *knots, short pnts, short order)
 
 
 
-void makeknots(Nurb *nu, short uv)
+static void makeknots(Nurb *nu, short uv)
 {
        if(nu->type == CU_NURBS) {
                if(uv == 1) {
@@ -662,6 +684,16 @@ void makeknots(Nurb *nu, short uv)
        }
 }
 
+void nurbs_knot_calc_u(Nurb *nu)
+{
+       makeknots(nu, 1);
+}
+
+void nurbs_knot_calc_v(Nurb *nu)
+{
+       makeknots(nu, 2);
+}
+
 static void basisNurb(float t, short order, short pnts, float *knots, float *basis, int *start, int *end)
 {
        float d, e;
@@ -699,12 +731,12 @@ static void basisNurb(float t, short order, short pnts, float *knots, float *bas
                if(i2+j>= orderpluspnts) i2= opp2-j;
 
                for(i= i1; i<=i2; i++) {
-                       if(basis[i]!=0.0)
+                       if(basis[i]!=0.0f)
                                d= ((t-knots[i])*basis[i]) / (knots[i+j-1]-knots[i]);
                        else
-                               d= 0.0;
+                               d= 0.0f;
 
-                       if(basis[i+1]!=0.0)
+                       if(basis[i+1] != 0.0f)
                                e= ((knots[i+j]-t)*basis[i+1]) / (knots[i+j]-knots[i+1]);
                        else
                                e= 0.0;
@@ -717,7 +749,7 @@ static void basisNurb(float t, short order, short pnts, float *knots, float *bas
        *end= 0;
 
        for(i=i1; i<=i2; i++) {
-               if(basis[i]>0.0) {
+               if(basis[i] > 0.0f) {
                        *end= i;
                        if(*start==1000) *start= i;
                }
@@ -725,16 +757,16 @@ static void basisNurb(float t, short order, short pnts, float *knots, float *bas
 }
 
 
-void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride
+void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride, int resolu, int resolv)
 /* coord_array  has to be 3*4*resolu*resolv in size, and zero-ed */
 {
        BPoint *bp;
        float *basisu, *basis, *basisv, *sum, *fp, *in;
        float u, v, ustart, uend, ustep, vstart, vend, vstep, sumdiv;
-       int i, j, iofs, jofs, cycl, len, resolu, resolv;
+       int i, j, iofs, jofs, cycl, len, curu, curv;
        int istart, iend, jsta, jen, *jstart, *jend, ratcomp;
        
-       int totu = nu->pntsu*nu->resolu, totv = nu->pntsv*nu->resolv;
+       int totu = nu->pntsu*resolu, totv = nu->pntsv*resolv;
        
        if(nu->knotsu==NULL || nu->knotsv==NULL) return;
        if(nu->orderu>nu->pntsu) return;
@@ -759,7 +791,7 @@ void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride)
        i= nu->pntsu*nu->pntsv;
        ratcomp=0;
        while(i--) {
-               if(bp->vec[3]!=1.0) {
+               if(bp->vec[3] != 1.0f) {
                        ratcomp= 1;
                        break;
                }
@@ -791,9 +823,9 @@ void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride)
        else cycl= 0;
        v= vstart;
        basis= basisv;
-       resolv= totv;
-       while(resolv--) {
-               basisNurb(v, nu->orderv, (short)(nu->pntsv+cycl), nu->knotsv, basis, jstart+resolv, jend+resolv);
+       curv= totv;
+       while(curv--) {
+               basisNurb(v, nu->orderv, (short)(nu->pntsv+cycl), nu->knotsv, basis, jstart+curv, jend+curv);
                basis+= KNOTSV(nu);
                v+= vstep;
        }
@@ -802,17 +834,17 @@ void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride)
        else cycl= 0;
        in= coord_array;
        u= ustart;
-       resolu= totu;
-       while(resolu--) {
+       curu= totu;
+       while(curu--) {
 
                basisNurb(u, nu->orderu, (short)(nu->pntsu+cycl), nu->knotsu, basisu, &istart, &iend);
 
                basis= basisv;
-               resolv= totv;
-               while(resolv--) {
+               curv= totv;
+               while(curv--) {
 
-                       jsta= jstart[resolv];
-                       jen= jend[resolv];
+                       jsta= jstart[curv];
+                       jen= jend[curv];
 
                        /* calculate sum */
                        sumdiv= 0.0;
@@ -865,7 +897,7 @@ void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride)
                                        }
                                        else bp++;
 
-                                       if(*fp!=0.0) {
+                                       if(*fp != 0.0f) {
                                                in[0]+= (*fp) * bp->vec[0];
                                                in[1]+= (*fp) * bp->vec[1];
                                                in[2]+= (*fp) * bp->vec[2];
@@ -900,7 +932,7 @@ void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radiu
 
        if(nu->knotsu==NULL) return;
        if(nu->orderu>nu->pntsu) return;
-       if(coord_array==0) return;
+       if(coord_array==NULL) return;
 
        /* allocate and initialize */
        len= nu->pntsu;
@@ -941,7 +973,7 @@ void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radiu
                        *fp= basisu[i]*bp->vec[3];
                        sumdiv+= *fp;
                }
-               if(sumdiv!=0.0) if(sumdiv<0.999 || sumdiv>1.001) {
+               if(sumdiv != 0.0f) if(sumdiv < 0.999f || sumdiv > 1.001f) {
                        /* is normalizing needed? */
                        fp= sum;
                        for(i= istart; i<=iend; i++, fp++) {
@@ -957,7 +989,7 @@ void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radiu
                        if(i>=nu->pntsu) bp= nu->bp+(i - nu->pntsu);
                        else bp++;
 
-                       if(*fp!=0.0) {
+                       if(*fp != 0.0f) {
                                
                                coord_fp[0]+= (*fp) * bp->vec[0];
                                coord_fp[1]+= (*fp) * bp->vec[1];
@@ -1002,19 +1034,19 @@ void forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int i
        rt2= 3.0f*(q0-2.0f*q1+q2)/f;
        f*= it;
        rt3= (q3-q0+3.0f*(q1-q2))/f;
-       
-         q0= rt0;
+
+       q0= rt0;
        q1= rt1+rt2+rt3;
        q2= 2*rt2+6*rt3;
        q3= 6*rt3;
-  
-         for(a=0; a<=it; a++) {
+
+       for(a=0; a<=it; a++) {
                *p= q0;
                p = (float *)(((char *)p)+stride);
                q0+= q1;
-                q1+= q2;
-                q2+= q3;
-        }
+               q1+= q2;
+               q2+= q3;
+       }
 }
 
 static void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float *p3, float *p, int it, int stride)
@@ -1024,7 +1056,7 @@ static void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float
         *
         * This could also be optimized like forward_diff_bezier */
        int a;
-         for(a=0; a<=it; a++) {
+       for(a=0; a<=it; a++) {
                float t = (float)a / (float)it;
 
                int i;
@@ -1033,17 +1065,20 @@ static void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float
                }
                normalize_v3(p);
                p = (float *)(((char *)p)+stride);
-        }
+       }
 }
 
 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
 
 float *make_orco_surf(Object *ob)
 {
+       /* Note: this function is used in convertblender only atm, so
+        * suppose nonzero curve's render resolution should always be used */
        Curve *cu= ob->data;
        Nurb *nu;
        int a, b, tot=0;
        int sizeu, sizev;
+       int resolu, resolv;
        float *fp, *coord_array;
        
        /* first calculate the size of the datablock */
@@ -1057,12 +1092,15 @@ float *make_orco_surf(Object *ob)
                
                See also convertblender.c: init_render_surf()
                */
+
+               resolu= cu->resolu_ren ? cu->resolu_ren : nu->resolu;
+               resolv= cu->resolv_ren ? cu->resolv_ren : nu->resolv;
                
-               sizeu = nu->pntsu*nu->resolu; 
-               sizev = nu->pntsv*nu->resolv;
+               sizeu = nu->pntsu*resolu;
+               sizev = nu->pntsv*resolv;
                if (nu->flagu & CU_NURB_CYCLIC) sizeu++;
                if (nu->flagv & CU_NURB_CYCLIC) sizev++;
-                if(nu->pntsv>1) tot+= sizeu * sizev;
+               if(nu->pntsv>1) tot+= sizeu * sizev;
                
                nu= nu->next;
        }
@@ -1071,9 +1109,12 @@ float *make_orco_surf(Object *ob)
        
        nu= cu->nurb.first;
        while(nu) {
+               resolu= cu->resolu_ren ? cu->resolu_ren : nu->resolu;
+               resolv= cu->resolv_ren ? cu->resolv_ren : nu->resolv;
+
                if(nu->pntsv>1) {
-                       sizeu = nu->pntsu*nu->resolu; 
-                       sizev = nu->pntsv*nu->resolv;
+                       sizeu = nu->pntsu*resolu;
+                       sizev = nu->pntsv*resolv;
                        if (nu->flagu & CU_NURB_CYCLIC) sizeu++;
                        if (nu->flagv & CU_NURB_CYCLIC) sizev++;
                        
@@ -1094,10 +1135,10 @@ float *make_orco_surf(Object *ob)
                                }
                        }
                        else {
-                               float *_tdata= MEM_callocN((nu->pntsu*nu->resolu) * (nu->pntsv*nu->resolv) *3*sizeof(float), "temp data");
+                               float *_tdata= MEM_callocN((nu->pntsu*resolu) * (nu->pntsv*resolv) *3*sizeof(float), "temp data");
                                float *tdata= _tdata;
                                
-                               makeNurbfaces(nu, tdata, 0);
+                               makeNurbfaces(nu, tdata, 0, resolu, resolv);
                                
                                for(b=0; b<sizeu; b++) {
                                        int use_b= b;
@@ -1109,7 +1150,7 @@ float *make_orco_surf(Object *ob)
                                                if (a==sizev-1 && (nu->flagv & CU_NURB_CYCLIC))
                                                        use_a= 0;
                                                
-                                               tdata = _tdata + 3 * (use_b * (nu->pntsv*nu->resolv) + use_a);
+                                               tdata = _tdata + 3 * (use_b * (nu->pntsv*resolv) + use_a);
                                                
                                                fp[0]= (tdata[0]-cu->loc[0])/cu->size[0];
                                                fp[1]= (tdata[1]-cu->loc[1])/cu->size[1];
@@ -1187,8 +1228,8 @@ float *make_orco_curve(Scene *scene, Object *ob)
                        for (u=0; u<sizev; u++) {
                                for (v=0; v<sizeu; v++,fp+=3) {
                                        if (cu->flag & CU_UV_ORCO) {
-                                               fp[0]= 2.0f*u/(dl->parts-1) - 1.0f;
-                                               fp[1]= 2.0f*v/(dl->nr-1) - 1.0f;
+                                               fp[0]= 2.0f*u/(sizev - 1) - 1.0f;
+                                               fp[1]= 2.0f*v/(sizeu - 1) - 1.0f;
                                                fp[2]= 0.0;
                                        } else {
                                                float *vert;
@@ -1229,8 +1270,10 @@ void makebevelcurve(Scene *scene, Object *ob, ListBase *disp, int forRender)
 // XXX if( ob == obedit && ob->type == OB_FONT ) return;
 
        if(cu->bevobj) {
+               if (cu->bevobj->type!=OB_CURVE) return;
+
                bevcu= cu->bevobj->data;
-               if(bevcu->ext1==0.0 && bevcu->ext2==0.0) {
+               if(bevcu->ext1==0.0f && bevcu->ext2==0.0f) {
                        ListBase bevdisp= {NULL, NULL};
                        facx= cu->bevobj->size[0];
                        facy= cu->bevobj->size[1];
@@ -1239,10 +1282,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;
-                               if(dl==0) {
+                               dl= cu->bevobj->disp.first;
+                               if(dl==NULL) {
                                        makeDispListCurveTypes(scene, cu->bevobj, 0);
-                                       dl= bevcu->disp.first;
+                                       dl= cu->bevobj->disp.first;
                                }
                        }
 
@@ -1271,10 +1314,10 @@ void makebevelcurve(Scene *scene, Object *ob, ListBase *disp, int forRender)
                        freedisplist(&bevdisp);
                }
        }
-       else if(cu->ext1==0.0 && cu->ext2==0.0) {
+       else if(cu->ext1==0.0f && cu->ext2==0.0f) {
                ;
        }
-       else if(cu->ext2==0.0) {
+       else if(cu->ext2==0.0f) {
                dl= MEM_callocN(sizeof(DispList), "makebevelcurve2");
                dl->verts= MEM_mallocN(2*3*sizeof(float), "makebevelcurve2");
                BLI_addtail(disp, dl);
@@ -1303,13 +1346,13 @@ void makebevelcurve(Scene *scene, Object *ob, ListBase *disp, int forRender)
 
                /* a circle */
                fp= dl->verts;
-               dangle= (2.0f*M_PI/(nr));
+               dangle= (2.0f*(float)M_PI/(nr));
                angle= -(nr-1)*dangle;
                
                for(a=0; a<nr; a++) {
                        fp[0]= 0.0;
-                       fp[1]= (float)(cos(angle)*(cu->ext2));
-                       fp[2]= (float)(sin(angle)*(cu->ext2)) - cu->ext1;
+                       fp[1]= (cosf(angle)*(cu->ext2));
+                       fp[2]= (sinf(angle)*(cu->ext2)) - cu->ext1;
                        angle+= dangle;
                        fp+= 3;
                }
@@ -1340,15 +1383,15 @@ void makebevelcurve(Scene *scene, Object *ob, ListBase *disp, int forRender)
 
                        for(a=0; a<nr; a++) {
                                fp[0]= 0.0;
-                               fp[1]= (float)(cos(angle)*(cu->ext2));
-                               fp[2]= (float)(sin(angle)*(cu->ext2)) - cu->ext1;
+                               fp[1]= (float)(cosf(angle)*(cu->ext2));
+                               fp[2]= (float)(sinf(angle)*(cu->ext2)) - cu->ext1;
                                angle+= dangle;
                                fp+= 3;
                        }
                }
                
                /* part 2, sidefaces */
-               if(cu->ext1!=0.0) {
+               if(cu->ext1!=0.0f) {
                        nr= 2;
                        
                        dl= MEM_callocN(sizeof(DispList), "makebevelcurve p2");
@@ -1398,8 +1441,8 @@ void makebevelcurve(Scene *scene, Object *ob, ListBase *disp, int forRender)
 
                        for(a=0; a<nr; a++) {
                                fp[0]= 0.0;
-                               fp[1]= (float)(cos(angle)*(cu->ext2));
-                               fp[2]= (float)(sin(angle)*(cu->ext2)) + cu->ext1;
+                               fp[1]= (float)(cosf(angle)*(cu->ext2));
+                               fp[2]= (float)(sinf(angle)*(cu->ext2)) + cu->ext1;
                                angle+= dangle;
                                fp+= 3;
                        }
@@ -1418,7 +1461,7 @@ static int cu_isectLL(float *v1, float *v2, float *v3, float *v4, short cox, sho
        float deler;
 
        deler= (v1[cox]-v2[cox])*(v3[coy]-v4[coy])-(v3[cox]-v4[cox])*(v1[coy]-v2[coy]);
-       if(deler==0.0) return -1;
+       if(deler==0.0f) return -1;
 
        *labda= (v1[coy]-v3[coy])*(v3[cox]-v4[cox])-(v1[cox]-v3[cox])*(v3[coy]-v4[coy]);
        *labda= -(*labda/deler);
@@ -1433,8 +1476,8 @@ static int cu_isectLL(float *v1, float *v2, float *v3, float *v4, short cox, sho
        vec[cox]= *labda*(v2[cox]-v1[cox])+v1[cox];
        vec[coy]= *labda*(v2[coy]-v1[coy])+v1[coy];
 
-       if(*labda>=0.0 && *labda<=1.0 && *mu>=0.0 && *mu<=1.0) {
-               if(*labda==0.0 || *labda==1.0 || *mu==0.0 || *mu==1.0) return 1;
+       if(*labda>=0.0f && *labda<=1.0f && *mu>=0.0f && *mu<=1.0f) {
+               if(*labda==0.0f || *labda==1.0f || *mu==0.0f || *mu==1.0f) return 1;
                return 2;
        }
        return 0;
@@ -1479,7 +1522,7 @@ static short bevelinside(BevList *bl1,BevList *bl2)
                                /* if lab==0.0 or lab==1.0 then the edge intersects exactly a transition
                                           only allow for one situation: we choose lab= 1.0
                                 */
-                               if(mode>=0 && lab!=0.0) {
+                               if(mode >= 0 && lab != 0.0f) {
                                        if(vec[0]<hvec1[0]) links++;
                                        else rechts++;
                                }
@@ -1517,8 +1560,8 @@ static void calc_bevel_sin_cos(float x1, float y1, float x2, float y2, float *si
 
        t01= (float)sqrt(x1*x1+y1*y1);
        t02= (float)sqrt(x2*x2+y2*y2);
-       if(t01==0.0) t01= 1.0;
-       if(t02==0.0) t02= 1.0;
+       if(t01==0.0f) t01= 1.0f;
+       if(t02==0.0f) t02= 1.0f;
 
        x1/=t01; 
        y1/=t01;
@@ -1530,7 +1573,7 @@ static void calc_bevel_sin_cos(float x1, float y1, float x2, float y2, float *si
        else t02= (saacos(t02))/2.0f;
 
        t02= (float)sin(t02);
-       if(t02==0.0) t02= 1.0;
+       if(t02==0.0f) t02= 1.0f;
 
        x3= x1-x2;
        y3= y1-y2;
@@ -1578,7 +1621,7 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *
        
        for(a=0; a<resolu; a++, fac+= dfac) {
                if (tilt_array) {
-                       if (nu->tilt_interp==3) { /* May as well support for tilt also 2.47 ease interp */
+                       if (nu->tilt_interp==KEY_CU_EASE) { /* May as well support for tilt also 2.47 ease interp */
                                *tilt_array = prevbezt->alfa + (bezt->alfa - prevbezt->alfa)*(3.0f*fac*fac - 2.0f*fac*fac*fac);
                        } else {
                                key_curve_position_weights(fac, t, nu->tilt_interp);
@@ -1589,7 +1632,7 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *
                }
                
                if (radius_array) {
-                       if (nu->radius_interp==3) {
+                       if (nu->radius_interp==KEY_CU_EASE) {
                                /* Support 2.47 ease interp
                                 * Note! - this only takes the 2 points into account,
                                 * giving much more localized results to changes in radius, sometimes you want that */
@@ -1667,7 +1710,7 @@ static void bevel_list_flip_tangents(BevList *bl)
 
        nr= bl->nr;
        while(nr--) {
-               if(RAD2DEG(angle_v2v2(bevp0->tan, bevp1->tan)) > 90)
+               if(RAD2DEGF(angle_v2v2(bevp0->tan, bevp1->tan)) > 90.0f)
                        negate_v3(bevp1->tan);
 
                bevp0= bevp1;
@@ -1678,13 +1721,12 @@ static void bevel_list_flip_tangents(BevList *bl)
 /* apply user tilt */
 static void bevel_list_apply_tilt(BevList *bl)
 {
-       BevPoint *bevp2, *bevp1, *bevp0;
+       BevPoint *bevp2, *bevp1;
        int nr;
        float q[4];
 
        bevp2= (BevPoint *)(bl+1);
        bevp1= bevp2+(bl->nr-1);
-       bevp0= bevp1-1;
 
        nr= bl->nr;
        while(nr--) {
@@ -1692,7 +1734,6 @@ static void bevel_list_apply_tilt(BevList *bl)
                mul_qt_qtqt(bevp1->quat, q, bevp1->quat);
                normalize_qt(bevp1->quat);
 
-               bevp0= bevp1;
                bevp1= bevp2;
                bevp2++;
        }
@@ -1717,7 +1758,7 @@ static void bevel_list_smooth(BevList *bl, int smooth_iter)
 
                if(bl->poly== -1) { /* check its not cyclic */
                        /* skip the first point */
-                       bevp0= bevp1;
+                       /* bevp0= bevp1; */
                        bevp1= bevp2;
                        bevp2++;
                        nr--;
@@ -1748,7 +1789,7 @@ static void bevel_list_smooth(BevList *bl, int smooth_iter)
                        normalize_qt(bevp1->quat);
 
 
-                       bevp0= bevp1;
+                       /* bevp0= bevp1; */ /* UNUSED */
                        bevp1= bevp2;
                        bevp2++;
                }
@@ -1782,8 +1823,6 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl)
        int nr;
        float q[4];
 
-       float cross_tmp[3];
-
        bevel_list_calc_bisect(bl);
 
        bevp2= (BevPoint *)(bl+1);
@@ -1800,6 +1839,7 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl)
                        float angle= angle_normalized_v3v3(bevp0->dir, bevp1->dir);
 
                        if(angle > 0.0f) { /* otherwise we can keep as is */
+                               float cross_tmp[3];
                                cross_v3_v3v3(cross_tmp, bevp0->dir, bevp1->dir);
                                axis_angle_to_quat(q, cross_tmp, angle);
                                mul_qt_qtqt(bevp1->quat, q, bevp0->quat);
@@ -1820,7 +1860,7 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl)
                 * do this by calculating the tilt angle difference, then apply
                 * the rotation gradually over the entire curve
                 *
-                * note that the split is between last and second last, rather then first/last as youd expect.
+                * note that the split is between last and second last, rather than first/last as youd expect.
                 *
                 * real order is like this
                 * 0,1,2,3,4 --> 1,2,3,4,0
@@ -1858,7 +1898,7 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl)
                /* flip rotation if needs be */
                cross_v3_v3v3(cross_tmp, vec_1, vec_2);
                normalize_v3(cross_tmp);
-               if(angle_normalized_v3v3(bevp_first->dir, cross_tmp) < 90/(180.0/M_PI))
+               if(angle_normalized_v3v3(bevp_first->dir, cross_tmp) < 90.0f/(float)(180.0/M_PI))
                        angle = -angle;
 
                bevp2= (BevPoint *)(bl+1);
@@ -1927,7 +1967,7 @@ static void make_bevel_list_3D_tangent(BevList *bl)
                normalize_v3(cross_tmp);
                tri_to_quat( bevp1->quat,zero, cross_tmp, bevp1->tan); /* XXX - could be faster */
 
-               bevp0= bevp1;
+               /* bevp0= bevp1; */ /* UNUSED */
                bevp1= bevp2;
                bevp2++;
        }
@@ -2008,8 +2048,10 @@ void makeBevelList(Object *ob)
        /* STEP 1: MAKE POLYS  */
 
        BLI_freelistN(&(cu->bev));
-       if(cu->editnurb && ob->type!=OB_FONT) nu= cu->editnurb->first;
-       else nu= cu->nurb.first;
+       if(cu->editnurb && ob->type!=OB_FONT) {
+               ListBase *nurbs= ED_curve_editnurbs(cu);
+               nu= nurbs->first;
+       } else nu= cu->nurb.first;
        
        while(nu) {
                
@@ -2250,7 +2292,7 @@ void makeBevelList(Object *ob)
 
                                inp= (bevp1->vec[0]- bevp0->vec[0]) * (bevp0->vec[1]- bevp2->vec[1]) + (bevp0->vec[1]- bevp1->vec[1]) * (bevp0->vec[0]- bevp2->vec[0]);
 
-                               if(inp>0.0) sd->dir= 1;
+                               if(inp > 0.0f) sd->dir= 1;
                                else sd->dir= 0;
 
                                sd++;
@@ -2395,7 +2437,7 @@ void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode)
 
        p2= bezt->vec[1];
 
-       if(prev==0) {
+       if(prev==NULL) {
                p3= next->vec[1];
                pt[0]= 2*p2[0]- p3[0];
                pt[1]= 2*p2[1]- p3[1];
@@ -2404,7 +2446,7 @@ void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode)
        }
        else p1= prev->vec[1];
 
-       if(next==0) {
+       if(next==NULL) {
                pt[0]= 2*p2[0]- p1[0];
                pt[1]= 2*p2[1]- p1[1];
                pt[2]= 2*p2[2]- p1[2];
@@ -2450,11 +2492,11 @@ void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode)
                                if(mode==2 && next && prev) {   // keep horizontal if extrema
                                        float ydiff1= prev->vec[1][1] - bezt->vec[1][1];
                                        float ydiff2= next->vec[1][1] - bezt->vec[1][1];
-                                       if( (ydiff1<=0.0 && ydiff2<=0.0) || (ydiff1>=0.0 && ydiff2>=0.0) ) {
+                                       if( (ydiff1 <= 0.0f && ydiff2 <= 0.0f) || (ydiff1 >= 0.0f && ydiff2 >= 0.0f) ) {
                                                bezt->vec[0][1]= bezt->vec[1][1];
                                        }
                                        else {                                          // handles should not be beyond y coord of two others
-                                               if(ydiff1<=0.0) { 
+                                               if(ydiff1 <= 0.0f) {
                                                        if(prev->vec[1][1] > bezt->vec[0][1]) {
                                                                bezt->vec[0][1]= prev->vec[1][1]; 
                                                                leftviolate= 1;
@@ -2478,11 +2520,11 @@ void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode)
                                if(mode==2 && next && prev) {   // keep horizontal if extrema
                                        float ydiff1= prev->vec[1][1] - bezt->vec[1][1];
                                        float ydiff2= next->vec[1][1] - bezt->vec[1][1];
-                                       if( (ydiff1<=0.0 && ydiff2<=0.0) || (ydiff1>=0.0 && ydiff2>=0.0) ) {
+                                       if( (ydiff1 <= 0.0f && ydiff2 <= 0.0f) || (ydiff1 >= 0.0f && ydiff2 >= 0.0f) ) {
                                                bezt->vec[2][1]= bezt->vec[1][1];
                                        }
                                        else {                                          // handles should not be beyond y coord of two others
-                                               if(ydiff1<=0.0) { 
+                                               if(ydiff1 <= 0.0f) {
                                                        if(next->vec[1][1] < bezt->vec[2][1]) {
                                                                bezt->vec[2][1]= next->vec[1][1]; 
                                                                rightviolate= 1;
@@ -2523,17 +2565,17 @@ void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode)
        }
 
        if(bezt->h1==HD_VECT) { /* vector */
-               dx/=3.0
-               dy/=3.0
-               dz/=3.0;
+               dx/=3.0f;
+               dy/=3.0f;
+               dz/=3.0f;
                *(p2-3)= *p2-dx;
                *(p2-2)= *(p2+1)-dy;
                *(p2-1)= *(p2+2)-dz;
        }
        if(bezt->h2==HD_VECT) {
-               dx1/=3.0
-               dy1/=3.0
-               dz1/=3.0;
+               dx1/=3.0f;
+               dy1/=3.0f;
+               dz1/=3.0f;
                *(p2+3)= *p2+dx1;
                *(p2+4)= *(p2+1)+dy1;
                *(p2+5)= *(p2+2)+dz1;
@@ -2541,8 +2583,8 @@ void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode)
 
        len2= len_v3v3(p2, p2+3);
        len1= len_v3v3(p2, p2-3);
-       if(len1==0.0) len1=1.0;
-       if(len2==0.0) len2=1.0;
+       if(len1==0.0f) len1= 1.0f;
+       if(len2==0.0f) len2= 1.0f;
 
        if(bezt->f1 & SELECT) { /* order of calculation */
                if(bezt->h2==HD_ALIGN) {        /* aligned */
@@ -2585,7 +2627,7 @@ void calchandlesNurb(Nurb *nu) /* first, if needed, set handle flags */
        a= nu->pntsu;
        bezt= nu->bezt;
        if(nu->flagu & CU_NURB_CYCLIC) prev= bezt+(a-1);
-       else prev= 0;
+       else prev= NULL;
        next= bezt+1;
 
        while(a--) {
@@ -2593,7 +2635,7 @@ void calchandlesNurb(Nurb *nu) /* first, if needed, set handle flags */
                prev= bezt;
                if(a==1) {
                        if(nu->flagu & CU_NURB_CYCLIC) next= nu->bezt;
-                       else next= 0;
+                       else next= NULL;
                }
                else next++;
 
@@ -2652,7 +2694,7 @@ void autocalchandlesNurb(Nurb *nu, int flag)
        BezTriple *bezt2, *bezt1, *bezt0;
        int i, align, leftsmall, rightsmall;
 
-       if(nu==0 || nu->bezt==0) return;
+       if(nu==NULL || nu->bezt==NULL) return;
        
        bezt2 = nu->bezt;
        bezt1 = bezt2 + (nu->pntsu-1);
@@ -2667,18 +2709,18 @@ void autocalchandlesNurb(Nurb *nu, int flag)
                if(flag==0 || (bezt1->f1 & flag) ) {
                        bezt1->h1= 0;
                        /* distance too short: vectorhandle */
-                       if( len_v3v3( bezt1->vec[1], bezt0->vec[1] ) < 0.0001) {
+                       if( len_v3v3( bezt1->vec[1], bezt0->vec[1] ) < 0.0001f) {
                                bezt1->h1= HD_VECT;
                                leftsmall= 1;
                        }
                        else {
                                /* aligned handle? */
-                               if(dist_to_line_v2(bezt1->vec[1], bezt1->vec[0], bezt1->vec[2]) < 0.0001) {
+                               if(dist_to_line_v2(bezt1->vec[1], bezt1->vec[0], bezt1->vec[2]) < 0.0001f) {
                                        align= 1;
                                        bezt1->h1= HD_ALIGN;
                                }
                                /* or vector handle? */
-                               if(dist_to_line_v2(bezt1->vec[0], bezt1->vec[1], bezt0->vec[1]) < 0.0001)
+                               if(dist_to_line_v2(bezt1->vec[0], bezt1->vec[1], bezt0->vec[1]) < 0.0001f)
                                        bezt1->h1= HD_VECT;
                                
                        }
@@ -2687,7 +2729,7 @@ void autocalchandlesNurb(Nurb *nu, int flag)
                if(flag==0 || (bezt1->f3 & flag) ) {
                        bezt1->h2= 0;
                        /* distance too short: vectorhandle */
-                       if( len_v3v3( bezt1->vec[1], bezt2->vec[1] ) < 0.0001) {
+                       if( len_v3v3( bezt1->vec[1], bezt2->vec[1] ) < 0.0001f) {
                                bezt1->h2= HD_VECT;
                                rightsmall= 1;
                        }
@@ -2696,7 +2738,7 @@ void autocalchandlesNurb(Nurb *nu, int flag)
                                if(align) bezt1->h2= HD_ALIGN;
 
                                /* or vector handle? */
-                               if(dist_to_line_v2(bezt1->vec[2], bezt1->vec[1], bezt2->vec[1]) < 0.0001)
+                               if(dist_to_line_v2(bezt1->vec[2], bezt1->vec[1], bezt2->vec[1]) < 0.0001f)
                                        bezt1->h2= HD_VECT;
                                
                        }
@@ -2877,38 +2919,41 @@ void switchdirectionNurb(Nurb *nu)
                        bp2--;
                }
                if(nu->type == CU_NURBS) {
-                       /* inverse knots */
-                       a= KNOTSU(nu);
-                       fp1= nu->knotsu;
-                       fp2= fp1+(a-1);
-                       a/= 2;
-                       while(fp1!=fp2 && a>0) {
-                               SWAP(float, *fp1, *fp2);
-                               a--;
-                               fp1++; 
-                               fp2--;
-                       }
-                       /* and make in increasing order again */
-                       a= KNOTSU(nu);
-                       fp1= nu->knotsu;
-                       fp2=tempf= MEM_mallocN(sizeof(float)*a, "switchdirect");
-                       while(a--) {
-                               fp2[0]= fabs(fp1[1]-fp1[0]);
-                               fp1++;
-                               fp2++;
-                       }
-       
-                       a= KNOTSU(nu)-1;
-                       fp1= nu->knotsu;
-                       fp2= tempf;
-                       fp1[0]= 0.0;
-                       fp1++;
-                       while(a--) {
-                               fp1[0]= fp1[-1]+fp2[0];
+                       /* no knots for too short paths */
+                       if(nu->knotsu) {
+                               /* inverse knots */
+                               a= KNOTSU(nu);
+                               fp1= nu->knotsu;
+                               fp2= fp1+(a-1);
+                               a/= 2;
+                               while(fp1!=fp2 && a>0) {
+                                       SWAP(float, *fp1, *fp2);
+                                       a--;
+                                       fp1++; 
+                                       fp2--;
+                               }
+                               /* and make in increasing order again */
+                               a= KNOTSU(nu);
+                               fp1= nu->knotsu;
+                               fp2=tempf= MEM_mallocN(sizeof(float)*a, "switchdirect");
+                               while(a--) {
+                                       fp2[0]= fabs(fp1[1]-fp1[0]);
+                                       fp1++;
+                                       fp2++;
+                               }
+               
+                               a= KNOTSU(nu)-1;
+                               fp1= nu->knotsu;
+                               fp2= tempf;
+                               fp1[0]= 0.0;
                                fp1++;
-                               fp2++;
+                               while(a--) {
+                                       fp1[0]= fp1[-1]+fp2[0];
+                                       fp1++;
+                                       fp2++;
+                               }
+                               MEM_freeN(tempf);
                        }
-                       MEM_freeN(tempf);
                }
        }
        else {
@@ -2931,7 +2976,7 @@ void switchdirectionNurb(Nurb *nu)
 }
 
 
-float (*curve_getVertexCos(Curve *cu, ListBase *lb, int *numVerts_r))[3]
+float (*curve_getVertexCos(Curve *UNUSED(cu), ListBase *lb, int *numVerts_r))[3]
 {
        int i, numVerts = *numVerts_r = count_curveverts(lb);
        float *co, (*cos)[3] = MEM_mallocN(sizeof(*cos)*numVerts, "cu_vcos");
@@ -2959,7 +3004,7 @@ float (*curve_getVertexCos(Curve *cu, ListBase *lb, int *numVerts_r))[3]
        return cos;
 }
 
-void curve_applyVertexCos(Curve *cu, ListBase *lb, float (*vertexCos)[3])
+void curve_applyVertexCos(Curve *UNUSED(cu), ListBase *lb, float (*vertexCos)[3])
 {
        float *co = vertexCos[0];
        Nurb *nu;
@@ -2984,7 +3029,7 @@ void curve_applyVertexCos(Curve *cu, ListBase *lb, float (*vertexCos)[3])
        }
 }
 
-float (*curve_getKeyVertexCos(Curve *cu, ListBase *lb, float *key))[3]
+float (*curve_getKeyVertexCos(Curve *UNUSED(cu), ListBase *lb, float *key))[3]
 {
        int i, numVerts = count_curveverts(lb);
        float *co, (*cos)[3] = MEM_mallocN(sizeof(*cos)*numVerts, "cu_vcos");
@@ -2999,7 +3044,7 @@ float (*curve_getKeyVertexCos(Curve *cu, ListBase *lb, float *key))[3]
                                VECCOPY(co, key); co+=3; key+=3;
                                VECCOPY(co, key); co+=3; key+=3;
                                VECCOPY(co, key); co+=3; key+=3;
-                               key++; /* skip tilt */
+                               key+=3; /* skip tilt */
                        }
                }
                else {
@@ -3015,7 +3060,7 @@ float (*curve_getKeyVertexCos(Curve *cu, ListBase *lb, float *key))[3]
        return cos;
 }
 
-void curve_applyKeyVertexTilts(Curve *cu, ListBase *lb, float *key)
+void curve_applyKeyVertexTilts(Curve *UNUSED(cu), ListBase *lb, float *key)
 {
        Nurb *nu;
        int i;
@@ -3027,7 +3072,7 @@ void curve_applyKeyVertexTilts(Curve *cu, ListBase *lb, float *key)
                        for(i=0; i<nu->pntsu; i++,bezt++) {
                                key+=3*3;
                                bezt->alfa= *key;
-                               key++;
+                               key+=3;
                        }
                }
                else {
@@ -3099,5 +3144,110 @@ int clamp_nurb_order_v( struct Nurb *nu)
        return change;
 }
 
+/* Get edit nurbs or normal nurbs list */
+ListBase *BKE_curve_nurbs(Curve *cu)
+{
+       if (cu->editnurb) {
+               return ED_curve_editnurbs(cu);
+       }
+
+       return &cu->nurb;
+}
+
+
+/* basic vertex data functions */
+int minmax_curve(Curve *cu, float min[3], float max[3])
+{
+       ListBase *nurb_lb= BKE_curve_nurbs(cu);
+       Nurb *nu;
+
+       for(nu= nurb_lb->first; nu; nu= nu->next)
+               minmaxNurb(nu, min, max);
+
+       return (nurb_lb->first != NULL);
+}
+
+int curve_center_median(Curve *cu, float cent[3])
+{
+       ListBase *nurb_lb= BKE_curve_nurbs(cu);
+       Nurb *nu;
+       int total= 0;
+
+       zero_v3(cent);
+
+       for(nu= nurb_lb->first; nu; nu= nu->next) {
+               int i;
+
+               if(nu->type == CU_BEZIER) {
+                       BezTriple *bezt;
+                       i= nu->pntsu;
+                       total += i * 3;
+                       for(bezt= nu->bezt; i--; bezt++) {
+                               add_v3_v3(cent, bezt->vec[0]);
+                               add_v3_v3(cent, bezt->vec[1]);
+                               add_v3_v3(cent, bezt->vec[2]);
+                       }
+               }
+               else {
+                       BPoint *bp;
+                       i= nu->pntsu*nu->pntsv;
+                       total += i;
+                       for(bp= nu->bp; i--; bp++) {
+                               add_v3_v3(cent, bp->vec);
+                       }
+               }
+       }
+
+       mul_v3_fl(cent, 1.0f/(float)total);
+
+       return (total != 0);
+}
+
+int curve_center_bounds(Curve *cu, float cent[3])
+{
+       float min[3], max[3];
+       INIT_MINMAX(min, max);
+       if(minmax_curve(cu, min, max)) {
+               mid_v3_v3v3(cent, min, max);
+               return 1;
+       }
+
+       return 0;
+}
+
+void curve_translate(Curve *cu, float offset[3], int do_keys)
+{
+       ListBase *nurb_lb= BKE_curve_nurbs(cu);
+       Nurb *nu;
+       int i;
 
+       for(nu= nurb_lb->first; nu; nu= nu->next) {
+               BezTriple *bezt;
+               BPoint *bp;
 
+               if(nu->type == CU_BEZIER) {
+                       i= nu->pntsu;
+                       for(bezt= nu->bezt; i--; bezt++) {
+                               add_v3_v3(bezt->vec[0], offset);
+                               add_v3_v3(bezt->vec[1], offset);
+                               add_v3_v3(bezt->vec[2], offset);
+                       }
+               }
+               else {
+                       i= nu->pntsu*nu->pntsv;
+                       for(bp= nu->bp; i--; bp++) {
+                               add_v3_v3(bp->vec, offset);
+                       }
+               }
+       }
+
+       if (do_keys && cu->key) {
+               KeyBlock *kb;
+               for (kb=cu->key->block.first; kb; kb=kb->next) {
+                       float *fp= kb->data;
+                       for (i= kb->totelem; i--; fp+=3) {
+                               add_v3_v3(fp, offset);
+                       }
+               }
+       }
+}