diff options
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/curve/editcurve.c | 1014 | ||||
-rw-r--r-- | source/blender/editors/include/ED_curve.h | 10 | ||||
-rw-r--r-- | source/blender/editors/render/render_shading.c | 10 | ||||
-rw-r--r-- | source/blender/editors/space_info/info_stats.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_info/space_info.c | 1 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 7 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_buttons.c | 11 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_snap.c | 13 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 9 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_generics.c | 6 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_manipulator.c | 4 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_orientations.c | 6 |
12 files changed, 950 insertions, 145 deletions
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) |