mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
268 lines
9.2 KiB
C++
268 lines
9.2 KiB
C++
/*=========================================================================
|
|
|
|
Program: ParaView
|
|
Module: $RCSfile$
|
|
|
|
Copyright (c) Kitware, Inc.
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
#include "vtkSMAnimationSceneProxy.h"
|
|
|
|
#include "vtkCompositeAnimationPlayer.h"
|
|
#include "vtkNew.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPVXMLElement.h"
|
|
#include "vtkSMAnimationScene.h"
|
|
#include "vtkSMParaViewPipelineController.h"
|
|
#include "vtkSMPropertyHelper.h"
|
|
#include "vtkSMProxyIterator.h"
|
|
#include "vtkSMTimeKeeperProxy.h"
|
|
#include "vtkSMTrace.h"
|
|
#include "vtkVector.h"
|
|
|
|
namespace
|
|
{
|
|
// This is a terrible way to address BUG #0015407. What's happening is that
|
|
// when state is being loaded the timekeeper gets updated timesteps which are
|
|
// then correctly propagated to the animation scene, which then, correctly (I
|
|
// might add) updates the start and end times. However all this happends
|
|
// before the "EndTime"/"StartTime" properties from the XML state are loaded.
|
|
// Hence they get set and loose the values just updated by the application,
|
|
// instead use the old values from the state files.
|
|
// This function will prune the EndTime/StartTime XML elements from the state
|
|
// being loaded if they should not be loaded.
|
|
void PruneEndTimesIfNeeded(vtkPVXMLElement* element, vtkSMAnimationScene* self)
|
|
{
|
|
vtkPVXMLElement* startTimeElement = NULL;
|
|
vtkPVXMLElement* endTimeElement = NULL;
|
|
int playMode = self? self->GetPlayMode() : vtkCompositeAnimationPlayer::SEQUENCE ;
|
|
int lockEndTime = self? (self->GetLockEndTime()? 1 : 0) : 0;
|
|
int lockStartTime = self? (self->GetLockStartTime()? 1 : 0) : 0;
|
|
for (unsigned int cc=0, max = element->GetNumberOfNestedElements(); cc < max; cc++)
|
|
{
|
|
vtkPVXMLElement* cur = element->GetNestedElement(cc);
|
|
if (cur && cur->GetName() &&
|
|
strcmp(cur->GetName(), "Property") == 0)
|
|
{
|
|
const char* name = cur->GetAttributeOrDefault("name", "");
|
|
if (strcmp(name, "EndTime") == 0)
|
|
{
|
|
endTimeElement = cur;
|
|
}
|
|
else if (strcmp(name, "StartTime") == 0)
|
|
{
|
|
startTimeElement = cur;
|
|
}
|
|
else if (strcmp(name, "PlayMode") == 0)
|
|
{
|
|
if (vtkPVXMLElement* valueElem = cur->FindNestedElementByName("Element"))
|
|
{
|
|
valueElem->GetScalarAttribute("value", &playMode);
|
|
}
|
|
}
|
|
else if (strcmp(name, "LockEndTime") == 0)
|
|
{
|
|
if (vtkPVXMLElement* valueElem = cur->FindNestedElementByName("Element"))
|
|
{
|
|
valueElem->GetScalarAttribute("value", &lockEndTime);
|
|
}
|
|
}
|
|
else if (strcmp(name, "LockStartTime") == 0)
|
|
{
|
|
if (vtkPVXMLElement* valueElem = cur->FindNestedElementByName("Element"))
|
|
{
|
|
valueElem->GetScalarAttribute("value", &lockStartTime);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (playMode == vtkCompositeAnimationPlayer::SNAP_TO_TIMESTEPS)
|
|
{
|
|
if (lockStartTime != 1 && startTimeElement)
|
|
{
|
|
element->RemoveNestedElement(startTimeElement);
|
|
}
|
|
if (lockEndTime != 1 && endTimeElement)
|
|
{
|
|
element->RemoveNestedElement(endTimeElement);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
vtkStandardNewMacro(vtkSMAnimationSceneProxy);
|
|
//----------------------------------------------------------------------------
|
|
vtkSMAnimationSceneProxy::vtkSMAnimationSceneProxy()
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkSMAnimationSceneProxy::~vtkSMAnimationSceneProxy()
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMAnimationSceneProxy::CreateVTKObjects()
|
|
{
|
|
if (this->ObjectsCreated)
|
|
{
|
|
return;
|
|
}
|
|
this->Superclass::CreateVTKObjects();
|
|
if (vtkObject* object = vtkObject::SafeDownCast(this->GetClientSideObject()))
|
|
{
|
|
object->AddObserver(vtkSMAnimationScene::UpdateStartEndTimesEvent,
|
|
this, &vtkSMAnimationSceneProxy::OnUpdateStartEndTimesEvent);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMAnimationSceneProxy::OnUpdateStartEndTimesEvent(
|
|
vtkObject* object, unsigned long, void* calldata)
|
|
{
|
|
const vtkVector2d &range = *(reinterpret_cast<vtkVector2d*>(calldata));
|
|
vtkSMAnimationScene* caller = vtkSMAnimationScene::SafeDownCast(object);
|
|
assert(caller == this->GetClientSideObject());
|
|
|
|
vtkSMPropertyHelper startTime(this, "StartTime");
|
|
vtkSMPropertyHelper endTime(this, "EndTime");
|
|
vtkVector2d newRange(startTime.GetAsDouble(0), endTime.GetAsDouble(0));
|
|
if (!caller->GetLockStartTime())
|
|
{
|
|
newRange.SetX(range.GetX());
|
|
}
|
|
if (!caller->GetLockEndTime())
|
|
{
|
|
newRange.SetY(range.GetY());
|
|
}
|
|
startTime.Set(newRange.GetX());
|
|
endTime.Set(newRange.GetY());
|
|
// XXX: What to do if the start or end time was locked and the suggested start
|
|
// or end time would make the range invalid?
|
|
this->UpdateVTKObjects();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkSMAnimationSceneProxy::UpdateAnimationUsingDataTimeSteps()
|
|
{
|
|
vtkSMProxy* timeKeeper = vtkSMPropertyHelper(this, "TimeKeeper").GetAsProxy();
|
|
if (!timeKeeper)
|
|
{
|
|
vtkWarningMacro("Failed to locate TimeKeeper proxy.");
|
|
return false;
|
|
}
|
|
|
|
SM_SCOPED_TRACE(CallMethodIfPropertiesModified)
|
|
.arg("proxy", this)
|
|
.arg("methodname", "UpdateAnimationUsingDataTimeSteps")
|
|
.arg("comment", "update animation scene based on data timesteps");
|
|
|
|
bool using_snap_to_timesteps_mode = false;
|
|
vtkSMPropertyHelper timestepsHelper(timeKeeper, "TimestepValues");
|
|
if (timestepsHelper.GetNumberOfElements() > 1)
|
|
{
|
|
vtkSMPropertyHelper(this, "PlayMode").Set(vtkCompositeAnimationPlayer::SNAP_TO_TIMESTEPS);
|
|
using_snap_to_timesteps_mode = true;
|
|
}
|
|
else
|
|
{
|
|
vtkSMPropertyHelper playmodeHelper(this, "PlayMode");
|
|
if (playmodeHelper.GetAsInt() == vtkCompositeAnimationPlayer::SNAP_TO_TIMESTEPS)
|
|
{
|
|
playmodeHelper.Set(vtkCompositeAnimationPlayer::SEQUENCE);
|
|
}
|
|
}
|
|
|
|
this->UpdateVTKObjects();
|
|
// This will internally adjust the Start and End times for the animation scene
|
|
// based of the Locks for the times. We not simply need to copy the info
|
|
// property values.
|
|
|
|
/// If the animation time is not in the scene time range, set it to the min
|
|
/// value.
|
|
double minTime = vtkSMPropertyHelper(this, "StartTime").GetAsDouble();
|
|
double maxTime = vtkSMPropertyHelper(this, "EndTime").GetAsDouble();
|
|
double animationTime = vtkSMPropertyHelper(this, "AnimationTime").GetAsDouble();
|
|
if (animationTime < minTime || animationTime > maxTime)
|
|
{
|
|
vtkSMPropertyHelper(this, "AnimationTime").Set(minTime);
|
|
}
|
|
else if (using_snap_to_timesteps_mode)
|
|
{
|
|
// BUG #15060. When using SNAP_TO_TIMESTEPS mode, ensure that the timestep
|
|
// is "snapped".
|
|
vtkSMPropertyHelper(this, "AnimationTime").Set(
|
|
vtkSMTimeKeeperProxy::GetLowerBoundTimeStep(timeKeeper, animationTime));
|
|
}
|
|
this->UpdateVTKObjects();
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkSMProxy* vtkSMAnimationSceneProxy::FindAnimationCue(
|
|
vtkSMProxy* animatedProxy, const char* animatedPropertyName)
|
|
{
|
|
if (!animatedProxy || !animatedPropertyName)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
vtkSMPropertyHelper cuesHelper(this, "Cues");
|
|
for (unsigned int cc=0, max = cuesHelper.GetNumberOfElements(); cc<max; ++cc)
|
|
{
|
|
vtkSMProxy* cueProxy = cuesHelper.GetAsProxy(cc);
|
|
if (cueProxy)
|
|
{
|
|
vtkSMPropertyHelper proxyHelper(cueProxy, "AnimatedProxy");
|
|
if (proxyHelper.GetAsProxy() == animatedProxy)
|
|
{
|
|
vtkSMPropertyHelper pnameHelper(cueProxy, "AnimatedPropertyName");
|
|
if (pnameHelper.GetAsString() &&
|
|
strcmp(animatedPropertyName, pnameHelper.GetAsString()) == 0)
|
|
{
|
|
return cueProxy;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check if we're animating a helper proxy on the proxy.
|
|
std::string groupname =
|
|
vtkSMParaViewPipelineController::GetHelperProxyGroupName(animatedProxy);
|
|
|
|
vtkNew<vtkSMProxyIterator> iter;
|
|
iter->SetSessionProxyManager(animatedProxy->GetSessionProxyManager());
|
|
iter->SetModeToOneGroup();
|
|
for (iter->Begin(groupname.c_str()); !iter->IsAtEnd(); iter->Next())
|
|
{
|
|
vtkSMProxy* cue = this->FindAnimationCue(iter->GetProxy(), animatedPropertyName);
|
|
if (cue)
|
|
{
|
|
return cue;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkSMAnimationSceneProxy::LoadXMLState(
|
|
vtkPVXMLElement* element, vtkSMProxyLocator* locator)
|
|
{
|
|
PruneEndTimesIfNeeded(element,
|
|
(this->ObjectsCreated?
|
|
vtkSMAnimationScene::SafeDownCast(this->GetClientSideObject()): NULL));
|
|
return this->Superclass::LoadXMLState(element, locator);;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMAnimationSceneProxy::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
}
|