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:
-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
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c3
21 files changed, 1117 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
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 735258220cb..6400628fb08 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -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;}