/*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkTemporalShiftScale.cxx,v $ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm 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 "vtkTemporalShiftScale.h" #include "vtkTemporalDataSet.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkObjectFactory.h" #include "vtkStreamingDemandDrivenPipeline.h" vtkCxxRevisionMacro(vtkTemporalShiftScale, "$Revision: 1.4 $"); vtkStandardNewMacro(vtkTemporalShiftScale); //---------------------------------------------------------------------------- vtkTemporalShiftScale::vtkTemporalShiftScale() { this->Shift = 0; this->Scale = 1; } //---------------------------------------------------------------------------- vtkTemporalShiftScale::~vtkTemporalShiftScale() { } //---------------------------------------------------------------------------- void vtkTemporalShiftScale::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os,indent); os << indent << "Scale: " << this->Scale << endl; os << indent << "Shift: " << this->Shift << endl; } //---------------------------------------------------------------------------- // Change the information int vtkTemporalShiftScale::RequestInformation ( vtkInformation * vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *outputVector) { // get the info objects vtkInformation *outInfo = outputVector->GetInformationObject(0); vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); if (inInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_STEPS())) { double *inTimes = inInfo->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS()); int numTimes = inInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS()); double *outTimes = new double [numTimes]; int i; for (i = 0; i < numTimes; ++i) { outTimes[i] = inTimes[i]*this->Scale+this->Shift; } outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(), outTimes,numTimes); delete [] outTimes; } if (inInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_RANGE())) { double *inRange = inInfo->Get(vtkStreamingDemandDrivenPipeline::TIME_RANGE()); double outRange[2]; outRange[0] = inRange[0]*this->Scale+this->Shift; outRange[1] = inRange[1]*this->Scale+this->Shift; outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(), outRange,2); } return 1; } //---------------------------------------------------------------------------- // This method simply copies by reference the input data to the output. int vtkTemporalShiftScale::RequestData( vtkInformation *vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *outputVector) { vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); vtkInformation *outInfo = outputVector->GetInformationObject(0); vtkTemporalDataSet *inData = vtkTemporalDataSet::SafeDownCast (inInfo->Get(vtkDataObject::DATA_OBJECT())); vtkTemporalDataSet *outData = vtkTemporalDataSet::SafeDownCast (outInfo->Get(vtkDataObject::DATA_OBJECT())); // shallow copy the data if (inData && outData) { outData->ShallowCopy(inData); } #if 0 // fill in the time steps int inLength = inData->GetInformation()->Length(vtkDataObject::DATA_TIME_STEPS()); double *inTimes = inData->GetInformation()->Get(vtkDataObject::DATA_TIME_STEPS()); double *outTimes = new double [inLength]; int i; for (i = 0; i < inLength; ++i) { outTimes[i] = inTimes[i]*this->Scale + this->Shift; } outData->GetInformation()->Set(vtkDataObject::DATA_TIME_STEPS(), outTimes, inLength); delete [] outTimes; // adjust the time steps of the internal data for (i = 0; i < (int)outData->GetNumberOfTimeSteps(); i++) { vtkInformation *dataInfo = outData->GetDataSet(i, 0)->GetInformation(); int numtimes = dataInfo->Length(vtkDataObject::DATA_TIME_STEPS()); double *times = dataInfo->Get(vtkDataObject::DATA_TIME_STEPS()); for (int j = 0; j < numtimes; j++) { times[j] = times[j]*this->Scale + this->Shift; } } #else this->AdjustDataTime(outData); #endif return 1; } //---------------------------------------------------------------------------- int vtkTemporalShiftScale::RequestUpdateExtent ( vtkInformation * vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *outputVector) { // get the info objects vtkInformation* outInfo = outputVector->GetInformationObject(0); vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); // reverse trnslate the times if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS())) { double *upTimes = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS()); int numTimes = outInfo->Length(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS()); double *inTimes = new double [numTimes]; int i; for (i = 0; i < numTimes; ++i) { inTimes[i] = (upTimes[i] - this->Shift)/this->Scale; } inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS(), inTimes,numTimes); delete [] inTimes; } return 1; } //----------------------------------------------------------------------------- void vtkTemporalShiftScale::AdjustDataTime(vtkDataObject *obj) { vtkInformation *dataInfo = obj->GetInformation(); // Get the time of the original data. int numTimeSteps = dataInfo->Length(vtkDataObject::DATA_TIME_STEPS()); double *inTimes = dataInfo->Get(vtkDataObject::DATA_TIME_STEPS()); double *outTimes = new double[numTimeSteps]; for (int i = 0; i < numTimeSteps; i++) { outTimes[i] = inTimes[i]*this->Scale + this->Shift; } dataInfo->Set(vtkDataObject::DATA_TIME_STEPS(), outTimes, numTimeSteps); delete[] outTimes; // If the data object is a group data set, recurse to all contained data // objects. Note that we do not recurse into any vtkCompositeDataSet that // is not a vtkMultiGroupDataSet. This is because the interface to // vtkCompositeDataSet does not let us switch out the data sets, which we // need to do to safely change the data time. vtkMultiGroupDataSet *multiDS = vtkMultiGroupDataSet::SafeDownCast(obj); if (multiDS) { unsigned int numGroups = multiDS->GetNumberOfGroups(); for (unsigned int group = 0; group < numGroups; group++) { unsigned int numDataSets = multiDS->GetNumberOfDataSets(group); for (unsigned int ds = 0; ds < numDataSets; ds++) { vtkDataObject *oldObj = multiDS->GetDataSet(group, ds); // When a vtkMultiGroupDataSet is shallow copied, it just copies // pointers to all the data objects within it. Thus, oldObj is just // points to the data object held higher up in the pipeline. If we // change the time of oldObj, it can mess up the time checking of the // pipeline wherever that object is shared. Instead, create a new // object and adjust the time of that. vtkDataObject *newObj = oldObj->NewInstance(); newObj->ShallowCopy(oldObj); this->AdjustDataTime(newObj); multiDS->SetDataSet(group, ds, newObj); newObj->Delete(); } } } }