[vtkusers] Wiki example: Progress report of a filter

Roman Grothausmann roman.grothausmann at helmholtz-berlin.de
Tue Mar 16 05:39:05 EDT 2010


Dear mailing list members,


I found that this example 
(http://www.cmake.org/Wiki/VTK/Examples/ProgressReport) needs a filter 
with a progress report. I used it for the code below using also the 
example for vtkDiscreteMarchingCubes.
I changed to a static_cast<vtkAlgorithm*> to be independent of the 
filter calling the progress function. Is that a proper way of doing this?

I also wonder if (in the code below) the writing of the writer/writer2 
executes vtkDiscreteMarchingCubes again?
How do I know how far a pipeline update goes up the pipeline?

Thanks for any help or hints on this.
Roman

//
// GenerateModelsFromLabels
//   Usage: GenerateModelsFromLabels InputVolume Startlabel Endlabel
//          where
//          InputVolume is a meta file containing a 3 volume of
//            discrete labels.
//          StartLabel is the first label to be processed
//          EndLabel is the last label to be processed
//          NOTE: There can be gaps in the labeling. If a label does
//          not exist in the volume, it will be skipped.
//
//
#include <vtkMetaImageReader.h>
#include <vtkImageAccumulate.h>
#include <vtkDiscreteMarchingCubes.h>
#include <vtkWindowedSincPolyDataFilter.h>
//#include <vtkMaskFields.h>
#include <vtkThreshold.h>
#include <vtkGeometryFilter.h>
#include <vtkXMLPolyDataWriter.h>
#include <vtkSmartPointer.h>
#include <vtkImageWrapPad.h>

#include <vtkCallbackCommand.h>
#include <vtkCommand.h>

#include <vtkImageData.h>
#include <vtkPointData.h>
#include <vtkUnstructuredGrid.h>
#include <vtksys/ios/sstream>


void ProgressFunction ( vtkObject* caller, long unsigned int eventId, 
void* clientData, void* callData )
     {
     //vtkDiscreteMarchingCubes *d= 
static_cast<vtkDiscreteMarchingCubes*>(caller);

     vtkAlgorithm *d= static_cast<vtkAlgorithm*>(caller);
     fprintf(stderr, "\rFilter progress: %5.1f%%", 100.0 * 
d->GetProgress());
     std::cerr.flush();

     }

int main (int argc, char *argv[])
     {
     if (argc < 4)
         {
         cout << "Usage: " << argv[0] << " InputVolume StartLabel 
EndLabel" << endl;
         return EXIT_FAILURE;
         }

     // Create all of the classes we will need
     vtkSmartPointer<vtkMetaImageReader> reader =
         vtkSmartPointer<vtkMetaImageReader>::New();
     vtkSmartPointer<vtkImageAccumulate> histogram =
         vtkSmartPointer<vtkImageAccumulate>::New();
     vtkSmartPointer<vtkDiscreteMarchingCubes> discreteCubes =
         vtkSmartPointer<vtkDiscreteMarchingCubes>::New();
     vtkSmartPointer<vtkWindowedSincPolyDataFilter> smoother =
         vtkSmartPointer<vtkWindowedSincPolyDataFilter>::New();
     vtkSmartPointer<vtkImageWrapPad> pad =
         vtkSmartPointer<vtkImageWrapPad>::New();
     vtkSmartPointer<vtkThreshold> selector =
         vtkSmartPointer<vtkThreshold>::New();
     vtkSmartPointer<vtkGeometryFilter> geometry =
         vtkSmartPointer<vtkGeometryFilter>::New();
     vtkSmartPointer<vtkXMLPolyDataWriter> writer =
         vtkSmartPointer<vtkXMLPolyDataWriter>::New();
     vtkSmartPointer<vtkXMLPolyDataWriter> writer2 =
         vtkSmartPointer<vtkXMLPolyDataWriter>::New();

     vtkSmartPointer<vtkCallbackCommand> progressCallback = 
vtkSmartPointer<vtkCallbackCommand>::New();
     progressCallback->SetCallback(ProgressFunction);


     // Define all of the variables
     unsigned int startLabel = atoi(argv[2]);
     unsigned int endLabel = atoi(argv[3]);
     vtkstd::string filePrefix = "Label";
     unsigned int smoothingIterations = 20;
     //double passBand = 0.001;
     //double featureAngle = 120.0;

     // Generate models from labels
     // 1) Read the meta file
     // 2) Generate a histogram of the labels
     // 3) Generate models from the labeled volume
     // 4) Smooth the models
     // 5) Output each model into a separate file

     reader->SetFileName(argv[1]);

     histogram->SetInput(reader->GetOutput());
     histogram->SetComponentExtent(0, endLabel, 0, 0, 0, 0);
     histogram->SetComponentOrigin(0, 0, 0);
     histogram->SetComponentSpacing(1, 1, 1);
     histogram->Update();


     int *extent = reader->GetOutput()->GetExtent();
     pad->SetInput(reader->GetOutput());
     pad->SetOutputWholeExtent(
         extent[0], extent[1] + 1,
         extent[2], extent[3] + 1,
         extent[4], extent[5] + 1);
     pad->Update();

     discreteCubes->SetInput(pad->GetOutput());
     discreteCubes->GenerateValues(
         endLabel - startLabel + 1, startLabel, endLabel);
     cout << "Executing discrete marching cubes..." << endl;
     discreteCubes->AddObserver(vtkCommand::ProgressEvent, 
progressCallback);
     discreteCubes->Update();

     cout << "\ndone." << endl;

     smoother->SetInput(discreteCubes->GetOutput());
     smoother->SetNumberOfIterations(smoothingIterations);
     //smoother->BoundarySmoothingOff();
     //smoother->FeatureEdgeSmoothingOff();
     //smoother->SetFeatureAngle(featureAngle);
     //smoother->SetPassBand(passBand);
     smoother->NonManifoldSmoothingOn(); //Smooth non-manifold vertices
     smoother->NormalizeCoordinatesOn();
     cout << "Executing windowed sinc smoothing..." << endl;
     smoother->AddObserver(vtkCommand::ProgressEvent, progressCallback);
     smoother->Update();

     cout << "\ndone." << endl;

     selector->SetInput(smoother->GetOutput());
     selector->SetInputArrayToProcess(0, 0, 0,
         vtkDataObject::FIELD_ASSOCIATION_CELLS,
         vtkDataSetAttributes::SCALARS); //choose on what to do the 
thresholding of the mesh!

     geometry->SetInput(selector->GetOutput()); //writer needs vtkPolyData
     writer->SetInput(geometry->GetOutput()); //writer needs vtkPolyData
     //writer->SetInput(selector->GetOutput()); //cannot write 
UnstructuredGrid
     writer2->SetInput(discreteCubes->GetOutput());

     for (unsigned int i = startLabel; i <= endLabel; i++)
         {
         // see if the label exists, if not skip it
         double frequency =
 
histogram->GetOutput()->GetPointData()->GetScalars()->GetTuple1(i);
         if (frequency == 0.0)
             {
             continue;
             }

         // select the cells for a given label
         selector->ThresholdBetween(i, i);

         // output the polydata
         vtksys_stl::stringstream ss;
         ss << filePrefix << i << "_smoothed.vtp";
         cout << "Converting and Writing " << ss.str() << endl;

         writer->SetFileName(ss.str().c_str());
         writer->AddObserver(vtkCommand::ProgressEvent, progressCallback);
         writer->Write();
         cout << "\ndone." << endl;

         vtksys_stl::stringstream ss2;
         ss2 << filePrefix << i << "_unsmoothed.vtp";
         cout << "Writing " << ss2.str() << endl;

         writer2->SetFileName(ss2.str().c_str());
         writer2->AddObserver(vtkCommand::ProgressEvent, progressCallback);
         writer2->Write();
         cout << "\ndone." << endl;

         }
     return EXIT_SUCCESS;
     }



-- 
Roman Grothausmann

Helmholtz-Zentrum Berlin für Materialien und Energie GmbH
Bereich Funktionale Materialien
Institut für angewandte Materialforschung
Hahn-Meitner-Platz 1
D-14109 Berlin	

Tel.: +49-(0)30-8062-2816
Fax.: +49-(0)30-8062-3059

Vorsitzender des Aufsichtsrats: Prof. Dr. Dr. h.c. mult. Joachim Treusch
Stellvertretende Vorsitzende: Dr. Beatrix Vierkorn-Rudolph
Geschäftsführer: Prof. Dr. Anke Rita Kaysser-Pyzalla, Prof. Dr. Dr. h.c. 
Wolfgang Eberhardt, Dr. Ulrich Breuer
Sitz der Gesellschaft: Berlin
Handelsregister: AG Charlottenburg, 89 HRB 5583




More information about the vtkusers mailing list