Added classes AIS_Animation, AIS_AnimationCamera, AIS_AnimationObjectLocatio.
Draw Harness command vanimation has been modified to manage animation timeline.
Command vfit has been extended with option -noupdate.
Formatting of vviewparams command output has been improved.
Functionality of commands vlocreset, vlocmove, vloctranslate, vlocrotate,
vlocmirror, vlocscale has been merged into vlocation/vsetlocation.
vlocation now can print the current local transformation of the object.
v3d/ivtk test group does not call vfit anymore.
Fixed misprint in test cases bugs/vis/bug24623_3 and bug25532.
--- /dev/null
+// Created by: Anastasia BORISOVA
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <AIS_Animation.hxx>
+
+#include <Standard_Assert.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(AIS_Animation, Standard_Transient)
+
+//=============================================================================
+//function : Constructor
+//purpose :
+//=============================================================================
+AIS_Animation::AIS_Animation (const TCollection_AsciiString& theAnimationName)
+: myName (theAnimationName),
+ myState (AnimationState_Stopped),
+ myPtsStart (0.0),
+ myOwnDuration (0.0),
+ myChildrenDuration (0.0)
+{
+ //
+}
+
+//=============================================================================
+//function : ~AIS_Animation
+//purpose :
+//=============================================================================
+AIS_Animation::~AIS_Animation()
+{
+ Clear();
+}
+
+//=============================================================================
+//function : Clear
+//purpose :
+//=============================================================================
+void AIS_Animation::Clear()
+{
+ myAnimations.Clear();
+ myOwnDuration = 0.0;
+}
+
+//=============================================================================
+//function : Add
+//purpose :
+//=============================================================================
+void AIS_Animation::Add (const Handle(AIS_Animation)& theAnimation)
+{
+ if (theAnimation.IsNull())
+ {
+ Standard_ProgramError::Raise ("AIS_Animation::Add() - attempt to add a NULL animation!");
+ }
+
+ for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
+ {
+ if (anIter.Value() == theAnimation)
+ {
+ UpdateTotalDuration();
+ return;
+ }
+ }
+
+ myAnimations.Append (theAnimation);
+ UpdateTotalDuration();
+}
+
+//=============================================================================
+//function : Find
+//purpose :
+//=============================================================================
+Handle(AIS_Animation) AIS_Animation::Find (const TCollection_AsciiString& theAnimationName) const
+{
+ for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
+ {
+ if (anIter.Value()->Name() == theAnimationName)
+ {
+ return anIter.Value();
+ }
+ }
+ return Handle(AIS_Animation)();
+}
+
+//=============================================================================
+//function : Remove
+//purpose :
+//=============================================================================
+Standard_Boolean AIS_Animation::Remove (const Handle(AIS_Animation)& theAnimation)
+{
+ for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
+ {
+ if (anIter.Value() == theAnimation)
+ {
+ myAnimations.Remove (anIter);
+ UpdateTotalDuration();
+ return Standard_True;
+ }
+ }
+ return Standard_False;
+}
+
+//=============================================================================
+//function : Replace
+//purpose :
+//=============================================================================
+Standard_Boolean AIS_Animation::Replace (const Handle(AIS_Animation)& theAnimationOld,
+ const Handle(AIS_Animation)& theAnimationNew)
+{
+ for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
+ {
+ if (anIter.Value() == theAnimationOld)
+ {
+ anIter.ChangeValue() = theAnimationNew;
+ UpdateTotalDuration();
+ return Standard_True;
+ }
+ }
+ return Standard_False;
+}
+
+//=============================================================================
+//function : CopyFrom
+//purpose :
+//=============================================================================
+void AIS_Animation::CopyFrom (const Handle(AIS_Animation)& theOther)
+{
+ myAnimations.Clear();
+ for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (theOther->myAnimations); anIter.More(); anIter.Next())
+ {
+ myAnimations.Append (anIter.Value());
+ }
+ UpdateTotalDuration();
+ myPtsStart = theOther->myPtsStart;
+ myOwnDuration = theOther->myOwnDuration;
+}
+
+//=============================================================================
+//function : UpdateTotalDuration
+//purpose :
+//=============================================================================
+void AIS_Animation::UpdateTotalDuration()
+{
+ myChildrenDuration = 0.0;
+ for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
+ {
+ myChildrenDuration = Max (myChildrenDuration, anIter.Value()->StartPts() + anIter.Value()->Duration());
+ }
+}
+
+//=============================================================================
+//function : StartTimer
+//purpose :
+//=============================================================================
+void AIS_Animation::StartTimer (const Standard_Real theStartPts,
+ const Standard_Real thePlaySpeed,
+ const Standard_Boolean theToUpdate)
+{
+ if (myTimer.IsNull())
+ {
+ myTimer = new AIS_AnimationTimer();
+ }
+ myTimer->Stop();
+ myTimer->Seek (theStartPts);
+ myTimer->SetPlaybackSpeed (thePlaySpeed);
+ Start (theToUpdate);
+}
+
+//=============================================================================
+//function : UpdateTimer
+//purpose :
+//=============================================================================
+Standard_Real AIS_Animation::UpdateTimer()
+{
+ if (myTimer.IsNull())
+ {
+ Standard_ProgramError::Raise ("AIS_Animation::UpdateTimer() - timer was not created!");
+ }
+
+ const Standard_Real anElapsedTime = myTimer->ElapsedTime();
+ Update (anElapsedTime);
+ return anElapsedTime;
+}
+
+//=============================================================================
+//function : Start
+//purpose :
+//=============================================================================
+void AIS_Animation::Start (const Standard_Boolean theToUpdate)
+{
+ UpdateTotalDuration();
+ myState = AnimationState_Started;
+ for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
+ {
+ anIter.ChangeValue()->Start (Standard_False);
+ }
+
+ if (theToUpdate)
+ {
+ const Standard_Real anElapsedTime = !myTimer.IsNull()
+ ? myTimer->ElapsedTime()
+ : 0.0;
+ Update (anElapsedTime);
+ }
+
+ if (!myTimer.IsNull())
+ {
+ myTimer->Start();
+ }
+}
+
+//=============================================================================
+//function : Pause
+//purpose :
+//=============================================================================
+void AIS_Animation::Pause()
+{
+ myState = AnimationState_Paused;
+ if (!myTimer.IsNull())
+ {
+ myTimer->Pause();
+ }
+
+ for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
+ {
+ anIter.ChangeValue()->Stop();
+ }
+}
+
+//=============================================================================
+//function : Stop
+//purpose :
+//=============================================================================
+void AIS_Animation::Stop()
+{
+ myState = AnimationState_Stopped;
+ if (!myTimer.IsNull())
+ {
+ myTimer->Stop();
+ }
+
+ for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
+ {
+ anIter.ChangeValue()->Stop();
+ }
+}
+
+//=============================================================================
+//function : Update
+//purpose :
+//=============================================================================
+Standard_Boolean AIS_Animation::Update (const Standard_Real thePts)
+{
+ AIS_AnimationProgress aPosition;
+ aPosition.Pts = thePts;
+ aPosition.LocalPts = thePts - myPtsStart;
+ aPosition.LocalNormalized = HasOwnDuration()
+ ? (aPosition.LocalPts / myOwnDuration)
+ : 0.0;
+ aPosition.LocalNormalized = Max (0.0, aPosition.LocalNormalized);
+ aPosition.LocalNormalized = Min (1.0, aPosition.LocalNormalized);
+ updateWithChildren (aPosition);
+ return thePts < myPtsStart + Duration();
+}
+
+//=============================================================================
+//function : updateWithChildren
+//purpose :
+//=============================================================================
+void AIS_Animation::updateWithChildren (const AIS_AnimationProgress& thePosition)
+{
+ if (thePosition.LocalPts < 0.0
+ || IsStopped())
+ {
+ return;
+ }
+
+ for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anIter (myAnimations); anIter.More(); anIter.Next())
+ {
+ const Handle(AIS_Animation)& anAnim = anIter.Value();
+ AIS_AnimationProgress aPosition = thePosition;
+ aPosition.LocalPts = aPosition.LocalPts - anAnim->StartPts();
+ aPosition.LocalNormalized = anAnim->HasOwnDuration()
+ ? (aPosition.LocalPts / anAnim->OwnDuration())
+ : 0.0;
+ aPosition.LocalNormalized = Max (0.0, aPosition.LocalNormalized);
+ aPosition.LocalNormalized = Min (1.0, aPosition.LocalNormalized);
+ anAnim->updateWithChildren (aPosition);
+ }
+
+ if (thePosition.LocalPts >= Duration())
+ {
+ Stop();
+ }
+
+ update (thePosition);
+}
--- /dev/null
+// Created by: Anastasia BORISOVA
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _AIS_Animation_HeaderFile
+#define _AIS_Animation_HeaderFile
+
+#include <AIS_AnimationTimer.hxx>
+#include <NCollection_Sequence.hxx>
+#include <TCollection_AsciiString.hxx>
+
+//! Structure defining current animation progress.
+struct AIS_AnimationProgress
+{
+ Standard_Real Pts; //!< global presentation timestamp
+ Standard_Real LocalPts; //!< presentation within current animation
+ Standard_Real LocalNormalized; //!< normalized position within current animation within 0..1 range
+
+ AIS_AnimationProgress() : Pts (-1.0), LocalPts (-1.0), LocalNormalized (-1.0) {}
+};
+
+DEFINE_STANDARD_HANDLE(AIS_Animation, Standard_Transient)
+
+//! Class represents single animation.
+//! It is defined with:
+//! - Start time on the timeline started from 0, in seconds
+//! - Duration, in seconds
+//! - virtual method Update() for handling an update
+class AIS_Animation : public Standard_Transient
+{
+ DEFINE_STANDARD_RTTIEXT(AIS_Animation, Standard_Transient)
+public:
+
+ //! Creates empty animation.
+ Standard_EXPORT AIS_Animation (const TCollection_AsciiString& theAnimationName);
+
+ //! Destruct object, clear arguments
+ Standard_EXPORT virtual ~AIS_Animation();
+
+ //! Animation name.
+ const TCollection_AsciiString& Name() const { return myName; }
+
+public:
+
+ //! @return start time of the animation in the timeline
+ Standard_Real StartPts() const { return myPtsStart; }
+
+ //! Sets time limits for animation in the animation timeline
+ void SetStartPts (const Standard_Real thePtsStart) { myPtsStart = thePtsStart; }
+
+ //! @return duration of the animation in the timeline
+ Standard_Real Duration() const { return Max (myOwnDuration, myChildrenDuration); }
+
+ //! Update total duration considering all animations on timeline.
+ Standard_EXPORT void UpdateTotalDuration();
+
+ //! Return true if duration is defined.
+ Standard_Boolean HasOwnDuration() const { return myOwnDuration > 0.0; }
+
+ //! @return own duration of the animation in the timeline
+ Standard_Real OwnDuration() const { return myOwnDuration; }
+
+ //! Defines duration of the animation.
+ void SetOwnDuration (const Standard_Real theDuration) { myOwnDuration = theDuration; }
+
+ //! Add single animation to the timeline.
+ //! @param theAnimation input animation
+ Standard_EXPORT void Add (const Handle(AIS_Animation)& theAnimation);
+
+ //! Clear animation timeline - remove all animations from it.
+ Standard_EXPORT void Clear();
+
+ //! Return the child animation with the given name.
+ Standard_EXPORT Handle(AIS_Animation) Find (const TCollection_AsciiString& theAnimationName) const;
+
+ //! Remove the child animation.
+ Standard_EXPORT Standard_Boolean Remove (const Handle(AIS_Animation)& theAnimation);
+
+ //! Replace the child animation.
+ Standard_EXPORT Standard_Boolean Replace (const Handle(AIS_Animation)& theAnimationOld,
+ const Handle(AIS_Animation)& theAnimationNew);
+
+ //! Clears own children and then copy child animations from another object.
+ //! Copy also Start Time and Duration values.
+ Standard_EXPORT void CopyFrom (const Handle(AIS_Animation)& theOther);
+
+ //! Return sequence of child animations.
+ const NCollection_Sequence<Handle(AIS_Animation)>& Children() const { return myAnimations; }
+
+public:
+
+ //! Start animation with internally defined timer instance.
+ //! Calls ::Start() internally.
+ Standard_EXPORT virtual void StartTimer (const Standard_Real theStartPts,
+ const Standard_Real thePlaySpeed,
+ const Standard_Boolean theToUpdate);
+
+ //! Update single frame of animation, update timer state
+ //! @return current time of timeline progress.
+ Standard_EXPORT virtual Standard_Real UpdateTimer();
+
+ //! Return elapsed time.
+ Standard_Real ElapsedTime() const { return !myTimer.IsNull() ? myTimer->ElapsedTime() : 0.0; }
+
+public:
+
+ //! Start animation. This method changes status of the animation to Started.
+ //! This status defines whether animation is to be performed in the timeline or not.
+ //! @param theToUpdate call Update() method
+ Standard_EXPORT virtual void Start (const Standard_Boolean theToUpdate);
+
+ //! Pause the process timeline.
+ Standard_EXPORT virtual void Pause();
+
+ //! Stop animation. This method changed status of the animation to Stopped.
+ //! This status shows that animation will not be performed in the timeline or it is finished.
+ Standard_EXPORT virtual void Stop();
+
+ //! Check if animation is to be performed in the animation timeline.
+ //! @return True if it is stopped of finished.
+ bool IsStopped() { return myState != AnimationState_Started; }
+
+ //! Update single frame of animation, update timer state
+ //! @param thePts [in] the time moment within [0; Duration()]
+ //! @return True if timeline is in progress
+ Standard_EXPORT virtual Standard_Boolean Update (const Standard_Real thePts);
+
+protected:
+
+ //! Process one step of the animation according to the input time progress, including all children.
+ //! Calls also ::update() to update own animation.
+ Standard_EXPORT virtual void updateWithChildren (const AIS_AnimationProgress& thePosition);
+
+ //! Update the own animation to specified position - should be overridden by sub-class.
+ virtual void update (const AIS_AnimationProgress& theProgress) { (void )theProgress; }
+
+protected:
+
+ //! Defines animation state.
+ enum AnimationState
+ {
+ AnimationState_Started, //!< animation is in progress
+ AnimationState_Stopped, //!< animation is finished, force stopped or not started
+ AnimationState_Paused //!< animation is paused and can be started from the pause moment
+ };
+
+protected:
+
+ Handle(AIS_AnimationTimer) myTimer;
+
+ TCollection_AsciiString myName; //!< animation name
+ NCollection_Sequence<Handle(AIS_Animation)>
+ myAnimations; //!< sequence of child animations
+
+ AnimationState myState; //!< animation state - started, stopped of paused
+ Standard_Real myPtsStart; //!< time of start in the timeline
+ Standard_Real myOwnDuration; //!< duration of animation excluding children
+ Standard_Real myChildrenDuration; //!< duration of animation including children
+
+};
+
+#endif // _AIS_Animation_HeaderFile
--- /dev/null
+// Created by: Anastasia BORISOVA
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <AIS_AnimationCamera.hxx>
+
+#include <Graphic3d_Camera.hxx>
+#include <Precision.hxx>
+#include <V3d_View.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(AIS_AnimationCamera, AIS_Animation)
+
+//=============================================================================
+//function : AIS_AnimationCamera
+//purpose :
+//=============================================================================
+AIS_AnimationCamera::AIS_AnimationCamera (const TCollection_AsciiString& theAnimationName,
+ const Handle(V3d_View)& theView)
+: AIS_Animation (theAnimationName),
+ myView (theView)
+{
+ //
+}
+
+//=============================================================================
+//function : update
+//purpose :
+//=============================================================================
+void AIS_AnimationCamera::update (const AIS_AnimationProgress& theProgress)
+{
+ if (myView.IsNull()
+ || myCamStart.IsNull()
+ || myCamEnd.IsNull())
+ {
+ return;
+ }
+
+ Handle(Graphic3d_Camera) aCamera = myView->Camera();
+
+ Graphic3d_CameraLerp aCamLerp (myCamStart, myCamEnd);
+ aCamLerp.Interpolate (theProgress.LocalNormalized, aCamera);
+
+ const Standard_Boolean aPrevImmUpdate = myView->SetImmediateUpdate (Standard_False);
+ myView->SetCamera (aCamera);
+ myView->SetImmediateUpdate (aPrevImmUpdate);
+ myView->Invalidate();
+}
--- /dev/null
+// Created by: Anastasia BORISOVA
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _AIS_AnimationCamera_HeaderFile
+#define _AIS_AnimationCamera_HeaderFile
+
+#include <AIS_Animation.hxx>
+
+class Graphic3d_Camera;
+class V3d_View;
+
+//! Camera animation.
+class AIS_AnimationCamera : public AIS_Animation
+{
+ DEFINE_STANDARD_RTTIEXT(AIS_AnimationCamera, AIS_Animation)
+public:
+
+ //! Main constructor.
+ Standard_EXPORT AIS_AnimationCamera (const TCollection_AsciiString& theAnimationName,
+ const Handle(V3d_View)& theView);
+
+ //! Return the target view.
+ const Handle(V3d_View)& View() const { return myView; }
+
+ //! Return camera start position.
+ const Handle(Graphic3d_Camera)& CameraStart() const { return myCamStart; }
+
+ //! Define camera start position.
+ void SetCameraStart (const Handle(Graphic3d_Camera)& theCameraStart) { myCamStart = theCameraStart; }
+
+ //! Return camera end position.
+ const Handle(Graphic3d_Camera)& CameraEnd() const { return myCamEnd; }
+
+ //! Define camera end position.
+ void SetCameraEnd (const Handle(Graphic3d_Camera)& theCameraEnd) { myCamEnd = theCameraEnd; }
+
+protected:
+
+ //! Update the progress.
+ Standard_EXPORT virtual void update (const AIS_AnimationProgress& theProgress) Standard_OVERRIDE;
+
+protected:
+
+ Handle(V3d_View) myView; //!< view to setup camera
+ Handle(Graphic3d_Camera) myCamStart; //!< starting camera position
+ Handle(Graphic3d_Camera) myCamEnd; //!< end camera position
+
+};
+
+DEFINE_STANDARD_HANDLE(AIS_AnimationCamera, AIS_Animation)
+
+#endif // _AIS_AnimationCamera_HeaderFile
--- /dev/null
+// Created by: Anastasia BORISOVA
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <AIS_AnimationObject.hxx>
+
+#include <AIS_InteractiveContext.hxx>
+#include <TopLoc_Location.hxx>
+#include <V3d_Viewer.hxx>
+#include <V3d_View.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(AIS_AnimationObject, AIS_Animation)
+
+//=============================================================================
+//function : Constructor
+//purpose :
+//=============================================================================
+AIS_AnimationObject::AIS_AnimationObject (const TCollection_AsciiString& theAnimationName,
+ const Handle(AIS_InteractiveContext)& theContext,
+ const Handle(AIS_InteractiveObject)& theObject,
+ const gp_Trsf& theTrsfStart,
+ const gp_Trsf& theTrsfEnd)
+: AIS_Animation (theAnimationName),
+ myContext (theContext),
+ myObject (theObject),
+ myTrsfLerp (theTrsfStart, theTrsfEnd)
+{
+ //
+}
+
+//=============================================================================
+//function : update
+//purpose :
+//=============================================================================
+void AIS_AnimationObject::update (const AIS_AnimationProgress& theProgress)
+{
+ if (myObject.IsNull())
+ {
+ return;
+ }
+
+ gp_Trsf aTrsf;
+ myTrsfLerp.Interpolate (theProgress.LocalNormalized, aTrsf);
+ if (!myContext.IsNull())
+ {
+ myContext->SetLocation (myObject, aTrsf);
+ invalidateViewer();
+ }
+ else
+ {
+ myObject->SetLocalTransformation (aTrsf);
+ }
+}
+
+//=============================================================================
+//function : invalidateViewer
+//purpose :
+//=============================================================================
+void AIS_AnimationObject::invalidateViewer()
+{
+ if (myContext.IsNull())
+ {
+ return;
+ }
+
+ const Standard_Boolean isImmediate = myContext->CurrentViewer()->ZLayerSettings (myObject->ZLayer()).IsImmediate();
+ if (!isImmediate)
+ {
+ myContext->CurrentViewer()->Invalidate();
+ return;
+ }
+
+ // Invalidate immediate view only if it is going out of z-fit range.
+ // This might be sub-optimal performing this for each animated objects in case of many animated objects.
+ for (V3d_ListOfView::Iterator aDefViewIter = myContext->CurrentViewer()->DefinedViewIterator();
+ aDefViewIter.More(); aDefViewIter.Next())
+ {
+ const Handle(V3d_View)& aView = aDefViewIter.Value();
+ const Bnd_Box aMinMaxBox = aView->View()->MinMaxValues (Standard_False);
+ const Bnd_Box aGraphicBox = aView->View()->MinMaxValues (Standard_True);
+ Standard_Real aZNear = 0.0;
+ Standard_Real aZFar = 0.0;
+ if (aView->Camera()->ZFitAll (aDefViewIter.Value()->AutoZFitScaleFactor(), aMinMaxBox, aGraphicBox, aZNear, aZFar))
+ {
+ if (aZNear < aView->Camera()->ZNear()
+ || aZFar > aView->Camera()->ZFar())
+ {
+ aDefViewIter.Value()->Invalidate();
+ }
+ }
+ }
+}
--- /dev/null
+// Created by: Anastasia BORISOVA
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _AIS_AnimationObject_HeaderFile
+#define _AIS_AnimationObject_HeaderFile
+
+#include <AIS_Animation.hxx>
+#include <AIS_InteractiveContext.hxx>
+#include <gp_TrsfNLerp.hxx>
+
+//! Animation defining object transformation.
+class AIS_AnimationObject : public AIS_Animation
+{
+ DEFINE_STANDARD_RTTIEXT(AIS_AnimationObject, AIS_Animation)
+public:
+
+ //! Constructor with initialization.
+ //! Note that start/end transformations specify exactly local transformation of the object,
+ //! not the transformation to be applied to existing local transformation.
+ //! @param theAnimationName animation identifier
+ //! @param theContext interactive context where object have been displayed
+ //! @param theObject object to apply local transformation
+ //! @param theTrsfStart local transformation at the start of animation (e.g. theObject->LocalTransformation())
+ //! @param theTrsfEnd local transformation at the end of animation
+ Standard_EXPORT AIS_AnimationObject (const TCollection_AsciiString& theAnimationName,
+ const Handle(AIS_InteractiveContext)& theContext,
+ const Handle(AIS_InteractiveObject)& theObject,
+ const gp_Trsf& theTrsfStart,
+ const gp_Trsf& theTrsfEnd);
+
+protected:
+
+ //! Update the progress.
+ Standard_EXPORT virtual void update (const AIS_AnimationProgress& theProgress) Standard_OVERRIDE;
+
+ //! Invalidate the viewer for proper update.
+ Standard_EXPORT void invalidateViewer();
+
+protected:
+
+ Handle(AIS_InteractiveContext) myContext; //!< context where object is displayed
+ Handle(AIS_InteractiveObject) myObject; //!< presentation object to set location
+ gp_TrsfNLerp myTrsfLerp; //!< interpolation tool
+
+};
+
+DEFINE_STANDARD_HANDLE(AIS_AnimationObject, AIS_Animation)
+
+#endif // _AIS_AnimationObject_HeaderFile
--- /dev/null
+// Created by: Kirill Gavrilov
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <AIS_AnimationTimer.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(AIS_AnimationTimer, Standard_Transient)
+
+//=============================================================================
+//function : Pause
+//purpose :
+//=============================================================================
+void AIS_AnimationTimer::Pause()
+{
+ myTimer.Stop();
+ myTimerFrom += myTimer.ElapsedTime() * myTimerSpeed;
+ myTimer.Reset();
+}
+
+//=============================================================================
+//function : Stop
+//purpose :
+//=============================================================================
+void AIS_AnimationTimer::Stop()
+{
+ myTimer.Stop();
+ myTimer.Reset();
+ myTimerFrom = 0.0;
+}
+
+//=============================================================================
+//function : SetPlaybackSpeed
+//purpose :
+//=============================================================================
+void AIS_AnimationTimer::SetPlaybackSpeed (const Standard_Real theSpeed)
+{
+ if (!myTimer.IsStarted())
+ {
+ myTimerSpeed = theSpeed;
+ return;
+ }
+
+ myTimer.Stop();
+ myTimerFrom += myTimer.ElapsedTime() * myTimerSpeed;
+ myTimer.Reset();
+ myTimerSpeed = theSpeed;
+ myTimer.Start();
+}
+
+//=============================================================================
+//function : SetPlaybackSpeed
+//purpose :
+//=============================================================================
+void AIS_AnimationTimer::Seek (const Standard_Real theTime)
+{
+ const Standard_Boolean isStarted = myTimer.IsStarted();
+ myTimer.Stop();
+ myTimer.Reset();
+ myTimerFrom = theTime;
+ if (isStarted)
+ {
+ myTimer.Start();
+ }
+}
--- /dev/null
+// Created by: Kirill Gavrilov
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _AIS_AnimationTimer_HeaderFile
+#define _AIS_AnimationTimer_HeaderFile
+
+#include <OSD_Timer.hxx>
+#include <Standard_Transient.hxx>
+#include <Standard_Type.hxx>
+
+//! Auxiliary class defining the animation timer.
+class AIS_AnimationTimer : public Standard_Transient
+{
+ DEFINE_STANDARD_RTTIEXT(AIS_Animation, Standard_Transient)
+public:
+
+ //! Empty constructor.
+ AIS_AnimationTimer() : myTimerFrom (0.0), myTimerSpeed (1.0) {}
+
+ //! Return elapsed time in seconds.
+ Standard_Real ElapsedTime() const
+ {
+ return myTimerFrom + myTimer.ElapsedTime() * myTimerSpeed;
+ }
+
+ //! Return playback speed coefficient (1.0 means normal speed).
+ Standard_Real PlaybackSpeed() const { return myTimerSpeed; }
+
+ //! Setup playback speed coefficient.
+ Standard_EXPORT void SetPlaybackSpeed (const Standard_Real theSpeed);
+
+ //! Return true if timer has been started.
+ Standard_Boolean IsStarted() const
+ {
+ return myTimer.IsStarted();
+ }
+
+ //! Start the timer.
+ void Start()
+ {
+ myTimer.Start();
+ }
+
+ //! Pause the timer.
+ Standard_EXPORT void Pause();
+
+ //! Stop the timer.
+ Standard_EXPORT void Stop();
+
+ //! Seek the timer to specified position.
+ Standard_EXPORT void Seek (const Standard_Real theTime);
+
+protected:
+
+ OSD_Timer myTimer;
+ Standard_Real myTimerFrom;
+ Standard_Real myTimerSpeed;
+
+};
+
+DEFINE_STANDARD_HANDLE(AIS_AnimationTimer, Standard_Transient)
+
+#endif // _AIS_AnimationTimer_HeaderFile
aDefViewIter.Value()->View()->ChangeHiddenObjects()->Remove (theIObj.get());
}
- if (!myLastinMain.IsNull() && myLastinMain->IsSameSelectable (theIObj))
- myLastinMain.Nullify();
- if (!myLastPicked.IsNull() && myLastPicked->IsSameSelectable (theIObj))
- myLastPicked.Nullify();
- myMainPM->ClearImmediateDraw();
+ if (!myLastinMain.IsNull())
+ {
+ if (myLastinMain->IsSameSelectable (theIObj)
+ || myLastPicked->IsSameSelectable(theIObj))
+ {
+ myLastinMain.Nullify();
+ myMainPM->ClearImmediateDraw();
+ }
+ }
if (theToUpdateviewer && aStatus->GraphicStatus() == AIS_DS_Displayed)
{
AIS.cxx
AIS.hxx
+AIS_Animation.cxx
+AIS_Animation.hxx
+AIS_AnimationTimer.cxx
+AIS_AnimationTimer.hxx
+AIS_AnimationCamera.cxx
+AIS_AnimationCamera.hxx
+AIS_AnimationObject.cxx
+AIS_AnimationObject.hxx
AIS_AngleDimension.cxx
AIS_AngleDimension.hxx
AIS_AttributeFilter.cxx
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-#include <gp_Pln.hxx>
-#include <Standard_ShortReal.hxx>
-
#include <Graphic3d_Camera.hxx>
+
+#include <gp_Pln.hxx>
+#include <gp_QuaternionNLerp.hxx>
+#include <gp_QuaternionSLerp.hxx>
#include <Graphic3d_Vec4.hxx>
#include <Graphic3d_WorldViewProjState.hxx>
-
+#include <NCollection_Sequence.hxx>
+#include <Standard_ShortReal.hxx>
#include <Standard_Atomic.hxx>
#include <Standard_Assert.hxx>
-#include <NCollection_Sequence.hxx>
-
-
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Camera,Standard_Transient)
namespace
Standard_Real aExp = Floor (aLogRadix);
return FLT_EPSILON * Pow (FLT_RADIX, aExp);
}
+
+ //! Convert camera definition to Ax3
+ gp_Ax3 cameraToAx3 (const Graphic3d_Camera& theCamera)
+ {
+ const gp_Dir aBackDir(gp_Vec(theCamera.Center(), theCamera.Eye()));
+ const gp_Dir anXAxis (theCamera.Up().Crossed (aBackDir));
+ const gp_Dir anYAxis (aBackDir .Crossed (anXAxis));
+ const gp_Dir aZAxis (anXAxis .Crossed (anYAxis));
+ return gp_Ax3 (gp_Pnt (0.0, 0.0, 0.0), aZAxis, anXAxis);
+ }
}
// =======================================================================
theZFar = aZFar;
return true;
}
+
+//=============================================================================
+//function : Interpolate
+//purpose :
+//=============================================================================
+template<>
+Standard_EXPORT void NCollection_Lerp<Handle(Graphic3d_Camera)>::Interpolate (const double theT,
+ Handle(Graphic3d_Camera)& theCamera) const
+{
+ if (Abs (theT - 1.0) < Precision::Confusion())
+ {
+ // just copy end-point transformation
+ theCamera->Copy (myEnd);
+ return;
+ }
+
+ theCamera->Copy (myStart);
+ if (Abs (theT - 0.0) < Precision::Confusion())
+ {
+ return;
+ }
+
+ // apply rotation
+ {
+ gp_Ax3 aCamStart = cameraToAx3 (*myStart);
+ gp_Ax3 aCamEnd = cameraToAx3 (*myEnd);
+ gp_Trsf aTrsfStart, aTrsfEnd;
+ aTrsfStart.SetTransformation (aCamStart, gp::XOY());
+ aTrsfEnd .SetTransformation (aCamEnd, gp::XOY());
+
+ gp_Quaternion aRotStart = aTrsfStart.GetRotation();
+ gp_Quaternion aRotEnd = aTrsfEnd .GetRotation();
+ gp_Quaternion aRotDelta = aRotEnd * aRotStart.Inverted();
+ gp_Quaternion aRot = gp_QuaternionNLerp::Interpolate (gp_Quaternion(), aRotDelta, theT);
+ gp_Trsf aTrsfRot;
+ aTrsfRot.SetRotation (aRot);
+ theCamera->Transform (aTrsfRot);
+ }
+
+ // apply translation
+ {
+ gp_XYZ aCenter = NCollection_Lerp<gp_XYZ>::Interpolate (myStart->Center().XYZ(), myEnd->Center().XYZ(), theT);
+ gp_XYZ anEye = NCollection_Lerp<gp_XYZ>::Interpolate (myStart->Eye().XYZ(), myEnd->Eye().XYZ(), theT);
+ gp_XYZ anAnchor = aCenter;
+ Standard_Real aKc = 0.0;
+
+ const Standard_Real aDeltaCenter = myStart->Center().Distance (myEnd->Center());
+ const Standard_Real aDeltaEye = myStart->Eye() .Distance (myEnd->Eye());
+ if (aDeltaEye <= gp::Resolution())
+ {
+ anAnchor = anEye;
+ aKc = 1.0;
+ }
+ else if (aDeltaCenter > gp::Resolution())
+ {
+ aKc = aDeltaCenter / (aDeltaCenter + aDeltaEye);
+
+ const gp_XYZ anAnchorStart = NCollection_Lerp<gp_XYZ>::Interpolate (myStart->Center().XYZ(), myStart->Eye().XYZ(), aKc);
+ const gp_XYZ anAnchorEnd = NCollection_Lerp<gp_XYZ>::Interpolate (myEnd ->Center().XYZ(), myEnd ->Eye().XYZ(), aKc);
+ anAnchor = NCollection_Lerp<gp_XYZ>::Interpolate (anAnchorStart, anAnchorEnd, theT);
+ }
+
+ const gp_Vec aDirEyeToCenter = theCamera->Direction();
+ const Standard_Real aDistEyeCenterStart = myStart->Eye().Distance (myStart->Center());
+ const Standard_Real aDistEyeCenterEnd = myEnd ->Eye().Distance (myEnd ->Center());
+ const Standard_Real aDistEyeCenter = NCollection_Lerp<Standard_Real>::Interpolate (aDistEyeCenterStart, aDistEyeCenterEnd, theT);
+ aCenter = anAnchor + aDirEyeToCenter.XYZ() * aDistEyeCenter * aKc;
+ anEye = anAnchor - aDirEyeToCenter.XYZ() * aDistEyeCenter * (1.0 - aKc);
+
+ theCamera->SetCenter (aCenter);
+ theCamera->SetEye (anEye);
+ }
+
+ // apply scaling
+ if (Abs(myStart->Scale() - myEnd->Scale()) > Precision::Confusion()
+ && myStart->IsOrthographic())
+ {
+ const Standard_Real aScale = NCollection_Lerp<Standard_Real>::Interpolate (myStart->Scale(), myEnd->Scale(), theT);
+ theCamera->SetScale (aScale);
+ }
+}
#include <Graphic3d_Mat4.hxx>
#include <Graphic3d_Vec3.hxx>
#include <Graphic3d_WorldViewProjState.hxx>
+#include <NCollection_Lerp.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
DEFINE_STANDARD_HANDLE (Graphic3d_Camera, Standard_Transient)
+//! Linear interpolation tool for camera orientation and position.
+//! This tool interpolates camera parameters scale, eye, center, rotation (up and direction vectors) independently.
+//!
+//! Eye/Center interpolation is performed through defining an anchor point in-between Center and Eye.
+//! The anchor position is defined as point near to the camera point which has smaller translation part.
+//! The main idea is to keep the distance between Center and Eye
+//! (which will change if Center and Eye translation will be interpolated independently).
+//! E.g.:
+//! - When both Center and Eye are moved at the same vector -> both will be just translated by straight line
+//! - When Center is not moved -> camera Eye will move around Center through arc
+//! - When Eye is not moved -> camera Center will move around Eye through arc
+//! - When both Center and Eye are move by different vectors -> transformation will be something in between,
+//! and will try interpolate linearly the distance between Center and Eye.
+//!
+//! This transformation might be not in line with user expectations.
+//! In this case, application might define intermediate camera positions for interpolation
+//! or implement own interpolation logic.
+template<>
+Standard_EXPORT void NCollection_Lerp<Handle(Graphic3d_Camera)>::Interpolate (const double theT,
+ Handle(Graphic3d_Camera)& theResult) const;
+typedef NCollection_Lerp<Handle(Graphic3d_Camera)> Graphic3d_CameraLerp;
+
#endif
NCollection_IncAllocator.hxx
NCollection_IndexedDataMap.hxx
NCollection_IndexedMap.hxx
+NCollection_Lerp.hxx
NCollection_List.hxx
NCollection_ListNode.hxx
NCollection_LocalArray.hxx
--- /dev/null
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _NCollection_Lerp_HeaderFile
+#define _NCollection_Lerp_HeaderFile
+
+//! Simple linear interpolation tool (also known as mix() in GLSL).
+//! The main purpose of this template class is making interpolation routines more readable.
+template<class T>
+class NCollection_Lerp
+{
+public:
+ //! Compute interpolated value between two values.
+ //! @param theStart first value
+ //! @param theEnd second value
+ //! @param theT normalized interpolation coefficient within [0, 1] range,
+ //! with 0 pointing to theStart and 1 to theEnd.
+ static T Interpolate (const T& theStart,
+ const T& theEnd,
+ double theT)
+ {
+ T aResult;
+ NCollection_Lerp aLerp (theStart, theEnd);
+ aLerp.Interpolate (theT, aResult);
+ return aResult;
+ }
+
+public:
+
+ //! Empty constructor
+ NCollection_Lerp() : myStart(), myEnd() {}
+
+ //! Main constructor.
+ NCollection_Lerp (const T& theStart, const T& theEnd)
+ {
+ Init (theStart, theEnd);
+ }
+
+ //! Initialize values.
+ void Init (const T& theStart, const T& theEnd)
+ {
+ myStart = theStart;
+ myEnd = theEnd;
+ }
+
+ //! Compute interpolated value between two values.
+ //! @param theT normalized interpolation coefficient within [0, 1] range,
+ //! with 0 pointing to first value and 1 to the second value.
+ //! @param theResult [out] interpolated value
+ void Interpolate (double theT, T& theResult) const
+ {
+ theResult = (1.0 - theT) * myStart + theT * myEnd;
+ }
+
+private:
+ T myStart;
+ T myEnd;
+};
+
+#endif // _NCollection_Lerp_HeaderFile
//! process (all threads, and completed children) is measured.
Standard_EXPORT OSD_Chronometer(const Standard_Boolean ThisThreadOnly = Standard_False);
Standard_EXPORT virtual ~OSD_Chronometer();
-
+
+ //! Return true if timer has been started.
+ Standard_Boolean IsStarted() const { return !Stopped; }
+
//! Stops and Reinitializes the Chronometer.
Standard_EXPORT virtual void Reset();
second = Time - heure * 3600 - minut * 60;
}
+//=======================================================================
+//function : Reset
+//purpose :
+//=======================================================================
+
+void OSD_Timer::Reset (const Standard_Real theTimeElapsedSec)
+{
+ TimeStart = 0.0;
+ TimeCumul = theTimeElapsedSec;
+ OSD_Chronometer::Reset();
+}
+
//=======================================================================
//function : Reset
//purpose :
DEFINE_STANDARD_ALLOC
-
//! Builds a Chronometer initialized and stopped.
Standard_EXPORT OSD_Timer();
-
- //! Stops and reinitializes the timer.
+
+ //! Stops and reinitializes the timer with specified elapsed time.
+ Standard_EXPORT void Reset (const Standard_Real theTimeElapsedSec);
+
+ //! Stops and reinitializes the timer with zero elapsed time.
Standard_EXPORT virtual void Reset() Standard_OVERRIDE;
//! Shows both the elapsed time and CPU time on the standard output
//! Returns elapsed time in seconds.
Standard_EXPORT Standard_Real ElapsedTime() const;
-
-
-
-protected:
-
-
-
-
-
private:
-
-
Standard_Real TimeStart;
Standard_Real TimeCumul;
-
};
-
-
-
-
-
-
#endif // _OSD_Timer_HeaderFile
//! the camera approach.
Standard_EXPORT const Handle(Graphic3d_Camera)& Camera() const;
+ //! Return default camera.
+ const Handle(Graphic3d_Camera)& DefaultCamera() const { return myDefaultCamera; }
+
//! Returns current rendering parameters and effect settings.
//! By default it returns default parameters of current viewer.
//! To define view-specific settings use method V3d_View::ChangeRenderingParams().
Handle(AIS_InteractiveObject) anOldObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (theName));
if (!anOldObj.IsNull())
{
- aCtx->Remove (anOldObj, Standard_True);
+ aCtx->Remove (anOldObj, theObject.IsNull() && theToUpdate);
}
aMap.UnBind2 (theName);
}
return 0;
}
-
-//==================================================================================
-// Function : VAnimation
-//==================================================================================
-static int VAnimation (Draw_Interpretor& di, Standard_Integer argc, const char** argv) {
- if (argc != 5) {
- di<<"Use: "<<argv[0]<<" CrankArmFile CylinderHeadFile PropellerFile EngineBlockFile\n";
- return 1;
- }
-
- Standard_Real thread = 4;
- Standard_Real angleA=0;
- Standard_Real angleB;
- Standard_Real X;
- gp_Ax1 Ax1(gp_Pnt(0,0,0),gp_Vec(0,0,1));
-
- BRep_Builder B;
- TopoDS_Shape CrankArm;
- TopoDS_Shape CylinderHead;
- TopoDS_Shape Propeller;
- TopoDS_Shape EngineBlock;
-
- //BRepTools::Read(CrankArm,"/dp_26/Indus/ege/assemblage/CrankArm.rle",B);
- //BRepTools::Read(CylinderHead,"/dp_26/Indus/ege/assemblage/CylinderHead.rle",B);
- //BRepTools::Read(Propeller,"/dp_26/Indus/ege/assemblage/Propeller.rle",B);
- //BRepTools::Read(EngineBlock,"/dp_26/Indus/ege/assemblage/EngineBlock.rle",B);
- BRepTools::Read(CrankArm,argv[1],B);
- BRepTools::Read(CylinderHead,argv[2],B);
- BRepTools::Read(Propeller,argv[3],B);
- BRepTools::Read(EngineBlock,argv[4],B);
-
- if (CrankArm.IsNull() || CylinderHead.IsNull() || Propeller.IsNull() || EngineBlock.IsNull()) {di<<" Syntaxe error:loading failure.\n";}
-
-
- OSD_Timer myTimer;
- myTimer.Start();
-
- Handle(AIS_Shape) myAisCylinderHead = new AIS_Shape (CylinderHead);
- Handle(AIS_Shape) myAisEngineBlock = new AIS_Shape (EngineBlock);
- Handle(AIS_Shape) myAisCrankArm = new AIS_Shape (CrankArm);
- Handle(AIS_Shape) myAisPropeller = new AIS_Shape (Propeller);
-
- GetMapOfAIS().Bind(myAisCylinderHead,"a");
- GetMapOfAIS().Bind(myAisEngineBlock,"b");
- GetMapOfAIS().Bind(myAisCrankArm,"c");
- GetMapOfAIS().Bind(myAisPropeller,"d");
-
- myAisCylinderHead->SetMutable (Standard_True);
- myAisEngineBlock ->SetMutable (Standard_True);
- myAisCrankArm ->SetMutable (Standard_True);
- myAisPropeller ->SetMutable (Standard_True);
-
- TheAISContext()->SetColor (myAisCylinderHead, Quantity_NOC_INDIANRED);
- TheAISContext()->SetColor (myAisEngineBlock, Quantity_NOC_RED);
- TheAISContext()->SetColor (myAisPropeller, Quantity_NOC_GREEN);
-
- TheAISContext()->Display (myAisCylinderHead, Standard_False);
- TheAISContext()->Display (myAisEngineBlock, Standard_False);
- TheAISContext()->Display (myAisCrankArm, Standard_False);
- TheAISContext()->Display (myAisPropeller, Standard_False);
-
- TheAISContext()->Deactivate(myAisCylinderHead);
- TheAISContext()->Deactivate(myAisEngineBlock );
- TheAISContext()->Deactivate(myAisCrankArm );
- TheAISContext()->Deactivate(myAisPropeller );
-
- // Boucle de mouvement
- for (Standard_Real myAngle = 0;angleA<2*M_PI*10.175 ;myAngle++) {
-
- angleA = thread*myAngle*M_PI/180;
- X = Sin(angleA)*3/8;
- angleB = atan(X / Sqrt(-X * X + 1));
- Standard_Real decal(25*0.6);
-
-
- //Build a transformation on the display
- gp_Trsf aPropellerTrsf;
- aPropellerTrsf.SetRotation(Ax1,angleA);
- TheAISContext()->SetLocation(myAisPropeller,aPropellerTrsf);
-
- gp_Ax3 base(gp_Pnt(3*decal*(1-Cos(angleA)),-3*decal*Sin(angleA),0),gp_Vec(0,0,1),gp_Vec(1,0,0));
- gp_Trsf aCrankArmTrsf;
- aCrankArmTrsf.SetTransformation( base.Rotated(gp_Ax1(gp_Pnt(3*decal,0,0),gp_Dir(0,0,1)),angleB));
- TheAISContext()->SetLocation(myAisCrankArm,aCrankArmTrsf);
-
- TheAISContext()->UpdateCurrentViewer();
- }
-
- TopoDS_Shape myNewCrankArm =myAisCrankArm ->Shape().Located( myAisCrankArm ->Transformation() );
- TopoDS_Shape myNewPropeller =myAisPropeller->Shape().Located( myAisPropeller->Transformation() );
-
- myAisCrankArm ->ResetTransformation();
- myAisPropeller->ResetTransformation();
-
- myAisCrankArm -> Set(myNewCrankArm );
- myAisPropeller -> Set(myNewPropeller);
-
- TheAISContext()->Activate(myAisCylinderHead,0);
- TheAISContext()->Activate(myAisEngineBlock,0 );
- TheAISContext()->Activate(myAisCrankArm ,0 );
- TheAISContext()->Activate(myAisPropeller ,0 );
-
- myTimer.Stop();
- myTimer.Show();
- myTimer.Start();
-
- TheAISContext()->Redisplay(myAisCrankArm ,Standard_False);
- TheAISContext()->Redisplay(myAisPropeller,Standard_False);
-
- TheAISContext()->UpdateCurrentViewer();
- a3DView()->Redraw();
-
- myTimer.Stop();
- myTimer.Show();
-
- return 0;
-
-}
-
//==============================================================================
//function : VShading
//purpose : Sharpen or roughten the quality of the shading
"\n\t\t: Tests the animation of an object along a predefined trajectory.",
__FILE__,VPerf,group);
- theCommands.Add("vanimation",
- "vanimation CrankArmFile CylinderHeadFile PropellerFile EngineBlockFile",
- __FILE__,VAnimation,group);
-
theCommands.Add("vsetshading",
"vsetshading : vsetshading name Quality(default=0.0008) "
"\n\t\t: Sets deflection coefficient that defines the quality of the shape representation in the shading mode.",
//=======================================================================
void ViewerTest_AutoUpdater::Invalidate()
{
- myContext.Nullify();
- if (myWasAutoUpdate)
+ myToUpdate = ViewerTest_AutoUpdater::RedrawMode_Suppressed;
+ if (myWasAutoUpdate
+ && !myView.IsNull())
{
myView->SetImmediateUpdate (myWasAutoUpdate);
}
//=======================================================================
void ViewerTest_AutoUpdater::Update()
{
- if (myContext.IsNull())
+ if (!myView.IsNull())
{
- return;
+ myView->SetImmediateUpdate (myWasAutoUpdate);
}
- // update the screen and redraw the view
- myView->SetImmediateUpdate (myWasAutoUpdate);
- if ((myWasAutoUpdate && myToUpdate != ViewerTest_AutoUpdater::RedrawMode_Suppressed)
- || myToUpdate == ViewerTest_AutoUpdater::RedrawMode_Forced)
+ switch (myToUpdate)
{
- myContext->UpdateCurrentViewer();
+ case ViewerTest_AutoUpdater::RedrawMode_Suppressed:
+ {
+ return;
+ }
+ case ViewerTest_AutoUpdater::RedrawMode_Auto:
+ {
+ if (!myWasAutoUpdate)
+ {
+ return;
+ }
+ }
+ case ViewerTest_AutoUpdater::RedrawMode_Forced:
+ {
+ if (!myContext.IsNull())
+ {
+ myContext->UpdateCurrentViewer();
+ }
+ else if (!myView.IsNull())
+ {
+ myView->Redraw();
+ }
+ }
}
}
#include <AIS_Trihedron.hxx>
#include <AIS_Axis.hxx>
#include <gp_Trsf.hxx>
+#include <gp_Quaternion.hxx>
#include <TopLoc_Location.hxx>
#include <HLRAlgo_Projector.hxx>
Handle(AIS_TextLabel) aTextPrs;
ViewerTest_AutoUpdater anAutoUpdater (aContext, ViewerTest::CurrentView());
+ Standard_Boolean isNewPrs = Standard_False;
if (GetMapOfAIS().IsBound2 (aName))
{
- aTextPrs = Handle(AIS_TextLabel)::DownCast (GetMapOfAIS().Find2 (aName));
+ aTextPrs = Handle(AIS_TextLabel)::DownCast (GetMapOfAIS().Find2 (aName));
}
- else
+
+ if (aTextPrs.IsNull())
{
+ isNewPrs = Standard_True;
aTextPrs = new AIS_TextLabel();
aTextPrs->SetFont ("Courier");
}
{
aContext->SetTransformPersistence (aTextPrs, Handle(Graphic3d_TransformPers)());
}
- ViewerTest::Display (aName, aTextPrs, Standard_False);
+
+ if (isNewPrs)
+ {
+ ViewerTest::Display (aName, aTextPrs, Standard_False);
+ }
+ else
+ {
+ aContext->Redisplay (aTextPrs, Standard_False, Standard_True);
+ }
return 0;
}
return 0;
}
+namespace
+{
+ //! Auxiliary function for parsing translation vector - either 2D or 3D.
+ static Standard_Integer parseTranslationVec (Standard_Integer theArgNb,
+ const char** theArgVec,
+ gp_Vec& theVec)
+ {
+ if (theArgNb < 2)
+ {
+ return 0;
+ }
+
+ TCollection_AsciiString anX (theArgVec[0]);
+ TCollection_AsciiString anY (theArgVec[1]);
+ if (!anX.IsRealValue()
+ || !anY.IsRealValue())
+ {
+ return 0;
+ }
+
+ theVec.SetX (anX.RealValue());
+ theVec.SetY (anY.RealValue());
+ if (theArgNb >= 3)
+ {
+ TCollection_AsciiString anZ (theArgVec[2]);
+ if (anZ.IsRealValue())
+ {
+ theVec.SetZ (anZ.RealValue());
+ return 3;
+ }
+ }
+ return 2;
+ }
+}
+
//=======================================================================
//function : VSetLocation
//purpose : Change location of AIS interactive object
//=======================================================================
-static Standard_Integer VSetLocation (Draw_Interpretor& /*di*/,
+static Standard_Integer VSetLocation (Draw_Interpretor& theDI,
Standard_Integer theArgNb,
const char** theArgVec)
{
return 1;
}
- TCollection_AsciiString aName;
- gp_Vec aLocVec;
- Standard_Boolean isSetLoc = Standard_False;
-
- Standard_Integer anArgIter = 1;
- for (; anArgIter < theArgNb; ++anArgIter)
+ Standard_Boolean toPrintInfo = Standard_True;
+ Handle(AIS_InteractiveObject) anObj;
+ TCollection_AsciiString aCmdName (theArgVec[0]);
+ aCmdName.LowerCase();
+ for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
{
- Standard_CString anArg = theArgVec[anArgIter];
- if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
+ TCollection_AsciiString anArg = theArgVec[anArgIter];
+ anArg.LowerCase();
+ if (anUpdateTool.parseRedrawMode (anArg))
{
continue;
}
- else if (aName.IsEmpty())
+ else if (anObj.IsNull())
{
- aName = anArg;
+ const TCollection_AsciiString aName (theArgVec[anArgIter]);
+ const ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
+ if (aMap.IsBound2 (aName))
+ {
+ anObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName));
+ }
+ if (anObj.IsNull())
+ {
+ std::cout << "Error: object '" << aName << "' is not displayed!\n";
+ return 1;
+ }
}
- else if (!isSetLoc)
+ else if (anArg == "-reset")
+ {
+ toPrintInfo = Standard_False;
+ aContext->SetLocation (anObj, gp_Trsf());
+ }
+ else if (anArg == "-copyfrom"
+ || anArg == "-copy")
{
- isSetLoc = Standard_True;
if (anArgIter + 1 >= theArgNb)
{
- std::cout << "Error: syntax error at '" << anArg << "'\n";
+ std::cout << "Syntax error at '" << anArg << "'\n";
return 1;
}
- aLocVec.SetX (Draw::Atof (theArgVec[anArgIter++]));
- aLocVec.SetY (Draw::Atof (theArgVec[anArgIter]));
- if (anArgIter + 1 < theArgNb)
+
+ const TCollection_AsciiString aName2 (theArgVec[anArgIter + 1]);
+ const ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
+ Handle(AIS_InteractiveObject) anObj2;
+ if (aMap.IsBound2 (aName2))
+ {
+ anObj2 = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName2));
+ }
+ if (anObj2.IsNull())
{
- aLocVec.SetZ (Draw::Atof (theArgVec[++anArgIter]));
+ std::cout << "Error: object '" << aName2 << "' is not displayed!\n";
+ return 1;
}
+
+ ++anArgIter;
+ aContext->SetLocation (anObj, anObj2->LocalTransformation());
}
- else
+ else if (anArg == "-rotate")
{
- std::cout << "Error: unknown argument '" << anArg << "'\n";
- return 1;
- }
- }
-
- // find object
- const ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
- Handle(AIS_InteractiveObject) anIObj;
- if (aMap.IsBound2 (aName))
- {
- anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName));
- }
- if (anIObj.IsNull())
- {
- std::cout << "Error: object '" << aName << "' is not displayed!\n";
- return 1;
- }
-
- gp_Trsf aTrsf;
- aTrsf.SetTranslation (aLocVec);
- TopLoc_Location aLocation (aTrsf);
- aContext->SetLocation (anIObj, aLocation);
- return 0;
-}
-
-//=======================================================================
-//function : TransformPresentation
-//purpose : Change transformation of AIS interactive object
-//=======================================================================
-static Standard_Integer LocalTransformPresentation (Draw_Interpretor& /*theDi*/,
- Standard_Integer theArgNb,
- const char** theArgVec)
-{
- if (theArgNb <= 1)
- {
- std::cout << "Error: too few arguments.\n";
- return 1;
- }
-
- Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
- ViewerTest_AutoUpdater anUpdateTool(aContext, ViewerTest::CurrentView());
- if (aContext.IsNull())
- {
- std::cout << "Error: no active view!\n";
- return 1;
- }
-
- gp_Trsf aTrsf;
- Standard_Integer aLast = theArgNb;
- const char* aName = theArgVec[0];
-
- Standard_Boolean isReset = Standard_False;
- Standard_Boolean isMove = Standard_False;
+ toPrintInfo = Standard_False;
+ if (anArgIter + 7 >= theArgNb)
+ {
+ std::cout << "Syntax error at '" << anArg << "'\n";
+ return 1;
+ }
- // Prefix 'vloc'
- aName += 4;
+ gp_Trsf aTrsf;
+ aTrsf.SetRotation (gp_Ax1 (gp_Pnt (Draw::Atof (theArgVec[anArgIter + 1]),
+ Draw::Atof (theArgVec[anArgIter + 2]),
+ Draw::Atof (theArgVec[anArgIter + 3])),
+ gp_Vec (Draw::Atof (theArgVec[anArgIter + 4]),
+ Draw::Atof (theArgVec[anArgIter + 5]),
+ Draw::Atof (theArgVec[anArgIter + 6]))),
+ Draw::Atof (theArgVec[anArgIter + 7]) * (M_PI / 180.0));
+ anArgIter += 7;
- if (!strcmp (aName, "reset"))
- {
- isReset = Standard_True;
- }
- else if (!strcmp (aName, "move"))
- {
- if (theArgNb < 3)
- {
- std::cout << "Error: too few arguments.\n";
- return 1;
+ aTrsf = anObj->LocalTransformation() * aTrsf;
+ aContext->SetLocation (anObj, aTrsf);
}
-
- const ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
-
- Handle(AIS_InteractiveObject) anIObj;
- if (aMap.IsBound2 (theArgVec[theArgNb - 1]))
+ else if (anArg == "-translate")
{
- anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (theArgVec[theArgNb - 1]));
- }
+ toPrintInfo = Standard_False;
+ gp_Vec aLocVec;
+ Standard_Integer aNbParsed = parseTranslationVec (theArgNb - anArgIter - 1, theArgVec + anArgIter + 1, aLocVec);
+ anArgIter += aNbParsed;
+ if (aNbParsed == 0)
+ {
+ std::cout << "Syntax error at '" << anArg << "'\n";
+ return 1;
+ }
- if (anIObj.IsNull())
- {
- std::cout << "Error: object '" << theArgVec[theArgNb - 1] << "' is not displayed!\n";
- return 1;
+ gp_Trsf aTrsf;
+ aTrsf.SetTranslationPart (aLocVec);
+ aTrsf = anObj->LocalTransformation() * aTrsf;
+ aContext->SetLocation (anObj, aTrsf);
}
+ else if (anArg == "-scale"
+ || anArg == "-setscale")
+ {
+ toPrintInfo = Standard_False;
+ gp_XYZ aScaleLoc;
+ Standard_Real aScale = 1.0;
+ Standard_Boolean toPrintScale = Standard_True;
+ Standard_Boolean hasScaleLoc = Standard_False;
+ if (anArgIter + 4 < theArgNb)
+ {
+ TCollection_AsciiString aScaleArgs[4] =
+ {
+ TCollection_AsciiString (theArgVec[anArgIter + 1]),
+ TCollection_AsciiString (theArgVec[anArgIter + 2]),
+ TCollection_AsciiString (theArgVec[anArgIter + 3]),
+ TCollection_AsciiString (theArgVec[anArgIter + 4])
+ };
+ Standard_Integer aScaleArgIter = 0;
+ for (; aScaleArgIter < 4; ++aScaleArgIter)
+ {
+ if (!aScaleArgs[aScaleArgIter].IsRealValue())
+ {
+ break;
+ }
+ }
+ if (aScaleArgIter == 4)
+ {
+ aScaleLoc.SetCoord (aScaleArgs[0].RealValue(), aScaleArgs[1].RealValue(), aScaleArgs[2].RealValue());
+ aScale = aScaleArgs[3].RealValue();
+ anArgIter += 4;
+ toPrintScale = Standard_False;
+ hasScaleLoc = Standard_True;
+ }
+ else if (aScaleArgIter >= 1)
+ {
+ aScale = aScaleArgs[0].RealValue();
+ ++anArgIter;
+ toPrintScale = Standard_False;
+ }
+ }
+ else if (anArgIter + 1 < theArgNb)
+ {
+ TCollection_AsciiString aScaleArg (theArgVec[anArgIter + 1]);
+ if (aScaleArg.IsRealValue())
+ {
+ aScale = aScaleArg.RealValue();
+ ++anArgIter;
+ toPrintScale = Standard_False;
+ }
+ }
+
+ if (toPrintScale)
+ {
+ if (anArg == "-setscale")
+ {
+ std::cout << "Syntax error at '" << anArg << "'\n";
+ return 1;
+ }
- isMove = Standard_True;
+ char aText[1024];
+ Sprintf (aText, "%g ", anObj->LocalTransformation().ScaleFactor());
+ theDI << aText;
+ continue;
+ }
- aTrsf = anIObj->Transformation();
- aLast = theArgNb - 1;
- }
- else if (!strcmp (aName, "translate"))
- {
- if (theArgNb < 5)
- {
- std::cout << "Error: too few arguments.\n";
- return 1;
+ if (anArg == "-setscale")
+ {
+ gp_Trsf aTrsf = anObj->LocalTransformation();
+ if (hasScaleLoc)
+ {
+ aTrsf.SetScale (aScaleLoc, aScale);
+ }
+ else
+ {
+ aTrsf.SetScaleFactor (aScale);
+ }
+ aContext->SetLocation (anObj, aTrsf);
+ }
+ else
+ {
+ gp_Trsf aTrsf;
+ if (hasScaleLoc)
+ {
+ aTrsf.SetScale (aScaleLoc, aScale);
+ aTrsf = anObj->LocalTransformation() * aTrsf;
+ }
+ else
+ {
+ aTrsf = anObj->LocalTransformation();
+ aTrsf.SetScaleFactor (aTrsf.ScaleFactor() * aScale);
+ }
+ aContext->SetLocation (anObj, aTrsf);
+ }
}
- aTrsf.SetTranslation (gp_Vec (Draw::Atof (theArgVec[theArgNb - 3]),
- Draw::Atof (theArgVec[theArgNb - 2]),
- Draw::Atof (theArgVec[theArgNb - 1])));
- aLast = theArgNb - 3;
- }
- else if (!strcmp (aName, "rotate"))
- {
- if (theArgNb < 9)
+ else if (anArg == "-mirror")
{
- std::cout << "Error: too few arguments.\n";
- return 1;
- }
-
- aTrsf.SetRotation (
- gp_Ax1 (gp_Pnt (Draw::Atof (theArgVec[theArgNb - 7]),
- Draw::Atof (theArgVec[theArgNb - 6]),
- Draw::Atof (theArgVec[theArgNb - 5])),
- gp_Vec (Draw::Atof (theArgVec[theArgNb - 4]),
- Draw::Atof (theArgVec[theArgNb - 3]),
- Draw::Atof (theArgVec[theArgNb - 2]))),
- Draw::Atof (theArgVec[theArgNb - 1]) * (M_PI / 180.0));
+ toPrintInfo = Standard_False;
+ if (anArgIter + 6 >= theArgNb)
+ {
+ std::cout << "Syntax error at '" << anArg << "'\n";
+ return 1;
+ }
- aLast = theArgNb - 7;
- }
- else if (!strcmp (aName, "mirror"))
- {
- if (theArgNb < 8)
- {
- std::cout << "Error: too few arguments.\n";
- return 1;
+ gp_Trsf aTrsf;
+ aTrsf.SetMirror (gp_Ax2 (gp_Pnt (Draw::Atof(theArgVec[theArgNb - 6]),
+ Draw::Atof(theArgVec[theArgNb - 5]),
+ Draw::Atof(theArgVec[theArgNb - 4])),
+ gp_Vec (Draw::Atof(theArgVec[theArgNb - 3]),
+ Draw::Atof(theArgVec[theArgNb - 2]),
+ Draw::Atof(theArgVec[theArgNb - 1]))));
+ anArgIter += 6;
+ aTrsf = anObj->LocalTransformation() * aTrsf;
+ aContext->SetLocation (anObj, aTrsf);
}
-
- aTrsf.SetMirror (gp_Ax2 (gp_Pnt (Draw::Atof(theArgVec[theArgNb - 6]),
- Draw::Atof(theArgVec[theArgNb - 5]),
- Draw::Atof(theArgVec[theArgNb - 4])),
- gp_Vec (Draw::Atof(theArgVec[theArgNb - 3]),
- Draw::Atof(theArgVec[theArgNb - 2]),
- Draw::Atof(theArgVec[theArgNb - 1]))));
- aLast = theArgNb - 6;
- }
- else if (!strcmp (aName, "scale"))
- {
- if (theArgNb < 6)
+ else if (anArg == "-setrotation"
+ || anArg == "-rotation")
{
- std::cout << "Error: too few arguments.\n";
- return 1;
- }
+ toPrintInfo = Standard_False;
+ if (anArgIter + 4 < theArgNb)
+ {
+ TCollection_AsciiString aQuatArgs[4] =
+ {
+ TCollection_AsciiString (theArgVec[anArgIter + 1]),
+ TCollection_AsciiString (theArgVec[anArgIter + 2]),
+ TCollection_AsciiString (theArgVec[anArgIter + 3]),
+ TCollection_AsciiString (theArgVec[anArgIter + 4])
+ };
+ Standard_Integer aQuatArgIter = 0;
+ for (; aQuatArgIter < 4; ++aQuatArgIter)
+ {
+ if (!aQuatArgs[aQuatArgIter].IsRealValue())
+ {
+ break;
+ }
+ }
- aTrsf.SetScale (gp_Pnt (Draw::Atof(theArgVec[theArgNb - 4]),
- Draw::Atof(theArgVec[theArgNb - 3]),
- Draw::Atof(theArgVec[theArgNb - 2])),
- Draw::Atof(theArgVec[theArgNb - 1]));
- aLast = theArgNb - 4;
- }
+ if (aQuatArgIter == 4)
+ {
+ anArgIter += 4;
+ const gp_Quaternion aQuat (aQuatArgs[0].RealValue(),
+ aQuatArgs[1].RealValue(),
+ aQuatArgs[2].RealValue(),
+ aQuatArgs[3].RealValue());
+ gp_Trsf aTrsf = anObj->LocalTransformation();
+ aTrsf.SetRotation (aQuat);
+ aContext->SetLocation (anObj, aTrsf);
+ continue;
+ }
+ else if (anArg == "-setrotation")
+ {
+ std::cout << "Syntax error at '" << anArg << "'\n";
+ return 1;
+ }
+ }
- for (Standard_Integer anIdx = 1; anIdx < aLast; anIdx++)
- {
- // find object
- const ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
- Handle(AIS_InteractiveObject) anIObj;
- if (aMap.IsBound2 (theArgVec[anIdx]))
- {
- anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (theArgVec[anIdx]));
+ char aText[1024];
+ const gp_Quaternion aQuat = anObj->LocalTransformation().GetRotation();
+ Sprintf (aText, "%g %g %g %g ", aQuat.X(), aQuat.Y(), aQuat.Z(), aQuat.W());
+ theDI << aText;
}
- if (anIObj.IsNull())
+ else if (anArg == "-setlocation"
+ || anArg == "-location")
{
- std::cout << "Error: object '" << theArgVec[anIdx] << "' is not displayed!\n";
- return 1;
- }
-
- if (isReset)
- {
- // aTrsf already identity
+ toPrintInfo = Standard_False;
+ gp_Vec aLocVec;
+ Standard_Integer aNbParsed = parseTranslationVec (theArgNb - anArgIter - 1, theArgVec + anArgIter + 1, aLocVec);
+ anArgIter += aNbParsed;
+ if (aNbParsed != 0)
+ {
+ gp_Trsf aTrsf = anObj->LocalTransformation();
+ aTrsf.SetTranslationPart (aLocVec);
+ aContext->SetLocation (anObj, aTrsf);
+ }
+ else if (anArg == "-setlocation")
+ {
+ std::cout << "Syntax error at '" << anArg << "'\n";
+ return 1;
+ }
+
+ char aText[1024];
+ const gp_XYZ aLoc = anObj->LocalTransformation().TranslationPart();
+ Sprintf (aText, "%g %g %g ", aLoc.X(), aLoc.Y(), aLoc.Z());
+ theDI << aText;
}
- else if (isMove)
+ else if (aCmdName == "vsetlocation")
{
- aTrsf = anIObj->LocalTransformation() * anIObj->Transformation().Inverted() * aTrsf;
+ // compatibility with old syntax
+ gp_Vec aLocVec;
+ Standard_Integer aNbParsed = parseTranslationVec (theArgNb - anArgIter, theArgVec + anArgIter, aLocVec);
+ if (aNbParsed == 0)
+ {
+ std::cout << "Syntax error at '" << anArg << "'\n";
+ return 1;
+ }
+ anArgIter = anArgIter + aNbParsed - 1;
+
+ gp_Trsf aTrsf;
+ aTrsf.SetTranslationPart (aLocVec);
+ aContext->SetLocation (anObj, aTrsf);
+ toPrintInfo = Standard_False;
}
else
{
- aTrsf = anIObj->LocalTransformation() * aTrsf;
+ std::cout << "Error: unknown argument '" << anArg << "'\n";
+ return 1;
}
+ }
- TopLoc_Location aLocation (aTrsf);
- aContext->SetLocation (anIObj, aLocation);
+ if (anObj.IsNull())
+ {
+ std::cout << "Syntax error - wrong number of arguments\n";
+ return 1;
+ }
+ else if (!toPrintInfo)
+ {
+ return 0;
}
+ const gp_Trsf aTrsf = anObj->LocalTransformation();
+ const gp_XYZ aLoc = aTrsf.TranslationPart();
+ const gp_Quaternion aRot = aTrsf.GetRotation();
+ char aText[4096];
+ Sprintf (aText, "Location: %g %g %g\n"
+ "Rotation: %g %g %g %g\n"
+ "Scale: %g\n",
+ aLoc.X(), aLoc.Y(), aLoc.Z(),
+ aRot.X(), aRot.Y(), aRot.Z(), aRot.W(),
+ aTrsf.ScaleFactor());
+ theDI << aText;
return 0;
}
"vdrawsphere: vdrawsphere shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0] [ToPrintInfo=1]\n",
__FILE__,VDrawSphere,group);
+ theCommands.Add ("vlocation",
+ "vlocation name"
+ "\n\t\t: [-reset]"
+ "\n\t\t: [-copyFrom otherName]"
+ "\n\t\t: [-translate X Y [Z]]"
+ "\n\t\t: [-rotate x y z dx dy dz angle]"
+ "\n\t\t: [-scale [X Y Z] scale]"
+ "\n\t\t: [-mirror x y z dx dy dz]"
+ "\n\t\t: [-setLocation X Y [Z]]"
+ "\n\t\t: [-setRotation QX QY QZ QW]"
+ "\n\t\t: [-setScale [X Y Z] scale]"
+ "\n\t\t: Object local transformation management:"
+ "\n\t\t: -reset reset transformation to identity"
+ "\n\t\t: -translate translate object"
+ "\n\t\t: -rotate applies rotation to local transformation"
+ "\n\t\t: -scale applies scale to local transformation"
+ "\n\t\t: -mirror applies mirror to local transformation"
+ "\n\t\t: -setLocation assign object location"
+ "\n\t\t: -setRotation assign object rotation (quaternion)"
+ "\n\t\t: -setScale assign object scale factor",
+ __FILE__, VSetLocation, group);
theCommands.Add ("vsetlocation",
- "vsetlocation [-noupdate|-update] name x y z"
- "\n\t\t: Set new location for an interactive object.",
+ "alias for vlocation",
__FILE__, VSetLocation, group);
theCommands.Add (
"\n",
__FILE__, VPointCloud, group);
- theCommands.Add("vlocreset",
- "vlocreset name1 name2 ...\n\t\t remove object local transformation",
- __FILE__,
- LocalTransformPresentation, group);
-
- theCommands.Add("vlocmove",
- "vlocmove name1 name2 ... name\n\t\t set local transform to match transform of 'name'",
- __FILE__,
- LocalTransformPresentation, group);
-
- theCommands.Add("vloctranslate",
- "vloctranslate name1 name2 ... dx dy dz\n\t\t applies translation to local transformation",
- __FILE__,
- LocalTransformPresentation, group);
-
- theCommands.Add("vlocrotate",
- "vlocrotate name1 name2 ... x y z dx dy dz angle\n\t\t applies rotation to local transformation",
- __FILE__,
- LocalTransformPresentation, group);
-
- theCommands.Add("vlocmirror",
- "vlocmirror name x y z dx dy dz\n\t\t applies mirror to local transformation",
- __FILE__,
- LocalTransformPresentation, group);
-
- theCommands.Add("vlocscale",
- "vlocscale name x y z scale\n\t\t applies scale to local transformation",
- __FILE__,
- LocalTransformPresentation, group);
-
theCommands.Add("vpriority",
"vpriority [-noupdate|-update] name [value]\n\t\t prints or sets the display priority for an object",
__FILE__,
// commercial license or contractual agreement.
#include <OpenGl_GlCore20.hxx>
+
+#include <AIS_Animation.hxx>
+#include <AIS_AnimationCamera.hxx>
+#include <AIS_AnimationObject.hxx>
#include <AIS_ColorScale.hxx>
#include <AIS_Manipulator.hxx>
#include <AIS_RubberBand.hxx>
int Y_ButtonPress = 0;
Standard_Boolean IsDragged = Standard_False;
Standard_Boolean DragFirst = Standard_False;
+Standard_Boolean TheIsAnimating = Standard_False;
Standard_EXPORT const Handle(AIS_RubberBand)& GetRubberBand()
Standard_Boolean theToPick,
Standard_Boolean theIsShift)
{
+ if (TheIsAnimating)
+ {
+ TheIsAnimating = Standard_False;
+ return Standard_False;
+ }
+
if (theToPick)
{
Standard_Real X, Y, Z;
//==============================================================================
//function : VFit
-
-//purpose : Fitall, no DRAW arguments
-//Draw arg : No args
+//purpose :
//==============================================================================
-static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgc, const char** theArgv)
+static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgv)
{
- if (theArgc > 2)
+ const Handle(V3d_View) aView = ViewerTest::CurrentView();
+ if (aView.IsNull())
{
- std::cout << "Wrong number of arguments! Use: vfit [-selected]" << std::endl;
+ std::cout << "Error: no active viewer!\n";
+ return 1;
}
- const Handle(V3d_View) aView = ViewerTest::CurrentView();
-
- if (theArgc == 2)
+ Standard_Boolean toFit = Standard_True;
+ ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
+ for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
{
- TCollection_AsciiString anArg (theArgv[1]);
+ TCollection_AsciiString anArg (theArgv[anArgIter]);
anArg.LowerCase();
- if (anArg == "-selected")
+ if (anUpdateTool.parseRedrawMode (anArg))
{
- ViewerTest::GetAISContext()->FitSelected (aView);
- return 0;
+ continue;
+ }
+ else if (anArg == "-selected")
+ {
+ ViewerTest::GetAISContext()->FitSelected (aView, 0.01, Standard_False);
+ toFit = Standard_False;
+ }
+ else
+ {
+ std::cout << "Syntax error at '" << anArg << "'\n";
}
}
- if (aView.IsNull() == Standard_False) {
- aView->FitAll();
+ if (toFit)
+ {
+ aView->FitAll (0.01, Standard_False);
}
return 0;
}
return 0;
}
+namespace
+{
+ //! Global map storing all animations registered in ViewerTest.
+ static NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)> ViewerTest_AnimationTimelineMap;
+
+ //! The animation calling the Draw Harness command.
+ class ViewerTest_AnimationProc : public AIS_Animation
+ {
+ public:
+
+ //! Main constructor.
+ ViewerTest_AnimationProc (const TCollection_AsciiString& theAnimationName,
+ Draw_Interpretor* theDI,
+ const TCollection_AsciiString& theCommand)
+ : AIS_Animation (theAnimationName),
+ myDrawInter(theDI),
+ myCommand (theCommand)
+ {
+ //
+ }
+
+ protected:
+
+ //! Evaluate the command.
+ virtual void update (const AIS_AnimationProgress& theProgress) Standard_OVERRIDE
+ {
+ TCollection_AsciiString aCmd = myCommand;
+ replace (aCmd, "%pts", TCollection_AsciiString(theProgress.Pts));
+ replace (aCmd, "%localpts", TCollection_AsciiString(theProgress.LocalPts));
+ replace (aCmd, "%ptslocal", TCollection_AsciiString(theProgress.LocalPts));
+ replace (aCmd, "%normalized", TCollection_AsciiString(theProgress.LocalNormalized));
+ replace (aCmd, "%localnormalized", TCollection_AsciiString(theProgress.LocalNormalized));
+ myDrawInter->Eval (aCmd.ToCString());
+ }
+
+ //! Find the keyword in the command and replace it with value.
+ //! @return the position of the keyword to pass value
+ void replace (TCollection_AsciiString& theCmd,
+ const TCollection_AsciiString& theKey,
+ const TCollection_AsciiString& theVal)
+ {
+ TCollection_AsciiString aCmd (theCmd);
+ aCmd.LowerCase();
+ const Standard_Integer aPos = aCmd.Search (theKey);
+ if (aPos == -1)
+ {
+ return;
+ }
+
+ TCollection_AsciiString aPart1, aPart2;
+ Standard_Integer aPart1To = aPos - 1;
+ if (aPart1To >= 1
+ && aPart1To <= theCmd.Length())
+ {
+ aPart1 = theCmd.SubString (1, aPart1To);
+ }
+
+ Standard_Integer aPart2From = aPos + theKey.Length();
+ if (aPart2From >= 1
+ && aPart2From <= theCmd.Length())
+ {
+ aPart2 = theCmd.SubString (aPart2From, theCmd.Length());
+ }
+
+ theCmd = aPart1 + theVal + aPart2;
+ }
+
+ protected:
+
+ Draw_Interpretor* myDrawInter;
+ TCollection_AsciiString myCommand;
+
+ };
+
+ //! Replace the animation with the new one.
+ static void replaceAnimation (const Handle(AIS_Animation)& theParentAnimation,
+ Handle(AIS_Animation)& theAnimation,
+ const Handle(AIS_Animation)& theAnimationNew)
+ {
+ theAnimationNew->CopyFrom (theAnimation);
+ if (!theParentAnimation.IsNull())
+ {
+ theParentAnimation->Replace (theAnimation, theAnimationNew);
+ }
+ else
+ {
+ ViewerTest_AnimationTimelineMap.UnBind (theAnimationNew->Name());
+ ViewerTest_AnimationTimelineMap.Bind (theAnimationNew->Name(), theAnimationNew);
+ }
+ theAnimation = theAnimationNew;
+ }
+
+ //! Parse the point.
+ static Standard_Boolean parseXYZ (const char** theArgVec, gp_XYZ& thePnt)
+ {
+ const TCollection_AsciiString anXYZ[3] = { theArgVec[0], theArgVec[1], theArgVec[2] };
+ if (!anXYZ[0].IsRealValue()
+ || !anXYZ[1].IsRealValue()
+ || !anXYZ[2].IsRealValue())
+ {
+ return Standard_False;
+ }
+
+ thePnt.SetCoord (anXYZ[0].RealValue(), anXYZ[1].RealValue(), anXYZ[2].RealValue());
+ return Standard_True;
+ }
+
+ //! Parse the quaternion.
+ static Standard_Boolean parseQuaternion (const char** theArgVec, gp_Quaternion& theQRot)
+ {
+ const TCollection_AsciiString anXYZW[4] = {theArgVec[0], theArgVec[1], theArgVec[2], theArgVec[3]};
+ if (!anXYZW[0].IsRealValue()
+ || !anXYZW[1].IsRealValue()
+ || !anXYZW[2].IsRealValue()
+ || !anXYZW[3].IsRealValue())
+ {
+ return Standard_False;
+ }
+
+ theQRot.Set (anXYZW[0].RealValue(), anXYZW[1].RealValue(), anXYZW[2].RealValue(), anXYZW[3].RealValue());
+ return Standard_True;
+ }
+
+}
+
//=================================================================================================
//function : VViewParams
//purpose : Gets or sets AIS View characteristics
//=================================================================================================
static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
{
- Handle(V3d_View) anAISView = ViewerTest::CurrentView();
- if (anAISView.IsNull())
+ Handle(V3d_View) aView = ViewerTest::CurrentView();
+ if (aView.IsNull())
{
std::cout << theArgVec[0] << ": please initialize or activate view.\n";
return 1;
}
+ Standard_Boolean toSetProj = Standard_False;
+ Standard_Boolean toSetUp = Standard_False;
+ Standard_Boolean toSetAt = Standard_False;
+ Standard_Boolean toSetEye = Standard_False;
+ Standard_Boolean toSetScale = Standard_False;
+ Standard_Boolean toSetSize = Standard_False;
+ Standard_Boolean toSetCenter2d = Standard_False;
+ Quantity_Factor aViewScale = aView->Scale();
+ Quantity_Length aViewSize = 1.0;
+ Graphic3d_Vec2i aCenter2d;
+ gp_XYZ aViewProj, aViewUp, aViewAt, aViewEye;
+ aView->Proj (aViewProj.ChangeCoord (1), aViewProj.ChangeCoord (2), aViewProj.ChangeCoord (3));
+ aView->Up (aViewUp .ChangeCoord (1), aViewUp .ChangeCoord (2), aViewUp .ChangeCoord (3));
+ aView->At (aViewAt .ChangeCoord (1), aViewAt .ChangeCoord (2), aViewAt .ChangeCoord (3));
+ aView->Eye (aViewEye .ChangeCoord (1), aViewEye .ChangeCoord (2), aViewEye .ChangeCoord (3));
if (theArgsNb == 1)
{
// print all of the available view parameters
- Quantity_Factor anAISViewScale = anAISView->Scale();
-
- Standard_Real anAISViewProjX = 0.0;
- Standard_Real anAISViewProjY = 0.0;
- Standard_Real anAISViewProjZ = 0.0;
- anAISView->Proj (anAISViewProjX, anAISViewProjY, anAISViewProjZ);
-
- Standard_Real anAISViewUpX = 0.0;
- Standard_Real anAISViewUpY = 0.0;
- Standard_Real anAISViewUpZ = 0.0;
- anAISView->Up (anAISViewUpX, anAISViewUpY, anAISViewUpZ);
-
- Standard_Real anAISViewAtX = 0.0;
- Standard_Real anAISViewAtY = 0.0;
- Standard_Real anAISViewAtZ = 0.0;
- anAISView->At (anAISViewAtX, anAISViewAtY, anAISViewAtZ);
-
- Standard_Real anAISViewEyeX = 0.0;
- Standard_Real anAISViewEyeY = 0.0;
- Standard_Real anAISViewEyeZ = 0.0;
- anAISView->Eye (anAISViewEyeX, anAISViewEyeY, anAISViewEyeZ);
-
- theDi << "Scale of current view: " << anAISViewScale << "\n";
- theDi << "Proj on X : " << anAISViewProjX << "; on Y: " << anAISViewProjY << "; on Z: " << anAISViewProjZ << "\n";
- theDi << "Up on X : " << anAISViewUpX << "; on Y: " << anAISViewUpY << "; on Z: " << anAISViewUpZ << "\n";
- theDi << "At on X : " << anAISViewAtX << "; on Y: " << anAISViewAtY << "; on Z: " << anAISViewAtZ << "\n";
- theDi << "Eye on X : " << anAISViewEyeX << "; on Y: " << anAISViewEyeY << "; on Z: " << anAISViewEyeZ << "\n";
+ char aText[4096];
+ Sprintf (aText,
+ "Scale: %g\n"
+ "Proj: %12g %12g %12g\n"
+ "Up: %12g %12g %12g\n"
+ "At: %12g %12g %12g\n"
+ "Eye: %12g %12g %12g\n",
+ aViewScale,
+ aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
+ aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
+ aViewAt.X(), aViewAt.Y(), aViewAt.Z(),
+ aViewEye.X(), aViewEye.Y(), aViewEye.Z());
+ theDi << aText;
return 0;
}
- // -------------------------
- // Parse options and values
- // -------------------------
-
- NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfKeysByValues;
- TCollection_AsciiString aParseKey;
- for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
+ ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
+ for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
{
- TCollection_AsciiString anArg (theArgVec [anArgIt]);
-
- if (anArg.Value (1) == '-' && !anArg.IsRealValue())
+ TCollection_AsciiString anArg (theArgVec[anArgIter]);
+ anArg.LowerCase();
+ if (anUpdateTool.parseRedrawMode (anArg))
{
- aParseKey = anArg;
- aParseKey.Remove (1);
- aParseKey.UpperCase();
- aMapOfKeysByValues.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
continue;
}
+ else if (anArg == "-cmd"
+ || anArg == "-command"
+ || anArg == "-args")
+ {
+ char aText[4096];
+ Sprintf (aText,
+ "-scale %g "
+ "-proj %g %g %g "
+ "-up %g %g %g "
+ "-at %g %g %g\n",
+ aViewScale,
+ aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
+ aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
+ aViewAt.X(), aViewAt.Y(), aViewAt.Z());
+ theDi << aText;
+ }
+ else if (anArg == "-scale"
+ || anArg == "-size")
+ {
+ if (anArgIter + 1 < theArgsNb
+ && *theArgVec[anArgIter + 1] != '-')
+ {
+ const TCollection_AsciiString aValueArg (theArgVec[anArgIter + 1]);
+ if (aValueArg.IsRealValue())
+ {
+ ++anArgIter;
+ if (anArg == "-scale")
+ {
+ toSetScale = Standard_True;
+ aViewScale = aValueArg.RealValue();
+ }
+ else if (anArg == "-size")
+ {
+ toSetSize = Standard_True;
+ aViewSize = aValueArg.RealValue();
+ }
+ continue;
+ }
+ }
+ if (anArg == "-scale")
+ {
+ theDi << "Scale: " << aView->Scale() << "\n";
+ }
+ else if (anArg == "-size")
+ {
+ Graphic3d_Vec2d aSizeXY;
+ aView->Size (aSizeXY.x(), aSizeXY.y());
+ theDi << "Size: " << aSizeXY.x() << " " << aSizeXY.y() << "\n";
+ }
+ }
+ else if (anArg == "-eye"
+ || anArg == "-at"
+ || anArg == "-up"
+ || anArg == "-proj")
+ {
+ if (anArgIter + 3 < theArgsNb)
+ {
+ gp_XYZ anXYZ;
+ if (parseXYZ (theArgVec + anArgIter + 1, anXYZ))
+ {
+ anArgIter += 3;
+ if (anArg == "-eye")
+ {
+ toSetEye = Standard_True;
+ aViewEye = anXYZ;
+ }
+ else if (anArg == "-at")
+ {
+ toSetAt = Standard_True;
+ aViewAt = anXYZ;
+ }
+ else if (anArg == "-up")
+ {
+ toSetUp = Standard_True;
+ aViewUp = anXYZ;
+ }
+ else if (anArg == "-proj")
+ {
+ toSetProj = Standard_True;
+ aViewProj = anXYZ;
+ }
+ continue;
+ }
+ }
- if (aParseKey.IsEmpty())
+ if (anArg == "-eye")
+ {
+ theDi << "Eye: " << aViewEye.X() << " " << aViewEye.Y() << " " << aViewEye.Z() << "\n";
+ }
+ else if (anArg == "-at")
+ {
+ theDi << "At: " << aViewAt.X() << " " << aViewAt.Y() << " " << aViewAt.Z() << "\n";
+ }
+ else if (anArg == "-up")
+ {
+ theDi << "Up: " << aViewUp.X() << " " << aViewUp.Y() << " " << aViewUp.Z() << "\n";
+ }
+ else if (anArg == "-proj")
+ {
+ theDi << "Proj: " << aViewProj.X() << " " << aViewProj.Y() << " " << aViewProj.Z() << "\n";
+ }
+ }
+ else if (anArg == "-center")
{
- std::cout << theArgVec[0] << ": values should be passed with key.\n";
- std::cout << "Type help for more information.\n";
+ if (anArgIter + 2 < theArgsNb)
+ {
+ const TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
+ const TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
+ if (anX.IsIntegerValue()
+ && anY.IsIntegerValue())
+ {
+ toSetCenter2d = Standard_True;
+ aCenter2d = Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue());
+ }
+ }
+ }
+ else
+ {
+ std::cout << "Syntax error at '" << anArg << "'\n";
return 1;
}
+ }
- aMapOfKeysByValues(aParseKey)->Append (anArg);
+ // change view parameters in proper order
+ if (toSetScale)
+ {
+ aView->SetScale (aViewScale);
+ }
+ if (toSetSize)
+ {
+ aView->SetSize (aViewSize);
+ }
+ if (toSetEye)
+ {
+ aView->SetEye (aViewEye.X(), aViewEye.Y(), aViewEye.Z());
+ }
+ if (toSetAt)
+ {
+ aView->SetAt (aViewAt.X(), aViewAt.Y(), aViewAt.Z());
+ }
+ if (toSetProj)
+ {
+ aView->SetProj (aViewProj.X(), aViewProj.Y(), aViewProj.Z());
+ }
+ if (toSetUp)
+ {
+ aView->SetUp (aViewUp.X(), aViewUp.Y(), aViewUp.Z());
+ }
+ if (toSetCenter2d)
+ {
+ aView->SetCenter (aCenter2d.x(), aCenter2d.y());
}
- // ---------------------------------------------
- // Change or print parameters, order plays role
- // ---------------------------------------------
+ return 0;
+}
- // Check arguments for validity
- NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfKeysByValues);
- for (; aMapIt.More(); aMapIt.Next())
+//==============================================================================
+//function : VAnimation
+//purpose :
+//==============================================================================
+static Standard_Integer VAnimation (Draw_Interpretor& theDI,
+ Standard_Integer theArgNb,
+ const char** theArgVec)
+{
+ Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
+ if (theArgNb < 2)
{
- const TCollection_AsciiString& aKey = aMapIt.Key();
- const Handle(TColStd_HSequenceOfAsciiString)& aValues = aMapIt.Value();
-
- if (!(aKey.IsEqual ("SCALE") && (aValues->Length() == 1 || aValues->IsEmpty()))
- && !(aKey.IsEqual ("SIZE") && (aValues->Length() == 1 || aValues->IsEmpty()))
- && !(aKey.IsEqual ("EYE") && (aValues->Length() == 3 || aValues->IsEmpty()))
- && !(aKey.IsEqual ("AT") && (aValues->Length() == 3 || aValues->IsEmpty()))
- && !(aKey.IsEqual ("UP") && (aValues->Length() == 3 || aValues->IsEmpty()))
- && !(aKey.IsEqual ("PROJ") && (aValues->Length() == 3 || aValues->IsEmpty()))
- && !(aKey.IsEqual ("CENTER") && aValues->Length() == 2))
- {
- TCollection_AsciiString aLowerKey;
- aLowerKey = "-";
- aLowerKey += aKey;
- aLowerKey.LowerCase();
- std::cout << theArgVec[0] << ": " << aLowerKey << " is unknown option, or number of arguments is invalid.\n";
- std::cout << "Type help for more information.\n";
- return 1;
+ for (NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)>::Iterator
+ anAnimIter (ViewerTest_AnimationTimelineMap); anAnimIter.More(); anAnimIter.Next())
+ {
+ theDI << anAnimIter.Key() << " " << anAnimIter.Value()->Duration() << " sec\n";
}
+ return 0;
+ }
+ if (aCtx.IsNull())
+ {
+ std::cout << "Error: no active view\n";
+ return 1;
}
- Handle(TColStd_HSequenceOfAsciiString) aValues;
+ Standard_Integer anArgIter = 1;
+ TCollection_AsciiString aNameArg (theArgVec[anArgIter++]);
+ if (aNameArg.IsEmpty())
+ {
+ std::cout << "Syntax error: animation name is not defined.\n";
+ return 1;
+ }
+
+ TCollection_AsciiString aNameArgLower = aNameArg;
+ aNameArgLower.LowerCase();
+ if (aNameArgLower == "-reset"
+ || aNameArgLower == "-clear")
+ {
+ ViewerTest_AnimationTimelineMap.Clear();
+ return 0;
+ }
+ else if (aNameArg.Value (1) == '-')
+ {
+ std::cout << "Syntax error: invalid animation name '" << aNameArg << "'.\n";
+ return 1;
+ }
- // Change view parameters in proper order
- if (aMapOfKeysByValues.Find ("SCALE", aValues))
+ const char* aNameSplitter = "/";
+ Standard_Integer aSplitPos = aNameArg.Search (aNameSplitter);
+ if (aSplitPos == -1)
{
- if (aValues->IsEmpty())
+ aNameSplitter = ".";
+ aSplitPos = aNameArg.Search (aNameSplitter);
+ }
+
+ // find existing or create a new animation by specified name within syntax "parent.child".
+ Handle(AIS_Animation) aRootAnimation, aParentAnimation, anAnimation;
+ for (; !aNameArg.IsEmpty();)
+ {
+ TCollection_AsciiString aNameParent;
+ if (aSplitPos != -1)
{
- theDi << "Scale: " << anAISView->Scale() << "\n";
+ if (aSplitPos == aNameArg.Length())
+ {
+ std::cout << "Syntax error: animation name is not defined.\n";
+ return 1;
+ }
+
+ aNameParent = aNameArg.SubString ( 1, aSplitPos - 1);
+ aNameArg = aNameArg.SubString (aSplitPos + 1, aNameArg.Length());
+
+ aSplitPos = aNameArg.Search (aNameSplitter);
}
else
{
- anAISView->SetScale (aValues->Value(1).RealValue());
+ aNameParent = aNameArg;
+ aNameArg.Clear();
}
- }
- if (aMapOfKeysByValues.Find ("SIZE", aValues))
- {
- if (aValues->IsEmpty())
+
+ if (anAnimation.IsNull())
{
- Standard_Real aSizeX = 0.0;
- Standard_Real aSizeY = 0.0;
- anAISView->Size (aSizeX, aSizeY);
- theDi << "Size X: " << aSizeX << " Y: " << aSizeY << "\n";
+ if (!ViewerTest_AnimationTimelineMap.Find (aNameParent, anAnimation))
+ {
+ anAnimation = new AIS_Animation (aNameParent);
+ ViewerTest_AnimationTimelineMap.Bind (aNameParent, anAnimation);
+ }
+ aRootAnimation = anAnimation;
}
else
{
- anAISView->SetSize (aValues->Value(1).RealValue());
+ aParentAnimation = anAnimation;
+ anAnimation = aParentAnimation->Find (aNameParent);
+ if (anAnimation.IsNull())
+ {
+ anAnimation = new AIS_Animation (aNameParent);
+ aParentAnimation->Add (anAnimation);
+ }
}
}
- if (aMapOfKeysByValues.Find ("EYE", aValues))
+
+ if (anArgIter >= theArgNb)
{
- if (aValues->IsEmpty())
- {
- Standard_Real anEyeX = 0.0;
- Standard_Real anEyeY = 0.0;
- Standard_Real anEyeZ = 0.0;
- anAISView->Eye (anEyeX, anEyeY, anEyeZ);
- theDi << "Eye X: " << anEyeX << " Y: " << anEyeY << " Z: " << anEyeZ << "\n";
- }
- else
+ // just print the list of children
+ for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anAnimIter (anAnimation->Children()); anAnimIter.More(); anAnimIter.Next())
{
- anAISView->SetEye (aValues->Value(1).RealValue(), aValues->Value(2).RealValue(), aValues->Value(3).RealValue());
+ theDI << anAnimIter.Value()->Name() << " " << anAnimIter.Value()->Duration() << " sec\n";
}
+ return 0;
}
- if (aMapOfKeysByValues.Find ("AT", aValues))
+
+ Standard_Boolean toPlay = Standard_False;
+ Standard_Real aPlaySpeed = 1.0;
+ Standard_Real aPlayStartTime = anAnimation->StartPts();
+ Standard_Real aPlayDuration = anAnimation->Duration();
+ Standard_Real aPlayFrameRate = 0.0;
+ Standard_Boolean isFreeCamera = Standard_False;
+ Standard_Boolean isLockLoop = Standard_False;
+ Handle(V3d_View) aView = ViewerTest::CurrentView();
+ for (; anArgIter < theArgNb; ++anArgIter)
{
- if (aValues->IsEmpty())
+ TCollection_AsciiString anArg (theArgVec[anArgIter]);
+ anArg.LowerCase();
+ if (anArg == "-reset"
+ || anArg == "-clear")
{
- Standard_Real anAtX = 0.0;
- Standard_Real anAtY = 0.0;
- Standard_Real anAtZ = 0.0;
- anAISView->At (anAtX, anAtY, anAtZ);
- theDi << "At X: " << anAtX << " Y: " << anAtY << " Z: " << anAtZ << "\n";
+ anAnimation->Clear();
+ }
+ else if (anArg == "-remove"
+ || anArg == "-del"
+ || anArg == "-delete")
+ {
+ if (!aParentAnimation.IsNull())
+ {
+ ViewerTest_AnimationTimelineMap.UnBind (anAnimation->Name());
+ }
+ else
+ {
+ aParentAnimation->Remove (anAnimation);
+ }
+ }
+ else if (anArg == "-play")
+ {
+ toPlay = Standard_True;
+ if (++anArgIter < theArgNb)
+ {
+ if (*theArgVec[anArgIter] == '-')
+ {
+ --anArgIter;
+ continue;
+ }
+ aPlayStartTime = Draw::Atof (theArgVec[anArgIter]);
+
+ if (++anArgIter < theArgNb)
+ {
+ if (*theArgVec[anArgIter] == '-')
+ {
+ --anArgIter;
+ continue;
+ }
+ aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
+ }
+ }
+ }
+ else if (anArg == "-resume")
+ {
+ toPlay = Standard_True;
+ aPlayStartTime = anAnimation->ElapsedTime();
+ if (++anArgIter < theArgNb)
+ {
+ if (*theArgVec[anArgIter] == '-')
+ {
+ --anArgIter;
+ continue;
+ }
+
+ aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
+ }
+ }
+ else if (anArg == "-playspeed"
+ || anArg == "-speed")
+ {
+ if (++anArgIter >= theArgNb)
+ {
+ std::cout << "Syntax error at " << anArg << ".\n";
+ return 1;
+ }
+ aPlaySpeed = Draw::Atof (theArgVec[anArgIter]);
+ }
+ else if (anArg == "-lock"
+ || anArg == "-lockloop"
+ || anArg == "-playlockloop")
+ {
+ isLockLoop = Standard_True;
+ }
+ else if (anArg == "-freecamera"
+ || anArg == "-playfreecamera"
+ || anArg == "-freelook")
+ {
+ isFreeCamera = Standard_True;
+ }
+ else if (anArg == "-fps")
+ {
+ if (++anArgIter >= theArgNb)
+ {
+ std::cout << "Syntax error at " << anArg << ".\n";
+ return 1;
+ }
+ aPlayFrameRate = Draw::Atof (theArgVec[anArgIter]);
+ }
+ else if (anArg == "-start"
+ || anArg == "-starttime"
+ || anArg == "-startpts")
+ {
+ if (++anArgIter >= theArgNb)
+ {
+ std::cout << "Syntax error at " << anArg << ".\n";
+ return 1;
+ }
+
+ anAnimation->SetStartPts (Draw::Atof (theArgVec[anArgIter]));
+ aRootAnimation->UpdateTotalDuration();
+ }
+ else if (anArg == "-end"
+ || anArg == "-endtime"
+ || anArg == "-endpts")
+ {
+ if (++anArgIter >= theArgNb)
+ {
+ std::cout << "Syntax error at " << anArg << ".\n";
+ return 1;
+ }
+
+ anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]) - anAnimation->StartPts());
+ aRootAnimation->UpdateTotalDuration();
+ }
+ else if (anArg == "-dur"
+ || anArg == "-duration")
+ {
+ if (++anArgIter >= theArgNb)
+ {
+ std::cout << "Syntax error at " << anArg << ".\n";
+ return 1;
+ }
+
+ anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]));
+ aRootAnimation->UpdateTotalDuration();
+ }
+ else if (anArg == "-command"
+ || anArg == "-cmd"
+ || anArg == "-invoke"
+ || anArg == "-eval"
+ || anArg == "-proc")
+ {
+ if (++anArgIter >= theArgNb)
+ {
+ std::cout << "Syntax error at " << anArg << ".\n";
+ return 1;
+ }
+
+ Handle(ViewerTest_AnimationProc) aCmdAnimation = new ViewerTest_AnimationProc (anAnimation->Name(), &theDI, theArgVec[anArgIter]);
+ replaceAnimation (aParentAnimation, anAnimation, aCmdAnimation);
+ }
+ else if (anArg == "-objecttrsf"
+ || anArg == "-objectransformation"
+ || anArg == "-objtransformation"
+ || anArg == "-objtrsf"
+ || anArg == "-object"
+ || anArg == "-obj")
+ {
+ if (++anArgIter >= theArgNb)
+ {
+ std::cout << "Syntax error at " << anArg << ".\n";
+ return 1;
+ }
+
+ TCollection_AsciiString anObjName (theArgVec[anArgIter]);
+ const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfAIS = GetMapOfAIS();
+ if (!aMapOfAIS.IsBound2 (anObjName))
+ {
+ std::cout << "Syntax error: wrong object name at " << anArg << "\n";
+ return 1;
+ }
+
+ Handle(AIS_InteractiveObject) anObject = Handle(AIS_InteractiveObject)::DownCast (aMapOfAIS.Find2 (anObjName));
+ gp_Trsf aTrsfs [2] = { anObject->LocalTransformation(), anObject->LocalTransformation() };
+ gp_Quaternion aRotQuats[2] = { aTrsfs[0].GetRotation(), aTrsfs[1].GetRotation() };
+ gp_XYZ aLocPnts [2] = { aTrsfs[0].TranslationPart(), aTrsfs[1].TranslationPart() };
+ Standard_Real aScales [2] = { aTrsfs[0].ScaleFactor(), aTrsfs[1].ScaleFactor() };
+ Standard_Boolean isTrsfSet = Standard_False;
+ Standard_Integer aTrsfArgIter = anArgIter + 1;
+ for (; aTrsfArgIter < theArgNb; ++aTrsfArgIter)
+ {
+ TCollection_AsciiString aTrsfArg (theArgVec[aTrsfArgIter]);
+ aTrsfArg.LowerCase();
+ const Standard_Integer anIndex = aTrsfArg.EndsWith ("1") ? 0 : 1;
+ if (aTrsfArg.StartsWith ("-rotation")
+ || aTrsfArg.StartsWith ("-rot"))
+ {
+ isTrsfSet = Standard_True;
+ if (aTrsfArgIter + 4 >= theArgNb
+ || !parseQuaternion (theArgVec + aTrsfArgIter + 1, aRotQuats[anIndex]))
+ {
+ std::cout << "Syntax error at " << aTrsfArg << ".\n";
+ return 1;
+ }
+ aTrsfArgIter += 4;
+ }
+ else if (aTrsfArg.StartsWith ("-location")
+ || aTrsfArg.StartsWith ("-loc"))
+ {
+ isTrsfSet = Standard_True;
+ if (aTrsfArgIter + 3 >= theArgNb
+ || !parseXYZ (theArgVec + aTrsfArgIter + 1, aLocPnts[anIndex]))
+ {
+ std::cout << "Syntax error at " << aTrsfArg << ".\n";
+ return 1;
+ }
+ aTrsfArgIter += 3;
+ }
+ else if (aTrsfArg.StartsWith ("-scale"))
+ {
+ isTrsfSet = Standard_True;
+ if (++aTrsfArgIter >= theArgNb)
+ {
+ std::cout << "Syntax error at " << aTrsfArg << ".\n";
+ return 1;
+ }
+
+ const TCollection_AsciiString aScaleStr (theArgVec[aTrsfArgIter]);
+ if (!aScaleStr.IsRealValue())
+ {
+ std::cout << "Syntax error at " << aTrsfArg << ".\n";
+ return 1;
+ }
+ aScales[anIndex] = aScaleStr.RealValue();
+ }
+ else
+ {
+ anArgIter = aTrsfArgIter - 1;
+ break;
+ }
+ }
+ if (!isTrsfSet)
+ {
+ std::cout << "Syntax error at " << anArg << ".\n";
+ return 1;
+ }
+ else if (aTrsfArgIter >= theArgNb)
+ {
+ anArgIter = theArgNb;
+ }
+
+ aTrsfs[0].SetRotation (aRotQuats[0]);
+ aTrsfs[1].SetRotation (aRotQuats[1]);
+ aTrsfs[0].SetTranslationPart (aLocPnts[0]);
+ aTrsfs[1].SetTranslationPart (aLocPnts[1]);
+ aTrsfs[0].SetScaleFactor (aScales[0]);
+ aTrsfs[1].SetScaleFactor (aScales[1]);
+
+ Handle(AIS_AnimationObject) anObjAnimation = new AIS_AnimationObject (anAnimation->Name(), aCtx, anObject, aTrsfs[0], aTrsfs[1]);
+ replaceAnimation (aParentAnimation, anAnimation, anObjAnimation);
+ }
+ else if (anArg == "-viewtrsf"
+ || anArg == "-view")
+ {
+ Handle(AIS_AnimationCamera) aCamAnimation = Handle(AIS_AnimationCamera)::DownCast (anAnimation);
+ if (aCamAnimation.IsNull())
+ {
+ aCamAnimation = new AIS_AnimationCamera (anAnimation->Name(), aView);
+ replaceAnimation (aParentAnimation, anAnimation, aCamAnimation);
+ }
+
+ Handle(Graphic3d_Camera) aCams[2] =
+ {
+ new Graphic3d_Camera (aCamAnimation->View()->Camera()),
+ new Graphic3d_Camera (aCamAnimation->View()->Camera())
+ };
+
+ Standard_Boolean isTrsfSet = Standard_False;
+ Standard_Integer aViewArgIter = anArgIter + 1;
+ for (; aViewArgIter < theArgNb; ++aViewArgIter)
+ {
+ TCollection_AsciiString aViewArg (theArgVec[aViewArgIter]);
+ aViewArg.LowerCase();
+ const Standard_Integer anIndex = aViewArg.EndsWith("1") ? 0 : 1;
+ if (aViewArg.StartsWith ("-scale"))
+ {
+ isTrsfSet = Standard_True;
+ if (++aViewArgIter >= theArgNb)
+ {
+ std::cout << "Syntax error at " << anArg << ".\n";
+ return 1;
+ }
+
+ const TCollection_AsciiString aScaleStr (theArgVec[aViewArgIter]);
+ if (!aScaleStr.IsRealValue())
+ {
+ std::cout << "Syntax error at " << aViewArg << ".\n";
+ return 1;
+ }
+ Standard_Real aScale = aScaleStr.RealValue();
+ aScale = aCamAnimation->View()->DefaultCamera()->Scale() / aScale;
+ aCams[anIndex]->SetScale (aScale);
+ }
+ else if (aViewArg.StartsWith ("-eye")
+ || aViewArg.StartsWith ("-center")
+ || aViewArg.StartsWith ("-at")
+ || aViewArg.StartsWith ("-up"))
+ {
+ isTrsfSet = Standard_True;
+ gp_XYZ anXYZ;
+ if (aViewArgIter + 3 >= theArgNb
+ || !parseXYZ (theArgVec + aViewArgIter + 1, anXYZ))
+ {
+ std::cout << "Syntax error at " << aViewArg << ".\n";
+ return 1;
+ }
+ aViewArgIter += 3;
+
+ if (aViewArg.StartsWith ("-eye"))
+ {
+ aCams[anIndex]->SetEye (anXYZ);
+ }
+ else if (aViewArg.StartsWith ("-center")
+ || aViewArg.StartsWith ("-at"))
+ {
+ aCams[anIndex]->SetCenter (anXYZ);
+ }
+ else if (aViewArg.StartsWith ("-up"))
+ {
+ aCams[anIndex]->SetUp (anXYZ);
+ }
+ }
+ else
+ {
+ anArgIter = aViewArgIter - 1;
+ break;
+ }
+ }
+ if (!isTrsfSet)
+ {
+ std::cout << "Syntax error at " << anArg << ".\n";
+ return 1;
+ }
+ else if (aViewArgIter >= theArgNb)
+ {
+ anArgIter = theArgNb;
+ }
+
+ aCamAnimation->SetCameraStart(aCams[0]);
+ aCamAnimation->SetCameraEnd (aCams[1]);
}
else
{
- anAISView->SetAt (aValues->Value(1).RealValue(), aValues->Value(2).RealValue(), aValues->Value(3).RealValue());
+ std::cout << "Syntax error at " << anArg << ".\n";
+ return 1;
}
}
- if (aMapOfKeysByValues.Find ("PROJ", aValues))
+
+ if (!toPlay)
{
- if (aValues->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);
+ if (isFreeCamera)
+ {
+ aView->Camera()->Copy (aCameraBack);
+ }
+
+ const Standard_Real anUpperPts = aPlayStartTime + aPlayDuration;
+ if (aPlayFrameRate < Precision::Confusion())
+ {
+ while (!anAnimation->IsStopped())
{
- Standard_Real aProjX = 0.0;
- Standard_Real aProjY = 0.0;
- Standard_Real aProjZ = 0.0;
- anAISView->Proj (aProjX, aProjY, aProjZ);
- theDi << "Proj X: " << aProjX << " Y: " << aProjY << " Z: " << aProjZ << "\n";
+ aCameraBack->Copy (aView->Camera());
+ const Standard_Real aPts = anAnimation->UpdateTimer();
+ if (isFreeCamera)
+ {
+ aView->Camera()->Copy (aCameraBack);
+ }
+
+ if (aPts >= anUpperPts)
+ {
+ anAnimation->Pause();
+ break;
+ }
+
+ if (aView->IsInvalidated())
+ {
+ aView->Redraw();
+ }
+ else
+ {
+ aView->RedrawImmediate();
+ }
+
+ if (!isLockLoop)
+ {
+ // handle user events
+ theDI.Eval ("after 1 set waiter 1");
+ theDI.Eval ("vwait waiter");
+ }
+ if (!TheIsAnimating)
+ {
+ anAnimation->Pause();
+ theDI << aPts;
+ break;
+ }
+ }
+
+ if (aView->IsInvalidated())
+ {
+ aView->Redraw();
}
else
{
- anAISView->SetProj (aValues->Value(1).RealValue(), aValues->Value(2).RealValue(), aValues->Value(3).RealValue());
+ aView->RedrawImmediate();
}
}
- if (aMapOfKeysByValues.Find ("UP", aValues))
+ else
{
- if (aValues->IsEmpty())
+ Standard_Real aMaxFPS = 0.0;
+
+ // Manage frame-rated animation here
+ Standard_Real aPts = aPlayStartTime;
+ while (aPts <= anUpperPts)
{
- Standard_Real anUpX = 0.0;
- Standard_Real anUpY = 0.0;
- Standard_Real anUpZ = 0.0;
- anAISView->Up (anUpX, anUpY, anUpZ);
- theDi << "Up X: " << anUpX << " Y: " << anUpY << " Z: " << anUpZ << "\n";
+ if (!anAnimation->Update (aPts))
+ {
+ break;
+ }
+
+ Standard_Real aProgress = anAnimation->ElapsedTime();
+ Standard_Real aNextRatedPts = aPts + 1.0 / aPlayFrameRate;
+ Standard_Real aPrevPts = aPts;
+ aPts = aNextRatedPts < aProgress ? aNextRatedPts : aProgress;
+ Standard_Real aCurrentFPS = 1.0 / (aPts - aPrevPts);
+ if (aMaxFPS < aCurrentFPS)
+ {
+ aMaxFPS = aCurrentFPS;
+ }
+ }
+
+ if (aView->IsInvalidated())
+ {
+ aView->Redraw();
}
else
{
- anAISView->SetUp (aValues->Value(1).RealValue(), aValues->Value(2).RealValue(), aValues->Value(3).RealValue());
+ aView->RedrawImmediate();
}
- }
- if (aMapOfKeysByValues.Find ("CENTER", aValues))
- {
- anAISView->SetCenter (aValues->Value(1).IntegerValue(), aValues->Value(2).IntegerValue());
+ anAnimation->Stop();
+ theDI << aMaxFPS;
}
+ aView->SetImmediateUpdate (wasImmediateUpdate);
+ TheIsAnimating = Standard_False;
return 0;
}
+
//=======================================================================
//function : VChangeSelected
//purpose : Adds the shape to selection or remove one from it
theCommands.Add("vpick" ,
"vpick : vpick X Y Z [shape subshape] ( all variables as string )",
VPick,group);
- theCommands.Add("vfit" ,
- "vfit or <F> [-selected]"
+ theCommands.Add("vfit",
+ "vfit or <F> [-selected] [-noupdate]"
"\n\t\t: [-selected] fits the scene according to bounding box of currently selected objects",
__FILE__,VFit,group);
theCommands.Add ("vfitarea",
"vmoveto x y"
"- emulates cursor movement to pixel postion (x,y)",
__FILE__, VMoveTo, group);
- theCommands.Add ("vviewparams", "vviewparams usage:\n"
- "- vviewparams\n"
- "- vviewparams [-scale [s]] [-eye [x y z]] [-at [x y z]] [-up [x y z]]\n"
- " [-proj [x y z]] [-center x y] [-size sx]\n"
- "- Gets or sets current view parameters.\n"
- "- If called without arguments, all view parameters are printed.\n"
- "- The options are:\n"
- " -scale [s] : prints or sets viewport relative scale.\n"
- " -eye [x y z] : prints or sets eye location.\n"
- " -at [x y z] : prints or sets center of look.\n"
- " -up [x y z] : prints or sets direction of up vector.\n"
- " -proj [x y z] : prints or sets direction of look.\n"
- " -center x y : sets location of center of the screen in pixels.\n"
- " -size [sx] : prints viewport projection width and height sizes\n"
- " : or changes the size of its maximum dimension.\n",
+ theCommands.Add ("vviewparams",
+ "vviewparams [-args] [-scale [s]]"
+ "\n\t\t: [-eye [x y z]] [-at [x y z]] [-up [x y z]]"
+ "\n\t\t: [-proj [x y z]] [-center x y] [-size sx]"
+ "\n\t\t: Manage current view parameters or prints all"
+ "\n\t\t: current values when called without argument."
+ "\n\t\t: -scale [s] prints or sets viewport relative scale"
+ "\n\t\t: -eye [x y z] prints or sets eye location"
+ "\n\t\t: -at [x y z] prints or sets center of look"
+ "\n\t\t: -up [x y z] prints or sets direction of up vector"
+ "\n\t\t: -proj [x y z] prints or sets direction of look"
+ "\n\t\t: -center x y sets location of center of the screen in pixels"
+ "\n\t\t: -size [sx] prints viewport projection width and height sizes"
+ "\n\t\t: or changes the size of its maximum dimension"
+ "\n\t\t: -args prints vviewparams arguments for restoring current view",
__FILE__, VViewParams, group);
+
+ theCommands.Add("vanimation", "Alias for vanim",
+ __FILE__, VAnimation, group);
+
+ theCommands.Add("vanim",
+ "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: -speed playback speed (1.0 is normal speed)"
+ "\n\t\t: -freeLook skip camera animations"
+ "\n\t\t: -lockLoop disable any interactions"
+ "\n\t\t:"
+ "\n\t\t: Animation definition:"
+ "\n\t\t: vanim Name/sub/name [-clear] [-delete]"
+ "\n\t\t: [start TimeSec] [duration TimeSec]"
+ "\n\t\t:"
+ "\n\t\t: Animation name defined in path-style (anim/name or anim.name)"
+ "\n\t\t: specifies nested animations."
+ "\n\t\t: There is no syntax to explicitly add new animation,"
+ "\n\t\t: and all non-existing animations within the name will be"
+ "\n\t\t: implicitly created on first use (including parents)."
+ "\n\t\t:"
+ "\n\t\t: Each animation might define the SINGLE action (see below),"
+ "\n\t\t: like camera transition, object transformation or custom callback."
+ "\n\t\t: Child animations can be used for defining concurrent actions."
+ "\n\t\t:"
+ "\n\t\t: Camera animation:"
+ "\n\t\t: vanim name -view [-eye1 X Y Z] [-eye2 X Y Z]"
+ "\n\t\t: [-at1 X Y Z] [-at2 X Y Z]"
+ "\n\t\t: [-up1 X Y Z] [-up2 X Y Z]"
+ "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
+ "\n\t\t: -eyeX camera Eye positions pair (start and end)"
+ "\n\t\t: -atX camera Center positions pair"
+ "\n\t\t: -upX camera Up directions pair"
+ "\n\t\t: -scaleX camera Scale factors pair"
+ "\n\t\t: Object animation:"
+ "\n\t\t: vanim name -object [-loc1 X Y Z] [-loc2 X Y Z]"
+ "\n\t\t: [-rot1 QX QY QZ QW] [-rot2 QX QY QZ QW]"
+ "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
+ "\n\t\t: -locX object Location points pair (translation)"
+ "\n\t\t: -rotX object Orientations pair (quaternions)"
+ "\n\t\t: -scaleX object Scale factors pair (quaternions)"
+ "\n\t\t: Custom callback:"
+ "\n\t\t: vanim name -invoke \"Command Arg1 Arg2 %Pts %LocalPts %Normalized ArgN\""
+ "\n\t\t: %Pts overall animation presentation timestamp"
+ "\n\t\t: %LocalPts local animation timestamp"
+ "\n\t\t: %Normalized local animation normalized value in range 0..1"
+ __FILE__, VAnimation, group);
+
theCommands.Add("vchangeselected",
"vchangeselected shape"
"- adds to shape to selection or remove one from it",
gp_Trsf2d.hxx
gp_Trsf2d.lxx
gp_TrsfForm.hxx
+gp_TrsfNLerp.hxx
gp_Vec.cxx
gp_Vec.hxx
gp_Vec.lxx
#include <gp_Quaternion.hxx>
-/**
- * Class perform linear interpolation (approximate rotation interpolation),
- * result quaternion nonunit, its length lay between. sqrt(2)/2 and 1.0
- */
+//! Class perform linear interpolation (approximate rotation interpolation),
+//! result quaternion nonunit, its length lay between. sqrt(2)/2 and 1.0
class gp_QuaternionNLerp
{
+public:
+
+ //! Compute interpolated quaternion between two quaternions.
+ //! @param theStart first quaternion
+ //! @param theEnd second quaternion
+ //! @param theT normalized interpolation coefficient within 0..1 range,
+ //! with 0 pointing to theStart and 1 to theEnd.
+ static gp_Quaternion Interpolate (const gp_Quaternion& theQStart,
+ const gp_Quaternion& theQEnd,
+ Standard_Real theT)
+ {
+ gp_Quaternion aResult;
+ gp_QuaternionNLerp aLerp (theQStart, theQEnd);
+ aLerp.Interpolate (theT, aResult);
+ return aResult;
+ }
public:
+ //! Empty constructor,
gp_QuaternionNLerp() {}
+ //! Constructor with initialization.
gp_QuaternionNLerp (const gp_Quaternion& theQStart, const gp_Quaternion& theQEnd)
{
Init (theQStart, theQEnd);
}
+ //! Initialize the tool with Start and End values.
void Init (const gp_Quaternion& theQStart, const gp_Quaternion& theQEnd)
{
InitFromUnit (theQStart.Normalized(), theQEnd.Normalized());
}
+ //! Initialize the tool with Start and End unit quaternions.
void InitFromUnit (const gp_Quaternion& theQStart, const gp_Quaternion& theQEnd)
{
myQStart = theQStart;
theResultQ = myQStart + myQEnd * theT;
}
- static gp_Quaternion Interpolate (const gp_Quaternion& theQStart,
- const gp_Quaternion& theQEnd,
- Standard_Real theT)
- {
- gp_Quaternion aResultQ;
- gp_QuaternionNLerp aNLerp (theQStart, theQEnd);
- aNLerp.Interpolate (theT, aResultQ);
- return aResultQ;
- }
-
private:
gp_Quaternion myQStart;
#include <gp_Quaternion.hxx>
-/**
- * Perform Spherical Linear Interpolation of the quaternions,
- * return unit length quaternion.
- */
+//! Perform Spherical Linear Interpolation of the quaternions,
+//! return unit length quaternion.
class gp_QuaternionSLerp
{
+public:
+
+ //! Compute interpolated quaternion between two quaternions.
+ //! @param theStart first quaternion
+ //! @param theEnd second quaternion
+ //! @param theT normalized interpolation coefficient within 0..1 range,
+ //! with 0 pointing to theStart and 1 to theEnd.
+ static gp_Quaternion Interpolate (const gp_Quaternion& theQStart,
+ const gp_Quaternion& theQEnd,
+ Standard_Real theT)
+ {
+ gp_Quaternion aResult;
+ gp_QuaternionSLerp aLerp (theQStart, theQEnd);
+ aLerp.Interpolate (theT, aResult);
+ return aResult;
+ }
public:
+ //! Empty constructor,
gp_QuaternionSLerp() {}
+ //! Constructor with initialization.
gp_QuaternionSLerp (const gp_Quaternion& theQStart, const gp_Quaternion& theQEnd)
{
Init (theQStart, theQEnd);
}
+ //! Initialize the tool with Start and End values.
void Init (const gp_Quaternion& theQStart, const gp_Quaternion& theQEnd)
{
InitFromUnit (theQStart.Normalized(), theQEnd.Normalized());
}
+ //! Initialize the tool with Start and End unit quaternions.
void InitFromUnit (const gp_Quaternion& theQStart, const gp_Quaternion& theQEnd)
{
myQStart = theQStart;
--- /dev/null
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _gp_TrsfNLerp_HeaderFile
+#define _gp_TrsfNLerp_HeaderFile
+
+#include <gp_Trsf.hxx>
+#include <gp_QuaternionNLerp.hxx>
+#include <NCollection_Lerp.hxx>
+#include <Precision.hxx>
+
+//! Linear interpolation tool for transformation defined by gp_Trsf.
+//!
+//! In general case, there is a no well-defined interpolation between arbitrary transformations,
+//! because desired transient values might vary depending on application needs.
+//!
+//! This tool performs independent interpolation of three logical
+//! transformation parts - rotation (using gp_QuaternionNLerp), translation and scale factor.
+//! Result of such interpolation might be not what application expects,
+//! thus this tool might be considered for simple cases or for interpolating between small intervals.
+template<> class NCollection_Lerp<gp_Trsf>
+{
+public:
+
+ //! Empty constructor
+ NCollection_Lerp() {}
+
+ //! Main constructor.
+ NCollection_Lerp (const gp_Trsf& theStart, const gp_Trsf& theEnd)
+ {
+ Init (theStart, theEnd);
+ }
+
+ //! Initialize values.
+ void Init (const gp_Trsf& theStart, const gp_Trsf& theEnd)
+ {
+ myTrsfStart = theStart;
+ myTrsfEnd = theEnd;
+ myLocLerp .Init (theStart.TranslationPart(), theEnd.TranslationPart());
+ myRotLerp .Init (theStart.GetRotation(), theEnd.GetRotation());
+ myScaleLerp.Init (theStart.ScaleFactor(), theEnd.ScaleFactor());
+ }
+
+ //! Compute interpolated value between two values.
+ //! @param theT normalized interpolation coefficient within [0, 1] range,
+ //! with 0 pointing to first value and 1 to the second value.
+ //! @param theResult [out] interpolated value
+ void Interpolate (double theT, gp_Trsf& theResult) const
+ {
+ if (Abs (theT - 0.0) < Precision::Confusion())
+ {
+ theResult = myTrsfStart;
+ return;
+ }
+ else if (Abs (theT - 1.0) < Precision::Confusion())
+ {
+ theResult = myTrsfEnd;
+ return;
+ }
+
+ gp_XYZ aLoc;
+ gp_Quaternion aRot;
+ Standard_Real aScale = 1.0;
+ myLocLerp .Interpolate (theT, aLoc);
+ myRotLerp .Interpolate (theT, aRot);
+ myScaleLerp.Interpolate (theT, aScale);
+ theResult = gp_Trsf();
+ theResult.SetRotation (aRot);
+ theResult.SetTranslationPart (aLoc);
+ theResult.SetScaleFactor (aScale);
+ }
+
+private:
+ NCollection_Lerp<gp_XYZ> myLocLerp;
+ NCollection_Lerp<Standard_Real> myScaleLerp;
+ gp_QuaternionNLerp myRotLerp;
+ gp_Trsf myTrsfStart;
+ gp_Trsf myTrsfEnd;
+};
+
+typedef NCollection_Lerp<gp_Trsf> gp_TrsfNLerp;
+
+#endif // _gp_TrsfNLerp_HeaderFile
# display as copies
eval compound [lrepeat $aNb s] ss
explode ss
-for {set i 1} {$i <= $aNb} {incr i} { vloadselection ss_${i}; vsetlocation -noupdate ss_${i} 0 0 s }
+for {set i 1} {$i <= $aNb} {incr i} { vloadselection ss_${i}; vsetlocation -noupdate ss_${i} ${i} 0 0 }
vfit
set aMemSel1 [meminfo h]
vclear
vconnectto b2 6 0 0 b1
box b3 7 1 1
vdisplay b3
-vloctranslate b3 0 4 0
+vlocation b3 -translate 0 4 0
vconnect z 0 0 0 b1 b2 b3
vconnect z1 0 0 0 z
-vloctranslate z1 10 0 0
+vlocation z1 -translate 10 0 0
vconnect z2 0 10 0 z
-vlocrotate z2 0 0 0 1 0 0 90
+vlocation z2 -rotate 0 0 0 1 0 0 90
vconnect z3 -10 0 0 z
-vlocscale z3 0 0 0 0.5
+vlocation z3 -scale 0 0 0 0.5
vconnect z4 0 0 0 z
-vlocmove z4 z3
+vlocation z4 -copyFrom z3
psphere sp 3
vdisplay sp
-vlocmove sp z3
-vlocreset sp
+vlocation sp -copyFrom z3
+vlocation sp -reset
-vlocmirror z 0 -0.5 0 0 1 0
+vlocation z -mirror 0 -0.5 0 0 1 0
vfit
vdump $imagedir/${casename}.png
# display as copies
eval compound [lrepeat $aNb s] ss
explode ss
-for {set i 1} {$i <= $aNb} {incr i} { vdisplay -noupdate ss_${i}; vsetlocation -noupdate ss_${i} 0 0 s }
+for {set i 1} {$i <= $aNb} {incr i} { vdisplay -noupdate ss_${i}; vsetlocation -noupdate ss_${i} ${i} 0 0 }
vfit
set aMemDisp1 [meminfo h]
vclear
vfit
-vlocrotate b 0 0 0 0 0 1 50
+vlocation b -rotate 0 0 0 0 0 1 50
vmoveto 380 50
checkcolor 380 50 0.87450981140136719 0 0.12156862765550613
--- /dev/null
+puts "=================================="
+puts "Viewer animation - animate object moving"
+puts "=================================="
+
+pload MODELING VISUALIZATION
+
+vclear
+vinit View1
+vaxo
+
+psphere s 50
+box b1 -50 -50 0 100 100 100
+vdisplay -dispMode 1 b1 s
+
+vviewparams -scale 2.499 -proj 0.546611 -0.600024 -0.584114 -up -0.411832 0.414728 -0.811415 -at -5.3425 -2.983 49.216
+
+vanimation anim -clear
+vanimation anim/obj1 -objectTrsf b1 -loc1 0 0 0 -loc2 -100 0 -100 -start 0 -duration 2
+vanimation anim/obj2 -objectTrsf s -loc1 0 0 0 -loc2 100 0 100 -start 1 -duration 2
+
+vanimation anim -play 0.0 0.0
+vdump $imagedir/${casename}_0.png
+
+vanimation anim -play 1.0 0.0
+vdump $imagedir/${casename}_1.png
+
+vanimation anim -play 2.0 0.0
+vdump $imagedir/${casename}_2.png
+
+if {[vreadpixel 270 20 rgb name] != "DARKGOLDENROD3"} { puts "Error: Box moving result is wrong!" }
+if {[vreadpixel 120 255 rgb name] != "DARKGOLDENROD4"} { puts "Error: Sphere moving result is wrong!" }
+
+puts "Put the following command to start interactive animation:"
+puts " vanimation anim -play"
--- /dev/null
+puts "=================================="
+puts "Viewer animation - Propeller animation"
+puts "Regressions should be detected visually"
+puts "=================================="
+
+pload MODELING VISUALIZATION
+restore [locate_data_file occ/CrankArm.rle] a
+restore [locate_data_file occ/CylinderHead.rle] h
+restore [locate_data_file occ/Propeller.rle] p
+restore [locate_data_file occ/EngineBlock.rle] e
+
+vclear
+vinit name=View1 width=912 height=512
+vzbufftrihedron
+vcamera -persp -fovy 60
+vdisplay -dispMode 1 -mutable a h p e
+vfit
+vsetcolor p GREEN
+vsetcolor e RED
+vsetcolor h PURPLE
+
+vanimation anim -clear
+
+# custom callback
+proc drawAnimLabels {thePts} { vdrawtext lab "Current PTS: $thePts sec" -2d -persPos -1 1 30 -noupdate }
+#proc drawAnimPropeller {theLocalPts} { set aVal 0.0; if { $theLocalPts >= 1.0 && $theLocalPts <= 1.5 } { set aVal 0.9 }; vaspects -noupdate p -setTransparency $aVal }
+proc drawAnimProp1 {theNormalized} { vaspects -noupdate p -setTransparency [expr $theNormalized * 0.9] }
+proc drawAnimProp2 {theNormalized} { vaspects -noupdate p -setTransparency [expr (1.0 - $theNormalized) * 0.9] }
+vanimation anim/cmd/1 -start 0 -dur 2.0 -cmd "drawAnimLabels %pts"
+#vanimation anim/cmd/2 -start 0 -dur 2.0 -cmd "drawAnimPropeller %localPts"
+vanimation anim/cmd/2 -start 1.0 -dur 0.1 -cmd "drawAnimProp1 %localNormalized"
+vanimation anim/cmd/3 -start 1.5 -dur 0.1 -cmd "drawAnimProp2 %localNormalized"
+
+# camera animation
+vanimation anim/cam/1 -start 0 -dur 0.5 -view -up1 -0.408248 0.408248 0.816497 -up2 -0.70394 0.70394 -0.094542 -at1 0 0 -52.5 -at2 0 0 -52.5 -eye1 718.333 -718.333 665.833 -eye2 -83.1757 83.1757 1186.12 -scale1 0.736953 -scale2 1.3
+vanimation anim/cam/2 -start 0.5 -dur 0.5 -view -up1 -0.70394 0.70394 -0.094542 -up2 -0.0582751 -0.996311 0.0629907 -at1 0 0 -52.5 -at2 0 0 -52.5 -eye1 -83.1757 83.1757 1186.12 -eye2 -83.1757 83.1757 1186.12 -scale1 1.3 -scale2 2.5
+vanimation anim/cam/3 -start 1.0 -dur 0.5 -view -up1 -0.0582751 -0.996311 0.0629907 -up2 -0.0757833 -0.103462 0.991742 -at1 0 0 -52.5 -at2 0 0 -52.5 -eye1 -83.1757 83.1757 1186.12 -eye2 57.3134 1235.7 80.7922 -scale1 2.5 -scale2 5.0
+vanimation anim/cam/4 -start 1.5 -dur 0.5 -view -up1 -0.0757833 -0.103462 0.991742 -up2 -0.0757833 -0.103462 0.991742 -at1 0 0 -52.5 -at2 85.6748 -3.38673 -57.9416 -eye1 57.3134 1235.7 80.7922 -eye2 142.989 1232.32 75.3506 -scale1 5.0 -scale2 2.0
+
+# propeller animation
+vanimation anim/p/1 -start 0 -dur 0.5 -objectTrsf p -rot1 0 0 0 1 -rot2 0 0 0.707107 0.707107
+vanimation anim/p/2 -start 0.5 -dur 0.5 -objectTrsf p -rot1 0 0 0.707107 0.707107 -rot2 0 0 1 6.12323e-17
+vanimation anim/p/3 -start 1.0 -dur 0.5 -objectTrsf p -rot1 0 0 1 6.12323e-17 -rot2 0 0 -0.707107 0.707107
+vanimation anim/p/4 -start 1.5 -dur 0.5 -objectTrsf p -rot1 0 0 -0.707107 0.707107 -rot2 0 0 0 1
+
+# arm animation
+vanimation anim/a/1 -start 0 -dur 0.03125 -objectTrsf a -rot1 0 0 0 1 -rot2 0 0 -0.0183813 0.999831 -loc1 0 0 0 -loc2 -0.186279 6.06481 -0
+vanimation anim/a/2 -start 0.03125 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.0183813 0.999831 -rot2 0 0 -0.036604 0.99933 -loc1 -0.186279 6.06481 -0 -loc2 -0.744076 12.0712 -0
+vanimation anim/a/3 -start 0.0625 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.036604 0.99933 -rot2 0 0 -0.0545094 0.998513 -loc1 -0.744076 12.0712 -0 -loc2 -1.67027 17.9614 -0
+vanimation anim/a/4 -start 0.09375 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.0545094 0.998513 -rot2 0 0 -0.0719395 0.997409 -loc1 -1.67027 17.9614 -0 -loc2 -2.95964 23.6785 -0
+vanimation anim/a/5 -start 0.125 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.0719395 0.997409 -rot2 0 0 -0.0887369 0.996055 -loc1 -2.95964 23.6785 -0 -loc2 -4.60486 29.1677 -0
+vanimation anim/a/6 -start 0.15625 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.0887369 0.996055 -rot2 0 0 -0.104746 0.994499 -loc1 -4.60486 29.1677 -0 -loc2 -6.59642 34.3759 -0
+vanimation anim/a/7 -start 0.1875 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.104746 0.994499 -rot2 0 0 -0.119812 0.992797 -loc1 -6.59642 34.3759 -0 -loc2 -8.92259 39.2531 -0
+vanimation anim/a/8 -start 0.21875 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.119812 0.992797 -rot2 0 0 -0.133785 0.99101 -loc1 -8.92259 39.2531 -0 -loc2 -11.5693 43.7522 -0
+vanimation anim/a/9 -start 0.25 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.133785 0.99101 -rot2 0 0 -0.146521 0.989208 -loc1 -11.5693 43.7522 -0 -loc2 -14.5202 47.83 -0
+vanimation anim/a/10 -start 0.28125 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.146521 0.989208 -rot2 0 0 -0.157881 0.987458 -loc1 -14.5202 47.83 -0 -loc2 -17.756 51.4472 -0
+vanimation anim/a/11 -start 0.3125 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.157881 0.987458 -rot2 0 0 -0.167737 0.985832 -loc1 -17.756 51.4472 -0 -loc2 -21.2549 54.5689 -0
+vanimation anim/a/12 -start 0.34375 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.167737 0.985832 -rot2 0 0 -0.175973 0.984395 -loc1 -21.2549 54.5689 -0 -loc2 -24.9922 57.165 -0
+vanimation anim/a/13 -start 0.375 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.175973 0.984395 -rot2 0 0 -0.182491 0.983208 -loc1 -24.9922 57.165 -0 -loc2 -28.9399 59.2107 -0
+vanimation anim/a/14 -start 0.40625 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.182491 0.983208 -rot2 0 0 -0.187207 0.98232 -loc1 -28.9399 59.2107 -0 -loc2 -33.0668 60.6861 -0
+vanimation anim/a/15 -start 0.4375 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.187207 0.98232 -rot2 0 0 -0.190062 0.981772 -loc1 -33.0668 60.6861 -0 -loc2 -37.3381 61.5771 -0
+vanimation anim/a/16 -start 0.46875 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.190062 0.981772 -rot2 0 0 -0.191017 0.981587 -loc1 -37.3381 61.5771 -0 -loc2 -41.7161 61.875 -0
+vanimation anim/a/17 -start 0.5 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.191017 0.981587 -rot2 0 0 -0.190062 0.981772 -loc1 -41.7161 61.875 -0 -loc2 -46.1597 61.5771 -0
+vanimation anim/a/18 -start 0.53125 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.190062 0.981772 -rot2 0 0 -0.187207 0.98232 -loc1 -46.1597 61.5771 -0 -loc2 -50.6249 60.6861 -0
+vanimation anim/a/19 -start 0.5625 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.187207 0.98232 -rot2 0 0 -0.182491 0.983208 -loc1 -50.6249 60.6861 -0 -loc2 -55.0656 59.2107 -0
+vanimation anim/a/20 -start 0.59375 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.182491 0.983208 -rot2 0 0 -0.175973 0.984395 -loc1 -55.0656 59.2107 -0 -loc2 -59.4338 57.165 -0
+vanimation anim/a/21 -start 0.625 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.175973 0.984395 -rot2 0 0 -0.167737 0.985832 -loc1 -59.4338 57.165 -0 -loc2 -63.6806 54.5689 -0
+vanimation anim/a/22 -start 0.65625 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.167737 0.985832 -rot2 0 0 -0.157881 0.987458 -loc1 -63.6806 54.5689 -0 -loc2 -67.7573 51.4472 -0
+vanimation anim/a/23 -start 0.6875 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.157881 0.987458 -rot2 0 0 -0.146521 0.989208 -loc1 -67.7573 51.4472 -0 -loc2 -71.6155 47.83 -0
+vanimation anim/a/24 -start 0.71875 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.146521 0.989208 -rot2 0 0 -0.133785 0.99101 -loc1 -71.6155 47.83 -0 -loc2 -75.2089 43.7522 -0
+vanimation anim/a/25 -start 0.75 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.133785 0.99101 -rot2 0 0 -0.119812 0.992797 -loc1 -75.2089 43.7522 -0 -loc2 -78.4935 39.2531 -0
+vanimation anim/a/26 -start 0.78125 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.119812 0.992797 -rot2 0 0 -0.104746 0.994499 -loc1 -78.4935 39.2531 -0 -loc2 -81.4287 34.3759 -0
+vanimation anim/a/27 -start 0.8125 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.104746 0.994499 -rot2 0 0 -0.0887369 0.996055 -loc1 -81.4287 34.3759 -0 -loc2 -83.9778 29.1677 -0
+vanimation anim/a/28 -start 0.84375 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.0887369 0.996055 -rot2 0 0 -0.0719395 0.997409 -loc1 -83.9778 29.1677 -0 -loc2 -86.1088 23.6785 -0
+vanimation anim/a/29 -start 0.875 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.0719395 0.997409 -rot2 0 0 -0.0545094 0.998513 -loc1 -86.1088 23.6785 -0 -loc2 -87.7949 17.9614 -0
+vanimation anim/a/30 -start 0.90625 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.0545094 0.998513 -rot2 0 0 -0.036604 0.99933 -loc1 -87.7949 17.9614 -0 -loc2 -89.0148 12.0712 -0
+vanimation anim/a/31 -start 0.9375 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.036604 0.99933 -rot2 0 0 -0.0183813 0.999831 -loc1 -89.0148 12.0712 -0 -loc2 -89.7529 6.06481 -0
+vanimation anim/a/32 -start 0.96875 -dur 0.03125 -objectTrsf a -rot1 0 0 -0.0183813 0.999831 -rot2 0 0 -2.29621e-17 1 -loc1 -89.7529 6.06481 -0 -loc2 -90 7.5775e-15 -0
+vanimation anim/a/33 -start 1 -dur 0.03125 -objectTrsf a -rot1 0 0 -2.29621e-17 1 -rot2 0 0 0.0183813 0.999831 -loc1 -90 7.5775e-15 -0 -loc2 -89.7529 -6.06481 -0
+vanimation anim/a/34 -start 1.03125 -dur 0.03125 -objectTrsf a -rot1 0 0 0.0183813 0.999831 -rot2 0 0 0.036604 0.99933 -loc1 -89.7529 -6.06481 -0 -loc2 -89.0148 -12.0712 -0
+vanimation anim/a/35 -start 1.0625 -dur 0.03125 -objectTrsf a -rot1 0 0 0.036604 0.99933 -rot2 0 0 0.0545094 0.998513 -loc1 -89.0148 -12.0712 -0 -loc2 -87.7949 -17.9614 -0
+vanimation anim/a/36 -start 1.09375 -dur 0.03125 -objectTrsf a -rot1 0 0 0.0545094 0.998513 -rot2 0 0 0.0719395 0.997409 -loc1 -87.7949 -17.9614 -0 -loc2 -86.1088 -23.6785 -0
+vanimation anim/a/37 -start 1.125 -dur 0.03125 -objectTrsf a -rot1 0 0 0.0719395 0.997409 -rot2 0 0 0.0887369 0.996055 -loc1 -86.1088 -23.6785 -0 -loc2 -83.9778 -29.1677 -0
+vanimation anim/a/38 -start 1.15625 -dur 0.03125 -objectTrsf a -rot1 0 0 0.0887369 0.996055 -rot2 0 0 0.104746 0.994499 -loc1 -83.9778 -29.1677 -0 -loc2 -81.4287 -34.3759 -0
+vanimation anim/a/39 -start 1.1875 -dur 0.03125 -objectTrsf a -rot1 0 0 0.104746 0.994499 -rot2 0 0 0.119812 0.992797 -loc1 -81.4287 -34.3759 -0 -loc2 -78.4935 -39.2531 -0
+vanimation anim/a/40 -start 1.21875 -dur 0.03125 -objectTrsf a -rot1 0 0 0.119812 0.992797 -rot2 0 0 0.133785 0.99101 -loc1 -78.4935 -39.2531 -0 -loc2 -75.2089 -43.7522 -0
+vanimation anim/a/41 -start 1.25 -dur 0.03125 -objectTrsf a -rot1 0 0 0.133785 0.99101 -rot2 0 0 0.146521 0.989208 -loc1 -75.2089 -43.7522 -0 -loc2 -71.6155 -47.83 -0
+vanimation anim/a/42 -start 1.28125 -dur 0.03125 -objectTrsf a -rot1 0 0 0.146521 0.989208 -rot2 0 0 0.157881 0.987458 -loc1 -71.6155 -47.83 -0 -loc2 -67.7573 -51.4472 -0
+vanimation anim/a/43 -start 1.3125 -dur 0.03125 -objectTrsf a -rot1 0 0 0.157881 0.987458 -rot2 0 0 0.167737 0.985832 -loc1 -67.7573 -51.4472 -0 -loc2 -63.6806 -54.5689 -0
+vanimation anim/a/44 -start 1.34375 -dur 0.03125 -objectTrsf a -rot1 0 0 0.167737 0.985832 -rot2 0 0 0.175973 0.984395 -loc1 -63.6806 -54.5689 -0 -loc2 -59.4338 -57.165 -0
+vanimation anim/a/45 -start 1.375 -dur 0.03125 -objectTrsf a -rot1 0 0 0.175973 0.984395 -rot2 0 0 0.182491 0.983208 -loc1 -59.4338 -57.165 -0 -loc2 -55.0656 -59.2107 -0
+vanimation anim/a/46 -start 1.40625 -dur 0.03125 -objectTrsf a -rot1 0 0 0.182491 0.983208 -rot2 0 0 0.187207 0.98232 -loc1 -55.0656 -59.2107 -0 -loc2 -50.6249 -60.6861 -0
+vanimation anim/a/47 -start 1.4375 -dur 0.03125 -objectTrsf a -rot1 0 0 0.187207 0.98232 -rot2 0 0 0.190062 0.981772 -loc1 -50.6249 -60.6861 -0 -loc2 -46.1597 -61.5771 -0
+vanimation anim/a/48 -start 1.46875 -dur 0.03125 -objectTrsf a -rot1 0 0 0.190062 0.981772 -rot2 0 0 0.191017 0.981587 -loc1 -46.1597 -61.5771 -0 -loc2 -41.7161 -61.875 -0
+vanimation anim/a/49 -start 1.5 -dur 0.03125 -objectTrsf a -rot1 0 0 0.191017 0.981587 -rot2 0 0 0.190062 0.981772 -loc1 -41.7161 -61.875 -0 -loc2 -37.3381 -61.5771 -0
+vanimation anim/a/50 -start 1.53125 -dur 0.03125 -objectTrsf a -rot1 0 0 0.190062 0.981772 -rot2 0 0 0.187207 0.98232 -loc1 -37.3381 -61.5771 -0 -loc2 -33.0668 -60.6861 -0
+vanimation anim/a/51 -start 1.5625 -dur 0.03125 -objectTrsf a -rot1 0 0 0.187207 0.98232 -rot2 0 0 0.182491 0.983208 -loc1 -33.0668 -60.6861 -0 -loc2 -28.9399 -59.2107 -0
+vanimation anim/a/52 -start 1.59375 -dur 0.03125 -objectTrsf a -rot1 0 0 0.182491 0.983208 -rot2 0 0 0.175973 0.984395 -loc1 -28.9399 -59.2107 -0 -loc2 -24.9922 -57.165 -0
+vanimation anim/a/53 -start 1.625 -dur 0.03125 -objectTrsf a -rot1 0 0 0.175973 0.984395 -rot2 0 0 0.167737 0.985832 -loc1 -24.9922 -57.165 -0 -loc2 -21.2549 -54.5689 -0
+vanimation anim/a/54 -start 1.65625 -dur 0.03125 -objectTrsf a -rot1 0 0 0.167737 0.985832 -rot2 0 0 0.157881 0.987458 -loc1 -21.2549 -54.5689 -0 -loc2 -17.756 -51.4472 -0
+vanimation anim/a/55 -start 1.6875 -dur 0.03125 -objectTrsf a -rot1 0 0 0.157881 0.987458 -rot2 0 0 0.146521 0.989208 -loc1 -17.756 -51.4472 -0 -loc2 -14.5202 -47.83 -0
+vanimation anim/a/56 -start 1.71875 -dur 0.03125 -objectTrsf a -rot1 0 0 0.146521 0.989208 -rot2 0 0 0.133785 0.99101 -loc1 -14.5202 -47.83 -0 -loc2 -11.5693 -43.7522 -0
+vanimation anim/a/57 -start 1.75 -dur 0.03125 -objectTrsf a -rot1 0 0 0.133785 0.99101 -rot2 0 0 0.119812 0.992797 -loc1 -11.5693 -43.7522 -0 -loc2 -8.92259 -39.2531 -0
+vanimation anim/a/58 -start 1.78125 -dur 0.03125 -objectTrsf a -rot1 0 0 0.119812 0.992797 -rot2 0 0 0.104746 0.994499 -loc1 -8.92259 -39.2531 -0 -loc2 -6.59642 -34.3759 -0
+vanimation anim/a/59 -start 1.8125 -dur 0.03125 -objectTrsf a -rot1 0 0 0.104746 0.994499 -rot2 0 0 0.0887369 0.996055 -loc1 -6.59642 -34.3759 -0 -loc2 -4.60486 -29.1677 -0
+vanimation anim/a/60 -start 1.84375 -dur 0.03125 -objectTrsf a -rot1 0 0 0.0887369 0.996055 -rot2 0 0 0.0719395 0.997409 -loc1 -4.60486 -29.1677 -0 -loc2 -2.95964 -23.6785 -0
+vanimation anim/a/61 -start 1.875 -dur 0.03125 -objectTrsf a -rot1 0 0 0.0719395 0.997409 -rot2 0 0 0.0545094 0.998513 -loc1 -2.95964 -23.6785 -0 -loc2 -1.67027 -17.9614 -0
+vanimation anim/a/62 -start 1.90625 -dur 0.03125 -objectTrsf a -rot1 0 0 0.0545094 0.998513 -rot2 0 0 0.036604 0.99933 -loc1 -1.67027 -17.9614 -0 -loc2 -0.744076 -12.0712 -0
+vanimation anim/a/63 -start 1.9375 -dur 0.03125 -objectTrsf a -rot1 0 0 0.036604 0.99933 -rot2 0 0 0.0183813 0.999831 -loc1 -0.744076 -12.0712 -0 -loc2 -0.186279 -6.06481 -0
+vanimation anim/a/64 -start 1.96875 -dur 0.03125 -objectTrsf a -rot1 0 0 0.0183813 0.999831 -rot2 0 0 4.59243e-17 1 -loc1 -0.186279 -6.06481 -0 -loc2 3.79627e-31 -1.5155e-14 -0
+
+# take screenshots in non-interactive mode
+for {set i 0} {$i <= 10} {incr i} { vanimation anim -play [expr 2.0 * $i / 10] 0; set anIndex [format "%02d" $i]; vdump $imagedir/${casename}_$anIndex.png }
+
+puts "Put the following command to start interactive animation:"
+puts " vanimation anim -play -playSpeed 0.2"
--- /dev/null
+puts "=================================="
+puts "Viewer animation - rotate the view camera"
+puts "=================================="
+
+pload MODELING VISUALIZATION
+
+vclear
+vinit View1
+vaxo
+vzbufftrihedron
+
+box b1 -50 -50 0 100 100 100
+vdisplay -noupdate -dispMode 1 b1
+vfit -noupdate
+
+# Animation simulates the following rotation:
+# vrotate 2 0 0
+vanimation anim -clear
+vanimation anim/movecam -view -at1 0 0 50 -at2 0 0 50 -eye1 100 -100 150 -eye2 -153 -70 8 -duration 3
+
+vanimation anim -play 0.0 0.0
+if {[vreadpixel 306 280 rgb name] != "DARKGOLDENROD3" || [vreadpixel 325 280 rgb name] != "DARKGOLDENROD3"} { puts "Error: Camera rotate result is wrong!" }
+vdump $imagedir/${casename}_0.png
+
+vanimation anim -play 1.0 0.0
+if {[vreadpixel 306 280 rgb name] != "DARKORANGE4" || [vreadpixel 325 280 rgb name] != "BLACK"} { puts "Error: Camera rotate result is wrong!" }
+vdump $imagedir/${casename}_1.png
+
+vanimation anim -play 2.0 0.0
+if {[vreadpixel 306 280 rgb name] != "GOLDENROD2" || [vreadpixel 325 280 rgb name] != "GOLDENROD2"} { puts "Error: Camera rotate result is wrong!" }
+vdump $imagedir/${casename}_2.png
+
+puts "Put the following command to start interactive animation:"
+puts " vanimation anim -play"
--- /dev/null
+puts "=================================="
+puts "Viewer animation - scale the view camera"
+puts "=================================="
+
+pload MODELING VISUALIZATION
+
+vclear
+vinit View1
+vaxo
+vzbufftrihedron
+
+box b1 -50 -50 0 100 100 100
+vdisplay -noupdate -dispMode 1 b1
+vfit -noupdate
+vzoom 0.2
+
+vanimation anim -clear
+vanimation anim/zoom -view -scale1 1.2 -scale2 4.8 -duration 2
+
+vanimation anim -play 0.0 0.0
+if {[vreadpixel 230 220 rgb name] != "DARKGOLDENROD3" || [vreadpixel 250 220 rgb name] != "BLACK"} { puts "Error: Camera scale result is wrong!" }
+vdump $imagedir/${casename}_0.png
+
+vanimation anim -play 1.0 0.0
+if {[vreadpixel 250 220 rgb name] != "DARKGOLDENROD3" || [vreadpixel 270 220 rgb name] != "BLACK"} { puts "Error: Camera scale result is wrong!" }
+vdump $imagedir/${casename}_1.png
+
+vanimation anim -play 2.0 0.0
+if {[vreadpixel 334 220 rgb name] != "DARKGOLDENROD3" || [vreadpixel 350 220 rgb name] != "BLACK"} { puts "Error: Camera scale result is wrong!" }
+vdump $imagedir/${casename}_2.png
+
+puts "Put the following command to start interactive animation:"
+puts " vanimation anim -play"
--- /dev/null
+puts "=================================="
+puts "Viewer animation - translate the view camera"
+puts "=================================="
+
+pload MODELING VISUALIZATION
+
+vclear
+vinit View1
+vaxo
+vzbufftrihedron -position right_lower
+
+box b1 -50 -50 0 100 100 100
+vdisplay -noupdate -dispMode 1 b1
+vviewparams -scale 1.156 -up -0.3588 0.3458 0.867 -at 116 355 327 -eye 225 253 413
+
+# Animation simulates the following panning:
+# vpan 200 0
+# vviewparams -scale 1.156 -up -0.3588 0.3458 0.867 -at -174 47 330 -eye -65 -55 415
+vanimation anim -clear
+vanimation anim/movecam -view -at1 116 355 327 -at2 -174 47 330 -eye1 225 253 413 -eye2 -65 -55 415 -duration 2
+
+vanimation anim -play 0.0 0.0
+if {[vreadpixel 60 360 rgb name] != "GOLDENROD3"} { puts "Error: Camera translation result is wrong!" }
+vdump $imagedir/${casename}_0.png
+
+vanimation anim -play 1.0 0.0
+if {[vreadpixel 160 360 rgb name] != "GOLDENROD3"} { puts "Error: Camera translation result is wrong!" }
+vdump $imagedir/${casename}_1.png
+
+vanimation anim -play 2.0 0.0
+if {[vreadpixel 260 360 rgb name] != "GOLDENROD3"} { puts "Error: Camera translation result is wrong!" }
+vdump $imagedir/${casename}_2.png
+
+puts "Put the following command to start interactive animation:"
+puts " vanimation anim -play"
-catch { vfit }
+if { [info exists subgroup] && $subgroup != "motion" && $subgroup != "ivtk" } {
+ catch { vfit }
+}
if { [info exists subgroup] && $subgroup == "raytrace" } {
# dump final image for raytraced visualization tests
017 mesh
018 point_cloud
019 manipulator
+020 anim
vfit
vrenderparams -rayTrace -reflections
-vlocrotate res 0 0 0 0 0 1 180
+vlocation res -rotate 0 0 0 0 0 1 180
vfit