Commit 707da941 authored by Will Schroeder's avatar Will Schroeder

New class generates data from implicit function

This new class can generate scalar and/or vector information from
an implicit function. The generated scalar and vector arrays are
added to the input dataset, which is just passed to the output.
parent 2a3c6f07
Pipeline #7984 passed with stage
......@@ -61,6 +61,7 @@ set(Module_SRCS
vtkRecursiveDividingCubes.cxx
vtkReflectionFilter.cxx
vtkRotationFilter.cxx
vtkSampleDataSet.cxx
vtkShrinkFilter.cxx
vtkShrinkPolyData.cxx
vtkSpatialRepresentationFilter.cxx
......
......@@ -10,6 +10,7 @@ vtk_add_test_python(
TestGraphLayoutFilter.py
TestMultiBlockStreamer.py
TestRectilinearGridToTetrahedra.py
TestSampleDataSet.py
TestSplineFilter.py
WarpToImage.py
blankGrid.py
......
#!/usr/bin/env python
import vtk
from vtk.test import Testing
from vtk.util.misc import vtkGetDataRoot
VTK_DATA_ROOT = vtkGetDataRoot()
# Parameters for debugging
NPts = 100000
# create pipeline
#
points = vtk.vtkPointSource()
points.SetNumberOfPoints(NPts)
points.SetRadius(5)
# create some scalars based on implicit function
# Create a cylinder
cyl = vtk.vtkCylinder()
cyl.SetCenter(0,0,0)
cyl.SetRadius(0.1)
# Generate scalars and vector
sample = vtk.vtkSampleDataSet()
sample.SetInputConnection(points.GetOutputPort())
sample.SetImplicitFunction(cyl)
sample.Update()
print(sample.GetOutput().GetScalarRange())
# Draw the points
sampleMapper = vtk.vtkPointGaussianMapper()
sampleMapper.SetInputConnection(sample.GetOutputPort(0))
sampleMapper.EmissiveOff()
sampleMapper.SetScaleFactor(0.0)
sampleMapper.SetScalarRange(0,20)
sampleActor = vtk.vtkActor()
sampleActor.SetMapper(sampleMapper)
# Create an outline
outline = vtk.vtkOutlineFilter()
outline.SetInputConnection(sample.GetOutputPort())
outlineMapper = vtk.vtkPolyDataMapper()
outlineMapper.SetInputConnection(outline.GetOutputPort())
outlineActor = vtk.vtkActor()
outlineActor.SetMapper(outlineMapper)
# Create the RenderWindow, Renderer and both Actors
#
ren0 = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren0)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
# Add the actors to the renderer, set the background and size
#
ren0.AddActor(sampleActor)
ren0.AddActor(outlineActor)
ren0.SetBackground(0.1, 0.2, 0.4)
renWin.SetSize(250,250)
cam = ren0.GetActiveCamera()
cam.SetFocalPoint(0,0,0)
cam.SetPosition(1,1,1)
ren0.ResetCamera()
iren.Initialize()
# render the image
#
renWin.Render()
#iren.Start()
/*=========================================================================
Program: Visualization Toolkit
Module: vtkSampleDataSet.cxx
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 "vtkSampleDataSet.h"
#include "vtkFloatArray.h"
#include "vtkGarbageCollector.h"
#include "vtkImplicitFunction.h"
#include "vtkMath.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkDataSet.h"
#include "vtkPointData.h"
#include "vtkSMPTools.h"
vtkStandardNewMacro(vtkSampleDataSet);
vtkCxxSetObjectMacro(vtkSampleDataSet,ImplicitFunction,vtkImplicitFunction);
//Interface between vtkSMPTools and VTK pipeline
namespace {
struct SampleDataSet
{
vtkDataSet *Input;
vtkImplicitFunction *Function;
float *Scalars;
// Contructor
SampleDataSet(vtkDataSet *input, vtkImplicitFunction *imp, float *s) :
Input(input), Function(imp), Scalars(s)
{
}
void operator() (vtkIdType ptId, vtkIdType endPtId)
{
double x[3];
float *n = this->Scalars + ptId;
for ( ; ptId < endPtId; ++ptId )
{
this->Input->GetPoint(ptId, x);
*n++ = this->Function->FunctionValue(x);
}
}
};
struct SampleDataSetWithGradients
{
vtkDataSet *Input;
vtkImplicitFunction *Function;
float *Scalars;
float *Gradients;
// Contructor
SampleDataSetWithGradients(vtkDataSet *input, vtkImplicitFunction *imp, float *s, float *g) :
Input(input), Function(imp), Scalars(s), Gradients(g)
{
}
void operator() (vtkIdType ptId, vtkIdType endPtId)
{
double x[3], g[3];
float *n = this->Scalars + ptId;
float *v = this->Gradients + 3*ptId;
for ( ; ptId < endPtId; ++ptId )
{
this->Input->GetPoint(ptId, x);
*n++ = this->Function->FunctionValue(x);
this->Function->FunctionGradient(x,g);
*v++ = g[0];
*v++ = g[1];
*v++ = g[2];
}
}
};
} //anonymous namespace
//----------------------------------------------------------------------------
// Okay define the VTK class proper
vtkSampleDataSet::vtkSampleDataSet()
{
this->ImplicitFunction = NULL;
this->ComputeGradients = 1;
this->ScalarArrayName=0;
this->SetScalarArrayName("Implicit scalars");
this->GradientArrayName=0;
this->SetGradientArrayName("Implicit gradients");
}
//----------------------------------------------------------------------------
vtkSampleDataSet::~vtkSampleDataSet()
{
this->SetImplicitFunction(NULL);
this->SetScalarArrayName(NULL);
this->SetGradientArrayName(NULL);
}
//----------------------------------------------------------------------------
// Produce the output data
int vtkSampleDataSet::RequestData(
vtkInformation *vtkNotUsed(request),
vtkInformationVector **inputVector,
vtkInformationVector *outputVector)
{
vtkDebugMacro(<< "Generating implicit data");
// get the info objects
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
vtkInformation *outInfo = outputVector->GetInformationObject(0);
// get the input and output
vtkDataSet *input = vtkDataSet::SafeDownCast(
inInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkDataSet *output = vtkDataSet::SafeDownCast(
outInfo->Get(vtkDataObject::DATA_OBJECT()));
// Check the input
if ( !input || !output )
{
return 1;
}
vtkIdType numPts = input->GetNumberOfPoints();
if ( numPts < 1 )
{
return 1;
}
// Ensure implicit function is specified
//
if ( !this->ImplicitFunction )
{
vtkErrorMacro(<<"No implicit function specified");
return 1;
}
// The output geometic structure is the same as the input
output->CopyStructure(input);
// Set up for execution
vtkFloatArray *newScalars = vtkFloatArray::New();
newScalars->SetNumberOfTuples(numPts);
float *scalars = newScalars->WritePointer(0,numPts);
vtkFloatArray *newGradients=NULL;
float *gradients=NULL;
if ( this->ComputeGradients )
{
newGradients = vtkFloatArray::New();
newGradients->SetNumberOfComponents(3);
newGradients->SetNumberOfTuples(numPts);
gradients = newGradients->WritePointer(0,numPts);
}
// Threaded execute
if ( this->ComputeGradients )
{
SampleDataSetWithGradients
sample(input,this->ImplicitFunction,scalars,gradients);
vtkSMPTools::For(0,numPts, sample);
}
else
{
SampleDataSet sample(input,this->ImplicitFunction,scalars);
vtkSMPTools::For(0,numPts, sample);
}
// Update self
newScalars->SetName(this->ScalarArrayName);
output->GetPointData()->SetScalars(newScalars);
newScalars->Delete();
if ( this->ComputeGradients )
{
// For an unknown reason yet, if the following line is not commented out,
// it will make ImplicitSum, TestBoxFunction and TestDiscreteMarchingCubes
// to fail.
newGradients->SetName(this->GradientArrayName);
output->GetPointData()->SetVectors(newGradients);
newGradients->Delete();
}
return 1;
}
//----------------------------------------------------------------------------
int vtkSampleDataSet::
FillInputPortInformation(int, vtkInformation *info)
{
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
return 1;
}
//----------------------------------------------------------------------------
unsigned long vtkSampleDataSet::GetMTime()
{
unsigned long mTime=this->Superclass::GetMTime();
unsigned long impFuncMTime;
if ( this->ImplicitFunction != NULL )
{
impFuncMTime = this->ImplicitFunction->GetMTime();
mTime = ( impFuncMTime > mTime ? impFuncMTime : mTime );
}
return mTime;
}
//----------------------------------------------------------------------------
void vtkSampleDataSet::ReportReferences(vtkGarbageCollector* collector)
{
this->Superclass::ReportReferences(collector);
vtkGarbageCollectorReport(collector, this->ImplicitFunction,
"ImplicitFunction");
}
//----------------------------------------------------------------------------
void vtkSampleDataSet::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
if ( this->ImplicitFunction )
{
os << indent << "Implicit Function: " << this->ImplicitFunction << "\n";
}
else
{
os << indent << "No Implicit function defined\n";
}
os << indent << "Compute Gradients: " << (this->ComputeGradients ? "On\n" : "Off\n");
os << indent << "Scalar Array Name: ";
if(this->ScalarArrayName != 0)
{
os << this->ScalarArrayName << endl;
}
else
{
os << "(none)" << endl;
}
os << indent << "Gradient Array Name: ";
if(this->GradientArrayName != 0)
{
os << this->GradientArrayName << endl;
}
else
{
os << "(none)" << endl;
}
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkSampleDataSet.h
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.
=========================================================================*/
// .NAME vtkSampleDataSet - sample an implicit function over a dataset,
// generating scalar values and optional gradient vectors
// .SECTION Description
// vtkSampleDataSet is a filter that evaluates an implicit function and
// (optional) gradients at each point in an input vtkDataSet. The output
// of the filter are new scalar values (the function values) and the
// optional vector, gradient array.
// .SECTION Caveats
// This class has been threaded with vtkSMPTools. Using TBB or other
// non-sequential type (set in the CMake variable
// VTK_SMP_IMPLEMENTATION_TYPE) may improve performance significantly.
// .SECTION See Also
// vtkSampleFunction vtkImplicitModeller
#ifndef vtkSampleDataSet_h
#define vtkSampleDataSet_h
#include "vtkFiltersGeneralModule.h" // For export macro
#include "vtkDataSetAlgorithm.h"
class vtkImplicitFunction;
class vtkDataArray;
class VTKFILTERSGENERAL_EXPORT vtkSampleDataSet : public vtkDataSetAlgorithm
{
public:
// Description:
// Standard instantiation, type information, and print methods.
static vtkSampleDataSet *New();
vtkTypeMacro(vtkSampleDataSet,vtkDataSetAlgorithm);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Specify the implicit function to use to generate data.
virtual void SetImplicitFunction(vtkImplicitFunction*);
vtkGetObjectMacro(ImplicitFunction,vtkImplicitFunction);
// Description:
// Turn on/off the computation of gradients.
vtkSetMacro(ComputeGradients,int);
vtkGetMacro(ComputeGradients,int);
vtkBooleanMacro(ComputeGradients,int);
// Description:
// Set/get the scalar array name for this data set. Initial value is
// "Implicit scalars".
vtkSetStringMacro(ScalarArrayName);
vtkGetStringMacro(ScalarArrayName);
// Description:
// Set/get the gradient array name for this data set. Initial value is
// "Implicit gradients".
vtkSetStringMacro(GradientArrayName);
vtkGetStringMacro(GradientArrayName);
// Description:
// Return the MTime also considering the implicit function.
unsigned long GetMTime();
protected:
vtkSampleDataSet();
~vtkSampleDataSet();
vtkImplicitFunction *ImplicitFunction;
int ComputeGradients;
char *ScalarArrayName;
char *GradientArrayName;
virtual void ReportReferences(vtkGarbageCollector*);
virtual int RequestData(vtkInformation *, vtkInformationVector **,
vtkInformationVector *);
virtual int FillInputPortInformation(int port, vtkInformation *info);
private:
vtkSampleDataSet(const vtkSampleDataSet&); // Not implemented.
void operator=(const vtkSampleDataSet&); // Not implemented.
};
#endif
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