[vtkusers] Weird Render results with smartpointer in class

andyjk andrewkeeling at hotmail.com
Sun Jun 5 16:47:49 EDT 2016


I have a feeling I am using smart pointers wrongly in a class, and it is
causing weird rendering results. Can anyone help ?
I am trying to compare the distances between 2 polydatas using different
techniques. One function measures the vertex to surface distance. The other
takes lots of samples on the test polydata and measures the distance to the
surface of the reference polydata. The test and reference polydatas do not
change, and the numbers (mean distance etc ) given by the functions are
correct. However, the display deteriorates with use.

I guess I need to know how to completely reset the pipeline in the class,
ensuring the members are wiped before being reused (polydata, actor, mapper
and renderer), although I had hoped I could just reset the polydata witha
DeepCopy, and the pipeline would update.
 
I have a class and in the header  I declare : 
(QTCompare.h)

vtkSmartPointer<vtkPolyDataMapper> resultMapper_;
vtkSmartPointer<vtkRenderer> resultRenderer_;
vtkSmartPointer<vtkActor> resultActor_;
 
vtkSmartPointer<vtkPolyData> resultPolydata_;
 
vtkSmartPointer<vtkFloatArray> distances_; // The scalar array holding the
distances
vtkSmartPointer<vtkScalarBarActor> scalarBar_; // To show the colour scale
 
(I also declare two more polydatas : TestPolydata and targetPolydata, which
are read in fine from a file)
 
When the class is instantiated :
(QTCompare.cpp)
 
  resultPolydata_ = vtkSmartPointer<vtkPolyData>::New();
  resultMapper_ = vtkSmartPointer<vtkPolyDataMapper>::New();
  resultActor_ = vtkSmartPointer<vtkActor>::New();
  resultMapper_->SetInputData(resultPolydata_);
  resultActor_->SetMapper(resultMapper_);
  resultRenderer_ = vtkSmartPointer<vtkRenderer>::New();
  resultRenderer_->AddActor(resultActor_);
  // VTK/Qt wedded
  this->qvtkWidgetResult->GetRenderWindow()->AddRenderer(resultRenderer_);
 
  // The distances array
  distances_ = vtkSmartPointer<vtkFloatArray>::New();
  scalarBar_ = vtkSmartPointer<vtkScalarBarActor>::New();
 
 
So far, I have created the pipeline with a blank polydata. Then, when a
certain button is pressed I do :
 
void QtCompare::sampleVertices()
{
      
       txtOutput->append("Sampling vertices...");
 
       vtkIdType nPoints = testPolydata_->GetNumberOfPoints();
       if (nPoints == 0) return;
       distances_->Initialize();
       distances_->SetNumberOfValues(nPoints);
 
       resultPolydata_->DeepCopy(testPolydata_);
 
       // Create the tree
       if (referencePolydata_->GetNumberOfCells() == 0) return;
       vtkSmartPointer<vtkCellLocator> cellLocator =
vtkSmartPointer<vtkCellLocator>::New();
       cellLocator->SetDataSet(referencePolydata_);
       cellLocator->BuildLocator();
 
      
       txtOutput->append("Number of Samples : " + QString::number(nPoints));
 
 
       // Main loop
       for (vtkIdType i = 0; i < nPoints; i++) {
 
             double testPoint[3];
             testPolydata_->GetPoint(i, testPoint);
 
             //Find the closest points to TestPoint
             double closestPoint[3];//the coordinates of the closest point
will be returned here
             double closestPointDist2; //the squared distance to the closest
point will be returned here
             vtkIdType cellId; //the cell id of the cell containing the
closest point will be returned here
             int subId; //this is rarely used (in triangle strips only, I
believe)
             cellLocator->FindClosestPoint(testPoint, closestPoint, cellId,
subId, closestPointDist2);
 
             double distance = sqrt(closestPointDist2);
 
             distances_->SetValue(i, (float)distance);
 
       }
       cout << "N scalars :" << this->distances_->GetSize() << endl;
       // Add the distances to the result polydata (for colour)
       resultPolydata_->GetPointData()->SetScalars(distances_);
      
       // Get min and max
       double range[2];
       distances_->Modified();
       distances_->GetRange(range);
       txtOutput->append("Range of Samples : " +
QString::number(range[0],'f',4) + " to " + QString::number(range[1],'f',4));
       range[0] = 0.0; range[1] = 0.5;
 
       // Add in the mapper and set up scalar colours
       resultMapper_->ScalarVisibilityOn();
       resultMapper_->SetScalarModeToUsePointData();
       resultMapper_->SetColorModeToMapScalars();
       resultMapper_->SetScalarRange(range[0], range[1]);
       resultMapper_->Modified();
 
       //resultActor_->SetMapper(resultMapper_);
       resultActor_->GetProperty()->SetRepresentationToSurface();
       resultActor_->Modified();
      
 
       scalarBar_->SetTitle("Vertex Distances");
       scalarBar_->SetNumberOfLabels(6);
 
       vtkSmartPointer<vtkLookupTable> hueLUT =
