Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2010-07-25 15:57:36 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2010-07-25 15:57:36 +0400
commitcc0f3146e798479be0758b5c152ef67ef42ea8dc (patch)
tree669704799ec2a83908777d1b0d9cc1517dfb871c /source/blender
parent61a09d96b1c10decb732f77a50421101e43cf401 (diff)
Shapekeys for curves/surfeces
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.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_curve.h2
-rw-r--r--source/blender/blenkernel/intern/anim.c12
-rw-r--r--source/blender/blenkernel/intern/curve.c26
-rw-r--r--source/blender/blenkernel/intern/displist.c17
-rw-r--r--source/blender/blenkernel/intern/key.c151
-rw-r--r--source/blender/blenkernel/intern/object.c13
-rw-r--r--source/blender/editors/curve/editcurve.c1014
-rw-r--r--source/blender/editors/include/ED_curve.h10
-rw-r--r--source/blender/editors/render/render_shading.c10
-rw-r--r--source/blender/editors/space_info/info_stats.c4
-rw-r--r--source/blender/editors/space_info/space_info.c1
-rw-r--r--source/blender/editors/space_view3d/drawobject.c7
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c11
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c13
-rw-r--r--source/blender/editors/transform/transform_conversions.c9
-rw-r--r--source/blender/editors/transform/transform_generics.c6
-rw-r--r--source/blender/editors/transform/transform_manipulator.c4
-rw-r--r--source/blender/editors/transform/transform_orientations.c6
-rw-r--r--source/blender/makesdna/DNA_curve_types.h11
-rw-r--r--source/blender/makesrna/intern/rna_curve.c48
20 files changed, 1114 insertions, 261 deletions
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index ca45c2f318c..e83ea4b809c 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -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
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 157c0743c50..412084f7cd1 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -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;
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index d355a520a8c..4142ad7128f 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -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;
+}
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index bb020c936a6..ca659faa972 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -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));
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index b8219c4aa35..354b3b0e7d8 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -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);
}
}
}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 75b5e6d9331..efff3d138e6 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -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) {
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index c33565cee4b..8d8dac33f9f 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -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"
@@ -79,8 +81,15 @@
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);
+}
diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h
index a229d919e77..0ff98b504d0 100644
--- a/source/blender/editors/include/ED_curve.h
+++ b/source/blender/editors/include/ED_curve.h
@@ -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 */
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 4a947569e66..6e8c3b721d0 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -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;
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index cf23c488960..1b5cf133749 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -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;
diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c
index 0f483f4bcec..0b2d52d6e25 100644
--- a/source/blender/editors/space_info/space_info.c
+++ b/source/blender/editors/space_info/space_info.c
@@ -52,6 +52,7 @@
#include "UI_resources.h"
#include "UI_interface.h"
+
#include "info_intern.h" // own include
/* ******************** default callbacks for info space ***************** */
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index f5a14079682..981c11114b2 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -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)
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index c75b785aa11..19aaff2cea9 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -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;
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index ff716a640d8..160306ef300 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -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;
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 44a22da60e0..dc731d7a433 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -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;
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 98ecb07660f..8d98255d3d9 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -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 */
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index 016aca2b7ec..2a717f8b4d9 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -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;
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index e926762709d..8451b0c154a 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -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)
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 609c3a87dab..c13cb08badd 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -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
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index 394a17903e2..84807446f50 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -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