Commit 7b55db87 authored by David C. Lonie's avatar David C. Lonie

Expose the vtk-m clip filter.

parent 0e25e61c
......@@ -32,6 +32,7 @@ set(lib_srcs
#needed to properly setup language wrappers
set(headers
vtkmClip.h
vtkmContour.h
vtkmThreshold.h
vtkmLevelOfDetail.h
......@@ -41,6 +42,7 @@ set(headers
#implementation of the algorithms for cpu accelerators
set(cpu_accelerator_srcs
vtkmClip.cxx
vtkmContour.cxx
vtkmThreshold.cxx
vtkmLevelOfDetail.cxx
......@@ -54,6 +56,7 @@ set(cpu_accelerator_srcs
#implementation of the algorithms for gpu accelerators
set(cuda_accelerator_srcs
vtkmClip.cu
vtkmContour.cu
vtkmThreshold.cu
vtkmLevelOfDetail.cu
......
......@@ -3,6 +3,7 @@ find_package(VTKm REQUIRED COMPONENTS Base)
include_directories(${VTKm_INCLUDE_DIRS})
vtk_add_test_cxx(${vtk-module}CxxTests tests
TestVTKMClip.cxx
# TestVTKMGradientAndVorticity.cxx,NO_VALID
TestVTKMLevelOfDetail.cxx
TestVTKMMarchingCubes.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestVTKMClip.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 "vtkmClip.h"
#include "vtkActor.h"
#include "vtkCamera.h"
#include "vtkDataSetSurfaceFilter.h"
#include "vtkDelaunay3D.h"
#include "vtkDoubleArray.h"
#include "vtkImageData.h"
#include "vtkImageToPoints.h"
#include "vtkNew.h"
#include "vtkPointData.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRTAnalyticSource.h"
#include "vtkSphereSource.h"
#include "vtkUnstructuredGrid.h"
namespace {
template <typename DataSetT>
void GenerateScalars(DataSetT *dataset, bool negate)
{
vtkIdType numPoints = dataset->GetNumberOfPoints();
vtkNew<vtkDoubleArray> scalars;
scalars->SetName("x+y");
scalars->SetNumberOfComponents(1);
scalars->SetNumberOfTuples(numPoints);
double point[3];
for (vtkIdType i = 0; i < numPoints; ++i)
{
dataset->GetPoint(i, point);
scalars->SetTypedComponent(i, 0, (negate ?-point[0] - point[1]
: point[0] + point[1]));
}
dataset->GetPointData()->SetScalars(scalars.Get());
}
} // end anon namespace
int TestVTKMClip(int, char*[])
{
vtkNew<vtkRenderer> renderer;
// First input is a polydata with 2D cells. This should produce a polydata
// output from vtkmClip.
vtkNew<vtkSphereSource> sphereSource;
sphereSource->SetThetaResolution(50);
sphereSource->SetPhiResolution(50);
sphereSource->Update();
vtkPolyData *sphere = sphereSource->GetOutput();
GenerateScalars(sphere, false);
// Clip at zero:
vtkNew<vtkmClip> sphereClipper;
sphereClipper->SetInputData(sphere);
sphereClipper->SetComputeScalars(true);
sphereClipper->SetClipValue(0.);
sphereClipper->Update();
if (!sphereClipper->GetOutput()->IsA("vtkPolyData"))
{
std::cerr << "Expected an input with 2D cells to produce polydata. Got: "
<< sphereClipper->GetOutput()->GetClassName() << "\n";
return EXIT_FAILURE;
}
vtkNew<vtkPolyDataMapper> sphereMapper;
sphereMapper->SetInputConnection(sphereClipper->GetOutputPort());
sphereMapper->SetScalarVisibility(1);
sphereMapper->SetScalarModeToUsePointFieldData();
sphereMapper->SelectColorArray("x+y");
sphereMapper->SetScalarRange(0, 1);
vtkNew<vtkActor> sphereActor;
sphereActor->SetMapper(sphereMapper.Get());
sphereActor->SetPosition(0.5, 0.5, 0.);
sphereActor->RotateWXYZ(90., 0., 0., 1.);
renderer->AddActor(sphereActor.Get());
// Second input is an unstructured grid with 3D cells. This should produce an
// unstructured grid output from vtkmClip.
vtkNew<vtkRTAnalyticSource> imageSource;
imageSource->SetWholeExtent(-5, 5, -5, 5, -5, 5);
// Convert image to pointset
vtkNew<vtkImageToPoints> imageToPoints;
imageToPoints->SetInputConnection(imageSource->GetOutputPort());
// Convert point set to tets:
vtkNew<vtkDelaunay3D> tetrahedralizer;
tetrahedralizer->SetInputConnection(imageToPoints->GetOutputPort());
tetrahedralizer->Update();
vtkUnstructuredGrid *tets = tetrahedralizer->GetOutput();
GenerateScalars(tets, true);
// Clip at zero:
vtkNew<vtkmClip> tetClipper;
tetClipper->SetInputData(tets);
tetClipper->SetComputeScalars(true);
tetClipper->SetClipValue(0.);
tetClipper->Update();
if (!tetClipper->GetOutput()->IsA("vtkUnstructuredGrid"))
{
std::cerr << "Expected an input with 3D cells to produce an ugrid. Got: "
<< tetClipper->GetOutput()->GetClassName() << "\n";
return EXIT_FAILURE;
}
vtkNew<vtkDataSetSurfaceFilter> tetSurface;
tetSurface->SetInputConnection(tetClipper->GetOutputPort());
vtkNew<vtkPolyDataMapper> tetMapper;
tetMapper->SetInputConnection(tetSurface->GetOutputPort());
tetMapper->SetScalarVisibility(1);
tetMapper->SetScalarModeToUsePointFieldData();
tetMapper->SelectColorArray("x+y");
tetMapper->SetScalarRange(0, 10);
vtkNew<vtkActor> tetActor;
tetActor->SetMapper(tetMapper.Get());
tetActor->SetScale(1. / 5.);
renderer->AddActor(tetActor.Get());
// Third dataset tests imagedata. This should produce an unstructured grid:
vtkImageData *image = imageSource->GetOutput();
GenerateScalars(image, false);
vtkNew<vtkmClip> imageClipper;
imageClipper->SetInputData(image);
imageClipper->SetComputeScalars(true);
imageClipper->SetClipValue(0.);
imageClipper->Update();
if (!tetClipper->GetOutput()->IsA("vtkUnstructuredGrid"))
{
std::cerr << "Expected an imagedata to produce a clipped ugrid. Got: "
<< tetClipper->GetOutput()->GetClassName() << "\n";
return EXIT_FAILURE;
}
vtkNew<vtkDataSetSurfaceFilter> imageSurface;
imageSurface->SetInputConnection(imageClipper->GetOutputPort());
vtkNew<vtkPolyDataMapper> imageMapper;
imageMapper->SetInputConnection(imageSurface->GetOutputPort());
imageMapper->SetScalarVisibility(1);
imageMapper->SetScalarModeToUsePointFieldData();
imageMapper->SelectColorArray("x+y");
imageMapper->SetScalarRange(0, 10);
vtkNew<vtkActor> imageActor;
imageActor->SetMapper(imageMapper.Get());
imageActor->SetScale(1. / 5.);
imageActor->SetPosition(1.0, 1.0, 0.);
renderer->AddActor(imageActor.Get());
vtkNew<vtkRenderWindowInteractor> iren;
vtkNew<vtkRenderWindow> renWin;
renWin->SetMultiSamples(0);
iren->SetRenderWindow(renWin.Get());
renWin->AddRenderer(renderer.Get());
renWin->SetSize(500,500);
renderer->GetActiveCamera()->SetPosition(0,0,1);
renderer->GetActiveCamera()->SetFocalPoint(0,0,0);
renderer->GetActiveCamera()->SetViewUp(0,1,0);
renderer->ResetCamera();
renWin->Render();
iren->Start();
return EXIT_SUCCESS;
}
......@@ -13,6 +13,7 @@ vtk_module(vtkAcceleratorsVTKm
vtkRenderingVolume${VTK_RENDERING_BACKEND}
vtkIOLegacy
vtkIOXML
vtkImagingHybrid
vtkImagingSources
EXCLUDE_FROM_ALL
)
/*=========================================================================
Program: Visualization Toolkit
Module: vtkmClip.cu
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 "vtkmClip.cxx"
/*=========================================================================
Program: Visualization Toolkit
Module: vtkmClip.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 "vtkmClip.h"
#include "vtkCellIterator.h"
#include "vtkDataArray.h"
#include "vtkDataSet.h"
#include "vtkDemandDrivenPipeline.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
#include "vtkUnstructuredGrid.h"
#include "vtkmlib/ArrayConverters.h"
#include "vtkmlib/DataSetConverters.h"
#include "vtkmlib/PolyDataConverter.h"
#include "vtkmlib/Storage.h"
#include "vtkmlib/UnstructuredGridConverter.h"
#include "vtkmCellSetExplicit.h"
#include "vtkmCellSetSingleType.h"
#include "vtkmFilterPolicy.h"
#include <vtkm/filter/Clip.h>
vtkStandardNewMacro(vtkmClip)
//------------------------------------------------------------------------------
void vtkmClip::PrintSelf(std::ostream &os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "ClipValue: " << this->ClipValue << "\n";
os << indent << "ComputeScalars: " << this->ComputeScalars << "\n";
}
//------------------------------------------------------------------------------
vtkmClip::vtkmClip()
: ClipValue(0.),
ComputeScalars(true)
{
// Clip active point scalars by default
this->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS,
vtkDataSetAttributes::SCALARS);
}
//------------------------------------------------------------------------------
vtkmClip::~vtkmClip()
{
}
//------------------------------------------------------------------------------
int vtkmClip::RequestDataObject(vtkInformation *,
vtkInformationVector **inVec,
vtkInformationVector *outVec)
{
vtkInformation* inInfo = inVec[0]->GetInformationObject(0);
if (!inInfo)
{
return 0;
}
vtkDataSet *input =
vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
if (input)
{
// If the input has 3D cells, we will produce an unstructured grid. Otherwise,
// we'll make a polydata:
bool has3DCells = false;
vtkCellIterator *i = input->NewCellIterator();
for (i->InitTraversal(); !i->IsDoneWithTraversal(); i->GoToNextCell())
{
if (i->GetCellDimension() == 3)
{
has3DCells = true;
break;
}
}
i->Delete();
vtkInformation* info = outVec->GetInformationObject(0);
vtkDataObject *output = info->Get(vtkDataObject::DATA_OBJECT());
if (has3DCells && (!output || !output->IsA("vtkUnstructuredGrid")))
{
vtkNew<vtkUnstructuredGrid> newOutput;
info->Set(vtkDataObject::DATA_OBJECT(), newOutput.Get());
}
else if (!has3DCells && (!output || !output->IsA("vtkPolyData")))
{
vtkNew<vtkPolyData> newOutput;
info->Set(vtkDataObject::DATA_OBJECT(), newOutput.Get());
}
return 1;
}
return 0;
}
//------------------------------------------------------------------------------
int vtkmClip::RequestData(vtkInformation *,
vtkInformationVector **inInfoVec,
vtkInformationVector *outInfoVec)
{
vtkInformation* inInfo = inInfoVec[0]->GetInformationObject(0);
vtkInformation* outInfo = outInfoVec->GetInformationObject(0);
// Extract data objects from info:
vtkDataSet *input =
vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkDataObject *outputDO = outInfo->Get(vtkDataObject::DATA_OBJECT());
// Find the scalar array:
int assoc = this->GetInputArrayAssociation(0, inInfoVec);
vtkDataArray *scalars = this->GetInputArrayToProcess(0, inInfoVec);
// Validate input objects:
if (input->GetNumberOfPoints() == 0)
{
vtkErrorMacro("No points in input dataset!");
return 1;
}
if (input->GetNumberOfCells() == 0)
{
vtkErrorMacro("No cells in input dataset!");
return 1;
}
// Convert inputs to vtkm objects:
vtkm::cont::DataSet in = tovtkm::Convert(input);
vtkm::cont::Field field = tovtkm::Convert(scalars, assoc);
if (field.GetAssociation() != vtkm::cont::Field::ASSOC_POINTS ||
field.GetName() == std::string())
{
vtkErrorMacro("Invalid scalar array; array missing or not a point array.");
return 1;
}
// Configure vtkm filter:
vtkm::filter::Clip filter;
filter.SetClipValue(this->ClipValue);
// Run filter:
vtkm::filter::ResultDataSet result;
vtkmInputFilterPolicy policy;
result = filter.Execute(in, field, policy);
if (!result.IsValid())
{
vtkErrorMacro("vtkm Clip filter failed to run.");
return 1;
}
// ComputeScalars:
vtkPointData *pd = input->GetPointData();
if (this->ComputeScalars && pd)
{
for (vtkIdType i = 0; i < pd->GetNumberOfArrays(); ++i)
{
vtkDataArray *array = pd->GetArray(i);
if (!array)
{
continue;
}
vtkm::cont::Field pField =
tovtkm::Convert(array, vtkDataObject::FIELD_ASSOCIATION_POINTS);
try
{
if (!filter.MapFieldOntoOutput(result, pField, policy))
{
throw vtkm::cont::ErrorBadValue("MapFieldOntoOutput returned false.");
}
}
catch (vtkm::cont::Error &e)
{
vtkWarningMacro("Failed to map input point array '"
<< array->GetName() << "' (ValueType: "
<< array->GetDataTypeAsString() << ", "
<< array->GetNumberOfComponents() << " components) "
<< "onto output dataset: "
<< e.what());
}
}
}
// Convert result to output:
vtkUnstructuredGrid *outputUG = vtkUnstructuredGrid::SafeDownCast(outputDO);
vtkPolyData *outputPD = outputUG ? NULL : vtkPolyData::SafeDownCast(outputDO);
bool outputValid = false;
if (outputUG)
{
outputValid = fromvtkm::Convert(result.GetDataSet(), outputUG, input);
}
else if (outputPD)
{
outputValid = fromvtkm::Convert(result.GetDataSet(), outputPD, input);
}
else
{
vtkErrorMacro("Unsupported output data object type: "
<< (outputDO ? outputDO->GetClassName() : "(NULL)"));
return 1;
}
if (!outputValid)
{
vtkErrorMacro("Error generating vtkPolyData from vtkm's result.");
outputDO->Initialize();
return 1;
}
return 1;
}
//------------------------------------------------------------------------------
int vtkmClip::FillInputPortInformation(int, vtkInformation *info)
{
// These are the types supported by tovtkm::Convert:
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData");
info->Append(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkUnstructuredGrid");
info->Append(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkStructuredGrid");
info->Append(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkUniformGrid");
info->Append(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkImageData");
return 1;
}
//------------------------------------------------------------------------------
int vtkmClip::FillOutputPortInformation(int, vtkInformation *info)
{
info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkPointSet");
return 1;
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkmClip.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.
=========================================================================*/
/**
* @class vtkmClip
* @brief Clip a dataset using the accelerated vtk-m Clip filter.
*/
#ifndef vtkmClip_h
#define vtkmClip_h
#include "vtkAcceleratorsVTKmModule.h" // For export macro
#include "vtkDataSetAlgorithm.h"
class VTKACCELERATORSVTKM_EXPORT vtkmClip : public vtkDataSetAlgorithm
{
public:
static vtkmClip* New();
vtkTypeMacro(vtkmClip, vtkDataSetAlgorithm)
void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE;
/**
* The scalar value to use when clipping the dataset. Values greater than
* ClipValue are preserved in the output dataset. Default is 0.
*/
vtkGetMacro(ClipValue, double)
vtkSetMacro(ClipValue, double)
/**
* If true, all input point data arrays will be mapped onto the output
* dataset. Default is true.
*/
vtkGetMacro(ComputeScalars, bool)
vtkSetMacro(ComputeScalars, bool)
protected:
vtkmClip();
~vtkmClip();
int RequestDataObject(vtkInformation*, vtkInformationVector**,
vtkInformationVector*) VTK_OVERRIDE;
int RequestData(vtkInformation*, vtkInformationVector**,
vtkInformationVector*) VTK_OVERRIDE;
int FillInputPortInformation(int port, vtkInformation* info) VTK_OVERRIDE;
int FillOutputPortInformation(int port, vtkInformation* info) VTK_OVERRIDE;
double ClipValue;
bool ComputeScalars;
private:
vtkmClip(const vtkmClip&) VTK_DELETE_FUNCTION;
void operator=(const vtkmClip&) VTK_DELETE_FUNCTION;
};
#endif // vtkmClip_h
// VTK-HeaderTest-Exclude: vtkmClip.h
......@@ -366,8 +366,10 @@ vtkPoints* Convert(const vtkm::cont::CoordinateSystem& input)
points->SetData(pdata);
pdata->FastDelete();
}
catch (vtkm::cont::Error&)
catch (vtkm::cont::Error &e)
{
vtkGenericWarningMacro("Converting vtkm::cont::CoordinateSystem to "
"vtkPoints failed: " << e.what());
}
return points;
}
......
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