Shapekeys for curves/surfeces
authorSergey Sharybin <sergey.vfx@gmail.com>
Sun, 25 Jul 2010 11:57:36 +0000 (11:57 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Sun, 25 Jul 2010 11:57:36 +0000 (11:57 +0000)
Fix #21498: Edit curve Shape key /252_r 27318

Added full support of shape keys for curves and nurbs surfaces including
topology changing in edit mode, undo stuff, updating relative keys when
working under basis and so on.

21 files changed:
source/blender/blenkernel/BKE_curve.h
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/key.c
source/blender/blenkernel/intern/object.c
source/blender/editors/curve/editcurve.c
source/blender/editors/include/ED_curve.h
source/blender/editors/render/render_shading.c
source/blender/editors/space_info/info_stats.c
source/blender/editors/space_info/space_info.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_buttons.c
source/blender/editors/space_view3d/view3d_snap.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c
source/blender/editors/transform/transform_manipulator.c
source/blender/editors/transform/transform_orientations.c
source/blender/makesdna/DNA_curve_types.h
source/blender/makesrna/intern/rna_curve.c
source/blenderplayer/bad_level_call_stubs/stubs.c

index ca45c2f..e83ea4b 100644 (file)
@@ -105,5 +105,7 @@ int check_valid_nurb_v( struct Nurb *nu);
 int clamp_nurb_order_u( struct Nurb *nu);
 int clamp_nurb_order_v( struct Nurb *nu);
 
+ListBase *BKE_curve_nurbs(struct Curve *cu);
+
 #endif
 
index 157c074..412084f 100644 (file)
@@ -66,6 +66,8 @@
 #include "BKE_utildefines.h"
 #include "BKE_depsgraph.h"
 
+#include "ED_curve.h" /* for ED_curve_nurbs */
+
 // XXX bad level call...
 
 /* --------------------- */
@@ -458,17 +460,17 @@ void calc_curvepath(Object *ob)
        float *fp, *dist, *maxdist, xyz[3];
        float fac, d=0, fac1, fac2;
        int a, tot, cycl=0;
+       ListBase *nurbs;
        
        /* in a path vertices are with equal differences: path->len = number of verts */
        /* NOW WITH BEVELCURVE!!! */
        
        if(ob==NULL || ob->type != OB_CURVE) return;
        cu= ob->data;
-       if(cu->editnurb) 
-               nu= cu->editnurb->first;
-       else 
-               nu= cu->nurb.first;
-       
+
+       nurbs= BKE_curve_nurbs(cu);
+       nu= nurbs->first;
+
        if(cu->path) free_path(cu->path);
        cu->path= NULL;
        
index d355a52..4142ad7 100644 (file)
@@ -58,6 +58,8 @@
 #include "BKE_object.h"  
 #include "BKE_utildefines.h"  // VECCOPY
 
+#include "ED_curve.h"
+
 /* globals */
 
 /* local */
@@ -104,13 +106,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);
        
@@ -2008,8 +2005,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) {
                
@@ -2999,7 +2998,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 {
@@ -3099,5 +3098,12 @@ 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;
+}
index bb020c9..ca659fa 100644 (file)
@@ -63,6 +63,7 @@
 
 #include "BLO_sys_types.h" // for intptr_t support
 
+#include "ED_curve.h" /* for BKE_curve_nurbs */
 
 static void boundbox_displist(Object *ob);
 
@@ -1221,7 +1222,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;
@@ -1324,8 +1325,9 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
        ModifierData *md = modifiers_getVirtualModifierList(ob);
        ModifierData *preTesselatePoint;
        Curve *cu= ob->data;
-       ListBase *nurb= cu->editnurb?cu->editnurb:&cu->nurb;
-       int required_mode, totvert = 0;
+       ListBase *nurb= BKE_curve_nurbs(cu);
+       DispList *dl;
+       int required_mode = 0, totvert = 0;
        int editmode = (!forRender && cu->editnurb);
        DerivedMesh *dm= NULL, *ndm;
        float (*vertCos)[3] = NULL;
@@ -1590,9 +1592,9 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase,
        int numVerts;
        float (*originalVerts)[3];
        float (*deformedVerts)[3];
-               
+
        if(!forRender && cu->editnurb)
-               nubase= cu->editnurb;
+               nubase= ED_curve_editnurbs(cu);
        else
                nubase= &cu->nurb;
 
@@ -1689,10 +1691,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
                        cu->taperobj = NULL;
                }
 
-               if(cu->editnurb)
-                       nubase= cu->editnurb;
-               else
-                       nubase= &cu->nurb;
+               nubase= BKE_curve_nurbs(cu);
 
                BLI_freelistN(&(cu->bev));
 
index b8219c4..354b3b0 100644 (file)
@@ -542,11 +542,15 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
                poinsize= ofs[0];
        }
        else if( GS(key->from->name)==ID_CU ) {
-               if(mode==KEY_BPOINT) ofs[0]= sizeof(float)*4;
-               else ofs[0]= sizeof(float)*10;
-               
+               if(mode==KEY_BPOINT) {
+                       ofs[0]= sizeof(float)*4;
+                       poinsize= ofs[0];
+               }else {
+                       ofs[0]= sizeof(float)*12;
+                       poinsize= ofs[0]/3;
+               }
+
                ofs[1]= 0;
-               poinsize= ofs[0];
        }
 
        if(end>tot) end= tot;
@@ -612,7 +616,7 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
                                memcpy(poin, k1, sizeof(float)*4);
                                break;
                        case IPO_BEZTRIPLE:
-                               memcpy(poin, k1, sizeof(float)*10);
+                               memcpy(poin, k1, sizeof(float)*12);
                                break;
                        }
                        
@@ -644,28 +648,25 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
 static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock *kb, int start, int end, char *out, int tot)
 {
        Nurb *nu;
-       char *poin;
        int a, step, a1, a2;
 
        for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) {
                if(nu->bp) {
                        step= nu->pntsu*nu->pntsv;
-                       
-                       /* exception because keys prefer to work with complete blocks */
-                       poin= out - a*sizeof(float)*4;
+
                        a1= MAX2(a, start);
                        a2= MIN2(a+step, end);
-                       
-                       if(a1<a2) cp_key(a1, a2, tot, poin, key, actkb, kb, NULL, KEY_BPOINT);
+
+                       if(a1<a2) cp_key(a1, a2, tot, out, key, actkb, kb, NULL, KEY_BPOINT);
                }
                else if(nu->bezt) {
                        step= 3*nu->pntsu;
-                       
-                       poin= out - a*sizeof(float)*10;
+
+                       /* exception because keys prefer to work with complete blocks */
                        a1= MAX2(a, start);
                        a2= MIN2(a+step, end);
 
-                       if(a1<a2) cp_key(a1, a2, tot, poin, key, actkb, kb, NULL, KEY_BEZTRIPLE);
+                       if(a1<a2) cp_key(a1, a2, tot, out, key, actkb, kb, NULL, KEY_BEZTRIPLE);
                }
                else
                        step= 0;
@@ -679,26 +680,34 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, KeyBlock
        int *ofsp, ofs[3], elemsize, b;
        char *cp, *poin, *reffrom, *from, elemstr[8];
        char *freefrom, *freereffrom;
-       
+       int poinsize= 0;
+
        if(key->from==NULL) return;
-       
+
        if( GS(key->from->name)==ID_ME ) {
                ofs[0]= sizeof(float)*3;
                ofs[1]= 0;
+               poinsize= ofs[0];
        }
        else if( GS(key->from->name)==ID_LT ) {
                ofs[0]= sizeof(float)*3;
                ofs[1]= 0;
+               poinsize= ofs[0];
        }
        else if( GS(key->from->name)==ID_CU ) {
-               if(mode==KEY_BPOINT) ofs[0]= sizeof(float)*4;
-               else ofs[0]= sizeof(float)*10;
-               
+               if(mode==KEY_BPOINT) {
+                       ofs[0]= sizeof(float)*4;
+                       poinsize= ofs[0];
+               } else {
+                       ofs[0]= sizeof(float)*12;
+                       poinsize= ofs[0] / 3;
+               }
+
                ofs[1]= 0;
        }
-       
+
        if(end>tot) end= tot;
-       
+
        /* in case of beztriple */
        elemstr[0]= 1;                          /* nr of ipofloats */
        elemstr[1]= IPO_BEZTRIPLE;
@@ -730,7 +739,7 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, KeyBlock
                                from= key_block_get_data(key, actkb, kb, &freefrom);
                                reffrom= key_block_get_data(key, actkb, refb, &freereffrom);
                                
-                               poin+= start*ofs[0];
+                               poin+= start*poinsize;
                                reffrom+= key->elemsize*start;  // key elemsize yes!
                                from+= key->elemsize*start;
                                
@@ -756,7 +765,7 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, KeyBlock
                                                        rel_flerp(4, (float *)poin, (float *)reffrom, (float *)from, weight);
                                                        break;
                                                case IPO_BEZTRIPLE:
-                                                       rel_flerp(10, (float *)poin, (float *)reffrom, (float *)from, weight);
+                                                       rel_flerp(12, (float *)poin, (float *)reffrom, (float *)from, weight);
                                                        break;
                                                }
                                                
@@ -803,11 +812,15 @@ static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
                poinsize= ofs[0];
        }
        else if( GS(key->from->name)==ID_CU ) {
-               if(mode==KEY_BPOINT) ofs[0]= sizeof(float)*4;
-               else ofs[0]= sizeof(float)*10;
-               
+               if(mode==KEY_BPOINT) {
+                       ofs[0]= sizeof(float)*4;
+                       poinsize= ofs[0];
+               } else {
+                       ofs[0]= sizeof(float)*12;
+                       poinsize= ofs[0] / 3;
+               }
+
                ofs[1]= 0;
-               poinsize= ofs[0];
        }
        
        if(end>tot) end= tot;
@@ -929,7 +942,7 @@ static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
                                flerp(4, (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t);
                                break;
                        case IPO_BEZTRIPLE:
-                               flerp(10, (void *)poin, (void *)k1, (void *)k2, (void *)k3, (void *)k4, t);
+                               flerp(12, (void *)poin, (void *)k1, (void *)k2, (void *)k3, (void *)k4, t);
                                break;
                        }
                        
