Bugfix:
Copy/pasting multiple ipo curves in editmode, segfaulted due to some misplaced code.
This commit is contained in:
@@ -4107,127 +4107,131 @@ void paste_editipo(void)
|
||||
|
||||
if (totipo_vis==0) {
|
||||
error("No visible channels");
|
||||
return;
|
||||
}
|
||||
else if (totipo_vis!=totipocopybuf && totipo_sel!=totipocopybuf) {
|
||||
error("Incompatible paste");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
icu= ipocopybuf.first;
|
||||
if (icu==0) return;
|
||||
|
||||
for (a=0, ei=G.sipo->editipo; a<G.sipo->totipo; a++, ei++) {
|
||||
if (ei->flag & IPO_VISIBLE) {
|
||||
|
||||
icu= ipocopybuf.first;
|
||||
|
||||
for (a=0, ei=G.sipo->editipo; a<G.sipo->totipo; a++, ei++) {
|
||||
if (ei->flag & IPO_VISIBLE) {
|
||||
/* don't attempt pasting if no valid buffer-curve to paste from anymore */
|
||||
if (icu == 0) return;
|
||||
|
||||
/* if in editmode, paste keyframes */
|
||||
if (ei->flag & IPO_EDIT) {
|
||||
BezTriple *src, *dst, *newb;
|
||||
float offset= 0.0f;
|
||||
short offsetInit= 0;
|
||||
int i, j;
|
||||
|
||||
/* if in editmode, paste keyframes */
|
||||
if (ei->flag & IPO_EDIT) {
|
||||
BezTriple *src, *dst, *newb;
|
||||
float offset= 0.0f;
|
||||
short offsetInit= 0;
|
||||
int i, j;
|
||||
/* make sure an ipo-curve exists (it may not, as this is an editipo) */
|
||||
ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, ei->adrcode);
|
||||
if (ei->icu == NULL) return;
|
||||
|
||||
/* Copy selected beztriples from source icu onto this edit-icu,
|
||||
* with all added keyframes being offsetted by the difference between
|
||||
* the first source keyframe and the current frame.
|
||||
*/
|
||||
for (i=0, src=icu->bezt; i < icu->totvert; i++, src++) {
|
||||
/* skip if not selected */
|
||||
if (BEZSELECTED(src) == 0) continue;
|
||||
|
||||
/* make sure an ipo-curve exists (it may not, as this is an editipo) */
|
||||
ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, ei->adrcode);
|
||||
if (ei->icu==NULL) return;
|
||||
|
||||
/* Copy selected beztriples from source icu onto this edit-icu,
|
||||
* with all added keyframes being offsetted by the difference between
|
||||
* the first source keyframe and the current frame.
|
||||
*/
|
||||
for (i=0, src=icu->bezt; i < icu->totvert; i++, src++) {
|
||||
/* skip if not selected */
|
||||
if (BEZSELECTED(src) == 0) continue;
|
||||
/* initialise offset (if not already done) */
|
||||
if (offsetInit==0) {
|
||||
offset= CFRA - src->vec[1][0];
|
||||
offsetInit= 1;
|
||||
}
|
||||
/* temporarily apply offset to src beztriple while copying */
|
||||
src->vec[0][0] += offset;
|
||||
src->vec[1][0] += offset;
|
||||
src->vec[2][0] += offset;
|
||||
|
||||
/* initialise offset (if not already done) */
|
||||
if (offsetInit==0) {
|
||||
offset= CFRA - src->vec[1][0];
|
||||
offsetInit= 1;
|
||||
}
|
||||
/* temporarily apply offset to src beztriple while copying */
|
||||
src->vec[0][0] += offset;
|
||||
src->vec[1][0] += offset;
|
||||
src->vec[2][0] += offset;
|
||||
|
||||
/* find place to insert */
|
||||
if (ei->icu->bezt == NULL) {
|
||||
ei->icu->bezt= MEM_callocN( sizeof(BezTriple), "beztriple");
|
||||
*(ei->icu->bezt)= *src;
|
||||
ei->icu->totvert= 1;
|
||||
}
|
||||
else {
|
||||
dst= ei->icu->bezt;
|
||||
for (j=0; j <= ei->icu->totvert; j++, dst++) {
|
||||
/* no double points - threshold to determine this should be good enough */
|
||||
if ((j < ei->icu->totvert) && IS_EQT(dst->vec[1][0], src->vec[1][0], 0.00001)) {
|
||||
*(dst)= *src;
|
||||
break;
|
||||
}
|
||||
/* if we've reached the end of the ei->icu array, or src is to be pasted before current */
|
||||
if (j==icu->totvert || dst->vec[1][0] > src->vec[1][0]) {
|
||||
newb= MEM_callocN( (ei->icu->totvert+1)*sizeof(BezTriple), "beztriple");
|
||||
|
||||
if (j > 0)
|
||||
memcpy(newb, ei->icu->bezt, j*sizeof(BezTriple));
|
||||
|
||||
dst= newb+j;
|
||||
*(dst)= *src;
|
||||
|
||||
if (j < ei->icu->totvert)
|
||||
memcpy(newb+j+1, ei->icu->bezt+j, (ei->icu->totvert-j)*sizeof(BezTriple));
|
||||
|
||||
MEM_freeN(ei->icu->bezt);
|
||||
ei->icu->bezt= newb;
|
||||
|
||||
ei->icu->totvert++;
|
||||
break;
|
||||
}
|
||||
/* find place to insert */
|
||||
if (ei->icu->bezt == NULL) {
|
||||
ei->icu->bezt= MEM_callocN( sizeof(BezTriple), "beztriple");
|
||||
*(ei->icu->bezt)= *src;
|
||||
ei->icu->totvert= 1;
|
||||
}
|
||||
else {
|
||||
dst= ei->icu->bezt;
|
||||
for (j=0; j <= ei->icu->totvert; j++, dst++) {
|
||||
/* no double points - threshold to determine this should be good enough */
|
||||
if ((j < ei->icu->totvert) && IS_EQT(dst->vec[1][0], src->vec[1][0], 0.00001)) {
|
||||
*(dst)= *src;
|
||||
break;
|
||||
}
|
||||
/* if we've reached the end of the ei->icu array, or src is to be pasted before current */
|
||||
if (j==ei->icu->totvert || dst->vec[1][0] > src->vec[1][0]) {
|
||||
newb= MEM_callocN( (ei->icu->totvert+1)*sizeof(BezTriple), "beztriple");
|
||||
|
||||
/* add the beztriples that should occur before the beztriple to be pasted (originally in ei->icu) */
|
||||
if (j > 0)
|
||||
memcpy(newb, ei->icu->bezt, j*sizeof(BezTriple));
|
||||
|
||||
/* add beztriple to paste at index j */
|
||||
*(newb+j)= *src;
|
||||
|
||||
/* add the beztriples that occur after the beztriple to be pasted (originally in ei->icu) */
|
||||
if (j < ei->icu->totvert)
|
||||
memcpy(newb+j+1, ei->icu->bezt+j, (ei->icu->totvert-j)*sizeof(BezTriple));
|
||||
|
||||
MEM_freeN(ei->icu->bezt);
|
||||
ei->icu->bezt= newb;
|
||||
|
||||
ei->icu->totvert++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* un-apply offset from src beztriple after copying */
|
||||
src->vec[0][0] -= offset;
|
||||
src->vec[1][0] -= offset;
|
||||
src->vec[2][0] -= offset;
|
||||
|
||||
/* recalculate handles of curve that data was pasted into */
|
||||
calchandles_ipocurve(ei->icu);
|
||||
|
||||
/* advance to next copy/paste buffer ipo-curve */
|
||||
icu= icu->next;
|
||||
}
|
||||
|
||||
/* un-apply offset from src beztriple after copying */
|
||||
src->vec[0][0] -= offset;
|
||||
src->vec[1][0] -= offset;
|
||||
src->vec[2][0] -= offset;
|
||||
}
|
||||
|
||||
/* otherwise paste entire curve data if selected */
|
||||
else if (ei->flag & IPO_SELECT) {
|
||||
/* make sure an ipo-curve exists (it may not, as this is an editipo) */
|
||||
ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, ei->adrcode);
|
||||
if (ei->icu==NULL) return;
|
||||
|
||||
/* clear exisiting dynamic memory (keyframes, driver) */
|
||||
if (ei->icu->bezt) MEM_freeN(ei->icu->bezt);
|
||||
ei->icu->bezt= NULL;
|
||||
if (ei->icu->driver) MEM_freeN(ei->icu->driver);
|
||||
ei->icu->driver= NULL;
|
||||
|
||||
ei->icu->totvert= icu->totvert;
|
||||
ei->icu->flag= ei->flag= icu->flag;
|
||||
ei->icu->extrap= icu->extrap;
|
||||
ei->icu->ipo= icu->ipo;
|
||||
|
||||
/* make a copy of the source icu's data */
|
||||
if (icu->bezt)
|
||||
ei->icu->bezt= MEM_dupallocN(icu->bezt);
|
||||
if (icu->driver)
|
||||
ei->icu->driver= MEM_dupallocN(icu->driver);
|
||||
|
||||
/* advance to next copy/paste buffer ipo-curve */
|
||||
icu= icu->next;
|
||||
}
|
||||
/* recalculate handles of curve that data was pasted into */
|
||||
calchandles_ipocurve(ei->icu);
|
||||
|
||||
/* advance to next copy/paste buffer ipo-curve */
|
||||
icu= icu->next;
|
||||
}
|
||||
|
||||
/* otherwise paste entire curve data if selected */
|
||||
else if (ei->flag & IPO_SELECT) {
|
||||
/* make sure an ipo-curve exists (it may not, as this is an editipo) */
|
||||
ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, ei->adrcode);
|
||||
if (ei->icu==NULL) return;
|
||||
|
||||
/* clear exisiting dynamic memory (keyframes, driver) */
|
||||
if (ei->icu->bezt) MEM_freeN(ei->icu->bezt);
|
||||
ei->icu->bezt= NULL;
|
||||
if (ei->icu->driver) MEM_freeN(ei->icu->driver);
|
||||
ei->icu->driver= NULL;
|
||||
|
||||
ei->icu->totvert= icu->totvert;
|
||||
ei->icu->flag= ei->flag= icu->flag;
|
||||
ei->icu->extrap= icu->extrap;
|
||||
ei->icu->ipo= icu->ipo;
|
||||
|
||||
/* make a copy of the source icu's data */
|
||||
if (icu->bezt)
|
||||
ei->icu->bezt= MEM_dupallocN(icu->bezt);
|
||||
if (icu->driver)
|
||||
ei->icu->driver= MEM_dupallocN(icu->driver);
|
||||
|
||||
/* advance to next copy/paste buffer ipo-curve */
|
||||
icu= icu->next;
|
||||
}
|
||||
}
|
||||
|
||||
editipo_changed(G.sipo, 1);
|
||||
BIF_undo_push("Paste Ipo curves");
|
||||
}
|
||||
|
||||
editipo_changed(G.sipo, 1);
|
||||
BIF_undo_push("Paste Ipo curves");
|
||||
}
|
||||
|
||||
/* *********************** */
|
||||
|
||||
Reference in New Issue
Block a user