vtkSmartPointer<vtkLookupTable>::New();
       hueLUT->SetNumberOfTableValues(10);
       hueLUT->SetTableRange(range[0], range[1]);
       hueLUT->SetHueRange(0.625, 0.0);
       hueLUT->SetValueRange(1, 1);
       hueLUT->SetSaturationRange(1, 1);
       hueLUT->Build();
 
       resultMapper_->SetLookupTable(hueLUT);
       scalarBar_->SetLookupTable(hueLUT);
 
       this->resultRenderer_->Clear();
       this->resultRenderer_->AddActor2D(scalarBar_);
       this->resultRenderer_->ResetCamera();
       this->qvtkWidgetResult->GetRenderWindow()->Render();
 
       float sd = standard_deviation(); // Reports mean and SD in the output
window
 
}
 
This all works once, but I have another function (almost the same) which
refills the class members distances_, resultPolydata_, resultMapper_ and
resultActor_. In this function the pointrepresentation is set to points, and
the polydata has many more points than the original.
 
This function looks like :
void QtCompare::uniformSample()
{
       txtOutput->append("Uniform sampling at 10 microns...");
      
       // Sample points at 0.01mm intervals
       vtkSmartPointer<vtkPolyDataPointSampler> pointSampler =
vtkSmartPointer<vtkPolyDataPointSampler>::New();
       pointSampler->SetDistance(.01);
       pointSampler->SetInputData(testPolydata_);
       pointSampler->Update();
 
       vtkIdType nPoints = pointSampler->GetOutput()->GetNumberOfPoints();
 
       if (nPoints == 0) return;
       distances_->Initialize();
       distances_->SetNumberOfValues(nPoints);
 
       txtOutput->append("Number of Samples : " + QString::number(nPoints));
 
       // Create a polydata made from all the samples
       resultPolydata_->DeepCopy(pointSampler->GetOutput());
 
       // Create the tree
       if (referencePolydata_->GetNumberOfCells() == 0) return;
       vtkSmartPointer<vtkCellLocator> cellLocator =
vtkSmartPointer<vtkCellLocator>::New();
       cellLocator->SetDataSet(referencePolydata_);
       cellLocator->BuildLocator();
 
       // Main loop
       for (vtkIdType i = 0; i < nPoints; i++) {
 
             double testPoint[3];
             resultPolydata_->GetPoint(i, testPoint);
 
 
             //Find the closest points to TestPoint
             double closestPoint[3];//the coordinates of the closest point
will be returned here
             double closestPointDist2; //the squared distance to the closest
point will be returned here
             vtkIdType cellId; //the cell id of the cell containing the
closest point will be returned here
             int subId; //this is rarely used (in triangle strips only, I
believe)
             cellLocator->FindClosestPoint(testPoint, closestPoint, cellId,
subId, closestPointDist2);
 
             double distance = sqrt(closestPointDist2);
 
             distances_->SetValue(i, (float)distance);
 
       }
 
       // Add the distances to the result polydata (for colour)
       resultPolydata_->GetPointData()->SetScalars(distances_);
 
       // Get min and max
       double range[2];
       distances_->Modified();
       distances_->GetRange(range);
       txtOutput->append("Range of Samples : " +
QString::number(range[0],'f',4) + " to " + QString::number(range[1],'f',4));
      
       // Add in the mapper and set up scalar colours
       resultMapper_->ScalarVisibilityOn();
       resultMapper_->SetScalarModeToUsePointData();
       resultMapper_->SetColorModeToMapScalars();
       resultMapper_->SetScalarRange(range[0], range[1]);
       resultMapper_->Modified();
 
       resultActor_->SetMapper(resultMapper_);
       resultActor_->Modified();
       resultActor_->GetProperty()->SetRepresentationToPoints();
       resultActor_->Modified();
 
       scalarBar_->SetTitle("Uniform Sampling Distances");
       scalarBar_->SetNumberOfLabels(6);
 
       vtkSmartPointer<vtkLookupTable> hueLUT =
vtkSmartPointer<vtkLookupTable>::New();
       hueLUT->SetNumberOfTableValues(10);
       hueLUT->SetTableRange(range[0], range[1]);
       hueLUT->SetHueRange(0.3, 0.0);
       hueLUT->SetValueRange(1, 1);
       hueLUT->SetSaturationRange(1, 1);
       hueLUT->Build();
 
       resultMapper_->SetLookupTable(hueLUT);
       scalarBar_->SetLookupTable(hueLUT);
 
       txtOutput->append(QString::number(
resultActor_->GetReferenceCount()));
 
       this->resultRenderer_->Clear();
       this->resultRenderer_->AddActor2D(scalarBar_);
       this->resultRenderer_->ResetCamera();
       this->qvtkWidgetResult->GetRenderWindow()->Render();
 
      
       float sd = standard_deviation(); // Reports mean and SD in the output
window
 
 
}
 
 
This also works fine. Now the strange bit. If I call the first function
again, everything displays as expected. BUT, if I then call the first
function again (so nothing should change) the data from the second function
gets displayed. This toggles every time I call the first function! The
values given by my ‘standard_deviation()’ function remain correct
throughout, so the maths is being done on the correct data each time, but
for some reason the display keeps changing its source data!
 
Does anyone know what I am doing wrong ?
 
Thanks
 
 



--
View this message in context: http://vtk.1045678.n5.nabble.com/Weird-Render-results-with-smartpointer-in-class-tp5738563.html
Sent from the VTK - Users mailing list archive at Nabble.com.


More information about the vtkusers mailing list