]> OCCT Git - occt.git/commitdiff
0032464: Draw Harness, ViewerTest - rely on AIS_ViewController within vanimation... IR-2021-08-27
authorkgv <kgv@opencascade.com>
Sun, 27 Jun 2021 17:13:49 +0000 (20:13 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 27 Aug 2021 16:11:44 +0000 (19:11 +0300)
Added AIS_ViewController::ObjectsAnimation() property
similar to AIS_ViewController::ViewAnimation() but designed for objects animation.

src/AIS/AIS_Animation.hxx
src/AIS/AIS_ViewController.cxx
src/AIS/AIS_ViewController.hxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx

index 2658e431858468f4fe7d4a77c76bdf625244fb8b..ed31d0262bd91655742984a97ff30e6e1fab37dc 100644 (file)
@@ -147,6 +147,12 @@ public:
   //! Return elapsed time.
   Standard_Real ElapsedTime() const { return !myTimer.IsNull() ? myTimer->ElapsedTime() : 0.0; }
 
+  //! Return playback timer.
+  const Handle(Media_Timer)& Timer() const { return myTimer; }
+
+  //! Set playback timer.
+  void SetTimer (const Handle(Media_Timer)& theTimer) { myTimer = theTimer; }
+
 public:
 
   //! Start animation. This method changes status of the animation to Started.
index 76b04e285b8d94b919bfefcb57f60e5cc15113ec..2d086594259bef030c70e3214c045ce22fc8eec9 100644 (file)
@@ -63,6 +63,8 @@ AIS_ViewController::AIS_ViewController()
   myHasThrust (false),
   //
   myViewAnimation (new AIS_AnimationCamera ("AIS_ViewController_ViewAnimation", Handle(V3d_View)())),
+  myObjAnimation (new AIS_Animation ("AIS_ViewController_ObjectsAnimation")),
+  myToPauseObjAnimation (false),
   myPrevMoveTo (-1, -1),
   myHasHlrOnBeforeRotation (false),
   //
@@ -610,6 +612,14 @@ bool AIS_ViewController::UpdateMouseClick (const Graphic3d_Vec2i& thePoint,
                                            bool theIsDoubleClick)
 {
   (void )theIsDoubleClick;
+
+  if (myToPauseObjAnimation
+  && !myObjAnimation.IsNull()
+  && !myObjAnimation->IsStopped())
+  {
+    myObjAnimation->Pause();
+  }
+
   AIS_SelectionScheme aScheme = AIS_SelectionScheme_UNKNOWN;
   if (myMouseSelectionSchemes.Find (theButton | theModifiers, aScheme))
   {
@@ -2944,6 +2954,14 @@ void AIS_ViewController::handleViewRedraw (const Handle(AIS_InteractiveContext)&
     setAskNextFrame();
   }
 
+  if (!myObjAnimation.IsNull()
+   && !myObjAnimation->IsStopped())
+  {
+    myObjAnimation->UpdateTimer();
+    ResetPreviousMoveTo();
+    setAskNextFrame();
+  }
+
   if (myIsContinuousRedraw)
   {
     myToAskNextFrame = true;
index 7d8e0fc50d07027ef14b934d5d6a66063e865c73..f22c8bf8e7022392f9c051a5189586290333adc7 100644 (file)
@@ -34,6 +34,7 @@
 #include <Quantity_ColorRGBA.hxx>
 #include <Standard_Mutex.hxx>
 
+class AIS_Animation;
 class AIS_AnimationCamera;
 class AIS_InteractiveObject;
 class AIS_InteractiveContext;
@@ -77,6 +78,18 @@ public:
   //! Interrupt active view animation.
   Standard_EXPORT void AbortViewAnimation();
 
+  //! Return objects animation; empty (but not NULL) animation by default.
+  const Handle(AIS_Animation)& ObjectsAnimation() const { return myObjAnimation; }
+
+  //! Set object animation to be handled within handleViewRedraw().
+  void SetObjectsAnimation (const Handle(AIS_Animation)& theAnimation) { myObjAnimation = theAnimation; }
+
+  //! Return TRUE if object animation should be paused on mouse click; FALSE by default.
+  bool ToPauseObjectsAnimation() const { return myToPauseObjAnimation; }
+
+  //! Set if object animation should be paused on mouse click.
+  void SetPauseObjectsAnimation (bool theToPause) { myToPauseObjAnimation = theToPause; }
+
   //! Return TRUE if continuous redrawing is enabled; FALSE by default.
   //! This option would request a next viewer frame to be completely redrawn right after current frame is finished.
   bool IsContinuousRedraw() const { return myIsContinuousRedraw; }
@@ -713,6 +726,8 @@ protected:
   Standard_Boolean    myHasThrust;                //!< flag indicating active thrust
 
   Handle(AIS_AnimationCamera) myViewAnimation;    //!< view animation
+  Handle(AIS_Animation)       myObjAnimation;     //!< objects animation
+  Standard_Boolean       myToPauseObjAnimation;   //!< flag to pause objects animation on mouse click; FALSE by default
   Handle(AIS_RubberBand) myRubberBand;            //!< Rubber-band presentation
   Handle(SelectMgr_EntityOwner) myDragOwner;      //!< detected owner of currently dragged object
   Handle(AIS_InteractiveObject) myDragObject;     //!< currently dragged object
index 235badc39466e5c7b7b8ef2052da2a6e52f5abc4..3caf99b262bcce18c903fd1155260d7881a698e0 100644 (file)
@@ -197,8 +197,6 @@ static struct
 //  EVENT GLOBAL VARIABLES
 //==============================================================================
 
-Standard_Boolean TheIsAnimating = Standard_False;
-
 namespace
 {
 
@@ -3325,11 +3323,6 @@ static LRESULT WINAPI AdvViewerWindowProc (HWND theWinHandle,
       }
       return 0;
     }
-    case WM_LBUTTONDOWN:
-    {
-      TheIsAnimating = Standard_False;
-    }
-    Standard_FALLTHROUGH
     default:
     {
       const Handle(V3d_View)& aView = ViewerTest::CurrentView();
@@ -3426,14 +3419,6 @@ int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
       }
       break;
     }
-    case ButtonPress:
-    {
-      if (aReport.xbutton.button == Button1)
-      {
-        TheIsAnimating = Standard_False;
-      }
-    }
-    Standard_FALLTHROUGH
     default:
     {
       const Handle(V3d_View)& aView = ViewerTest::CurrentView();
@@ -7294,6 +7279,7 @@ namespace
   //! The animation calling the Draw Harness command.
   class ViewerTest_AnimationProc : public AIS_Animation
   {
+    DEFINE_STANDARD_RTTI_INLINE(ViewerTest_AnimationProc, AIS_Animation)
   public:
 
     //! Main constructor.
@@ -7360,6 +7346,85 @@ namespace
 
   };
 
+  //! Auxiliary animation holder.
+  class ViewerTest_AnimationHolder : public AIS_AnimationCamera
+  {
+    DEFINE_STANDARD_RTTI_INLINE(ViewerTest_AnimationHolder, AIS_AnimationCamera)
+  public:
+    ViewerTest_AnimationHolder (const Handle(AIS_Animation)& theAnim,
+                                const Handle(V3d_View)& theView,
+                                const Standard_Boolean theIsFreeView)
+    : AIS_AnimationCamera ("ViewerTest_AnimationHolder", Handle(V3d_View)())
+    {
+      if (theAnim->Timer().IsNull())
+      {
+        theAnim->SetTimer (new Media_Timer());
+      }
+      myTimer = theAnim->Timer();
+      myView = theView;
+      if (theIsFreeView)
+      {
+        myCamStart = new Graphic3d_Camera (theView->Camera());
+      }
+      Add (theAnim);
+    }
+
+    //! Start playback.
+    virtual void StartTimer (const Standard_Real    theStartPts,
+                             const Standard_Real    thePlaySpeed,
+                             const Standard_Boolean theToUpdate,
+                             const Standard_Boolean theToStopTimer) Standard_OVERRIDE
+    {
+      base_type::StartTimer (theStartPts, thePlaySpeed, theToUpdate, theToStopTimer);
+      if (theToStopTimer)
+      {
+        abortPlayback();
+      }
+    }
+
+    //! Pause animation.
+    virtual void Pause() Standard_OVERRIDE
+    {
+      myState = AnimationState_Paused;
+      // default implementation would stop all children,
+      // but we want to keep wrapped animation paused
+      myAnimations.First()->Pause();
+      abortPlayback();
+    }
+
+    //! Stop animation.
+    virtual void Stop() Standard_OVERRIDE
+    {
+      base_type::Stop();
+      abortPlayback();
+    }
+
+    //! Process one step of the animation according to the input time progress, including all children.
+    virtual void updateWithChildren (const AIS_AnimationProgress& thePosition) Standard_OVERRIDE
+    {
+      Handle(V3d_View) aView = myView;
+      if (!aView.IsNull()
+       && !myCamStart.IsNull())
+      {
+        myCamStart->Copy (aView->Camera());
+      }
+      base_type::updateWithChildren (thePosition);
+      if (!aView.IsNull()
+       && !myCamStart.IsNull())
+      {
+        aView->Camera()->Copy (myCamStart);
+      }
+    }
+  private:
+    void abortPlayback()
+    {
+      if (!myView.IsNull())
+      {
+        myView.Nullify();
+      }
+    }
+  };
+
   //! Replace the animation with the new one.
   static void replaceAnimation (const Handle(AIS_Animation)& theParentAnimation,
                                 Handle(AIS_Animation)&       theAnimation,
@@ -7853,6 +7918,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
   Standard_Real aPlayStartTime = anAnimation->StartPts();
   Standard_Real aPlayDuration  = anAnimation->Duration();
   Standard_Boolean isFreeCamera = Standard_False;
+  Standard_Boolean toPauseOnClick = Standard_True;
   Standard_Boolean isLockLoop   = Standard_False;
 
   // video recording parameters
@@ -7922,6 +7988,14 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
         aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
       }
     }
+    else if (anArg == "-pause")
+    {
+      anAnimation->Pause();
+    }
+    else if (anArg == "-stop")
+    {
+      anAnimation->Stop();
+    }
     else if (anArg == "-playspeed"
           || anArg == "-speed")
     {
@@ -7936,13 +8010,22 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
           || anArg == "-lockloop"
           || anArg == "-playlockloop")
     {
-      isLockLoop = Standard_True;
+      isLockLoop = Draw::ParseOnOffIterator (theArgNb, theArgVec, anArgIter);
     }
     else if (anArg == "-freecamera"
+          || anArg == "-nofreecamera"
           || anArg == "-playfreecamera"
-          || anArg == "-freelook")
+          || anArg == "-noplayfreecamera"
+          || anArg == "-freelook"
+          || anArg == "-nofreelook")
+    {
+      isFreeCamera = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
+    }
+    else if (anArg == "-pauseonclick"
+          || anArg == "-nopauseonclick"
+          || anArg == "-nopause")
     {
-      isFreeCamera = Standard_True;
+      toPauseOnClick = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
     }
     // video recodring options
     else if (anArg == "-rec"
@@ -8298,155 +8381,118 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
     }
   }
 
+  ViewerTest::CurrentEventManager()->AbortViewAnimation();
+  ViewerTest::CurrentEventManager()->SetObjectsAnimation (Handle(AIS_Animation)());
   if (!toPlay && aRecFile.IsEmpty())
   {
     return 0;
   }
 
   // Start animation timeline and process frame updating.
-  TheIsAnimating = Standard_True;
-  const Standard_Boolean wasImmediateUpdate = aView->SetImmediateUpdate (Standard_False);
-  Handle(Graphic3d_Camera) aCameraBack = new Graphic3d_Camera (aView->Camera());
-  anAnimation->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
-  if (isFreeCamera)
-  {
-    aView->Camera()->Copy (aCameraBack);
+  if (aRecParams.FpsNum <= 0
+  && !isLockLoop)
+  {
+    Handle(ViewerTest_AnimationHolder) aHolder = new ViewerTest_AnimationHolder (anAnimation, aView, isFreeCamera);
+    aHolder->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
+    ViewerTest::CurrentEventManager()->SetPauseObjectsAnimation (toPauseOnClick);
+    ViewerTest::CurrentEventManager()->SetObjectsAnimation (aHolder);
+    ViewerTest::CurrentEventManager()->ProcessExpose();
+    return 0;
   }
 
+  // Perform video recording
+  const Standard_Boolean wasImmediateUpdate = aView->SetImmediateUpdate (Standard_False);
   const Standard_Real anUpperPts = aPlayStartTime + aPlayDuration;
-  if (aRecParams.FpsNum <= 0)
-  {
-    while (!anAnimation->IsStopped())
-    {
-      aCameraBack->Copy (aView->Camera());
-      const Standard_Real aPts = anAnimation->UpdateTimer();
-      if (isFreeCamera)
-      {
-        aView->Camera()->Copy (aCameraBack);
-      }
+  anAnimation->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
 
-      if (aPts >= anUpperPts)
-      {
-        anAnimation->Pause();
-        break;
-      }
+  OSD_Timer aPerfTimer;
+  aPerfTimer.Start();
 
-      if (aView->IsInvalidated())
-      {
-        aView->Redraw();
-      }
-      else
-      {
-        aView->RedrawImmediate();
-      }
+  Handle(Image_VideoRecorder) aRecorder;
+  ImageFlipper aFlipper;
+  Handle(Draw_ProgressIndicator) aProgress;
+  if (!aRecFile.IsEmpty())
+  {
+    if (aRecParams.Width  <= 0
+     || aRecParams.Height <= 0)
+    {
+      aView->Window()->Size (aRecParams.Width, aRecParams.Height);
+    }
 
-      if (!isLockLoop)
-      {
-        // handle user events
-        theDI.Eval ("after 1 set waiter 1");
-        theDI.Eval ("vwait waiter");
-      }
-      if (!TheIsAnimating)
-      {
-        anAnimation->Pause();
-        theDI << aPts;
-        break;
-      }
+    aRecorder = new Image_VideoRecorder();
+    if (!aRecorder->Open (aRecFile.ToCString(), aRecParams))
+    {
+      Message::SendFail ("Error: failed to open video file for recording");
+      return 0;
     }
 
-    if (aView->IsInvalidated())
+    aProgress = new Draw_ProgressIndicator (theDI, 1);
+  }
+
+  // Manage frame-rated animation here
+  Standard_Real aPts = aPlayStartTime;
+  int64_t aNbFrames = 0;
+  Message_ProgressScope aPS(Message_ProgressIndicator::Start(aProgress),
+                            "Video recording, sec", Max(1, Standard_Integer(aPlayDuration / aPlaySpeed)));
+  Standard_Integer aSecondsProgress = 0;
+  for (; aPts <= anUpperPts && aPS.More();)
+  {
+    Standard_Real aRecPts = 0.0;
+    if (aRecParams.FpsNum > 0)
     {
-      aView->Redraw();
+      aRecPts = aPlaySpeed * ((Standard_Real(aRecParams.FpsDen) / Standard_Real(aRecParams.FpsNum)) * Standard_Real(aNbFrames));
     }
     else
     {
-      aView->RedrawImmediate();
+      aRecPts = aPlaySpeed * aPerfTimer.ElapsedTime();
     }
-  }
-  else
-  {
-    OSD_Timer aPerfTimer;
-    aPerfTimer.Start();
 
-    Handle(Image_VideoRecorder) aRecorder;
-    ImageFlipper aFlipper;
-    Handle(Draw_ProgressIndicator) aProgress;
-    if (!aRecFile.IsEmpty())
+    aPts = aPlayStartTime + aRecPts;
+    ++aNbFrames;
+    if (!anAnimation->Update (aPts))
     {
-      if (aRecParams.Width  <= 0
-       || aRecParams.Height <= 0)
-      {
-        aView->Window()->Size (aRecParams.Width, aRecParams.Height);
-      }
-
-      aRecorder = new Image_VideoRecorder();
-      if (!aRecorder->Open (aRecFile.ToCString(), aRecParams))
-      {
-        Message::SendFail ("Error: failed to open video file for recording");
-        return 0;
-      }
-
-      aProgress = new Draw_ProgressIndicator (theDI, 1);
+      break;
     }
 
-    // Manage frame-rated animation here
-    Standard_Real aPts = aPlayStartTime;
-    int64_t aNbFrames = 0;
-    Message_ProgressScope aPS(Message_ProgressIndicator::Start(aProgress),
-                              "Video recording, sec", Max(1, Standard_Integer(aPlayDuration / aPlaySpeed)));
-    Standard_Integer aSecondsProgress = 0;
-    for (; aPts <= anUpperPts && aPS.More();)
+    if (!aRecorder.IsNull())
     {
-      const Standard_Real aRecPts = aPlaySpeed * ((Standard_Real(aRecParams.FpsDen) / Standard_Real(aRecParams.FpsNum)) * Standard_Real(aNbFrames));
-      aPts = aPlayStartTime + aRecPts;
-      ++aNbFrames;
-      if (!anAnimation->Update (aPts))
-      {
-        break;
-      }
-
-      if (!aRecorder.IsNull())
-      {
-        V3d_ImageDumpOptions aDumpParams;
-        aDumpParams.Width          = aRecParams.Width;
-        aDumpParams.Height         = aRecParams.Height;
-        aDumpParams.BufferType     = Graphic3d_BT_RGBA;
-        aDumpParams.StereoOptions  = V3d_SDO_MONO;
-        aDumpParams.ToAdjustAspect = Standard_True;
-        if (!aView->ToPixMap (aRecorder->ChangeFrame(), aDumpParams))
-        {
-          Message::SendFail ("Error: view dump is failed");
-          return 0;
-        }
-        aFlipper.FlipY (aRecorder->ChangeFrame());
-        if (!aRecorder->PushFrame())
-        {
-          return 0;
-        }
-      }
-      else
+      V3d_ImageDumpOptions aDumpParams;
+      aDumpParams.Width          = aRecParams.Width;
+      aDumpParams.Height         = aRecParams.Height;
+      aDumpParams.BufferType     = Graphic3d_BT_RGBA;
+      aDumpParams.StereoOptions  = V3d_SDO_MONO;
+      aDumpParams.ToAdjustAspect = Standard_True;
+      if (!aView->ToPixMap (aRecorder->ChangeFrame(), aDumpParams))
       {
-        aView->Redraw();
+        Message::SendFail ("Error: view dump is failed");
+        return 0;
       }
-
-      while (aSecondsProgress < Standard_Integer(aRecPts / aPlaySpeed))
+      aFlipper.FlipY (aRecorder->ChangeFrame());
+      if (!aRecorder->PushFrame())
       {
-        aPS.Next();
-        ++aSecondsProgress;
+        return 0;
       }
     }
+    else
+    {
+      aView->Redraw();
+    }
 
-    aPerfTimer.Stop();
-    anAnimation->Stop();
-    const Standard_Real aRecFps = Standard_Real(aNbFrames) / aPerfTimer.ElapsedTime();
-    theDI << "Average FPS: " << aRecFps << "\n"
-          << "Nb. Frames: "  << Standard_Real(aNbFrames);
-
-    aView->Redraw();
+    while (aSecondsProgress < Standard_Integer(aRecPts / aPlaySpeed))
+    {
+      aPS.Next();
+      ++aSecondsProgress;
+    }
   }
 
+  aPerfTimer.Stop();
+  anAnimation->Stop();
+  const Standard_Real aRecFps = Standard_Real(aNbFrames) / aPerfTimer.ElapsedTime();
+  theDI << "Average FPS: " << aRecFps << "\n"
+        << "Nb. Frames: "  << Standard_Real(aNbFrames);
+
+  aView->Redraw();
   aView->SetImmediateUpdate (wasImmediateUpdate);
-  TheIsAnimating = Standard_False;
   return 0;
 }
 
@@ -14740,10 +14786,11 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
             "List existing animations:"
     "\n\t\t:  vanim"
     "\n\t\t: Animation playback:"
-    "\n\t\t:  vanim name -play|-resume [playFrom [playDuration]]"
-    "\n\t\t:            [-speed Coeff] [-freeLook] [-lockLoop]"
+    "\n\t\t:  vanim name {-play|-resume|-pause|-stop} [playFrom [playDuration]]"
+    "\n\t\t:            [-speed Coeff] [-freeLook] [-noPauseOnClick] [-lockLoop]"
     "\n\t\t:   -speed    playback speed (1.0 is normal speed)"
     "\n\t\t:   -freeLook skip camera animations"
+    "\n\t\t:   -noPauseOnClick do not pause animation on mouse click"
     "\n\t\t:   -lockLoop disable any interactions"
     "\n\t\t:"
     "\n\t\t: Animation definition:"
@@ -14791,7 +14838,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "\n\t\t:   -vcodec  video codec identifier (ffv1, mjpeg, etc.)"
     "\n\t\t:   -pix_fmt image pixel format (yuv420p, rgb24, etc.)"
     "\n\t\t:   -crf     constant rate factor (specific to codec)"
-    "\n\t\t:   -preset  codec parameters preset (specific to codec)"
+    "\n\t\t:   -preset  codec parameters preset (specific to codec)",
     __FILE__, VAnimation, group);
 
   theCommands.Add("vchangeselected",