Commit 89ddc062 authored by Shawn Waldon's avatar Shawn Waldon

Make extract timesteps only output the requested timesteps

It checks the time step requested and returns the "best fit" of the
requested timesteps.  There are some options for "best fit": nearest,
floor, and ceiling.
parent 55aee9b9
......@@ -22,12 +22,13 @@
#include <algorithm>
#include <vector>
#include <cmath>
vtkStandardNewMacro(vtkExtractTimeSteps);
vtkExtractTimeSteps::vtkExtractTimeSteps() :
UseRange(false), TimeStepInterval(1)
UseRange(false), TimeStepInterval(1), TimeEstimationMode(PREVIOUS_TIMESTEP)
{
this->Range[0] = 0;
this->Range[1] = 0;
......@@ -64,6 +65,19 @@ void vtkExtractTimeSteps::PrintSelf(ostream& os, vtkIndent indent)
os << indent << "Range: " << this->Range[0] << ", " << this->Range[1]
<< std::endl;
os << indent << "TimeStepInterval: " << this->TimeStepInterval << std::endl;
os << indent << "TimeEstimationMode: ";
switch (this->TimeEstimationMode)
{
case PREVIOUS_TIMESTEP:
os << "Previous Timestep" << std::endl;
break;
case NEXT_TIMESTEP:
os << "Next Timestep" << std::endl;
break;
case NEAREST_TIMESTEP:
os << "Nearest Timestep" << std::endl;
break;
}
}
//----------------------------------------------------------------------------
......@@ -100,6 +114,45 @@ void vtkExtractTimeSteps::GenerateTimeStepIndices(int begin, int end, int step)
}
}
namespace
{
void getTimeSteps(vtkInformation* inInfo, const std::set<int>& timeStepIndices,
bool useRange, int* range, int timeStepInterval, std::vector<double>& outTimes)
{
double *inTimes =
inInfo->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
int numTimes =
inInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
if (!useRange)
{
for (std::set<int>::iterator it = timeStepIndices.begin();
it != timeStepIndices.end(); ++it)
{
if (*it >= 0 && *it < numTimes)
{
outTimes.push_back(inTimes[*it]);
}
}
}
else
{
for (int i = 0; i < numTimes; ++i)
{
if (i >= range[0] && i <= range[1])
{
if ((i - range[0]) % timeStepInterval == 0)
{
outTimes.push_back(inTimes[i]);
}
}
}
}
}
}
//----------------------------------------------------------------------------
int vtkExtractTimeSteps::RequestInformation(vtkInformation*,
vtkInformationVector **inputVector,
......@@ -112,47 +165,83 @@ int vtkExtractTimeSteps::RequestInformation(vtkInformation*,
if (!this->TimeStepIndices.empty() &&
inInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_STEPS()))
{
double *inTimes =
inInfo->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
int numTimes =
inInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
std::vector<double> outTimes;
if (!this->UseRange)
getTimeSteps(inInfo, this->TimeStepIndices, this->UseRange, this->Range, this->TimeStepInterval, outTimes);
if (!outTimes.empty())
{
for (std::set<int>::iterator it = this->TimeStepIndices.begin();
it != this->TimeStepIndices.end(); ++it)
{
if (*it >= 0 && *it < numTimes)
{
outTimes.push_back(inTimes[*it]);
}
}
outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(), &outTimes[0],
static_cast<int>(outTimes.size()));
double range[2] = { outTimes.front(), outTimes.back() };
outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(), range, 2);
}
}
return 1;
}
//----------------------------------------------------------------------------
int vtkExtractTimeSteps::RequestUpdateExtent(vtkInformation* vtkNotUsed(request),
vtkInformationVector **inputVector,
vtkInformationVector *outputVector)
{
vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
vtkInformation* outInfo = outputVector->GetInformationObject(0);
if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP()))
{
double updateTime =
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP());
std::vector<double> outTimes;
getTimeSteps(inInfo, this->TimeStepIndices, this->UseRange, this->Range, this->TimeStepInterval, outTimes);
double inputTime;
if (updateTime >= outTimes.back())
{
inputTime = outTimes.back();
}
else if (updateTime <= outTimes.front())
{
inputTime = outTimes.front();
}
else
{
for (int i = 0; i < numTimes; ++i)
auto gtindex = std::upper_bound(outTimes.begin(), outTimes.end(), updateTime);
auto leindex = gtindex - 1;
if (updateTime == *leindex)
{
inputTime = updateTime;
}
else
{
if (i >= this->Range[0] && i <= this->Range[1])
switch (this->TimeEstimationMode)
{
if ((i - this->Range[0]) % this->TimeStepInterval == 0)
default:
case PREVIOUS_TIMESTEP:
inputTime = *leindex;
break;
case NEXT_TIMESTEP:
inputTime = *gtindex;
break;
case NEAREST_TIMESTEP:
if (std::abs(updateTime - *leindex) <= std::abs(*gtindex - updateTime))
{
outTimes.push_back(inTimes[i]);
inputTime = *leindex;
}
else
{
inputTime = *gtindex;
}
break;
}
}
}
if (!outTimes.empty())
{
outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(), &outTimes[0],
static_cast<int>(outTimes.size()));
double range[2] = { outTimes.front(), outTimes.back() };
outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(), range, 2);
}
inInfo->Set(
vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP(), inputTime);
}
return 1;
}
......
......@@ -114,6 +114,26 @@ public:
vtkSetClampMacro(TimeStepInterval, int, 1, VTK_INT_MAX);
//@}
// What timestep to provide when the requested time is between the timesteps
// the filter is set to extract
enum {
PREVIOUS_TIMESTEP, // floor the time to the previous timestep
NEXT_TIMESTEP, // ceiling the time to the next timestep
NEAREST_TIMESTEP // take the timestep whose absolute difference from the requested time is smallest
} EstimationMode;
//@{
/**
* Get/Set what to do when the requested time is not one of the timesteps this filter
* is set to extract. Should be one of the values of the enum vtkExtractTimeSteps::EstimationMode.
* The default is PREVIOUS_TIMESTEP.
*/
vtkGetMacro(TimeEstimationMode, int);
vtkSetMacro(TimeEstimationMode, int);
void SetTimeEstimationModeToPrevious() { this->SetTimeEstimationMode(PREVIOUS_TIMESTEP); }
void SetTimeEstimationModeToNext() { this->SetTimeEstimationMode(NEXT_TIMESTEP); }
void SetTimeEstimationModeToNearest() { this->SetTimeEstimationMode(NEAREST_TIMESTEP); }
//@}
protected:
vtkExtractTimeSteps();
~vtkExtractTimeSteps()VTK_OVERRIDE {};
......@@ -122,12 +142,14 @@ protected:
vtkInformationVector *) VTK_OVERRIDE;
int RequestInformation(vtkInformation *, vtkInformationVector **,
vtkInformationVector *) VTK_OVERRIDE;
int RequestUpdateExtent(vtkInformation *, vtkInformationVector **,
vtkInformationVector *) VTK_OVERRIDE;
std::set<int> TimeStepIndices;
bool UseRange;
int Range[2];
int TimeStepInterval;
int TimeEstimationMode;
private:
vtkExtractTimeSteps(const vtkExtractTimeSteps&) VTK_DELETE_FUNCTION;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment