Commit 9289057d authored by T.J. Corona's avatar T.J. Corona
Browse files

Add vtkDataSetRegionSurfaceFilter to VTK.

Like vtkDataSetSurfaceFilter, vtkDataSetRegionSurfaceFilter is a filter that
extracts the surface from a dataset. Unlike vtkDataSetSurfaceFilter, the
filter accepts integer cell data to denote regions; the regions are then used
as an additional criterion for determining surfaces.

This filter has been ported from ParaView's VTKExtensions.
parent 5d113ed1
......@@ -12,6 +12,7 @@ set(Module_SRCS
vtkUnstructuredGridGeometryFilter.cxx
vtkDataSetSurfaceFilter.cxx
vtkDataSetRegionSurfaceFilter.cxx
vtkAbstractGridConnectivity.cxx
vtkDataSetGhostGenerator.cxx
......
vtk_add_test_cxx(${vtk-module}CxxTests tests
TestExtractSurfaceNonLinearSubdivision.cxx
TestDataSetSurfaceFieldData.cxx,NO_VALID
TestDataSetRegionSurfaceFilter.cxx
TestImageDataToUniformGrid.cxx,NO_VALID
TestLinearToQuadraticCellsFilter.cxx
TestProjectSphereFilter.cxx,NO_VALID
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestDataSetRegionSurfaceFilter.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 <vtkActor.h>
#include <vtkCamera.h>
#include <vtkCellArray.h>
#include <vtkCellData.h>
// #include <vtkCellIterator.h>
#include <vtkDataSetRegionSurfaceFilter.h>
// #include <vtkDoubleArray.h>
// #include <vtkGenericCell.h>
#include <vtkIntArray.h>
#include <vtkPointData.h>
#include <vtkPointLocator.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRegressionTestImage.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#include <vtkTestUtilities.h>
#include <vtkTetra.h>
#include <vtkTriangle.h>
#include <vtkUnstructuredGrid.h>
#include <vtkVersion.h>
namespace
{
void AddTetra(const double* p0,
const double* p1,
const double* p2,
const double* p3,
vtkPointLocator* pointLocator,
vtkCellArray* cells)
{
vtkSmartPointer<vtkTetra> t =
vtkSmartPointer<vtkTetra>::New();
static vtkIdType bIndices[4][4] = {{0,0,0,1},
{1,0,0,0},
{0,1,0,0},
{0,0,1,0}};
vtkIdType order = 1;
vtkIdType nPoints = 4;
t->GetPointIds()->SetNumberOfIds(nPoints);
t->GetPoints()->SetNumberOfPoints(nPoints);
t->Initialize();
double p[3];
vtkIdType pId;
vtkIdType* bIndex;
for (vtkIdType i = 0; i < nPoints; i++)
{
bIndex = bIndices[i];
for (vtkIdType j = 0; j < 3; j++)
{
p[j] = (p0[j]*bIndex[3])/order + (p1[j]*bIndex[0])/order +
(p2[j]*bIndex[1])/order + (p3[j]*bIndex[2])/order;
}
pointLocator->InsertUniquePoint(p, pId);
t->GetPointIds()->SetId(i,pId);
}
cells->InsertNextCell(t);
}
}
int TestDataSetRegionSurfaceFilter(int argc, char* argv[])
{
// This test constructs a meshed cube comprised of linear tetrahedra and
// assigns a material ID to each cell according to the octant in which it
// lies. It then applies the vtkDataSetRegionSurfaceFilter and visualizes the
// results.
vtkIdType nX = 2;
vtkIdType nY = 2;
vtkIdType nZ = 2;
vtkSmartPointer<vtkUnstructuredGrid> unstructuredGrid =
vtkSmartPointer<vtkUnstructuredGrid>::New();
vtkSmartPointer<vtkPoints> pointArray =
vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkPointLocator> pointLocator =
vtkSmartPointer<vtkPointLocator>::New();
double bounds[6] = {-1.,1.,-1.,1.,-1.,1.};
pointLocator->InitPointInsertion(pointArray,bounds);
vtkSmartPointer<vtkCellArray> cellArray =
vtkSmartPointer<vtkCellArray>::New();
double p[8][3];
double dx = (bounds[1] - bounds[0])/nX;
double dy = (bounds[3] - bounds[2])/nY;
double dz = (bounds[5] - bounds[4])/nZ;
for (vtkIdType i = 0; i < 8; i++)
{
for (vtkIdType j = 0; j < 3; j++)
{
p[i][j] = bounds[2*j];
}
}
p[1][0] += dx;
p[2][0] += dx;
p[2][1] += dy;
p[3][1] += dy;
p[5][0] += dx;
p[5][2] += dz;
p[6][0] += dx;
p[6][1] += dy;
p[6][2] += dz;
p[7][1] += dy;
p[7][2] += dz;
vtkSmartPointer<vtkIntArray> region = vtkSmartPointer<vtkIntArray>::New();
region->SetName("Regions");
region->SetNumberOfTuples(5*nX*nY*nZ);
int counter = 0;
for (vtkIdType xInc = 0; xInc < nX; xInc++)
{
p[0][1] = p[1][1] = p[4][1] = p[5][1] = bounds[2];
p[2][1] = p[3][1] = p[6][1] = p[7][1] = bounds[2] + dy;
for (vtkIdType yInc = 0; yInc < nY; yInc++)
{
p[0][2] = p[1][2] = p[2][2] = p[3][2] = bounds[4];
p[4][2] = p[5][2] = p[6][2] = p[7][2] = bounds[4] + dz;
for (vtkIdType zInc = 0; zInc < nZ; zInc++)
{
AddTetra(p[0],p[1],p[2],p[5], pointLocator, cellArray);
AddTetra(p[0],p[2],p[3],p[7], pointLocator, cellArray);
AddTetra(p[0],p[5],p[7],p[4], pointLocator, cellArray);
AddTetra(p[2],p[5],p[6],p[7], pointLocator, cellArray);
AddTetra(p[0],p[2],p[5],p[7], pointLocator, cellArray);
int r = 4*(2*xInc/nX) + 2*(2*yInc/nY) + (2*zInc/nZ);
for (vtkIdType i = 0; i < 5; i++)
{
region->SetTypedTuple(counter++, &r);
}
for (vtkIdType i = 0; i < 8; i++)
{
p[i][2] += dz;
}
}
for (vtkIdType i = 0; i < 8; i++)
{
p[i][1] += dy;
}
}
for (vtkIdType i = 0; i < 8; i++)
{
p[i][0] += dx;
}
}
unstructuredGrid->SetPoints(pointArray);
unstructuredGrid->SetCells(VTK_TETRA, cellArray);
vtkIdType nPoints = unstructuredGrid->GetPoints()->GetNumberOfPoints();
double maxDist = 0;
for (vtkIdType i = 0; i < nPoints; i++)
{
double xyz[3];
unstructuredGrid->GetPoints()->GetPoint(i,xyz);
double dist = sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1] + xyz[2]*xyz[2]);
maxDist = (dist > maxDist ? dist : maxDist);
}
unstructuredGrid->GetCellData()->AddArray(region);
unstructuredGrid->GetCellData()->SetScalars(region);
// Visualize
vtkSmartPointer<vtkDataSetRegionSurfaceFilter> surfaceFilter =
vtkSmartPointer<vtkDataSetRegionSurfaceFilter>::New();
surfaceFilter->SetRegionArrayName("Regions");
surfaceFilter->SetInputData(unstructuredGrid);
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(surfaceFilter->GetOutputPort());
mapper->SetScalarRange(0,7);
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
vtkSmartPointer<vtkCamera> camera =
vtkSmartPointer<vtkCamera>::New();
camera->SetPosition(3.*maxDist, 3.*maxDist, -3.*maxDist);
camera->SetFocalPoint(.0, .0, 0.);
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->SetActiveCamera(camera);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderer->AddActor(actor);
renderWindow->Render();
int retVal = vtkRegressionTestImage(renderWindow);
if (retVal == vtkRegressionTester::DO_INTERACTOR)
{
renderWindowInteractor->Start();
}
return !retVal;
}
This diff is collapsed.
//=========================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt 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 vtkDataSetRegionSurfaceFilter - Extract surface of materials.
// .SECTION Description
// This filter extracts surfaces of materials such that a surface
// could have a material on each side of it. It also stores a
// mapping of the original cells and their sides back to the original grid
// so that we can output boundary information for those cells given
// only surfaces.
#ifndef vtkDataSetRegionSurfaceFilter_h
#define vtkDataSetRegionSurfaceFilter_h
#include "vtkFiltersGeometryModule.h" // For export macro
#include "vtkDataSetSurfaceFilter.h"
class vtkCharArray;
class VTKFILTERSGEOMETRY_EXPORT vtkDataSetRegionSurfaceFilter : public vtkDataSetSurfaceFilter
{
public:
static vtkDataSetRegionSurfaceFilter* New();
vtkTypeMacro(vtkDataSetRegionSurfaceFilter, vtkDataSetSurfaceFilter);
void PrintSelf(ostream& os, vtkIndent indent);
//Description:
//The name of the cell based array that we use to extract interfaces from
//Default is "Regions"
vtkSetStringMacro(RegionArrayName);
vtkGetStringMacro(RegionArrayName);
virtual int UnstructuredGridExecute(vtkDataSet *input,
vtkPolyData *output);
//make it clear we want all the recordOrigCellId signatures from our parent
using vtkDataSetSurfaceFilter::RecordOrigCellId;
//override one of the signatures
virtual void RecordOrigCellId(vtkIdType newIndex, vtkFastGeomQuad *quad);
//Description:
//Whether to return single sided material interfaces or double sided
//Default is single
vtkSetMacro(SingleSided, bool);
vtkGetMacro(SingleSided, bool);
//Description:
//The name of the field array that has characteristics of each material
//Default is "material_properties"
vtkSetStringMacro(MaterialPropertiesName);
vtkGetStringMacro(MaterialPropertiesName);
//Description:
//The name of the field array that has material type identifiers in it
//Default is "material_ids"
vtkSetStringMacro(MaterialIDsName);
vtkGetStringMacro(MaterialIDsName);
//Description:
//The name of the output field array that records parent materials of each interface
//Default is "material_ancestors"
vtkSetStringMacro(MaterialPIDsName);
vtkGetStringMacro(MaterialPIDsName);
//Description:
//The name of the field array that has material interface type identifiers in it
//Default is "interface_ids"
vtkSetStringMacro(InterfaceIDsName);
vtkGetStringMacro(InterfaceIDsName);
protected:
vtkDataSetRegionSurfaceFilter();
~vtkDataSetRegionSurfaceFilter();
virtual int FillInputPortInformation(int port, vtkInformation *info);
/// Implementation of the algorithm.
virtual int RequestData(vtkInformation *,
vtkInformationVector **,
vtkInformationVector *);
virtual void InsertQuadInHash(vtkIdType a, vtkIdType b, vtkIdType c,
vtkIdType d, vtkIdType sourceId, vtkIdType faceId);
virtual void InsertQuadInHash(vtkIdType a, vtkIdType b, vtkIdType c,
vtkIdType d, vtkIdType sourceId)
{
this->InsertQuadInHash(a,b,c,d,sourceId, -1); //for -Woverloaded-virtual comp warning
}
virtual void InsertTriInHash(vtkIdType a, vtkIdType b, vtkIdType c,
vtkIdType sourceId, vtkIdType faceId);
virtual void InsertTriInHash(vtkIdType a, vtkIdType b, vtkIdType c,
vtkIdType sourceId)
{
this->InsertTriInHash(a,b,c,sourceId, -1); //for -Woverloaded-virtual comp warning
}
virtual vtkFastGeomQuad *GetNextVisibleQuadFromHash();
private:
vtkDataSetRegionSurfaceFilter(const vtkDataSetRegionSurfaceFilter&) VTK_DELETE_FUNCTION;
void operator=(const vtkDataSetRegionSurfaceFilter&) VTK_DELETE_FUNCTION;
char *RegionArrayName;
vtkIntArray *RegionArray;
vtkIdTypeArray *OrigCellIds;
vtkCharArray *CellFaceIds;
bool SingleSided;
char *MaterialPropertiesName;
char *MaterialIDsName;
char *MaterialPIDsName;
char *InterfaceIDsName;
class Internals;
Internals *Internal;
};
#endif
Supports Markdown
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