int MovieView()

in layer1/Movie.cpp [1157:1446]


int MovieView(PyMOLGlobals * G, int action, int first,
              int last, float power, float bias,
              int simple, float linear, int wrap,
              int hand, int window, int cycles,
              const char *scene_name, float scene_cut, int state, int quiet)
{
  CMovie *I = G->Movie;
  int frame;
  
  if(wrap<0) {
    wrap = SettingGetGlobal_b(G,cSetting_movie_loop);
  }
  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<I->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) {
    if(I->ViewElem) {
      int save_last = last;
      if(first < 0)
        first = 0;
      
      if(last < 0) {
        last = SceneGetNFrame(G, NULL) - 1;
      }
      if(last >= I->NFrame) {
        last = I->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(SettingGetGlobal_b(G, cSetting_movie_auto_interpolate)) {
        action = 3; /* reinterpolate */
        last = save_last;
      }
    }
  }
  switch (action) {
  case 0:                      /* store */
    if(I->ViewElem) {
      if(first < 0)
        first = SceneGetFrame(G);
      if(last < 0)
        last = first;

      VLACheck(I->ViewElem, CViewElem, last);

      for(frame = first; frame <= last; frame++) {
        if((frame >= 0) && (frame < I->NFrame)) {
          VLACheck(I->ViewElem, CViewElem, frame);
          if(!quiet) {
            PRINTFB(G, FB_Movie, FB_Details)
              " MovieView: Setting frame %d.\n", frame + 1 ENDFB(G);
          }
          if(scene_name && (!scene_name[0]))
            scene_name = NULL;
          SceneToViewElem(G, I->ViewElem + frame, scene_name);
          if(state>=0) {
            I->ViewElem[frame].state = state;
            I->ViewElem[frame].state_flag = true;
          } else if(state==-2) {
            I->ViewElem[frame].state = SceneGetState(G);
            I->ViewElem[frame].state_flag = true;
          }

          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 < I->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:
    if(I->ViewElem) {
      int view_found = false;
      CViewElem *first_view = NULL, *last_view = NULL;
      if(first < 0)
        first = 0;

      if(first > I->NFrame) {
        first = I->NFrame - 1;
      }
      /* note that we're leaving a blank frame at the end... */
      if(last < 0) {
        last = MovieGetLength(G);

        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 >= I->NFrame) {
        last = I->NFrame;
        if(last && (!wrap))
          last--;
      }
      
      VLACheck(I->ViewElem, CViewElem, last);

      if(wrap && (last >= I->NFrame)) {
        /* if we're interpolating beyond the last frame, then wrap by
           copying early frames to last frames */
        int a;
        for(a = I->NFrame; a <= last; a++) {
          ViewElemCopy(G, I->ViewElem + a - I->NFrame, I->ViewElem + a);
        }
      } else if(!wrap) { 
        /* if we're not wrapping, then make sure we nuke any stray / old
           interpolated frames */
        frame = I->NFrame - 1;
        while(frame>=0) {
          if(I->ViewElem[frame].specification_level > 1) 
            break;
          else
            UtilZeroMem((void *) (I->ViewElem + frame), sizeof(CViewElem));
          frame--;
        }
      }

      if(!quiet) {
        if(action == 2) {
          if(last == I->NFrame) {
            PRINTFB(G, FB_Movie, FB_Details)
              " MovieView: interpolating unspecified frames %d to %d (wrapping)\n",
              first + 1, last ENDFB(G);
          } else {
            PRINTFB(G, FB_Movie, FB_Details)
              " MovieView: interpolating unspecified frames %d to %d.\n", first + 1,
              last + 1 ENDFB(G);
          }

        } else {
          if(last == I->NFrame) {
            PRINTFB(G, FB_Movie, FB_Details)
              " MovieView: reinterpolating all frames %d to %d (wrapping).\n", first + 1,
              last ENDFB(G);
          } else {
            PRINTFB(G, FB_Movie, FB_Details)
              " MovieView: 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, scene_cut);
            }
            first_view = last_view;
            last_view = NULL;
          }
        }
      }

      if(first_view) {
        if(wrap && (last >= I->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 = I->NFrame; a <= last; a++) {
            ViewElemCopy(G, I->ViewElem + a, I->ViewElem + a - I->NFrame);
          }
        }
      }

      if((!view_found) && (last>=first) && (first>=0) && (last<=I->NFrame)) {
        UtilZeroMem(I->ViewElem + first, sizeof(CViewElem) * (1 + (last-first)));
      }

      if(last >= I->NFrame) {   /* now erase temporary views */
        ViewElemArrayPurge(G, I->ViewElem + I->NFrame, (1 + last - I->NFrame));
        UtilZeroMem((void *) (I->ViewElem + I->NFrame),
                    sizeof(CViewElem) * (1 + last - I->NFrame));
      }
    }
    break;
  case 5:                      /* reset */
    if(I->ViewElem) {
      int size = VLAGetSize(I->ViewElem);
      VLAFreeP(I->ViewElem);
      I->ViewElem = VLACalloc(CViewElem, size);
    }
    break;
  case 6:                      /* uninterpolate */
    if(I->ViewElem) {
      if(first < 0)
        first = 0;
      if(last < 0) {
        last = SceneGetNFrame(G, NULL) - 1;
      }
      for(frame = first; frame <= last; frame++) {
        if((frame >= 0) && (frame < I->NFrame)) {
          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;
  }
  /* adjust VLA to current movie length */
  if(I->ViewElem) {
    VLASize(I->ViewElem,CViewElem,I->NFrame);
  }
  SceneSetFrame(G,1,0); /* force frame update */
  return 1;
}