Commit 3f83a466 authored by Joachim Pouderoux's avatar Joachim Pouderoux Committed by Kitware Robot

Merge topic 'surfaceStreamlines'

d658e82f VTK Style
b117a066 Adding surface streamlines
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Merge-request: !169
parents 914c0761 d658e82f
vtk_add_test_cxx(${vtk-module}CxxTests tests
TestBSPTree.cxx
TestStreamTracer.cxx,NO_VALID
TestStreamTracerSurface.cxx
TestAMRInterpolatedVelocityField.cxx,NO_VALID
TestParticleTracers.cxx,NO_VALID
)
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestDistancePolyDataFilter.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 "vtkArrayCalculator.h"
#include "vtkDataSetMapper.h"
#include "vtkMath.h"
#include "vtkNew.h"
#include "vtkProperty.h"
#include "vtkPolyData.h"
#include "vtkPoints.h"
#include "vtkPointSource.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRTAnalyticSource.h"
#include "vtkStreamTracer.h"
#include "vtkWarpScalar.h"
int TestStreamTracerSurface(int argc, char* argv[])
{
vtkNew<vtkRTAnalyticSource> wavelet;
wavelet->SetWholeExtent(-10, 100, -10, 100, 0, 0);
vtkNew<vtkWarpScalar> warp;
warp->SetScaleFactor(0.1);
warp->SetInputConnection(wavelet->GetOutputPort());
vtkNew<vtkArrayCalculator> calc;
calc->AddScalarArrayName("RTData");
calc->SetFunction("abs(RTData)*iHat + abs(RTData)*jHat");
calc->SetInputConnection(warp->GetOutputPort());
calc->Update();
vtkNew<vtkPoints> points;
vtkDataSet* calcData = calc->GetOutput();
vtkIdType nLine = static_cast<vtkIdType>(sqrt(static_cast<double>(calcData->GetNumberOfPoints())));
for (vtkIdType i = 0; i < nLine; i += 10)
{
points->InsertNextPoint(calcData->GetPoint(i * (nLine - 1) + nLine));
}
vtkNew<vtkPolyData> pointsPolydata;
pointsPolydata->SetPoints(points.Get());
vtkNew<vtkStreamTracer> stream;
stream->SurfaceStreamlinesOn();
stream->SetMaximumPropagation(210);
stream->SetIntegrationDirection(vtkStreamTracer::BOTH);
stream->SetInputConnection(calc->GetOutputPort());
stream->SetSourceData(pointsPolydata.Get());
vtkNew<vtkDataSetMapper> streamMapper;
streamMapper->SetInputConnection(stream->GetOutputPort());
streamMapper->ScalarVisibilityOff();
vtkNew<vtkDataSetMapper> surfaceMapper;
surfaceMapper->SetInputConnection(calc->GetOutputPort());
vtkNew<vtkActor> streamActor;
streamActor->SetMapper(streamMapper.Get());
streamActor->GetProperty()->SetColor(1, 1, 1);
streamActor->GetProperty()->SetLineWidth(4.);
streamActor->SetPosition(0, 0, 1);
vtkNew<vtkActor> surfaceActor;
surfaceActor->SetMapper(surfaceMapper.Get());
surfaceActor->GetProperty()->SetRepresentationToSurface();
vtkNew<vtkRenderer> renderer;
renderer->AddActor(surfaceActor.GetPointer());
renderer->AddActor(streamActor.GetPointer());
renderer->ResetCamera();
renderer->SetBackground(1., 1., 1.);
vtkNew<vtkRenderWindow> renWin;
renWin->AddRenderer(renderer.GetPointer());
renWin->SetMultiSamples(0);
renWin->SetSize(300, 300);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin.GetPointer());
int retVal = vtkRegressionTestImage(renWin.GetPointer());
if (retVal == vtkRegressionTester::DO_INTERACTOR)
{
iren->Start();
}
return !retVal;
}
......@@ -142,6 +142,17 @@ public:
vtkSetMacro( NormalizeVector, bool );
vtkGetMacro( NormalizeVector, bool );
// Description:
// If set to true, the first three point of the cell will be used to compute a normal to the cell,
// this normal will then be removed from the vorticity so the resulting vector in tangent to the cell.
vtkSetMacro(ForceSurfaceTangentVector, bool);
vtkGetMacro(ForceSurfaceTangentVector, bool);
// Description:
// If set to true, cell within tolerance factor will always be found, except for edges.
vtkSetMacro(SurfaceDataset, bool);
vtkGetMacro(SurfaceDataset, bool);
// Description:
// Import parameters. Sub-classes can add more after chaining.
virtual void CopyParameters( vtkAbstractInterpolatedVelocityField * from )
......@@ -167,16 +178,20 @@ protected:
~vtkAbstractInterpolatedVelocityField();
static const double TOLERANCE_SCALE;
static const double SURFACE_TOLERANCE_SCALE;
int CacheHit;
int CacheMiss;
int WeightsSize;
bool Caching;
bool NormalizeVector;
bool ForceSurfaceTangentVector;
bool SurfaceDataset;
int VectorsType;
char * VectorsSelection;
double * Weights;
double LastPCoords[3];
int LastSubId;
vtkIdType LastCellId;
vtkDataSet * LastDataSet;
vtkGenericCell * Cell;
......@@ -195,8 +210,22 @@ protected:
// for cell location. In vtkCellLocatorInterpolatedVelocityField, this function
// is invoked just to handle vtkImageData and vtkRectilinearGrid that are not
// assigned with any vtkAbstractCellLocatot-type cell locator.
// If activated, returned vector will be tangential to the first
// three point of the cell
virtual int FunctionValues( vtkDataSet * ds, double * x, double * f );
// Description:
// Check that all three pcoords are between 0 and 1 included.
virtual bool CheckPCoords(double pcoords[3]);
// Description
// Try to find the cell closest to provided x point in provided dataset,
// By first testing inclusion in it's cached cell and neighbor
// Then testing globally
// Then , only if surfacic is activated finding the closest cell
// using FindPoint and comparing distance with tolerance
virtual bool FindAndUpdateCell(vtkDataSet* ds, double* x);
//BTX
friend class vtkTemporalInterpolatedVelocityField;
// Description:
......
......@@ -101,6 +101,23 @@ int vtkInterpolatedVelocityField::FunctionValues( double * x, double * f )
return retVal;
}
//----------------------------------------------------------------------------
int vtkInterpolatedVelocityField::SnapPointOnCell(double* pOrigin, double* pSnap)
{
if (this->LastDataSet == NULL)
{
return 0;
}
if (!this->FindAndUpdateCell(this->LastDataSet, pOrigin))
{
return 0;
}
double dist2;
this->GenCell->EvaluatePosition
(pOrigin, pSnap, this->LastSubId, this->LastPCoords, dist2, this->Weights);
return 1;
}
//----------------------------------------------------------------------------
void vtkInterpolatedVelocityField::PrintSelf( ostream & os, vtkIndent indent )
{
......
......@@ -78,6 +78,10 @@ public:
// Evaluate the velocity field f at point (x, y, z).
virtual int FunctionValues( double * x, double * f );
// Description:
// Project the provided point on current cell, current dataset.
virtual int SnapPointOnCell(double* pOrigin, double* pProj);
// Description:
// Set the cell id cached by the last evaluation within a specified dataset.
virtual void SetLastCellId( vtkIdType c, int dataindex );
......
......@@ -126,6 +126,8 @@ vtkStreamTracer::vtkStreamTracer()
vtkDataSetAttributes::VECTORS);
this->HasMatchingPointAttributes = true;
this->SurfaceStreamlines = false;
}
vtkStreamTracer::~vtkStreamTracer()
......@@ -700,6 +702,24 @@ void vtkStreamTracer::Integrate(vtkPointData *input0Data,
this->GetIntegrator()->NewInstance();
integrator->SetFunctionSet(func);
// Check Surface option
vtkInterpolatedVelocityField* surfaceFunc = NULL;
if (this->SurfaceStreamlines == true)
{
surfaceFunc = vtkInterpolatedVelocityField::SafeDownCast(func);
if (surfaceFunc == NULL)
{
vtkWarningMacro(<< "Surface Streamlines works only with Point Locator "
"Interpolated Velocity Field, setting it off");
this->SetSurfaceStreamlines(false);
}
else
{
surfaceFunc->SetForceSurfaceTangentVector(true);
surfaceFunc->SetSurfaceDataset(true);
}
}
// Since we do not know what the total number of points
// will be, we do not allocate any. This is important for
// cases where a lot of streamers are used at once. If we
......@@ -951,9 +971,21 @@ void vtkStreamTracer::Integrate(vtkPointData *input0Data,
}
// This is the next starting point
for(i=0; i<3; i++)
if (this->SurfaceStreamlines && surfaceFunc != NULL)
{
point1[i] = point2[i];
if (surfaceFunc->SnapPointOnCell(point2, point1) != 1)
{
retVal = OUT_OF_DOMAIN;
memcpy(lastPoint, point2, 3 * sizeof(double));
break;
}
}
else
{
for (i = 0; i < 3; i++)
{
point1[i] = point2[i];
}
}
// Interpolate the velocity at the next point
......
......@@ -244,6 +244,12 @@ public:
vtkSetMacro(TerminalSpeed, double);
vtkGetMacro(TerminalSpeed, double);
// Description:
// Set/Unset the streamlines to be computed on a surface
vtkGetMacro(SurfaceStreamlines, bool);
vtkSetMacro(SurfaceStreamlines, bool);
vtkBooleanMacro(SurfaceStreamlines, bool);
//BTX
enum
{
......@@ -384,6 +390,9 @@ protected:
bool ComputeVorticity;
double RotationScale;
// Compute streamlines only on surface.
bool SurfaceStreamlines;
vtkAbstractInterpolatedVelocityField * InterpolatorPrototype;
vtkCompositeDataSet* InputData;
......
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