Commit 1fa83aaf authored by Will Schroeder's avatar Will Schroeder Committed by Kitware Robot

Merge topic 'FlyingEdges-Attribute-Interpolation'

712e79a8 Working around dumb compilers
3bd159a4 Flying edges plane cutter interpolates attributes
74575a55 Now interpolating point attribute data on request
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Reviewed-by: Cory Quammen's avatarCory Quammen <cory.quammen@kitware.com>
Merge-request: !1301
parents 77e62423 712e79a8
......@@ -9,6 +9,7 @@ set(Module_SRCS
vtkAnnotation.cxx
vtkAnnotationLayers.cxx
vtkArrayData.cxx
vtkArrayListTemplate.txx
vtkAttributesErrorMetric.cxx
vtkBiQuadraticQuad.cxx
vtkBiQuadraticQuadraticHexahedron.cxx
......@@ -213,6 +214,7 @@ set(Module_SRCS
)
set(${vtk-module}_HDRS
vtkArrayListTemplate.h
vtkCellType.h
vtkMappedUnstructuredGrid.h
vtkMappedUnstructuredGridCellIterator.h
......@@ -260,6 +262,7 @@ set_source_files_properties(
set_source_files_properties(
vtkAMRBox
vtkArrayListTemplate.txx
vtkAtom
vtkBond
vtkBoundingBox
......
......@@ -26,10 +26,10 @@
// vtkDataSetAttributes::CopyInterpolate() or InterpolateAllocate() which
// performs the initial magic of constructing input and output arrays. Then
// the input attributes, and output attributes, are passed to initialize the
// internal structures. Internally, pairs of typed arrays are created; the
// operations (e.g., interpolate) occur on these typed arrays using a
// typeless, virtual dispatch base class.
// internal structures. Essentially these internal structures are pairs of
// arrays of the same type, which can be efficently accessed and
// assigned. The operations on these array pairs (e.g., interpolation) occur
// using a typeless, virtual dispatch base class.
// .SECTION See Also
// vtkFieldData vtkDataSetAttributes vtkPointData vtkCellData
......@@ -40,14 +40,19 @@
#include "vtkDataArray.h"
#include "vtkDataSetAttributes.h"
#include <vector>
#include <algorithm>
// Create a generic class supporting virtual dispatch to type-specific
// subclasses.
struct BaseArrayPair
{
vtkIdType Num;
int NumComp;
vtkDataArray *OutputArray;
BaseArrayPair(vtkIdType num, int numComp) : Num(num), NumComp(numComp)
BaseArrayPair(vtkIdType num, int numComp, vtkDataArray *outArray) :
Num(num), NumComp(numComp), OutputArray(outArray)
{
}
virtual ~BaseArrayPair()
......@@ -56,8 +61,11 @@ struct BaseArrayPair
virtual void Copy(vtkIdType inId, vtkIdType outId) = 0;
virtual void Interpolate(int numWeights, const vtkIdType *ids,
const double *weights, vtkIdType outPtId) = 0;
const double *weights, vtkIdType outId) = 0;
virtual void InterpolateEdge(vtkIdType v0, vtkIdType v1,
double t, vtkIdType outId) = 0;
virtual void AssignNullValue(vtkIdType outId) = 0;
virtual void Realloc(vtkIdType sze) = 0;
};
// Type specific interpolation on a matched pair of data arrays
......@@ -68,8 +76,8 @@ struct ArrayPair : public BaseArrayPair
T *Output;
T NullValue;
ArrayPair(T *in, T *out, vtkIdType num, int numComp, T null) :
BaseArrayPair(num,numComp), Input(in), Output(out), NullValue(null)
ArrayPair(T *in, T *out, vtkIdType num, int numComp, vtkDataArray *outArray, T null) :
BaseArrayPair(num,numComp,outArray), Input(in), Output(out), NullValue(null)
{
}
virtual ~ArrayPair() //calm down some finicky compilers
......@@ -85,7 +93,7 @@ struct ArrayPair : public BaseArrayPair
}
virtual void Interpolate(int numWeights, const vtkIdType *ids,
const double *weights, vtkIdType outPtId)
const double *weights, vtkIdType outId)
{
for (int j=0; j < this->NumComp; ++j)
{
......@@ -94,7 +102,19 @@ struct ArrayPair : public BaseArrayPair
{
v += weights[i] * static_cast<double>(this->Input[ids[i]*this->NumComp+j]);
}
this->Output[outPtId*this->NumComp+j] = static_cast<T>(v);
this->Output[outId*this->NumComp+j] = static_cast<T>(v);
}
}
virtual void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId)
{
double v;
vtkIdType numComp=this->NumComp;
for (int j=0; j < numComp; ++j)
{
v = this->Input[v0*numComp+j] +
t * (this->Input[v1*numComp+j] - this->Input[v0*numComp+j]);
this->Output[outId*numComp+j] = static_cast<T>(v);
}
}
......@@ -106,6 +126,12 @@ struct ArrayPair : public BaseArrayPair
}
}
virtual void Realloc(vtkIdType sze)
{
this->OutputArray->WriteVoidPointer(0,sze*this->NumComp);
this->Output = static_cast<T*>(this->OutputArray->GetVoidPointer(0));
}
};
// Forward declarations. This makes working with vtkTemplateMacro easier.
......@@ -119,13 +145,19 @@ void CreateArrayPair(ArrayList *list, T *inData, T *outData,
// A list of the arrays to interpolate, and a method to invoke interpolation on the list
struct ArrayList
{
// The list of arrays
// The list of arrays, and the arrays not to process
std::vector<BaseArrayPair*> Arrays;
std::vector<vtkDataArray*> ExcludedArrays;
// Add the arrays to interpolate here
void AddArrays(vtkIdType numOutPts, vtkDataSetAttributes *inPD,
vtkDataSetAttributes *outPD, double nullValue=0.0);
// Any array excluded here is not added by AddArrays(), hence not
// processed. Also check whether an array is excluded.
void ExcludeArray(vtkDataArray *da);
bool IsExcluded(vtkDataArray *da);
// Loop over the array pairs and copy data from one to another
void Copy(vtkIdType inId, vtkIdType outId)
{
......@@ -137,16 +169,26 @@ struct ArrayList
}
// Loop over the arrays and have them interpolate themselves
void Interpolate(int numWeights, const vtkIdType *ids, const double *weights, vtkIdType outPtId)
void Interpolate(int numWeights, const vtkIdType *ids, const double *weights, vtkIdType outId)
{
for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin();
it != Arrays.end(); ++it)
{
(*it)->Interpolate(numWeights, ids, weights, outPtId);
(*it)->Interpolate(numWeights, ids, weights, outId);
}
}
// Loop over the arrays and have them interpolate themselves
// Loop over the arrays perform edge interpolation
void InterpolateEdge(vtkIdType v0, vtkIdType v1, double t, vtkIdType outId)
{
for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin();
it != Arrays.end(); ++it)
{
(*it)->InterpolateEdge(v0, v1, t, outId);
}
}
// Loop over the arrays and assign the null value
void AssignNullValue(vtkIdType outId)
{
for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin();
......@@ -156,6 +198,16 @@ struct ArrayList
}
}
// Extend (realloc) the arrays
void Realloc(vtkIdType sze)
{
for (std::vector<BaseArrayPair*>::iterator it = Arrays.begin();
it != Arrays.end(); ++it)
{
(*it)->Realloc(sze);
}
}
// Only you can prevent memory leaks!
~ArrayList()
{
......@@ -165,6 +217,13 @@ struct ArrayList
delete (*it);
}
}
// Return the number of arrays
vtkIdType GetNumberOfArrays()
{
return Arrays.size();
}
};
......
......@@ -22,12 +22,26 @@
// Sort of a little object factory (in conjunction w/ vtkTemplateMacro())
template <typename T>
void CreateArrayPair(ArrayList *list, T *inData, T *outData,
vtkIdType numPts, int numComp, T nullValue)
vtkIdType numPts, int numComp, vtkDataArray *outArray, T nullValue)
{
ArrayPair<T> *pair = new ArrayPair<T>(inData,outData,numPts,numComp, nullValue);
ArrayPair<T> *pair = new ArrayPair<T>(inData,outData,numPts,numComp,outArray,nullValue);
list->Arrays.push_back(pair);
}
// Indicate arrays not to process
void ArrayList::
ExcludeArray(vtkDataArray *da)
{
ExcludedArrays.push_back(da);
}
// Has the specified array been excluded?
bool ArrayList::
IsExcluded(vtkDataArray *da)
{
return (std::find(ExcludedArrays.begin(), ExcludedArrays.end(), da) != ExcludedArrays.end());
}
// Add the arrays to interpolate here
void ArrayList::
AddArrays(vtkIdType numOutPts, vtkDataSetAttributes *inPD, vtkDataSetAttributes *outPD,
......@@ -44,11 +58,11 @@ AddArrays(vtkIdType numOutPts, vtkDataSetAttributes *inPD, vtkDataSetAttributes
for (i=0; i < numArrays; ++i)
{
oArray = outPD->GetArray(i);
if ( oArray )
if ( oArray && ! this->IsExcluded(oArray) )
{
name = oArray->GetName();
iArray = inPD->GetArray(name);
if ( iArray )
if ( iArray && ! this->IsExcluded(iArray) )
{
iType = iArray->GetDataType();
oType = oArray->GetDataType();
......@@ -64,7 +78,7 @@ AddArrays(vtkIdType numOutPts, vtkDataSetAttributes *inPD, vtkDataSetAttributes
{
vtkTemplateMacro(CreateArrayPair(this, static_cast<VTK_TT *>(iD),
static_cast<VTK_TT *>(oD),numOutPts,oNumComp,
static_cast<VTK_TT>(nullValue)));
oArray,static_cast<VTK_TT>(nullValue)));
}//over all VTK types
}//if matching types
}//if matching input array
......
......@@ -18,8 +18,10 @@ vtk_add_test_python(
TestElevationFilter.py
TestFlyingEdges2D.py
TestFlyingEdges3D.py
TestFlyingEdges3DWithInterpolation.py
TestFlyingEdgesExtents.py
TestFlyingEdgesPlaneCutter.py
TestFlyingEdgesPlaneCutterInterpolation.py
TestGridSynchronizedTemplates3D.py
TestMarchingSquares.py
TestProbeFilterImageInput.py
......
......@@ -31,6 +31,8 @@ iso.SetInputConnection(sample.GetOutputPort())
iso.SetValue(0,0.25)
iso.ComputeNormalsOn()
iso.ComputeGradientsOn()
iso.ComputeScalarsOn()
iso.InterpolateAttributesOff()
isoMapper = vtk.vtkPolyDataMapper()
isoMapper.SetInputConnection(iso.GetOutputPort())
......
#!/usr/bin/env python
import vtk
from vtk.test import Testing
from vtk.util.misc import vtkGetDataRoot
VTK_DATA_ROOT = vtkGetDataRoot()
# Create the RenderWindow, Renderer and both Actors
#
ren1 = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.SetMultiSamples(0)
renWin.AddRenderer(ren1)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
# Create a synthetic source
sphere = vtk.vtkSphere()
sphere.SetCenter( 0.0,0.0,0.0)
sphere.SetRadius(0.25)
# Iso-surface to create geometry. Demonstrate the ability to
# interpolate data attributes.
sample = vtk.vtkSampleFunction()
sample.SetImplicitFunction(sphere)
sample.SetModelBounds(-0.5,0.5, -0.5,0.5, -0.5,0.5)
sample.SetSampleDimensions(100,100,100)
# Now create some new attributes
cyl = vtk.vtkCylinder()
cyl.SetRadius(0.1)
cyl.SetAxis(1,1,1)
attr = vtk.vtkSampleImplicitFunctionFilter()
attr.SetInputConnection(sample.GetOutputPort())
attr.SetImplicitFunction(cyl)
attr.ComputeGradientsOn()
attr.Update()
iso = vtk.vtkFlyingEdges3D()
iso.SetInputConnection(attr.GetOutputPort())
iso.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_POINTS, "scalars")
iso.SetValue(0,0.25)
iso.ComputeNormalsOn()
iso.ComputeGradientsOn()
iso.ComputeScalarsOn()
iso.InterpolateAttributesOn()
# Time execution
timer = vtk.vtkTimerLog()
timer.StartTimer()
iso.Update()
timer.StopTimer()
time = timer.GetElapsedTime()
print("Flying edges with attributes: {0}".format(time))
isoMapper = vtk.vtkPolyDataMapper()
isoMapper.SetInputConnection(iso.GetOutputPort())
isoMapper.ScalarVisibilityOn()
isoMapper.SetScalarModeToUsePointFieldData()
isoMapper.SelectColorArray("Implicit scalars")
isoMapper.SetScalarRange(0,.3)
isoActor = vtk.vtkActor()
isoActor.SetMapper(isoMapper)
isoActor.GetProperty().SetColor(1,1,1)
isoActor.GetProperty().SetOpacity(1)
outline = vtk.vtkOutlineFilter()
outline.SetInputConnection(sample.GetOutputPort())
outlineMapper = vtk.vtkPolyDataMapper()
outlineMapper.SetInputConnection(outline.GetOutputPort())
outlineActor = vtk.vtkActor()
outlineActor.SetMapper(outlineMapper)
outlineProp = outlineActor.GetProperty()
# Add the actors to the renderer, set the background and size
#
ren1.AddActor(outlineActor)
ren1.AddActor(isoActor)
ren1.SetBackground(0,0,0)
renWin.SetSize(300,300)
ren1.ResetCamera()
iren.Initialize()
renWin.Render()
# --- end of script --
#!/usr/bin/env python
import vtk
from vtk.test import Testing
from vtk.util.misc import vtkGetDataRoot
VTK_DATA_ROOT = vtkGetDataRoot()
res = 100
# Create the RenderWindow, Renderer and both Actors
#
ren1 = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.SetMultiSamples(0)
renWin.AddRenderer(ren1)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
# Create a synthetic source: sample a sphere across a volume
sphere = vtk.vtkSphere()
sphere.SetCenter( 0.0,0.0,0.0)
sphere.SetRadius(0.25)
sample = vtk.vtkSampleFunction()
sample.SetImplicitFunction(sphere)
sample.SetModelBounds(-0.5,0.5, -0.5,0.5, -0.5,0.5)
sample.SetSampleDimensions(res,res,res)
sample.ComputeNormalsOff()
sample.Update()
# Now create some new attributes to interpolate
cyl = vtk.vtkCylinder()
cyl.SetRadius(0.1)
cyl.SetAxis(1,1,1)
attr = vtk.vtkSampleImplicitFunctionFilter()
attr.SetInputConnection(sample.GetOutputPort())
attr.SetImplicitFunction(cyl)
attr.ComputeGradientsOn()
attr.Update()
# The cut plane
plane = vtk.vtkPlane()
plane.SetOrigin(-.2,-.2,-.2)
plane.SetNormal(1,1,1)
# Perform the cutting on named scalars
cut = vtk.vtkFlyingEdgesPlaneCutter()
cut.SetInputConnection(attr.GetOutputPort())
cut.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_POINTS, "scalars")
cut.SetPlane(plane)
cut.ComputeNormalsOff()
cut.InterpolateAttributesOn()
# Time the execution of the filter
timer = vtk.vtkExecutionTimer()
timer.SetFilter(cut)
cut.Update()
CG = timer.GetElapsedWallClockTime()
print ("Cut and interpolate volume:", CG)
cutMapper = vtk.vtkPolyDataMapper()
cutMapper.SetInputConnection(cut.GetOutputPort())
cutMapper.SetScalarModeToUsePointFieldData()
cutMapper.SelectColorArray("Implicit scalars")
cutActor = vtk.vtkActor()
cutActor.SetMapper(cutMapper)
cutActor.GetProperty().SetColor(1,1,1)
cutActor.GetProperty().SetOpacity(1)
# Look at the vectors
ranPts = vtk.vtkMaskPoints()
ranPts.SetOnRatio(25)
ranPts.SetInputConnection(cut.GetOutputPort())
hhog = vtk.vtkHedgeHog()
hhog.SetInputConnection(ranPts.GetOutputPort())
hhog.SetVectorModeToUseVector()
hhog.SetScaleFactor(0.05)
hhogMapper = vtk.vtkPolyDataMapper()
hhogMapper.SetInputConnection(hhog.GetOutputPort())
hhogActor = vtk.vtkActor()
hhogActor.SetMapper(hhogMapper)
hhogActor.GetProperty().SetColor(1,1,1)
hhogActor.GetProperty().SetOpacity(1)
# Outline
outline = vtk.vtkOutlineFilter()
outline.SetInputConnection(sample.GetOutputPort())
outlineMapper = vtk.vtkPolyDataMapper()
outlineMapper.SetInputConnection(outline.GetOutputPort())
outlineActor = vtk.vtkActor()
outlineActor.SetMapper(outlineMapper)
outlineProp = outlineActor.GetProperty()
# Add the actors to the renderer, set the background and size
#
ren1.AddActor(outlineActor)
ren1.AddActor(cutActor)
ren1.AddActor(hhogActor)
ren1.SetBackground(0,0,0)
renWin.SetSize(400,400)
ren1.ResetCamera()
iren.Initialize()
renWin.Render()
# --- end of script --
This diff is collapsed.
......@@ -100,6 +100,15 @@ public:
vtkGetMacro(ComputeScalars,int);
vtkBooleanMacro(ComputeScalars,int);
// Description:
// Indicate whether to interpolate other attribute data. That is, as the
// isosurface is generated, interpolate all point attribute data across
// the edge. This is independent of scalar interpolation, which is
// controlled by the ComputeScalars flag.
vtkSetMacro(InterpolateAttributes,int);
vtkGetMacro(InterpolateAttributes,int);
vtkBooleanMacro(InterpolateAttributes,int);
// Description:
// Set a particular contour value at contour number i. The index i ranges
// between 0<=i<NumberOfContours.
......@@ -157,6 +166,7 @@ protected:
int ComputeNormals;
int ComputeGradients;
int ComputeScalars;
int InterpolateAttributes;
int ArrayComponent;
vtkContourValues *ContourValues;
......
This diff is collapsed.
......@@ -78,6 +78,14 @@ public:
vtkGetMacro(ComputeNormals,int);
vtkBooleanMacro(ComputeNormals,int);
// Description:
// Indicate whether to interpolate other attribute data besides the input
// scalars (which are required). That is, as the isosurface is generated,
// interpolate all other point attribute data across intersected edges.
vtkSetMacro(InterpolateAttributes,int);
vtkGetMacro(InterpolateAttributes,int);
vtkBooleanMacro(InterpolateAttributes,int);
// Description:
// Set/get which component of the scalar array to contour on; defaults to 0.
vtkSetMacro(ArrayComponent, int);
......@@ -89,6 +97,7 @@ protected:
vtkPlane *Plane;
int ComputeNormals;
int InterpolateAttributes;
int ArrayComponent;
virtual int RequestData(vtkInformation *, vtkInformationVector **,
......
set(Module_SRCS
vtkArrayListTemplate.txx
vtkEllipsoidalGaussianKernel.cxx
vtkGaussianKernel.cxx
vtkInterpolationKernel.cxx
......@@ -10,17 +9,9 @@ set(Module_SRCS
vtkVoronoiKernel.cxx
)
set(${vtk-module}_HDRS
vtkArrayListTemplate.h
)
set_source_files_properties(
vtkInterpolationKernel
ABSTRACT
)
set_source_files_properties(
vtkArrayListTemplate.txx
WRAP_EXCLUDE
)
vtk_module_library(vtkFiltersPoints ${Module_SRCS})
......@@ -113,6 +113,7 @@ public:
{
x[0] = this->Algo->Origin[0] + i*this->Algo->Spacing[0];
this->Algo->ImplicitFunction->FunctionGradient(x,n);
vtkMath::Normalize(n);
nPtr = this->Algo->Normals + 3*((i-extent[0])+jOffset+kOffset);
nPtr[0] = static_cast<TT>(-n[0]);
nPtr[1] = static_cast<TT>(-n[1]);
......
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