From ce3e6527f2f1abdb72cf34959606e10dbb63869d Mon Sep 17 00:00:00 2001 From: Utkarsh Ayachit <utkarsh.ayachit@kitware.com> Date: Wed, 3 Apr 2019 11:40:40 -0400 Subject: [PATCH] vtkAlgorithm: progress shift/scale vtkAlgorithm now supports ability to specify values for shifting and scaling progress. This enables internal vtkAlgorithm instances to report progress for part of the work without too much work. Also allows vtkCompositeDataPipeline to report progress was each iteration over the composite dataset as a part of the whole rather than having the progress be from [0, 1.0] for each block in the composite dataset. --- Common/ExecutionModel/vtkAlgorithm.cxx | 44 +++++++++++++------ Common/ExecutionModel/vtkAlgorithm.h | 30 ++++++++++++- .../vtkCompositeDataPipeline.cxx | 17 ++++++- IO/NetCDF/vtkNetCDFCAMReader.cxx | 8 ++-- Imaging/Stencil/vtkLassoStencilSource.cxx | 6 +-- 5 files changed, 81 insertions(+), 24 deletions(-) diff --git a/Common/ExecutionModel/vtkAlgorithm.cxx b/Common/ExecutionModel/vtkAlgorithm.cxx index 577fa317ebd..e7b4f957c9d 100644 --- a/Common/ExecutionModel/vtkAlgorithm.cxx +++ b/Common/ExecutionModel/vtkAlgorithm.cxx @@ -19,6 +19,7 @@ #include "vtkCollection.h" #include "vtkCollectionIterator.h" #include "vtkCommand.h" +#include "vtkCompositeDataPipeline.h" #include "vtkDataArray.h" #include "vtkDataObject.h" #include "vtkDataSet.h" @@ -27,25 +28,26 @@ #include "vtkGarbageCollector.h" #include "vtkGraph.h" #include "vtkHyperTreeGrid.h" -#include "vtkInformation.h" #include "vtkInformationExecutivePortKey.h" #include "vtkInformationExecutivePortVectorKey.h" +#include "vtkInformation.h" #include "vtkInformationInformationVectorKey.h" #include "vtkInformationIntegerKey.h" #include "vtkInformationStringKey.h" #include "vtkInformationStringVectorKey.h" #include "vtkInformationVector.h" +#include "vtkMath.h" +#include "vtkNew.h" #include "vtkObjectFactory.h" #include "vtkPointData.h" #include "vtkProgressObserver.h" #include "vtkSmartPointer.h" -#include "vtkCompositeDataPipeline.h" #include "vtkTable.h" #include "vtkTrivialProducer.h" -#include "vtkNew.h" #include <set> #include <vector> +#include <vtksys/SystemTools.hxx> vtkStandardNewMacro(vtkAlgorithm); @@ -98,6 +100,8 @@ vtkAlgorithm::vtkAlgorithm() this->Information = vtkInformation::New(); this->Information->Register(this); this->Information->Delete(); + this->ProgressShift = 0.0; + this->ProgressScale = 1.0; } //---------------------------------------------------------------------------- @@ -141,12 +145,25 @@ void vtkAlgorithm::SetProgressObserver(vtkProgressObserver* po) } } +//---------------------------------------------------------------------------- +void vtkAlgorithm::SetProgressShiftScale(double shift, double scale) +{ + this->ProgressShift = shift; + this->ProgressScale = scale; +} + //---------------------------------------------------------------------------- // Update the progress of the process object. If a ProgressMethod exists, // executes it. Then set the Progress ivar to amount. The parameter amount // should range between (0,1). void vtkAlgorithm::UpdateProgress(double amount) { + amount = this->GetProgressShift() + this->GetProgressScale() * amount; + + // clamp to [0, 1]. + amount = vtkMath::Min(amount, 1.0); + amount = vtkMath::Max(amount, 0.0); + if (this->ProgressObserver) { this->ProgressObserver->UpdateProgress(amount); @@ -158,7 +175,6 @@ void vtkAlgorithm::UpdateProgress(double amount) } } - //---------------------------------------------------------------------------- vtkInformation *vtkAlgorithm ::GetInputArrayFieldInformation(int idx, vtkInformationVector **inputVector) @@ -1732,16 +1748,7 @@ void vtkAlgorithm::SetProgressText(const char* ptext) return; } delete[] this->ProgressText; - this->ProgressText = nullptr; - - if (ptext) - { - size_t n = strlen(ptext) + 1; - char *cp1 = new char[n]; - const char *cp2 = ptext; - this->ProgressText = cp1; - do { *cp1++ = *cp2++; } while ( --n ); - } + this->ProgressText = vtksys::SystemTools::DuplicateString(ptext); } // This is here to shut off warnings about deprecated functions @@ -1877,3 +1884,12 @@ void vtkAlgorithm::AddInputDataObject(int port, vtkDataObject *input) tp->Delete(); } } + +//---------------------------------------------------------------------------- +#if !defined(VTK_LEGACY_REMOVE) +void vtkAlgorithm::SetProgress(double val) +{ + VTK_LEGACY_REPLACED_BODY(vtkAlgorithm::SetProgress, "VTK 8.3", vtkAlgorithm::UpdateProgress); + this->UpdateProgress(val); +} +#endif diff --git a/Common/ExecutionModel/vtkAlgorithm.h b/Common/ExecutionModel/vtkAlgorithm.h index 59c975f663e..e58bebde84f 100644 --- a/Common/ExecutionModel/vtkAlgorithm.h +++ b/Common/ExecutionModel/vtkAlgorithm.h @@ -213,12 +213,17 @@ public: //@{ /** - * Set/Get the execution progress of a process object. + * Get the execution progress of a process object. */ - vtkSetClampMacro(Progress,double,0.0,1.0); vtkGetMacro(Progress,double); //@} + /** + * `SetProgress` is deprecated. Subclasses should use `UpdateProgress` to + * report progress updates. + */ + VTK_LEGACY(void SetProgress(double)); + /** * Update the progress of the process object. If a ProgressMethod exists, * executes it. Then set the Progress ivar to amount. The parameter amount @@ -226,6 +231,24 @@ public: */ void UpdateProgress(double amount); + //@{ + /** + * Specify the shift and scale values to use to apply to the progress amount + * when `UpdateProgress` is called. By default shift is set to 0, and scale is + * set to 1.0. This is useful when the vtkAlgorithm instance is used as an + * internal algorithm to solve only a part of a whole problem. + * + * If calling on a internal vtkAlgorithm, make sure you take into + * consideration that values set of the outer vtkAlgorithm as well since the + * outer vtkAlgorithm itself may be nested in another algorithm. + * + * @note SetProgressShiftScale does not modify the MTime of the algorithm. + */ + void SetProgressShiftScale(double shift, double scale); + vtkGetMacro(ProgressShift, double); + vtkGetMacro(ProgressScale, double); + //@} + //@{ /** * Set the current text message associated with the progress state. @@ -937,6 +960,9 @@ private: private: vtkAlgorithm(const vtkAlgorithm&) = delete; void operator=(const vtkAlgorithm&) = delete; + + double ProgressShift; + double ProgressScale; }; #endif diff --git a/Common/ExecutionModel/vtkCompositeDataPipeline.cxx b/Common/ExecutionModel/vtkCompositeDataPipeline.cxx index 07efe655e77..cb257ae8266 100644 --- a/Common/ExecutionModel/vtkCompositeDataPipeline.cxx +++ b/Common/ExecutionModel/vtkCompositeDataPipeline.cxx @@ -281,13 +281,26 @@ void vtkCompositeDataPipeline::ExecuteEach(vtkCompositeDataIterator* iter, vtkInformation* request, std::vector<vtkSmartPointer<vtkCompositeDataSet>>& compositeOutputs) { - vtkInformation* inInfo =inInfoVec[compositePort]->GetInformationObject(connection); + vtkInformation* inInfo = inInfoVec[compositePort]->GetInformationObject(connection); + vtkIdType num_blocks = 0; + // a quick iteration to get the total number of blocks to iterate over which + // is necessary to scale progress events. for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem()) + { + ++num_blocks; + } + + const double progress_scale = 1.0 / num_blocks; + vtkIdType block_index = 0; + + auto algo = this->GetAlgorithm(); + for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem(), ++block_index) { vtkDataObject* dobj = iter->GetCurrentDataObject(); if (dobj) { + algo->SetProgressShiftScale(progress_scale * block_index, progress_scale); // Note that since VisitOnlyLeaves is ON on the iterator, // this method is called only for leaves, hence, we are assured that // neither dobj nor outObj are vtkCompositeDataSet subclasses. @@ -309,6 +322,8 @@ void vtkCompositeDataPipeline::ExecuteEach(vtkCompositeDataIterator* iter, } } } + + algo->SetProgressShiftScale(0.0, 1.0); } //---------------------------------------------------------------------------- diff --git a/IO/NetCDF/vtkNetCDFCAMReader.cxx b/IO/NetCDF/vtkNetCDFCAMReader.cxx index 784bdd9300a..a4175a40d86 100644 --- a/IO/NetCDF/vtkNetCDFCAMReader.cxx +++ b/IO/NetCDF/vtkNetCDFCAMReader.cxx @@ -581,7 +581,7 @@ int vtkNetCDFCAMReader::RequestData( outInfo->Get(vtkDataObject::DATA_OBJECT())); vtkDebugMacro(<<"Reading NetCDF CAM file."); - this->SetProgress(0); + this->UpdateProgress(0); if(this->CurrentConnectivityFileName != nullptr && strcmp(this->CurrentConnectivityFileName, this->ConnectivityFileName) != 0) { @@ -715,7 +715,7 @@ int vtkNetCDFCAMReader::RequestData( points->SetPoint(static_cast<vtkIdType>(i), array[i], array[i+numFilePoints], numLevels - 1); } } - this->SetProgress(.25); // educated guess for progress + this->UpdateProgress(.25); // educated guess for progress // now read in the cell connectivity. note that this is a periodic // domain and only the points on the left boundary are included in @@ -896,7 +896,7 @@ int vtkNetCDFCAMReader::RequestData( points->Modified(); points->Squeeze(); - this->SetProgress(.5); // educated guess for progress + this->UpdateProgress(.5); // educated guess for progress // Collect the time step requested vtkInformationDoubleKey* timeKey = @@ -1124,7 +1124,7 @@ int vtkNetCDFCAMReader::RequestData( output->GetPointData()->AddArray(levelPointData); } - this->SetProgress(.75); // educated guess for progress + this->UpdateProgress(.75); // educated guess for progress // now we actually create the cells if(this->VerticalDimension == VERTICAL_DIMENSION_SINGLE_LAYER || diff --git a/Imaging/Stencil/vtkLassoStencilSource.cxx b/Imaging/Stencil/vtkLassoStencilSource.cxx index 349268fd3ae..756c0269a8a 100644 --- a/Imaging/Stencil/vtkLassoStencilSource.cxx +++ b/Imaging/Stencil/vtkLassoStencilSource.cxx @@ -527,7 +527,7 @@ int vtkLassoStencilSource::RequestData( while (iter != maxiter && result != 0) { - this->SetProgress((slabExtent[2*zj] - zmin)*1.0/(zmax - zmin + 1)); + this->UpdateProgress((slabExtent[2*zj] - zmin)*1.0/(zmax - zmin + 1)); int i = iter->first; vtkPoints *points = iter->second; @@ -558,7 +558,7 @@ int vtkLassoStencilSource::RequestData( ++iter; } - this->SetProgress((slabExtent[2*zj] - zmin)*1.0/(zmax - zmin + 1)); + this->UpdateProgress((slabExtent[2*zj] - zmin)*1.0/(zmax - zmin + 1)); // fill in the rest if (result && slabExtent[2*zj] <= zmax) @@ -569,7 +569,7 @@ int vtkLassoStencilSource::RequestData( this->Points, data, &raster, slabExtent, origin, spacing, this->Shape, xj, yj, this->SplineX, this->SplineY); - this->SetProgress(1.0); + this->UpdateProgress(1.0); } return result; -- GitLab