@@ -1137,19 +1150,16 @@ static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
 static void do_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock **k, float *t, char *out, int tot)
 {
        Nurb *nu;
-       char *poin;
        int a, step;
        
        for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) {
                if(nu->bp) {
                        step= nu->pntsu*nu->pntsv;
-                       poin= out - a*sizeof(float)*4;
-                       do_key(a, a+step, tot, poin, key, actkb, k, t, KEY_BPOINT);
+                       do_key(a, a+step, tot, out, key, actkb, k, t, KEY_BPOINT);
                }
                else if(nu->bezt) {
                        step= 3*nu->pntsu;
-                       poin= out - a*sizeof(float)*10;
-                       do_key(a, a+step, tot, poin, key, actkb, k, t, KEY_BEZTRIPLE);
+                       do_key(a, a+step, tot, out, key, actkb, k, t, KEY_BEZTRIPLE);
                }
                else
                        step= 0;
@@ -1159,19 +1169,16 @@ static void do_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock **k, float
 static void do_rel_cu_key(Curve *cu, Key *key, KeyBlock *actkb, float ctime, char *out, int tot)
 {
        Nurb *nu;
-       char *poin;
        int a, step;
        
        for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) {
                if(nu->bp) {
                        step= nu->pntsu*nu->pntsv;
-                       poin= out - a*sizeof(float)*3;
                        do_rel_key(a, a+step, tot, out, key, actkb, KEY_BPOINT);
                }
                else if(nu->bezt) {
                        step= 3*nu->pntsu;
-                       poin= out - a*sizeof(float)*10;
-                       do_rel_key(a, a+step, tot, poin, key, actkb, KEY_BEZTRIPLE);
+                       do_rel_key(a, a+step, tot, out, key, actkb, KEY_BEZTRIPLE);
                }
                else
                        step= 0;
@@ -1184,35 +1191,61 @@ static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
        KeyBlock *k[4], *actkb= ob_get_keyblock(ob);
        float cfra, ctime, t[4], delta;
        int a, flag = 0, step = 0;
-       
-       if(key->slurph) {
-               delta= key->slurph;
-               delta/= tot;
-               
+
+       if(key->slurph  && key->type!=KEY_RELATIVE) {
+               Nurb *nu;
+               int mode, i= 0, remain= 0, estep, count;
+
+               delta= (float)key->slurph / tot;
+
                step= 1;
                if(tot>100 && slurph_opt) {
                        step= tot/50;
                        delta*= step;
                        /* in do_key and cp_key the case a>tot has been handled */
                }
-               
+
                cfra= (float)scene->r.cfra;
-               
-               for(a=0; a<tot; a+=step, cfra+= delta) {
-                       ctime= bsystem_time(scene, 0, cfra, 0.0f); // XXX old cruft
-#if 0 // XXX old animation system
-                       if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
-                               ctime /= 100.0;
-                               CLAMP(ctime, 0.0, 1.0);
+
+               for(nu=cu->nurb.first; nu; nu=nu->next) {
+                       if(nu->bp) {
+                               mode= KEY_BPOINT;
+                               estep= nu->pntsu*nu->pntsv;
+                       }
+                       else if(nu->bezt) {
+                               mode= KEY_BEZTRIPLE;
+                               estep= 3*nu->pntsu;
                        }
-#endif // XXX old animation system
-               
-                       flag= setkeys(ctime, &key->block, k, t, 0);
-                       
-                       if(flag==0)
-                               do_key(a, a+step, tot, (char *)out, key, actkb, k, t, 0);
                        else
-                               cp_key(a, a+step, tot, (char *)out, key, actkb, k[2], NULL, 0);
+                               step= 0;
+
+                       a= 0;
+                       while (a < estep) {
+                               if (remain <= 0) {
+                                       cfra+= delta;
+                                       ctime= bsystem_time(scene, 0, cfra, 0.0f); // XXX old cruft
+
+                                       ctime /= 100.0f;
+                                       CLAMP(ctime, 0.0f, 1.0f); // XXX for compat, we use this, but this clamping was confusing
+                                       flag= setkeys(ctime, &key->block, k, t, 0);
+
+                                       remain= step;
+                               }
+
+                               count= MIN2(remain, estep);
+                               if (mode == KEY_BEZTRIPLE) {
+                                       count += 3 - count % 3;
+                               }
+
+                               if(flag==0)
+                                       do_key(i, i+count, tot, (char *)out, key, actkb, k, t, mode);
+                               else
+                                       cp_key(i, i+count, tot, (char *)out, key, actkb, k[2], NULL, mode);
+
+                               a += count;
+                               i += count;
+                               remain -= count;
+                       }
                }
        }
        else {
@@ -1336,11 +1369,11 @@ float *do_ob_key(Scene *scene, Object *ob)
                for(nu=cu->nurb.first; nu; nu=nu->next) {
                        if(nu->bezt) {
                                tot += 3*nu->pntsu;
-                               size += nu->pntsu*10*sizeof(float);
+                               size += nu->pntsu*12*sizeof(float);
                        }
                        else if(nu->bp) {
                                tot += nu->pntsu*nu->pntsv;
-                               size += nu->pntsu*nu->pntsv*10*sizeof(float);
+                               size += nu->pntsu*nu->pntsv*12*sizeof(float);
                        }
                }
        }
index 75b5e6d..efff3d1 100644 (file)
@@ -1885,13 +1885,12 @@ static void give_parvert(Object *par, int nr, float *vec)
                BPoint *bp;
                BezTriple *bezt;
                int found= 0;
-               
+               ListBase *nurbs;
+
                cu= par->data;
-               if(cu->editnurb)
-                       nu= cu->editnurb->first;
-               else
-                       nu= cu->nurb.first;
-               
+               nurbs= BKE_curve_nurbs(cu);
+               nu= nurbs->first;
+
                count= 0;
                while(nu && !found) {
                        if(nu->type == CU_BEZIER) {
@@ -2946,7 +2945,7 @@ static KeyBlock *insert_curvekey(Scene *scene, Object *ob, char *name, int from_
        Curve *cu= ob->data;
        Key *key= cu->key;
        KeyBlock *kb;
-       ListBase *lb= (cu->editnurb)? cu->editnurb: &cu->nurb;
+       ListBase *lb= BKE_curve_nurbs(cu);
        int newkey= 0;
 
        if(key==NULL) {
index c33565c..8d8dac3 100644 (file)
@@ -42,6 +42,7 @@
 #include "BLI_math.h"
 #include "BLI_dynstr.h"
 #include "BLI_rand.h"
+#include "BLI_ghash.h"
 
 #include "DNA_key_types.h"
 #include "DNA_object_types.h"
@@ -69,6 +70,7 @@
 #include "ED_types.h"
 #include "ED_util.h"
 #include "ED_view3d.h"
+#include "ED_curve.h"
 
 #include "UI_interface.h"
 
 typedef struct {
        ListBase nubase;
        void *lastsel;
+       GHash *undoIndex;
 } UndoCurve;
 
+/* Definitions needed for shape keys */
+typedef struct {
+       void *origNode;
+       int index;
+} NodeKeyIndex;
+
 void selectend_nurb(Object *obedit, short selfirst, short doswap, short selstatus);
 static void select_adjacent_cp(ListBase *editnurb, short next, short cont, short selstatus);
 
@@ -96,7 +105,7 @@ ListBase *curve_get_editcurve(Object *ob)
 {
        if(ob && ELEM(ob->type, OB_CURVE, OB_SURF)) {
                Curve *cu= ob->data;
-               return cu->editnurb;
+               return &cu->editnurb->nurbs;
        }
        return NULL;
 }
@@ -108,15 +117,18 @@ void set_actNurb(Object *obedit, Nurb *nu)
        
        if(nu==NULL)
                cu->actnu = -1;
-       else
-               cu->actnu = BLI_findindex(cu->editnurb, nu);
+       else {
+               ListBase *nurbs= ED_curve_editnurbs(cu);
+               cu->actnu = BLI_findindex(nurbs, nu);
+       }
 }
 
 Nurb *get_actNurb(Object *obedit)
 {
        Curve *cu= obedit->data;
-       
-       return BLI_findlink(cu->editnurb, cu->actnu);
+       ListBase *nurbs= ED_curve_editnurbs(cu);
+
+       return BLI_findlink(nurbs, cu->actnu);
 }
 
 /* ******************* SELECTION FUNCTIONS ********************* */
@@ -258,6 +270,688 @@ void printknots(Object *obedit)
        }
 }
 
+/* ********************* Shape keys *************** */
+
+static NodeKeyIndex *init_nodeKeyIndex(void *node, int index)
+{
+       NodeKeyIndex *nodeIndex = MEM_callocN(sizeof(NodeKeyIndex), "init_nodeKeyIndex");
+
+       nodeIndex->origNode= node;
+       nodeIndex->index= index;
+
+       return nodeIndex;
+}
+
+static void free_nodeKeyIndex(NodeKeyIndex *pointIndex)
+{
+       MEM_freeN(pointIndex);
+}
+
+static void init_editNurb_keyIndex(EditNurb *editnurb, ListBase *origBase)
+{
+       Nurb *nu= editnurb->nurbs.first;
+       Nurb *orignu= origBase->first;
+       GHash *gh;
+       BezTriple *bezt, *origbezt;
+       BPoint *bp, *origbp;
+       int a, keyindex= 0;
+
+       gh= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "editNurb keyIndex");
+
+       while (orignu) {
+               if (orignu->bezt) {
+                       a= orignu->pntsu;
+                       bezt= nu->bezt;
+                       origbezt= orignu->bezt;
+                       while (a--) {
+                               BLI_ghash_insert(gh, bezt, init_nodeKeyIndex(origbezt, keyindex));
+                               keyindex+= 12;
+                               bezt++;
+                               origbezt++;
+                       }
+               } else {
+                       a= orignu->pntsu * orignu->pntsv;
+                       bp= nu->bp;
+                       origbp= orignu->bp;
+                       while (a--) {
+                               BLI_ghash_insert(gh, bp, init_nodeKeyIndex(origbp, keyindex));
+                               keyindex+= 4;
+                               bp++;
+                               origbp++;
+                       }
+               }
+
+               nu= nu->next;
+               orignu= orignu->next;
+       }
+
+       editnurb->keyindex= gh;
+}
+
+static void free_editNurb_keyIndex(EditNurb *editnurb)
+{
+       if (!editnurb->keyindex) {
+               return;
+       }
+       BLI_ghash_free(editnurb->keyindex, NULL, (GHashValFreeFP)free_nodeKeyIndex);
+}
+
+static NodeKeyIndex *getNodeKeyIndex(EditNurb *editnurb, void *node)
+{
+       return BLI_ghash_lookup(editnurb->keyindex, node);
+}
+
+static BezTriple *getKeyIndexOrig_bezt(EditNurb *editnurb, void *node)
+{
+       NodeKeyIndex *index= getNodeKeyIndex(editnurb, node);
+
+       if (!index) {
+               return NULL;
+       }
+
+       return (BezTriple*)index->origNode;
+}
+
+static BPoint *getKeyIndexOrig_bp(EditNurb *editnurb, void *node)
+{
+       NodeKeyIndex *index= getNodeKeyIndex(editnurb, node);
+
+       if (!index) {
+               return NULL;
+       }
+
+       return (BPoint*)index->origNode;
+}
+
+static int getKeyIndexOrig_index(EditNurb *editnurb, void *node)
+{
+       NodeKeyIndex *index= getNodeKeyIndex(editnurb, node);
+
+       if (!index) {
+               return -1;
+       }
+
+       return index->index;
+}
+
+static void keyIndex_delNode(EditNurb *editnurb, void *node)
+{
+       if (!editnurb->keyindex) {
+               return;
+       }
+
+       BLI_ghash_remove(editnurb->keyindex, node, NULL, (GHashValFreeFP)free_nodeKeyIndex);
+}
+
+static void keyIndex_delBezt(EditNurb *editnurb, BezTriple *bezt)
+{
+       keyIndex_delNode(editnurb, bezt);
+}
+
+static void keyIndex_delBP(EditNurb *editnurb, BPoint *bp)
+{
+       keyIndex_delNode(editnurb, bp);
+}
+
+static void keyIndex_delNurb(EditNurb *editnurb, Nurb *nu)
+{
+       int a;
+
+       if (nu->bezt) {
+               BezTriple *bezt= nu->bezt;
+               a= nu->pntsu;
+
+               while (a--) {
+                       BLI_ghash_remove(editnurb->keyindex, bezt, NULL, (GHashValFreeFP)free_nodeKeyIndex);
+                       ++bezt;
+               }
+       } else {
+               BPoint *bp= nu->bp;
+               a= nu->pntsu * nu->pntsv;
+
+               while (a--) {
+                       BLI_ghash_remove(editnurb->keyindex, bp, NULL, (GHashValFreeFP)free_nodeKeyIndex);
+                       ++bp;
+               }
+       }
+}
+
+static void keyIndex_delNurbList(EditNurb *editnurb, ListBase *nubase)
+{
+       Nurb *nu= nubase->first;
+
+       while (nu) {
+               keyIndex_delNurb(editnurb, nu);
+
+               nu= nu->next;
+       }
+}
+
+static void keyIndex_updateNode(EditNurb *editnurb, char *node,
+       char *newnode, int count, int size, int search)
+{
+       int i;
+       NodeKeyIndex *index;
+
+       if (editnurb->keyindex == NULL) {
+               /* No shape keys - updating not needed */
+               return;
+       }
+
+       for (i = 0; i < count; i++) {
+               for (;;) {
+                       index= getNodeKeyIndex(editnurb, node);
+                       if (!search || index) {
+                               break;
+                       }
+                       node += size;
+               }
+
+               BLI_ghash_remove(editnurb->keyindex, node, NULL, NULL);
+
+               if (index) {
+                       BLI_ghash_insert(editnurb->keyindex, newnode, index);
+               }
+
+               newnode += size;
+               node += size;
+       }
+}
+
+static void keyIndex_updateBezt(EditNurb *editnurb, BezTriple *bezt,
+       BezTriple *newbezt, int count, int search)
+{
+       keyIndex_updateNode(editnurb, (char*)bezt, (char*)newbezt, count, sizeof(BezTriple), search);
+}
+
+static void keyIndex_updateBP(EditNurb *editnurb, BPoint *bp,
+       BPoint *newbp, int count, int search)
+{
+       keyIndex_updateNode(editnurb, (char*)bp, (char*)newbp, count, sizeof(BPoint), search);
+}
+
+static void keyIndex_updateNurb(EditNurb *editnurb, Nurb *nu, Nurb *newnu)
+{
+       if (nu->bezt) {
+               keyIndex_updateBezt(editnurb, nu->bezt, newnu->bezt, newnu->pntsu, 0);
+       } else {
+               keyIndex_updateBP(editnurb, nu->bp, newnu->bp, newnu->pntsu * newnu->pntsv, 0);
+       }
+}
+
+static void keyIndex_swap(EditNurb *editnurb, void *a, void *b)
+{
+       NodeKeyIndex *index1= getNodeKeyIndex(editnurb, a);
+       NodeKeyIndex *index2= getNodeKeyIndex(editnurb, b);
+
+       BLI_ghash_remove(editnurb->keyindex, a, NULL, NULL);
+       BLI_ghash_remove(editnurb->keyindex, b, NULL, NULL);
+
+       BLI_ghash_insert(editnurb->keyindex, a, index2);
+       BLI_ghash_insert(editnurb->keyindex, b, index1);
+}
+
+static void keyIndex_switchDirection(EditNurb *editnurb, Nurb *nu)
+{
+       int a;
+
+       if (nu->bezt) {
+               BezTriple *bezt1, *bezt2;
+
+               a= nu->pntsu;
+
+               bezt1= nu->bezt;
+               bezt2= bezt1+(a-1);
+
+               if (a & 1) ++a;
+
+               a/=2;
+
+               while (a--) {
+                       if (bezt1 != bezt2) {
+                               keyIndex_swap(editnurb, bezt1, bezt2);
+                       }
+
+                       bezt1++;
+                       bezt2--;
+               }
+       } else {
+               BPoint *bp1, *bp2;
+
+               if (nu->pntsv == 1) {
+                       a= nu->pntsu;
+                       bp1= nu->bp;
+                       bp2= bp1+(a-1);
+                       a/= 2;
+                       while(bp1!=bp2 && a>0) {
+                               if (bp1 != bp2) {
+                                       keyIndex_swap(editnurb, bp1, bp2);
+                               }
+
+                               a--;
+                               bp1++;
+                               bp2--;
+                       }
+               } else {
+                       int b;
+
+                       for(b=0; b<nu->pntsv; b++) {
+
+                               bp1= nu->bp+b*nu->pntsu;
+                               a= nu->pntsu;
+                               bp2= bp1+(a-1);
+                               a/= 2;
+
+                               while(bp1!=bp2 && a>0) {
+                                       if (bp1 != bp2) {
+                                               keyIndex_swap(editnurb, bp1, bp2);
+                                       }
+
+                                       a--;
+                                       bp1++;
+                                       bp2--;
+                               }
+                       }
+
+               }
+       }
+}
+
+static void switch_keys_direction(Curve *cu, Nurb *actnu)
+{
+       KeyBlock *currkey;
+       ListBase *nubase= &cu->editnurb->nurbs;
+       Nurb *nu;
+       float *fp;
+       int a;
+
+       currkey = cu->key->block.first;
+       while(currkey) {
+               fp= currkey->data;
+
+               nu= nubase->first;
+               while (nu) {
+                       if (nu->bezt) {
+                               a= nu->pntsu;
+                               if (nu == actnu) {
+                                       while (a--) {
+                                               swap_v3_v3(fp, fp + 6);
+                                               *(fp+9) = -*(fp+9);
+                                               fp += 12;
+                                       }
+                               } else fp += a * 12;
+                       } else {
+                               a= nu->pntsu * nu->pntsv;
+                               if (nu == actnu) {
+                                       while (a--) {
+                                               *(fp+3) = -*(fp+3);
+                                               fp += 4;
+                                       }
+                               } else fp += a * 4;
+                       }
+
+                       nu= nu->next;
+               }
+
+               currkey= currkey->next;
+       }
+}
+
+static void keyData_switchDirectionNurb(Curve *cu, Nurb *nu)
+{
+       EditNurb *editnurb= cu->editnurb;
+
+       if (!editnurb->keyindex) {
+               /* no shape keys - nothing to do */
+               return;
+       }
+
+       keyIndex_switchDirection(editnurb, nu);
+       switch_keys_direction(cu, nu);
+}
+
+static GHash *dupli_keyIndexHash(GHash *keyindex)
+{
+       GHash *gh;
+       GHashIterator *hashIter;
+
+       gh= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "dupli_keyIndex gh");
+
+       for(hashIter = BLI_ghashIterator_new(keyindex);
+                                  !BLI_ghashIterator_isDone(hashIter);
+                                  BLI_ghashIterator_step(hashIter)) {
+               void *node = BLI_ghashIterator_getKey(hashIter);
+               NodeKeyIndex *index = BLI_ghashIterator_getValue(hashIter);
+               NodeKeyIndex *newIndex = MEM_callocN(sizeof(NodeKeyIndex), "dupli_keyIndexHash index");
+
+               memcpy(newIndex, index, sizeof(NodeKeyIndex));
+
+               BLI_ghash_insert(gh, node, newIndex);
+       }
+
+       BLI_ghashIterator_free(hashIter);
+
+       return gh;
+}
+
+static void key_to_bezt(float *key, BezTriple *basebezt, BezTriple *bezt)
+{
+       memcpy(bezt, basebezt, sizeof(BezTriple));
+       memcpy(bezt->vec, key, sizeof(float) * 9);
+       bezt->alfa= key[9];
+}
+
+static void bezt_to_key(BezTriple *bezt, float *key)
+{
+        memcpy(key, bezt->vec, sizeof(float) * 9);
+        key[9] = bezt->alfa;
+}
+
+static void calc_keyHandles(ListBase *nurb, float *key)
+{
+       Nurb *nu;
+       int a;
+       float *fp= key;
+       BezTriple *bezt;
+
+       nu= nurb->first;
+       while (nu) {
+               if (nu->bezt) {
+                       BezTriple *prevp, *nextp;
+                       BezTriple cur, prev, next;
+                       float *startfp, *prevfp, *nextfp;
+
+                       bezt= nu->bezt;
+                       a= nu->pntsu;
+                       startfp= fp;
+
+                       if(nu->flagu & CU_NURB_CYCLIC) {
+                               prevp= bezt+(a-1);
+                               prevfp= fp+(12 * (a-1));
+                       } else {
+                               prevp= NULL;
+                               prevfp= NULL;
+                       }
+
+                       nextp= bezt + 1;
+                       nextfp= fp + 12;
+
+                       while (a--) {
+                               key_to_bezt(fp, bezt, &cur);
+
+                               if (nextp) key_to_bezt(nextfp, nextp, &next);
+                               if (prevp) key_to_bezt(prevfp, prevp, &prev);
+
+                               calchandleNurb(&cur, prevp ? &prev : NULL, nextp ? &next : NULL, 0);
+                               bezt_to_key(&cur, fp);
+
+                               prevp= bezt;
+                               prevfp= fp;
+                               if(a==1) {
+                                       if(nu->flagu & CU_NURB_CYCLIC) {
+                                               nextp= nu->bezt;
+                                               nextfp= startfp;
+                                       } else {
+                                               nextp= NULL;
+                                               nextfp= NULL;
+                                       }
+                               }
+                               else {
+                                       ++nextp;
+                                       nextfp += 12;;
+                               }
+
+                               ++bezt;
+                               fp += 12;
+                       }
+               } else {
+                       a= nu->pntsu * nu->pntsv;
+                       fp += a * 4;
+               }
+
+               nu= nu->next;
+       }
+}
+
+static void calc_shapeKeys(Object *obedit)
+{
+       Curve *cu= (Curve*)obedit->data;
+
+       /* are there keys? */
+       if(cu->key) {
+               int a, i, j;
+               EditNurb *editnurb= cu->editnurb;
+               KeyBlock *currkey;
+               KeyBlock *actkey= ob_get_keyblock(obedit);
+               BezTriple *bezt, *oldbezt;
+               BPoint *bp, *oldbp;
+               Nurb *nu;
+               int totvert= count_curveverts(&editnurb->nurbs);
+
+               float (*ofs)[3] = NULL;
+               float *oldkey, *newkey, *fp, *ofp;
+
+               /* editing the base key should update others */
+               if(cu->key->type==KEY_RELATIVE) {
+                       int act_is_basis = 0;
+                       /* find if this key is a basis for any others */
+                       for(currkey = cu->key->block.first; currkey; currkey= currkey->next) {
+                               if(obedit->shapenr-1 == currkey->relative) {
+                                       act_is_basis = 1;
+                                       break;
+                               }
+                       }
+
+                       if(act_is_basis) { /* active key is a base */
+                               int j;
+                               int totvec= 0;
+
+                               /* Calculate needed memory to store offset */
+                               nu= editnurb->nurbs.first;
+                               while(nu) {
+                                       if (nu->bezt) {
+                                               /* Three vects to store handles and one for alfa */
+                                               totvec+= nu->pntsu * 4;
+                                       } else {
+                                               totvec+= 2 * nu->pntsu * nu->pntsv;
+                                       }
+
+                                       nu= nu->next;
+                               }
+
+                               ofs= MEM_callocN(sizeof(float) * 3 * totvec,  "currkey->data");
+                               nu= editnurb->nurbs.first;
+                               i= 0;
+                               while(nu) {
+                                       if(nu->bezt) {
+                                               bezt= nu->bezt;
+                                               a= nu->pntsu;
+                                               while(a--) {
+                                                       oldbezt= getKeyIndexOrig_bezt(editnurb, bezt);
+
+                                                       if (oldbezt) {
+                                                               for (j= 0; j < 3; ++j) {
+                                                                       VECSUB(ofs[i], bezt->vec[j], oldbezt->vec[j]);
+                                                                       i++;
+                                                                       fp+= 3;
+                                                               }
+                                                               ofs[i++][0]= bezt->alfa - oldbezt->alfa;
+                                                       } else {
+                                                               i += 4;
+                                                       }
+                                                       bezt++;
+                                               }
+                                       }
+                                       else {
+                                               bp= nu->bp;
+                                               a= nu->pntsu*nu->pntsv;
+                                               while(a--) {
+                                                       oldbp= getKeyIndexOrig_bp(editnurb, bp);
+                                                       if (oldbp) {
+                                                               VECSUB(ofs[i], bp->vec, oldbp->vec);
+                                                               ofs[i+1][0]= bp->alfa - oldbp->alfa;
+                                                       }
+                                                       i += 2;
+                                                       ++bp;
+                                                       fp += 4;
+                                               }
+                                       }
+
+                                       nu= nu->next;
+                               }
+                       }
+               }
+
+               currkey = cu->key->block.first;
+               while(currkey) {
+                       int apply_offset = (ofs && (currkey != actkey) && (obedit->shapenr-1 == currkey->relative));
+
+                       fp= newkey= MEM_callocN(cu->key->elemsize * totvert,  "currkey->data");
+                       ofp= oldkey = currkey->data;
+
+                       nu= editnurb->nurbs.first;
+                       i = 0;
+                       while(nu) {
+                               if(currkey == actkey) {
+                                       int restore= actkey != cu->key->refkey;
+
+                                       if(nu->bezt) {
+                                               bezt= nu->bezt;
+                                               a= nu->pntsu;
+                                               while(a--) {
+                                                       oldbezt= getKeyIndexOrig_bezt(editnurb, bezt);
+
+                                                       for (j= 0; j < 3; ++j, ++i) {
+                                                               VECCOPY(fp, bezt->vec[j]);
+
+                                                               if (restore && oldbezt) {
+                                                                       VECCOPY(bezt->vec[j], oldbezt->vec[j]);
+                                                               }
+
+                                                               fp+= 3;
+                                                       }
+                                                       fp[0]= bezt->alfa;
+
+                                                       if(restore && oldbezt) {
+                                                               bezt->alfa= oldbezt->alfa;
+                                                       }
+
+                                                       fp+= 3; ++i;/* alphas */
+                                                       ++bezt;
+                                               }
+                                       }
+                                       else {
+                                               bp= nu->bp;
+                                               a= nu->pntsu*nu->pntsv;
+                                               while(a--) {
+                                                       oldbp= getKeyIndexOrig_bp(editnurb, bp);
+
+                                                       VECCOPY(fp, bp->vec);
+
+                                                       fp[3]= bp->alfa;
+
+                                                       if(restore && oldbp) {
+                                                               VECCOPY(bp->vec, oldbp->vec);
+                                                               bp->alfa= oldbp->alfa;
+                                                       }
+
+                                                       fp+= 4;
+                                                       ++bp;
+                                                       i+=2;
+                                               }
+                                       }
+                               }
+                               else {
+                                       int index;
+                                       float *curofp;
+
+                                       if(oldkey) {
+                                               if(nu->bezt) {
+                                                       bezt= nu->bezt;
+                                                       a= nu->pntsu;
+
+                                                       while(a--) {
+                                                               index= getKeyIndexOrig_index(editnurb, bezt);
+                                                               if (index >= 0) {
+                                                                       curofp= ofp + index;
+
+                                                                       for (j= 0; j < 3; ++j, ++i) {
+                                                                               VECCOPY(fp, curofp);
+
+                                                                               if(apply_offset) {
+                                                                                       VECADD(fp, fp, ofs[i]);
+                                                                               }
+
+                                                                               fp+= 3; curofp+= 3;
+                                                                       }
+                                                                       fp[0]= ofp[0];
+
+                                                                       if(apply_offset) {
+                                                                               /* apply alfa offsets */
+                                                                               VECADD(fp, fp, ofs[i]);
+                                                                               ++i;
+                                                                       }
+
+                                                                       fp+= 3; curofp+= 3;     /* alphas */
+                                                               } else {
+                                                                       for (j= 0; j < 3; ++j, ++i) {
+                                                                               VECCOPY(fp, bezt->vec[j]);
+                                                                               fp+= 3;
+                                                                       }
+                                                                       fp[0]= bezt->alfa;
+
+                                                                       fp+= 3; /* alphas */
+                                                               }
+                                                               ++bezt;
+                                                       }
+                                               }
+                                               else {
+                                                       bp= nu->bp;
+                                                       a= nu->pntsu*nu->pntsv;
+                                                       while(a--) {
+                                                               index= getKeyIndexOrig_index(editnurb, bp);
+
+                                                               if (index >= 0) {
+                                                                       curofp= ofp + index;
+                                                                       VECCOPY(fp, curofp);
+                                                                       fp[3]= curofp[4];
+
+                                                                       if(apply_offset) {
+                                                                               VECADD(fp, fp, ofs[i]);
+                                                                               fp[3]+=ofs[i+1][0];
+                                                                       }
+                                                               } else {
+                                                                       VECCOPY(fp, bp->vec);
+                                                                       fp[3]= bp->alfa;
+                                                               }
+
+                                                               fp+= 4;
+                                                               ++bp;
+                                                               i+=2;
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               nu= nu->next;
+                       }
+
+                       if (apply_offset) {
+                               /* handles could become malicious after offsets applying */
+                               calc_keyHandles(&editnurb->nurbs, newkey);
+                       }
+
+                       currkey->totelem= totvert;
+                       if(currkey->data) MEM_freeN(currkey->data);
+                       currkey->data = newkey;
+
+                       currkey= currkey->next;
+               }
+
+               if(ofs) MEM_freeN(ofs);
+       }
+}
+
 /* ********************* LOAD and MAKE *************** */
 
 /* load editNurb in object */
@@ -272,48 +966,32 @@ void load_editNurb(Object *obedit)
        if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
                Curve *cu= obedit->data;
                Nurb *nu, *newnu;
-               KeyBlock *actkey;
-               int totvert= count_curveverts(editnurb);
+               ListBase newnurb= {NULL, NULL}, oldnurb= cu->nurb;
 
-               /* are there keys? */
-               actkey = ob_get_keyblock(obedit);
-               if(actkey) {
-                       /* active key: the vertices */
-                       
-                       if(totvert) {
-                               if(actkey->data) MEM_freeN(actkey->data);
-                       
-                               actkey->data= MEM_callocN(cu->key->elemsize*totvert, "actkey->data");
-                               actkey->totelem= totvert;
-               
-                               curve_to_key(cu, actkey, editnurb);
-                       }
-               }
-               
-               if(cu->key && actkey!=cu->key->refkey) {
-                       ;
-               }
-               else {
-                       freeNurblist(&(cu->nurb));
-                       
-                       for(nu= editnurb->first; nu; nu= nu->next) {
-                               newnu= duplicateNurb(nu);
-                               BLI_addtail(&(cu->nurb), newnu);
-                               
-                               if(nu->type == CU_NURBS) {
-                                       clamp_nurb_order_u(nu);
-                               }
+               for(nu= editnurb->first; nu; nu= nu->next) {
+                       newnu= duplicateNurb(nu);
+                       BLI_addtail(&newnurb, newnu);
+
+                       if(nu->type == CU_NURBS) {
+                               clamp_nurb_order_u(nu);
                        }
                }
+
+               cu->nurb= newnurb;
+
+               calc_shapeKeys(obedit);
+
+               freeNurblist(&oldnurb);
        }
-       
+
        set_actNurb(obedit, NULL);
 }
 
 /* make copy in cu->editnurb */
 void make_editNurb(Object *obedit)
 {
-       ListBase *editnurb= curve_get_editcurve(obedit);
+       Curve *cu= (Curve*)obedit->data;
+       EditNurb *editnurb= cu->editnurb;
        Nurb *nu, *newnu, *nu_act= NULL;
        KeyBlock *actkey;
 
@@ -322,20 +1000,29 @@ void make_editNurb(Object *obedit)
        set_actNurb(obedit, NULL);
 
        if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
-               Curve *cu= obedit->data;
-               
-               if(editnurb)
-                       freeNurblist(editnurb);
-               else
-                       editnurb= cu->editnurb= MEM_callocN(sizeof(ListBase), "editnurb");
-               
+               actkey = ob_get_keyblock(obedit);
+               if(actkey) {
+                       // XXX strcpy(G.editModeTitleExtra, "(Key) ");
+                       undo_editmode_clear();
+                       key_to_curve(actkey, cu, &cu->nurb);
+               }
+
+               if(editnurb) {
+                       freeNurblist(&editnurb->nurbs);
+                       free_editNurb_keyIndex(editnurb);
+                       editnurb->keyindex= NULL;
+               } else {
+                       editnurb= MEM_callocN(sizeof(EditNurb), "editnurb");
+                       cu->editnurb= editnurb;
+               }
+
                nu= cu->nurb.first;
                cu->lastsel= NULL;   /* for select row */
-               
+
                while(nu) {
                        newnu= duplicateNurb(nu);
                        test2DNurb(newnu);      // after join, or any other creation of curve
-                       BLI_addtail(editnurb, newnu);
+                       BLI_addtail(&editnurb->nurbs, newnu);
 
                        if (nu_act == NULL && isNurbsel(nu)) {
                                nu_act= newnu;
@@ -344,26 +1031,30 @@ void make_editNurb(Object *obedit)
 
                        nu= nu->next;
                }
-               
-               actkey = ob_get_keyblock(obedit);
+
                if(actkey) {
-                       // XXX strcpy(G.editModeTitleExtra, "(Key) ");
-                       key_to_curve(actkey, cu, editnurb);
+                       init_editNurb_keyIndex(editnurb, &cu->nurb);
                }
        }
 }
 
-void free_editNurb(Object *obedit)
+void free_curve_editNurb (Curve *cu)
 {
-       Curve *cu= obedit->data;
-
        if(cu->editnurb) {
-               freeNurblist(cu->editnurb);
+               freeNurblist(&cu->editnurb->nurbs);
+               free_editNurb_keyIndex(cu->editnurb);
                MEM_freeN(cu->editnurb);
                cu->editnurb= NULL;
        }
 }
 
+void free_editNurb(Object *obedit)
+{
+       Curve *cu= obedit->data;
+
+       free_curve_editNurb(cu);
+}
+
 void CU_deselect_all(Object *obedit)
 {
        ListBase *editnurb= curve_get_editcurve(obedit);
@@ -433,7 +1124,7 @@ static int separate_exec(bContext *C, wmOperator *op)
        Object *oldob, *newob;
        Base *oldbase, *newbase;
        Curve *oldcu, *newcu;
-       ListBase *oldedit, *newedit;
+       EditNurb *oldedit, *newedit;
 
        oldbase= CTX_data_active_base(C);
        oldob= oldbase->object;
@@ -459,15 +1150,16 @@ static int separate_exec(bContext *C, wmOperator *op)
        /* 2. put new object in editmode and clear it */
        make_editNurb(newob);
        newedit= newcu->editnurb;
-       freeNurblist(newedit);
+       freeNurblist(&newedit->nurbs);
+       free_editNurb_keyIndex(newedit);
 
        /* 3. move over parts from old object */
-       for(nu= oldedit->first; nu; nu=nu1) {
+       for(nu= oldedit->nurbs.first; nu; nu=nu1) {
                nu1= nu->next;
 
                if(isNurbsel(nu)) {
-                       BLI_remlink(oldedit, nu);
-                       BLI_addtail(newedit, nu);
+                       BLI_remlink(&oldedit->nurbs, nu);
+                       BLI_addtail(&newedit->nurbs, nu);
                }
        }
 
@@ -679,6 +1371,7 @@ static int deleteflagNurb(bContext *C, wmOperator *op, int flag)
                }
                if(a==0) {
                        BLI_remlink(editnurb, nu);
+                       keyIndex_delNurb(cu->editnurb, nu);
                        freeNurb(nu); nu=NULL;
                }
                else {
@@ -707,10 +1400,13 @@ static int deleteflagNurb(bContext *C, wmOperator *op, int flag)
                                        if((bp->f1 & flag)==0) {
                                                memcpy(bpn, bp, nu->pntsu*sizeof(BPoint));
                                                bpn+= nu->pntsu;
+                                       } else {
+                                               keyIndex_delBP(cu->editnurb, bp);
                                        }
                                        bp+= nu->pntsu;
                                }
                                nu->pntsv= newv;
+                               keyIndex_updateBP(cu->editnurb, nu->bp, newbp, newv * nu->pntsu, 1);
                                MEM_freeN(nu->bp);
                                nu->bp= newbp;
                                clamp_nurb_order_v(nu);
@@ -744,9 +1440,12 @@ static int deleteflagNurb(bContext *C, wmOperator *op, int flag)
                                                        if((bp->f1 & flag)==0) {
                                                                *bpn= *bp;
                                                                bpn++;
+                                                       } else {
+                                                               keyIndex_delBP(cu->editnurb, bp);
                                                        }
                                                }
                                        }
+                                       keyIndex_updateBP(cu->editnurb, nu->bp, newbp, newu * nu->pntsv, 1);
                                        MEM_freeN(nu->bp);
                                        nu->bp= newbp;
                                        if(newu==1 && nu->pntsv>1) {    /* make a U spline */
@@ -772,13 +1471,13 @@ static int deleteflagNurb(bContext *C, wmOperator *op, int flag)
 }
 
 /* only for OB_SURF */
-static short extrudeflagNurb(ListBase *editnurb, int flag)
+static short extrudeflagNurb(EditNurb *editnurb, int flag)
 {
        Nurb *nu;
        BPoint *bp, *bpn, *newbp;
        int ok= 0, a, u, v, len;
 
-       nu= editnurb->first;
+       nu= editnurb->nurbs.first;
        while(nu) {
 
                if(nu->pntsv==1) {
@@ -794,9 +1493,9 @@ static short extrudeflagNurb(ListBase *editnurb, int flag)
                                ok= 1;
                                newbp =
                                        (BPoint*)MEM_mallocN(2 * nu->pntsu * sizeof(BPoint), "extrudeNurb1");
-                               memcpy(newbp, nu->bp, nu->pntsu*sizeof(BPoint) );
+                               ED_curve_bpcpy(editnurb, newbp, nu->bp, nu->pntsu);
                                bp= newbp+ nu->pntsu;
-                               memcpy(bp, nu->bp, nu->pntsu*sizeof(BPoint) );
+                               ED_curve_bpcpy(editnurb, bp, nu->bp, nu->pntsu);
                                MEM_freeN(nu->bp);
                                nu->bp= newbp;
                                a= nu->pntsu;
@@ -813,7 +1512,7 @@ static short extrudeflagNurb(ListBase *editnurb, int flag)
                        }
                }
                else {
-                       /* which row or collumn is selected */
+                       /* which row or column is selected */
 
                        if( isNurbselUV(nu, &u, &v, flag) ) {
 
@@ -832,14 +1531,14 @@ static short extrudeflagNurb(ListBase *editnurb, int flag)
                                                                                  * sizeof(BPoint), "extrudeNurb1");
                                        if(u==0) {
                                                len= nu->pntsv*nu->pntsu;
-                                               memcpy(newbp+nu->pntsu, nu->bp, len*sizeof(BPoint) );
-                                               memcpy(newbp, nu->bp, nu->pntsu*sizeof(BPoint) );
+                                               ED_curve_bpcpy(editnurb, newbp+nu->pntsu, nu->bp, len);
+                                               ED_curve_bpcpy(editnurb, newbp, nu->bp, nu->pntsu);
                                                bp= newbp;
                                        }
                                        else {
                                                len= nu->pntsv*nu->pntsu;
-                                               memcpy(newbp, nu->bp, len*sizeof(BPoint) );
-                                               memcpy(newbp+len, nu->bp+len-nu->pntsu, nu->pntsu*sizeof(BPoint) );
+                                               ED_curve_bpcpy(editnurb, newbp, nu->bp, len);
+                                               ED_curve_bpcpy(editnurb, newbp+len, nu->bp+len-nu->pntsu, nu->pntsu);
                                                bp= newbp+len;
                                        }
 
@@ -866,7 +1565,7 @@ static short extrudeflagNurb(ListBase *editnurb, int flag)
                                                        bpn->f1 |= flag;
                                                        bpn++;
                                                }
-                                               memcpy(bpn, bp, nu->pntsu*sizeof(BPoint));
+                                               ED_curve_bpcpy(editnurb, bpn, bp, nu->pntsu);
                                                bp+= nu->pntsu;
                                                bpn+= nu->pntsu;
                                                if(v== nu->pntsu-1) {
@@ -1068,13 +1767,16 @@ static void adduplicateflagNurb(Object *obedit, short flag)
 static int switch_direction_exec(bContext *C, wmOperator *op)
 {
        Object *obedit= CTX_data_edit_object(C);
-       ListBase *editnurb= curve_get_editcurve(obedit);
+       Curve *cu= (Curve*)obedit->data;
+       EditNurb *editnurb= cu->editnurb;
        Nurb *nu;
-       
-       for(nu= editnurb->first; nu; nu= nu->next)
-               if(isNurbsel(nu))
+
+       for(nu= editnurb->nurbs.first; nu; nu= nu->next)
+               if(isNurbsel(nu)) {
                        switchdirectionNurb(nu);
-       
+                       keyData_switchDirectionNurb(cu, nu);
+               }
+
        DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
@@ -3004,7 +3706,7 @@ static int make_segment_exec(bContext *C, wmOperator *op)
        /* joins 2 curves */
        Object *obedit= CTX_data_edit_object(C);
        Curve *cu= obedit->data;
-       ListBase *editnurb= curve_get_editcurve(obedit);
+       ListBase *nubase= curve_get_editcurve(obedit);
        Nurb *nu, *nu1=0, *nu2=0;
        BezTriple *bezt;
        BPoint *bp;
@@ -3012,7 +3714,7 @@ static int make_segment_exec(bContext *C, wmOperator *op)
        int a;
 
        /* first decide if this is a surface merge! */
-       if(obedit->type==OB_SURF) nu= editnurb->first;
+       if(obedit->type==OB_SURF) nu= nubase->first;
        else nu= NULL;
        
        while(nu) {
@@ -3035,7 +3737,7 @@ static int make_segment_exec(bContext *C, wmOperator *op)
                return merge_nurb(C, op);
        
        /* find both nurbs and points, nu1 will be put behind nu2 */
-       for(nu= editnurb->first; nu; nu= nu->next) {
+       for(nu= nubase->first; nu; nu= nu->next) {
                if((nu->flagu & CU_NURB_CYCLIC)==0) {    /* not cyclic */
                        if(nu->type == CU_BEZIER) {
                                bezt= nu->bezt;
@@ -3046,6 +3748,7 @@ static int make_segment_exec(bContext *C, wmOperator *op)
                                                if( BEZSELECTED_HIDDENHANDLES(cu, bezt) ) {
                                                        nu1= nu;
                                                        switchdirectionNurb(nu);
+                                                       keyData_switchDirectionNurb(cu, nu);
                                                }
                                        }
                                }
@@ -3053,6 +3756,7 @@ static int make_segment_exec(bContext *C, wmOperator *op)
                                        if( BEZSELECTED_HIDDENHANDLES(cu, bezt) ) {
                                                nu2= nu;
                                                switchdirectionNurb(nu);
+                                               keyData_switchDirectionNurb(cu, nu);
                                        }
                                        else {
                                                bezt= bezt+(nu->pntsu-1);
@@ -3072,6 +3776,7 @@ static int make_segment_exec(bContext *C, wmOperator *op)
                                                if( bp->f1 & SELECT ) {
                                                        nu1= nu;
                                                        switchdirectionNurb(nu);
+                                                       keyData_switchDirectionNurb(cu, nu);
                                                }
                                        }
                                }
@@ -3079,6 +3784,7 @@ static int make_segment_exec(bContext *C, wmOperator *op)
                                        if( bp->f1 & SELECT ) {
                                                nu2= nu;
                                                switchdirectionNurb(nu);
+                                               keyData_switchDirectionNurb(cu, nu);
                                        }
                                        else {
                                                bp= bp+(nu->pntsu-1);
@@ -3097,27 +3803,28 @@ static int make_segment_exec(bContext *C, wmOperator *op)
                        if(nu1->type == CU_BEZIER) {
                                bezt =
                                        (BezTriple*)MEM_mallocN((nu1->pntsu+nu2->pntsu) * sizeof(BezTriple), "addsegmentN");
-                               memcpy(bezt, nu2->bezt, nu2->pntsu*sizeof(BezTriple));
-                               memcpy(bezt+nu2->pntsu, nu1->bezt, nu1->pntsu*sizeof(BezTriple));
+                               ED_curve_beztcpy(cu->editnurb, bezt, nu2->bezt, nu2->pntsu);
+                               ED_curve_beztcpy(cu->editnurb, bezt+nu2->pntsu, nu1->bezt, nu1->pntsu);
+
                                MEM_freeN(nu1->bezt);
                                nu1->bezt= bezt;
                                nu1->pntsu+= nu2->pntsu;
-                               BLI_remlink(editnurb, nu2);
+                               BLI_remlink(nubase, nu2);
                                freeNurb(nu2); nu2= NULL;
                                calchandlesNurb(nu1);
                        }
                        else {
                                bp =
                                        (BPoint*)MEM_mallocN((nu1->pntsu+nu2->pntsu) * sizeof(BPoint), "addsegmentN2");
-                               memcpy(bp, nu2->bp, nu2->pntsu*sizeof(BPoint) );
-                               memcpy(bp+nu2->pntsu, nu1->bp, nu1->pntsu*sizeof(BPoint));
+                               ED_curve_bpcpy(cu->editnurb, bp, nu2->bp, nu2->pntsu);
+                               ED_curve_bpcpy(cu->editnurb, bp+nu2->pntsu, nu1->bp, nu1->pntsu);
                                MEM_freeN(nu1->bp);
                                nu1->bp= bp;
 
                                a= nu1->pntsu+nu1->orderu;
 
                                nu1->pntsu+= nu2->pntsu;
-                               BLI_remlink(editnurb, nu2);
+                               BLI_remlink(nubase, nu2);
 
                                /* now join the knots */
                                if(nu1->type == CU_NURBS) {
@@ -3263,6 +3970,7 @@ int mouse_nurb(bContext *C, short mval[2], int extend)
 */
 static int spin_nurb(bContext *C, Scene *scene, Object *obedit, float *dvec, float *cent, short mode)
 {
+       Curve *cu= (Curve*)obedit->data;
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu;
        float si,phi,n[3],q[4],cmat[3][3],tmat[3][3],imat[3][3];
@@ -3311,7 +4019,7 @@ static int spin_nurb(bContext *C, Scene *scene, Object *obedit, float *dvec, flo
        ok= 1;
 
        for(a=0;a<7;a++) {
-               if(mode==0 || mode==2) ok= extrudeflagNurb(editnurb, 1);
+               if(mode==0 || mode==2) ok= extrudeflagNurb(cu->editnurb, 1);
                else adduplicateflagNurb(obedit, 1);
 
                if(ok==0)
@@ -3405,7 +4113,8 @@ void CURVE_OT_spin(wmOperatorType *ot)
 static int addvert_Nurb(bContext *C, short mode, float location[3])
 {
        Object *obedit= CTX_data_edit_object(C);
-       ListBase *editnurb= curve_get_editcurve(obedit);
+       Curve *cu= (Curve*)obedit->data;
+       EditNurb *editnurb= cu->editnurb;
        Nurb *nu;
        BezTriple *bezt, *newbezt = NULL;
        BPoint *bp, *newbp = NULL;
@@ -3414,7 +4123,7 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
        copy_m3_m4(mat, obedit->obmat);
        invert_m3_m3(imat,mat);
 
-       findselectedNurbvert(editnurb, &nu, &bezt, &bp);
+       findselectedNurbvert(&editnurb->nurbs, &nu, &bezt, &bp);
        if(bezt==0 && bp==0) return OPERATOR_CANCELLED;
 
        if(nu->type == CU_BEZIER) {
@@ -3423,7 +4132,7 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
                        BEZ_DESEL(bezt);
                        newbezt =
                                (BezTriple*)MEM_callocN((nu->pntsu+1) * sizeof(BezTriple), "addvert_Nurb");
-                       memcpy(newbezt+1, bezt, nu->pntsu*sizeof(BezTriple));
+                       ED_curve_beztcpy(editnurb, newbezt+1, bezt, nu->pntsu);
                        *newbezt= *bezt;
                        BEZ_SEL(newbezt);
                        newbezt->h2= newbezt->h1;
@@ -3436,7 +4145,7 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
                        BEZ_DESEL(bezt);
                        newbezt =
                                (BezTriple*)MEM_callocN((nu->pntsu+1) * sizeof(BezTriple), "addvert_Nurb");
-                       memcpy(newbezt, nu->bezt, nu->pntsu*sizeof(BezTriple));
+                       ED_curve_beztcpy(editnurb, newbezt, nu->bezt, nu->pntsu);
                        *(newbezt+nu->pntsu)= *bezt;
                        VECCOPY(temp, bezt->vec[1]);
                        MEM_freeN(nu->bezt);
@@ -3473,7 +4182,7 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
                        bp->f1= 0;
                        newbp =
                                (BPoint*)MEM_callocN((nu->pntsu+1) * sizeof(BPoint), "addvert_Nurb3");
-                       memcpy(newbp+1, bp, nu->pntsu*sizeof(BPoint));
+                       ED_curve_bpcpy(editnurb, newbp+1, bp, nu->pntsu);
                        *newbp= *bp;
                        newbp->f1= 1;
                        MEM_freeN(nu->bp);
@@ -3484,7 +4193,7 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
                        bp->f1= 0;
                        newbp =
                                (BPoint*)MEM_callocN((nu->pntsu+1) * sizeof(BPoint), "addvert_Nurb4");
-                       memcpy(newbp, nu->bp, nu->pntsu*sizeof(BPoint));
+                       ED_curve_bpcpy(editnurb, newbp, nu->bp, nu->pntsu);
                        *(newbp+nu->pntsu)= *bp;
                        MEM_freeN(nu->bp);
                        nu->bp= newbp;
@@ -3573,11 +4282,11 @@ static int extrude_exec(bContext *C, wmOperator *op)
 {
        Object *obedit= CTX_data_edit_object(C);
        Curve *cu= obedit->data;
-       ListBase *editnurb= curve_get_editcurve(obedit);
+       EditNurb *editnurb= cu->editnurb;
        Nurb *nu;
        
        /* first test: curve? */
-       for(nu= editnurb->first; nu; nu= nu->next)
+       for(nu= editnurb->nurbs.first; nu; nu= nu->next)
                if(nu->pntsv==1 && isNurbsel_count(cu, nu)==1)
                        break;
 
@@ -4333,7 +5042,7 @@ static void select_nth_bp(Nurb *nu, BPoint *bp, int nth)
 int CU_select_nth(Object *obedit, int nth)
 {
        Curve *cu= (Curve*)obedit->data;
-       ListBase *nubase= cu->editnurb;
+       ListBase *nubase= ED_curve_editnurbs(cu);
        Nurb *nu;
        int ok=0;
 
@@ -4441,15 +5150,20 @@ static int delete_exec(bContext *C, wmOperator *op)
 {
        Object *obedit= CTX_data_edit_object(C);
        Curve *cu= obedit->data;
-       ListBase *editnurb= curve_get_editcurve(obedit);
+       EditNurb *editnurb= cu->editnurb;
+       ListBase *nubase= &editnurb->nurbs;
        Nurb *nu, *next, *nu1;
        BezTriple *bezt, *bezt1, *bezt2;
        BPoint *bp, *bp1, *bp2;
        int a, cut= 0, type= RNA_enum_get(op->ptr, "type");
 
        if(obedit->type==OB_SURF) {
-               if(type==0) deleteflagNurb(C, op, 1);
-               else freeNurblist(editnurb);
+               if(type==0) {
+                       deleteflagNurb(C, op, 1);
+               } else {
+                       keyIndex_delNurbList(editnurb, nubase);
+                       freeNurblist(nubase);
+               }
 
                WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
                DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
@@ -4459,7 +5173,7 @@ static int delete_exec(bContext *C, wmOperator *op)
 
        if(type==0) {
                /* first loop, can we remove entire pieces? */
-               nu= editnurb->first;
+               nu= nubase->first;
                while(nu) {
                        next= nu->next;
                        if(nu->type == CU_BEZIER) {
@@ -4473,7 +5187,8 @@ static int delete_exec(bContext *C, wmOperator *op)
                                                bezt++;
                                        }
                                        if(a==0) {
-                                               BLI_remlink(editnurb, nu);
+                                               BLI_remlink(nubase, nu);
+                                               keyIndex_delNurb(editnurb, nu);
                                                freeNurb(nu); nu= NULL;
                                        }
                                }
@@ -4489,7 +5204,8 @@ static int delete_exec(bContext *C, wmOperator *op)
                                                bp++;
                                        }
                                        if(a==0) {
-                                               BLI_remlink(editnurb, nu);
+                                               BLI_remlink(nubase, nu);
+                                               keyIndex_delNurb(editnurb, nu);
                                                freeNurb(nu); nu= NULL;
                                        }
                                }
@@ -4505,18 +5221,21 @@ static int delete_exec(bContext *C, wmOperator *op)
                        nu= next;
                }
                /* 2nd loop, delete small pieces: just for curves */
-               nu= editnurb->first;
+               nu= nubase->first;
                while(nu) {
                        next= nu->next;
                        type= 0;
                        if(nu->type == CU_BEZIER) {
+                               int delta= 0;
                                bezt= nu->bezt;
                                for(a=0;a<nu->pntsu;a++) {
                                        if( BEZSELECTED_HIDDENHANDLES(cu, bezt) ) {
                                                memmove(bezt, bezt+1, (nu->pntsu-a-1)*sizeof(BezTriple));
+                                               keyIndex_delBezt(editnurb, bezt + delta);
                                                nu->pntsu--;
                                                a--;
                                                type= 1;
+                                               delta++;
                                        }
                                        else bezt++;
                                }
@@ -4524,20 +5243,24 @@ static int delete_exec(bContext *C, wmOperator *op)
                                        bezt1 =
                                                (BezTriple*)MEM_mallocN((nu->pntsu) * sizeof(BezTriple), "delNurb");
                                        memcpy(bezt1, nu->bezt, (nu->pntsu)*sizeof(BezTriple) );
+                                       keyIndex_updateBezt(editnurb, nu->bezt, bezt1, nu->pntsu, 1);
                                        MEM_freeN(nu->bezt);
                                        nu->bezt= bezt1;
                                        calchandlesNurb(nu);
                                }
                        }
                        else if(nu->pntsv==1) {
+                               int delta= 0;
                                bp= nu->bp;
                                
                                for(a=0;a<nu->pntsu;a++) {
                                        if( bp->f1 & SELECT ) {
                                                memmove(bp, bp+1, (nu->pntsu-a-1)*sizeof(BPoint));
+                                               keyIndex_delBP(editnurb, bp + delta);
                                                nu->pntsu--;
                                                a--;
                                                type= 1;
+                                               delta++;
                                        }
                                        else {
                                                bp++;
@@ -4546,6 +5269,7 @@ static int delete_exec(bContext *C, wmOperator *op)
                                if(type) {
                                        bp1 = (BPoint*)MEM_mallocN(nu->pntsu * sizeof(BPoint), "delNurb2");
                                        memcpy(bp1, nu->bp, (nu->pntsu)*sizeof(BPoint) );
+                                       keyIndex_updateBP(editnurb, nu->bp, bp1, nu->pntsu, 1);
                                        MEM_freeN(nu->bp);
                                        nu->bp= bp1;
                                        
@@ -4565,7 +5289,7 @@ static int delete_exec(bContext *C, wmOperator *op)
                /* find the 2 selected points */
                bezt1= bezt2= 0;
                bp1= bp2= 0;
-               nu= editnurb->first;
+               nu= nubase->first;
                nu1= 0;
                while(nu) {
                        next= nu->next;
@@ -4628,16 +5352,17 @@ static int delete_exec(bContext *C, wmOperator *op)
                if(nu1) {
                        if(bezt1) {
                                if(nu1->pntsu==2) {     /* remove completely */
-                                       BLI_remlink(editnurb, nu);
+                                       BLI_remlink(nubase, nu);
                                        freeNurb(nu); nu = NULL;
                                }
                                else if(nu1->flagu & CU_NURB_CYCLIC) {  /* cyclic */
                                        bezt =
                                                (BezTriple*)MEM_mallocN((cut+1) * sizeof(BezTriple), "delNurb1");
-                                       memcpy(bezt, nu1->bezt,(cut+1)*sizeof(BezTriple));
+                                       ED_curve_beztcpy(editnurb, bezt, nu1->bezt, cut+1);
                                        a= nu1->pntsu-cut-1;
-                                       memcpy(nu1->bezt, bezt2, a*sizeof(BezTriple));
-                                       memcpy(nu1->bezt+a, bezt, (cut+1)*sizeof(BezTriple));
+                                       ED_curve_beztcpy(editnurb, nu1->bezt, bezt2, a);
+                                       ED_curve_beztcpy(editnurb, nu1->bezt+a, bezt, cut+1);
+
                                        nu1->flagu &= ~CU_NURB_CYCLIC;
                                        MEM_freeN(bezt);
                                        calchandlesNurb(nu);
@@ -4649,15 +5374,15 @@ static int delete_exec(bContext *C, wmOperator *op)
                                        nu =
                                                (Nurb*)MEM_mallocN(sizeof(Nurb), "delNurb2");
                                        memcpy(nu, nu1, sizeof(Nurb));
-                                       BLI_addtail(editnurb, nu);
+                                       BLI_addtail(nubase, nu);
                                        nu->bezt =
                                                (BezTriple*)MEM_mallocN((cut+1) * sizeof(BezTriple), "delNurb3");
-                                       memcpy(nu->bezt, nu1->bezt,(cut+1)*sizeof(BezTriple));
+                                       ED_curve_beztcpy(editnurb, nu->bezt, nu1->bezt, cut+1);
                                        a= nu1->pntsu-cut-1;
                                        
                                        bezt =
                                                (BezTriple*)MEM_mallocN(a * sizeof(BezTriple), "delNurb4");
-                                       memcpy(bezt, nu1->bezt+cut+1,a*sizeof(BezTriple));
+                                       ED_curve_beztcpy(editnurb, bezt, nu1->bezt+cut+1, a);
                                        MEM_freeN(nu1->bezt);
                                        nu1->bezt= bezt;
                                        nu1->pntsu= a;
@@ -4670,30 +5395,31 @@ static int delete_exec(bContext *C, wmOperator *op)
                        }
                        else if(bp1) {
                                if(nu1->pntsu==2) {     /* remove completely */
-                                       BLI_remlink(editnurb, nu);
+                                       BLI_remlink(nubase, nu);
                                        freeNurb(nu); nu= NULL;
                                }
                                else if(nu1->flagu & CU_NURB_CYCLIC) {  /* cyclic */
                                        bp =
                                                (BPoint*)MEM_mallocN((cut+1) * sizeof(BPoint), "delNurb5");
-                                       memcpy(bp, nu1->bp,(cut+1)*sizeof(BPoint));
+                                       ED_curve_bpcpy(editnurb, bp, nu1->bp, cut+1);
                                        a= nu1->pntsu-cut-1;
-                                       memcpy(nu1->bp, bp2, a*sizeof(BPoint));
-                                       memcpy(nu1->bp+a, bp, (cut+1)*sizeof(BPoint));
+                                       ED_curve_bpcpy(editnurb, nu1->bp, bp2, a);
+                                       ED_curve_bpcpy(editnurb, nu1->bp+a, bp, cut+1);
+
                                        nu1->flagu &= ~CU_NURB_CYCLIC;
                                        MEM_freeN(bp);
                                }
                                else {                  /* add new curve */
                                        nu = (Nurb*)MEM_mallocN(sizeof(Nurb), "delNurb6");
                                        memcpy(nu, nu1, sizeof(Nurb));
-                                       BLI_addtail(editnurb, nu);
+                                       BLI_addtail(nubase, nu);
                                        nu->bp =
                                                (BPoint*)MEM_mallocN((cut+1) * sizeof(BPoint), "delNurb7");
-                                       memcpy(nu->bp, nu1->bp,(cut+1)*sizeof(BPoint));
+                                       ED_curve_bpcpy(editnurb, nu->bp, nu1->bp, cut+1);
                                        a= nu1->pntsu-cut-1;
                                        bp =
                                                (BPoint*)MEM_mallocN(a * sizeof(BPoint), "delNurb8");
-                                       memcpy(bp, nu1->bp+cut+1,a*sizeof(BPoint));
+                                       ED_curve_bpcpy(editnurb, bp, nu1->bp+cut+1, a);
                                        MEM_freeN(nu1->bp);
                                        nu1->bp= bp;
                                        nu1->pntsu= a;
@@ -4702,8 +5428,10 @@ static int delete_exec(bContext *C, wmOperator *op)
                        }
                }
        }
-       else if(type==2)
-               freeNurblist(editnurb);
+       else if(type==2) {
+               keyIndex_delNurbList(editnurb, nubase);
+               freeNurblist(nubase);
+       }
 
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
        DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
@@ -5135,6 +5863,7 @@ Nurb *add_nurbs_primitive(bContext *C, float mat[4][4], int type, int newname)
                break;
        case CU_PRIM_TUBE:      /* tube */
                if( cutype==CU_NURBS ) {
+                       Curve *cu= (Curve*)obedit->data;
                        
                        if(newname) {
                                rename_id((ID *)obedit, "SurfTube");
@@ -5149,7 +5878,7 @@ Nurb *add_nurbs_primitive(bContext *C, float mat[4][4], int type, int newname)
                        vec[2]= -grid;
 
                        translateflagNurb(editnurb, 1, vec);
-                       extrudeflagNurb(editnurb, 1);
+                       extrudeflagNurb(cu->editnurb, 1);
                        vec[0]= -2*vec[0]; 
                        vec[1]= -2*vec[1]; 
                        vec[2]= -2*vec[2];
@@ -5644,12 +6373,18 @@ static void undoCurve_to_editCurve(void *ucu, void *cue)
        Curve *cu= cue;
        UndoCurve *undoCurve= ucu;
        ListBase *undobase= &undoCurve->nubase;
-       ListBase *editbase= cu->editnurb;
+       ListBase *editbase= ED_curve_editnurbs(cu);
        Nurb *nu, *newnu;
+       EditNurb *editnurb= cu->editnurb;
        void *lastsel= NULL;
 
        freeNurblist(editbase);
 
+       if (undoCurve->undoIndex) {
+               BLI_ghash_free(editnurb->keyindex, NULL, (GHashValFreeFP)free_nodeKeyIndex);
+               editnurb->keyindex= dupli_keyIndexHash(undoCurve->undoIndex);
+       }
+
        /* copy  */
        for(nu= undobase->first; nu; nu= nu->next) {
                newnu= duplicateNurb(nu);
@@ -5658,6 +6393,10 @@ static void undoCurve_to_editCurve(void *ucu, void *cue)
                        lastsel= undo_check_lastsel(undoCurve->lastsel, nu, newnu);
                }
 
+               if (editnurb->keyindex) {
+                       keyIndex_updateNurb(editnurb, nu, newnu);
+               }
+
                BLI_addtail(editbase, newnu);
        }
 
@@ -5667,13 +6406,19 @@ static void undoCurve_to_editCurve(void *ucu, void *cue)
 static void *editCurve_to_undoCurve(void *cue)
 {
        Curve *cu= cue;
-       ListBase *nubase= cu->editnurb;
+       ListBase *nubase= ED_curve_editnurbs(cu);
        UndoCurve *undoCurve;
+       EditNurb *editnurb= cu->editnurb, tmpEditnurb;
        Nurb *nu, *newnu;
        void *lastsel= NULL;
 
        undoCurve= MEM_callocN(sizeof(UndoCurve), "undoCurve");
 
+       if (editnurb->keyindex) {
+               undoCurve->undoIndex= dupli_keyIndexHash(editnurb->keyindex);
+               tmpEditnurb.keyindex= undoCurve->undoIndex;
+       }
+
        /* copy  */
        for(nu= nubase->first; nu; nu= nu->next) {
                newnu= duplicateNurb(nu);
@@ -5682,6 +6427,10 @@ static void *editCurve_to_undoCurve(void *cue)
                        lastsel= undo_check_lastsel(cu->lastsel, nu, newnu);
                }
 
+               if (undoCurve->undoIndex) {
+                       keyIndex_updateNurb(&tmpEditnurb, nu, newnu);
+               }
+
                BLI_addtail(&undoCurve->nubase, newnu);
        }
 
@@ -5696,6 +6445,10 @@ static void free_undoCurve(void *ucv)
 
        freeNurblist(&undoCurve->nubase);
 
+       if (undoCurve->undoIndex) {
+               BLI_ghash_free(undoCurve->undoIndex, NULL, (GHashValFreeFP)free_nodeKeyIndex);
+       }
+
        MEM_freeN(undoCurve);
 }
 
@@ -5710,3 +6463,24 @@ void undo_push_curve(bContext *C, char *name)
 {
        undo_editmode_push(C, name, get_data, free_undoCurve, undoCurve_to_editCurve, editCurve_to_undoCurve, NULL);
 }
+
+/* Get list of nurbs from editnurbs structure */
+ListBase *ED_curve_editnurbs(Curve *cu)
+{
+       if (cu->editnurb) {
+               return &cu->editnurb->nurbs;
+       }
+
+       return NULL;
+}
+void ED_curve_beztcpy(EditNurb *editnurb, BezTriple *dst, BezTriple *src, int count)
+{
+       memcpy(dst, src, count*sizeof(BezTriple));
+       keyIndex_updateBezt(editnurb, src, dst, count, 0);
+}
+
+void ED_curve_bpcpy(EditNurb *editnurb, BPoint *dst, BPoint *src, int count)
+{
+       memcpy(dst, src, count*sizeof(BPoint));
+       keyIndex_updateBP(editnurb, src, dst, count, 0);
+}
index a229d91..0ff98b5 100644 (file)
@@ -37,6 +37,10 @@ struct Text;
 struct View3D;
 struct wmOperator;
 struct wmKeyConfig;
+struct Curve;
+struct EditNurb;
+struct BezTriple;
+struct BPoint;
 
 /* curve_ops.c */
 void   ED_operatortypes_curve(void);
@@ -55,6 +59,8 @@ void  load_editNurb   (struct Object *obedit);
 void   make_editNurb   (struct Object *obedit);
 void   free_editNurb   (struct Object *obedit);
 
+void   free_curve_editNurb     (struct Curve *cu);
+
 int    mouse_nurb              (struct bContext *C, short mval[2], int extend);
 
 struct Nurb *add_nurbs_primitive(struct bContext *C, float mat[4][4], int type, int newname);
@@ -72,6 +78,10 @@ void free_editText   (struct Object *obedit);
 void   ED_text_to_object(struct bContext *C, struct Text *text, int split_lines);
 
 int CU_select_nth(struct Object *obedit, int nth);
+ListBase *ED_curve_editnurbs(struct Curve *cu);
+
+void ED_curve_beztcpy(struct EditNurb *editnurb, struct BezTriple *dst, struct BezTriple *src, int count);
+void ED_curve_bpcpy(struct EditNurb *editnurb, struct BPoint *dst, struct BPoint *src, int count);
 
 #endif /* ED_CURVE_H */
 
index 4a94756..6e8c3b7 100644 (file)
@@ -310,11 +310,11 @@ static int material_slot_assign_exec(bContext *C, wmOperator *op)
                        }
                }
                else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
-                       ListBase *editnurb= ((Curve*)ob->data)->editnurb;
                        Nurb *nu;
+                       ListBase *nurbs= ED_curve_editnurbs((Curve*)ob->data);
 
-                       if(editnurb) {
-                               for(nu= editnurb->first; nu; nu= nu->next)
+                       if(nurbs) {
+                               for(nu= nurbs->first; nu; nu= nu->next)
                                        if(isNurbsel(nu))
                                                nu->mat_nr= nu->charidx= ob->actcol-1;
                        }
@@ -368,13 +368,13 @@ static int material_slot_de_select(bContext *C, int select)
                }
        }
        else if ELEM(ob->type, OB_CURVE, OB_SURF) {
-               ListBase *editnurb= ((Curve*)ob->data)->editnurb;
+               ListBase *nurbs= ED_curve_editnurbs((Curve*)ob->data);
                Nurb *nu;
                BPoint *bp;
                BezTriple *bezt;
                int a;
 
-               for(nu= editnurb->first; nu; nu=nu->next) {
+               for(nu= nurbs->first; nu; nu=nu->next) {
                        if(nu->mat_nr==ob->actcol-1) {
                                if(nu->bezt) {
                                        a= nu->pntsu;
index cf23c48..1b5cf13 100644 (file)
@@ -45,6 +45,7 @@
 
 #include "ED_armature.h"
 #include "ED_mesh.h"
+#include "ED_curve.h" /* for ED_curve_editnurbs */
 
 #include "BLI_editVert.h"
 
@@ -187,8 +188,9 @@ static void stats_object_edit(Object *obedit, SceneStats *stats)
                BezTriple *bezt;
                BPoint *bp;
                int a;
+               ListBase *nurbs= ED_curve_editnurbs(cu);
 
-               for(nu=cu->editnurb->first; nu; nu=nu->next) {
+               for(nu=nurbs->first; nu; nu=nu->next) {
                        if(nu->type == CU_BEZIER) {
                                bezt= nu->bezt;
                                a= nu->pntsu;
index 0f483f4..0b2d52d 100644 (file)
@@ -52,6 +52,7 @@
 #include "UI_resources.h"
 #include "UI_interface.h"
 
+
 #include "info_intern.h"       // own include
 
 /* ******************** default callbacks for info space ***************** */
index f5a1407..981c111 100644 (file)
@@ -86,6 +86,7 @@
 #include "ED_screen.h"
 #include "ED_sculpt.h"
 #include "ED_types.h"
+#include "ED_curve.h" /* for ED_curve_editnurbs */
 
 #include "UI_resources.h"
 
@@ -1610,10 +1611,11 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb
        short s[2] = {IS_CLIPPED, 0};
        Nurb *nu;
        int i;
+       ListBase *nurbs= ED_curve_editnurbs(cu);
 
        ED_view3d_local_clipping(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
 
-       for (nu= cu->editnurb->first; nu; nu=nu->next) {
+       for (nu= nurbs->first; nu; nu=nu->next) {
                if(nu->type == CU_BEZIER) {
                        for (i=0; i<nu->pntsu; i++) {
                                BezTriple *bezt = &nu->bezt[i];
@@ -5882,7 +5884,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        cu= ob->data;
 
                        if(cu->editnurb) {
-                               drawnurb(scene, v3d, rv3d, base, cu->editnurb->first, dt);
+                               ListBase *nurbs= ED_curve_editnurbs(cu);
+                               drawnurb(scene, v3d, rv3d, base, nurbs->first, dt);
                        }
                        else if(dt==OB_BOUNDBOX) {
                                if((v3d->flag2 & V3D_RENDER_OVERRIDE && v3d->drawtype >= OB_WIRE)==0)
index c75b785..19aaff2 100644 (file)
@@ -73,6 +73,7 @@
 #include "ED_mesh.h"
 #include "ED_screen.h"
 #include "ED_transform.h"
+#include "ED_curve.h"
 
 #include "UI_interface.h"
 #include "UI_resources.h"
@@ -205,8 +206,9 @@ static void v3d_editvertex_buts(const bContext *C, uiLayout *layout, View3D *v3d
                BPoint *bp;
                BezTriple *bezt;
                int a;
-               
-               nu= cu->editnurb->first;
+               ListBase *nurbs= ED_curve_editnurbs(cu);
+
+               nu= nurbs->first;
                while(nu) {
                        if(nu->type == CU_BEZIER) {
                                bezt= nu->bezt;
@@ -410,8 +412,9 @@ static void v3d_editvertex_buts(const bContext *C, uiLayout *layout, View3D *v3d
                        BPoint *bp;
                        BezTriple *bezt;
                        int a;
-                       
-                       nu= cu->editnurb->first;
+                       ListBase *nurbs= ED_curve_editnurbs(cu);
+
+                       nu= nurbs->first;
                        while(nu) {
                                if(nu->type == CU_BEZIER) {
                                        bezt= nu->bezt;
index ff716a6..160306e 100644 (file)
@@ -66,6 +66,7 @@
 #include "ED_armature.h"
 #include "ED_mesh.h"
 #include "ED_screen.h"
+#include "ED_curve.h" /* for ED_curve_editnurbs */
 
 #include "view3d_intern.h"
 
@@ -100,8 +101,9 @@ static void special_transvert_update(Scene *scene, Object *obedit)
                }
                else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
                        Curve *cu= obedit->data;
-                       Nurb *nu= cu->editnurb->first;
-                       
+                       ListBase *nurbs= ED_curve_editnurbs(cu);
+                       Nurb *nu= nurbs->first;
+
                        while(nu) {
                                test2DNurb(nu);
                                testhandlesNurb(nu); /* test for bezier too */
@@ -288,8 +290,9 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode)
        else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
                Curve *cu= obedit->data;
                int totmalloc= 0;
-               
-               for(nu= cu->editnurb->first; nu; nu= nu->next) {
+               ListBase *nurbs= ED_curve_editnurbs(cu);
+
+               for(nu= nurbs->first; nu; nu= nu->next) {
                        if(nu->type == CU_BEZIER)
                                totmalloc += 3*nu->pntsu;
                        else
@@ -297,7 +300,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode)
                }
                tv=transvmain= MEM_callocN(totmalloc*sizeof(TransVert), "maketransverts curve");
 
-               nu= cu->editnurb->first;
+               nu= nurbs->first;
                while(nu) {
                        if(nu->type == CU_BEZIER) {
                                a= nu->pntsu;
index 44a22da..dc731d7 100644 (file)
@@ -94,6 +94,7 @@
 #include "ED_mesh.h"
 #include "ED_types.h"
 #include "ED_uvedit.h"
+#include "ED_curve.h" /* for ED_curve_editnurbs */
 
 #include "UI_view2d.h"
 
@@ -1347,12 +1348,14 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
        int count=0, countsel=0;
        int propmode = t->flag & T_PROP_EDIT;
        short hide_handles = (cu->drawflag & CU_HIDE_HANDLES);
-       
+       ListBase *nurbs;
+
        /* to be sure */
        if(cu->editnurb==NULL) return;
 
        /* count total of vertices, check identical as in 2nd loop for making transdata! */
-       for(nu= cu->editnurb->first; nu; nu= nu->next) {
+       nurbs= ED_curve_editnurbs(cu);
+       for(nu= nurbs->first; nu; nu= nu->next) {
                if(nu->type == CU_BEZIER) {
                        for(a=0, bezt= nu->bezt; a<nu->pntsu; a++, bezt++) {
                                if(bezt->hide==0) {
@@ -1388,7 +1391,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
        invert_m3_m3(smtx, mtx);
 
        td = t->data;
-       for(nu= cu->editnurb->first; nu; nu= nu->next) {
+       for(nu= nurbs->first; nu; nu= nu->next) {
                if(nu->type == CU_BEZIER) {
                        TransData *head, *tail;
                        head = tail = td;
index 98ecb07..8d98255 100644 (file)
@@ -84,6 +84,7 @@
 #include "ED_space_api.h"
 #include "ED_uvedit.h"
 #include "ED_view3d.h"
+#include "ED_curve.h" /* for ED_curve_editnurbs */
 
 //#include "BDR_unwrapper.h"
 
@@ -636,14 +637,15 @@ void recalcData(TransInfo *t)
                if (t->obedit) {
                        if ELEM(t->obedit->type, OB_CURVE, OB_SURF) {
                                Curve *cu= t->obedit->data;
-                               Nurb *nu= cu->editnurb->first;
+                               ListBase *nurbs= ED_curve_editnurbs(cu);
+                               Nurb *nu= nurbs->first;
 
                                if(t->state != TRANS_CANCEL) {
                                        clipMirrorModifier(t, t->obedit);
                                }
 
                                DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA);  /* sets recalc flags */
-                               
+
                                if (t->state == TRANS_CANCEL) {
                                        while(nu) {
                                                calchandlesNurb(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */
index 016aca2..2a717f8 100644 (file)
@@ -73,6 +73,7 @@
 #include "ED_mesh.h"
 #include "ED_particle.h"
 #include "ED_view3d.h"
+#include "ED_curve.h" /* for ED_curve_editnurbs */
 
 #include "UI_resources.h"
 
@@ -311,8 +312,9 @@ int calc_manipulator_stats(const bContext *C)
                        Nurb *nu;
                        BezTriple *bezt;
                        BPoint *bp;
+                       ListBase *nurbs= ED_curve_editnurbs(cu);
 
-                       nu= cu->editnurb->first;
+                       nu= nurbs->first;
                        while(nu) {
                                if(nu->type == CU_BEZIER) {
                                        bezt= nu->bezt;
index e926762..8451b0c 100644 (file)
@@ -51,6 +51,7 @@
 
 #include "ED_armature.h"
 #include "ED_mesh.h"
+#include "ED_curve.h" /* for ED_curve_editnurbs */
 
 
 #include "RNA_define.h"
@@ -740,8 +741,9 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
                        Nurb *nu;
                        BezTriple *bezt;
                        int a;
-                       
-                       for (nu = cu->editnurb->first; nu; nu = nu->next)
+                       ListBase *nurbs= ED_curve_editnurbs(cu);
+
+                       for (nu = nurbs->first; nu; nu = nu->next)
                        {
                                /* only bezier has a normal */
                                if(nu->type == CU_BEZIER)
index 609c3a8..c13cb08 100644 (file)
@@ -48,6 +48,7 @@ struct VFont;
 struct AnimData;
 struct SelBox;
 struct EditFont;
+struct GHash;
 
 /* These two Lines with # tell makesdna this struct can be excluded. */
 #
@@ -150,6 +151,14 @@ typedef struct TextBox {
        float x, y, w, h;
 } TextBox;
 
+typedef struct EditNurb {
+       /* base of nurbs' list (old Curve->editnurb) */
+       ListBase nurbs;
+
+       /* index data for shape keys */
+       struct GHash *keyindex;
+} EditNurb;
+
 typedef struct Curve {
        ID id;
        struct AnimData *adt;           /* animation data (must be immediately after id for utilities to use it) */ 
@@ -159,7 +168,7 @@ typedef struct Curve {
        ListBase nurb;          /* actual data, called splines in rna */
        ListBase disp;
        
-       ListBase *editnurb;     /* edited data, not in file, use pointer so we can check for it */
+       EditNurb *editnurb;     /* edited data, not in file, use pointer so we can check for it */
        
        struct Object *bevobj, *taperobj, *textoncurve;
        struct Ipo *ipo;        // XXX depreceated... old animation system
index 394a179..8480744 100644 (file)
@@ -36,6 +36,9 @@
 
 #include "WM_types.h"
 
+#include "BKE_curve.h"
+#include "ED_curve.h"
+
 EnumPropertyItem beztriple_handle_type_items[] = {
                {HD_FREE, "FREE", 0, "Free", ""},
                {HD_AUTO, "AUTO", 0, "Auto", ""},
@@ -71,6 +74,8 @@ EnumPropertyItem curve_type_items[] = {
 
 #include "MEM_guardedalloc.h"
 
+#include "ED_curve.h" /* for BKE_curve_nurbs */
+
 static StructRNA *rna_Curve_refine(PointerRNA *ptr)
 {
        Curve *cu= (Curve*)ptr->data;
@@ -193,7 +198,8 @@ static void rna_Curve_active_textbox_index_range(PointerRNA *ptr, int *min, int
 static void rna_Curve_dimension_set(PointerRNA *ptr, int value)
 {
        Curve *cu= (Curve*)ptr->id.data;
-       Nurb *nu= cu->editnurb ? cu->editnurb->first : cu->nurb.first;
+       ListBase *nurbs= BKE_curve_nurbs(cu);
+       Nurb *nu= nurbs->first;
 
        if(value==CU_3D) {
                cu->flag |=  CU_3D;
@@ -309,11 +315,9 @@ static void rna_Curve_taperObject_set(PointerRNA *ptr, PointerRNA value)
 static void rna_Curve_resolution_u_update_data(Main *bmain, Scene *scene, PointerRNA *ptr)
 {
        Curve *cu= (Curve*)ptr->id.data;
-       Nurb *nu=NULL;
-       
-       if (cu->editnurb) nu= cu->editnurb->first;
-       else nu=cu->nurb.first;
-       
+       ListBase *nurbs= BKE_curve_nurbs(cu);
+       Nurb *nu= nurbs->first;
+
        while(nu) {
                nu->resolu= cu->resolu;
                nu= nu->next;
@@ -325,16 +329,15 @@ static void rna_Curve_resolution_u_update_data(Main *bmain, Scene *scene, Pointe
 static void rna_Curve_resolution_v_update_data(Main *bmain, Scene *scene, PointerRNA *ptr)
 {
        Curve *cu= (Curve*)ptr->id.data;
-       Nurb *nu=NULL;
-       
-       if (cu->editnurb) nu= cu->editnurb->first;
-       else nu=cu->nurb.first;
-       
+       ListBase *nurbs= BKE_curve_nurbs(cu);
+       Nurb *nu=nurbs->first;
+
+
        while(nu) {
                nu->resolv= cu->resolv;
                nu= nu->next;
        }
-       
+
        rna_Curve_update_data(bmain, scene, ptr);
 }
 
@@ -466,12 +469,9 @@ static void rna_Curve_spline_remove(Curve *cu, ReportList *reports, Nurb *nu)
 {
        /* todo, check we're in the list */
        int found= 0;
-       if(cu->editnurb) {
-               found= BLI_remlink_safe(cu->editnurb, nu);
-       }
-       else {
-               found= BLI_remlink_safe(&cu->nurb, nu);
-       }
+       ListBase *nurbs= BKE_curve_nurbs(cu);
+
+       found= BLI_remlink_safe(nurbs, nu);
 
        if(!found) {
                BKE_reportf(reports, RPT_ERROR, "Curve \"%s\" does not contain spline given", cu->id.name+2);
@@ -486,11 +486,10 @@ static PointerRNA rna_Curve_active_spline_get(PointerRNA *ptr)
 {
        Curve *cu= (Curve*)ptr->data;
        Nurb *nu;
+       ListBase *nurbs= BKE_curve_nurbs(cu);
 
-       if(cu->editnurb)
-               nu= BLI_findlink(cu->editnurb, cu->actnu);
-       else
-               nu= BLI_findlink(&cu->nurb, cu->actnu); // currently set to -1,  should be changed to be allowed outside of editmode.
+       // for curve outside editmode will set to -1,  should be changed to be allowed outside of editmode.
+       nu= BLI_findlink(nurbs, cu->actnu);
 
        if(nu)
                return rna_pointer_inherit_refine(ptr, &RNA_Spline, nu);
@@ -502,14 +501,13 @@ static void rna_Curve_active_spline_set(PointerRNA *ptr, PointerRNA value)
 {
        Curve *cu= (Curve*)ptr->data;
        Nurb *nu= value.data;
+       ListBase *nubase= BKE_curve_nurbs(cu);
 
        /* -1 is ok for an unset index */
        if(nu==NULL)
                cu->actnu= -1;
-       else if(cu->editnurb)
-               cu->actnu= BLI_findindex(cu->editnurb, nu);
        else
-               cu->actnu= BLI_findindex(&cu->nurb, nu);
+               cu->actnu= BLI_findindex(nubase, nu);
 }
 
 #else
index 7352582..6400628 100644 (file)
@@ -255,6 +255,9 @@ void ED_sequencer_update_view(struct bContext *C, int view){}
 float ED_rollBoneToVector(struct EditBone *bone, float new_up_axis[3]){return 0.0f;}
 void ED_space_image_size(struct SpaceImage *sima, int *width, int *height){}
 
+struct ListBase *ED_curve_editnurbs(struct Curve *cu){return NULL;}
+void free_curve_editNurb (struct Curve *cu){};
+
 void EM_selectmode_set(struct EditMesh *em){}
 int EM_texFaceCheck(struct EditMesh *em){return 0;}
 struct MTFace *EM_get_active_mtface(struct EditMesh *em, struct EditFace **act_efa, struct MCol **mcol, int sloopy){return (struct MTFace *)NULL;}