in layer1/PyMOLObject.cpp [231:549]
int ObjectMotion(CObject * I, int action, int first,
int last, float power, float bias,
int simple, float linear, int wrap,
int hand, int window, int cycles, int state, int quiet)
{
PyMOLGlobals *G = I->G;
if(I->type == cObjectGroup) { /* propagate */
return ExecutiveGroupMotion(G,I,action,first,last, power,bias,simple,linear,
wrap,hand,window,cycles,state,quiet);
} else {
int frame;
int nFrame = MovieGetLength(I->G);
if(wrap<0) {
wrap = SettingGet_b(I->G,NULL, I->Setting, cSetting_movie_loop);
}
if(nFrame < 0)
nFrame = -nFrame;
if(!I->ViewElem) {
I->ViewElem = VLACalloc(CViewElem, 0);
}
if((action == 7) || (action == 8)) { /* toggle */
frame = first;
if(first < 0)
frame = SceneGetFrame(G);
VLACheck(I->ViewElem, CViewElem, frame);
if(action == 7) {
if(I->ViewElem[frame].specification_level>1) {
action = 1;
} else {
action = 0;
}
} else if(action == 8) {
if(I->ViewElem[frame].specification_level>1) {
int frame;
action = 3;
for(frame=0;frame<nFrame;frame++) {
if(I->ViewElem[frame].specification_level==1) {
action = 6;
break;
}
}
}
else if(I->ViewElem[frame].specification_level>0) {
action = 6;
} else {
action = 3;
}
}
}
if(action == 4) { /* smooth */
int save_last = last;
if(first < 0)
first = 0;
if(last < 0) {
last = nFrame;
}
if(last >= nFrame) {
last = nFrame - 1;
}
if(first <= last) {
int a;
VLACheck(I->ViewElem, CViewElem, last);
for(a = 0; a < cycles; a++) {
ViewElemSmooth(I->ViewElem + first, I->ViewElem + last, window, wrap);
}
}
if(SettingGet_b(I->G, NULL, I->Setting, cSetting_movie_auto_interpolate)){
action = 3; /* reinterpolate */
last = save_last;
}
}
switch (action) {
case 0: /* store */
if(!I->TTTFlag) {
float mn[3], mx[3], orig[3];
if(ExecutiveGetExtent(G, I->Name, mn, mx, true, -1, true)) {
average3f(mn, mx, orig);
ObjectSetTTTOrigin(I, orig);
} else {
initializeTTT44f(I->TTT);
I->TTTFlag = true;
}
}
if(I->ViewElem && I->TTTFlag) {
if(first < 0)
first = SceneGetFrame(G);
if(last < 0)
last = first;
{
int state_tmp=0, state_flag = false;
if(state>=0) {
state_tmp = state;
state_flag = true;
} else if(SettingGetIfDefined_i(G, I->Setting, cSetting_state, &state_tmp)) {
state_flag = true;
state_tmp--;
}
for(frame = first; frame <= last; frame++) {
if((frame >= 0) && (frame < nFrame)) {
VLACheck(I->ViewElem, CViewElem, frame);
if(!quiet) {
PRINTFB(G, FB_Object, FB_Details)
" ObjectMotion: Setting frame %d.\n", frame + 1 ENDFB(G);
}
TTTToViewElem(I->TTT, I->ViewElem + frame);
if(state_flag) {
I->ViewElem[frame].state_flag = state_flag;
I->ViewElem[frame].state = state_tmp;
}
if(power!=0.0F) {
I->ViewElem[frame].power_flag = true;
I->ViewElem[frame].power = power;
}
if(bias > 0.0F) {
I->ViewElem[frame].bias_flag = true;
I->ViewElem[frame].bias = bias;
}
I->ViewElem[frame].specification_level = 2;
}
}
}
}
break;
case 1: /* clear */
if(I->ViewElem) {
if(first < 0)
first = SceneGetFrame(G);
if(last < 0)
last = first;
for(frame = first; frame <= last; frame++) {
if((frame >= 0) && (frame < nFrame)) {
VLACheck(I->ViewElem, CViewElem, frame);
ViewElemArrayPurge(G, I->ViewElem + frame, 1);
UtilZeroMem((void *) (I->ViewElem + frame), sizeof(CViewElem));
}
}
}
break;
case 2: /* interpolate & reinterpolate */
case 3:
{
CViewElem *first_view = NULL, *last_view = NULL;
int view_found = false;
if(first < 0)
first = 0;
if(first > nFrame) {
first = nFrame - 1;
}
if(last < 0) {
last = nFrame;
if(last) {
if(!wrap)
last--;
else {
int frame = 0;
VLACheck(I->ViewElem, CViewElem, last);
for(frame = 0; frame < last; frame++) {
if(I->ViewElem[frame].specification_level > 1) {
last += frame;
break;
}
}
}
}
} else {
if(last >= nFrame) {
last = nFrame;
if(last && !wrap)
last--;
}
}
VLACheck(I->ViewElem, CViewElem, last);
if(wrap && (last >= nFrame)) {
/* if we're interpolating beyond the last frame, then wrap by
copying early frames to last frames */
int a;
for(a = nFrame; a <= last; a++) {
ViewElemCopy(G, I->ViewElem + a - nFrame, I->ViewElem + a);
}
} else if(!wrap) {
/* if we're not wrapping, then make sure we nuke any stray / old
interpolated frames */
frame = nFrame - 1;
while(frame>=0) {
if(I->ViewElem[frame].specification_level > 1)
break;
else
UtilZeroMem((void *) (I->ViewElem + frame), sizeof(CViewElem));
frame--;
}
}
VLACheck(I->ViewElem, CViewElem, last);
if(!quiet) {
if(action == 2) {
if(last == nFrame) {
PRINTFB(G, FB_Object, FB_Details)
" ObjectMotion: interpolating unspecified frames %d to %d (wrapping).\n",
first + 1, last ENDFB(G);
} else {
PRINTFB(G, FB_Object, FB_Details)
" ObjectMotion: interpolating unspecified frames %d to %d.\n", first + 1,
last + 1 ENDFB(G);
}
} else {
if(last == nFrame) {
PRINTFB(G, FB_Object, FB_Details)
" ObjectMotion: reinterpolating all frames %d to %d (wrapping).\n", first + 1,
last ENDFB(G);
} else {
PRINTFB(G, FB_Object, FB_Details)
" ObjectMotion: reinterpolating all frames %d to %d.\n", first + 1, last + 1
ENDFB(G);
}
}
}
for(frame = first; frame <= last; frame++) {
if(!first_view) {
if(I->ViewElem[frame].specification_level == 2) { /* specified */
first_view = I->ViewElem + frame;
view_found = true;
}
} else {
CViewElem *view;
int interpolate_flag = false;
if(I->ViewElem[frame].specification_level == 2) { /* specified */
last_view = I->ViewElem + frame;
if(action == 2) { /* interpolate */
for(view = first_view + 1; view < last_view; view++) {
if(!view->specification_level)
interpolate_flag = true;
}
} else {
interpolate_flag = true;
}
if(interpolate_flag) {
ViewElemInterpolate(G, first_view, last_view,
power, bias, simple, linear, hand, 0.0F);
}
first_view = last_view;
last_view = NULL;
}
}
}
if(first_view) {
if(wrap && (last >= nFrame)) {
/* if we're interpolating beyond the last frame, then wrap by
copying the last frames back over the early frames */
int a;
for(a = nFrame; a <= last; a++) {
ViewElemCopy(G, I->ViewElem + a, I->ViewElem + a - nFrame);
}
}
}
if((!view_found) && (last>=first) && (first>=0) && (last<=nFrame)) {
UtilZeroMem(I->ViewElem + first, sizeof(CViewElem) * (1 + (last-first)));
}
if(last >= nFrame) { /* now erase temporary views */
ViewElemArrayPurge(G, I->ViewElem + nFrame, (1 + last - nFrame));
UtilZeroMem((void *) (I->ViewElem + nFrame),
sizeof(CViewElem) * (1 + last - nFrame));
}
}
break;
case 5: /* reset */
if(I->ViewElem) {
VLAFreeP(I->ViewElem);
}
I->ViewElem = VLACalloc(CViewElem, 0);
break;
case 6: /* uninterpolate */
if(I->ViewElem) {
if(first < 0)
first = 0;
if(last < 0) {
last = nFrame - 1;
}
for(frame = first; frame <= last; frame++) {
if((frame >= 0) && (frame <= last)) {
VLACheck(I->ViewElem, CViewElem, frame);
if(I->ViewElem[frame].specification_level < 2) {
ViewElemArrayPurge(G, I->ViewElem + frame, 1);
UtilZeroMem((void *) (I->ViewElem + frame), sizeof(CViewElem));
}
}
}
}
break;
case 9:
if(I->ViewElem) {
VLAFreeP(I->ViewElem);
}
break;
}
if(I->ViewElem) {
VLASize(I->ViewElem,CViewElem,nFrame);
}
}
return 1;
}