265 lines
9.3 KiB
C++
265 lines
9.3 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkSurfaceLICComposite.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 vtkSurfaceLICComposite
|
|
*
|
|
* This class decomposes the image space and shuffles image space
|
|
* data onto the new decomposition with the necessary guard cells
|
|
* to prevent artifacts at the decomposition boundaries. After the
|
|
* image LIC is computed on the new decomposition this class will
|
|
* un-shuffle the computed LIC back onto the original decomposition
|
|
*/
|
|
|
|
#ifndef vtkSurfaceLICComposite_h
|
|
#define vtkSurfaceLICComposite_h
|
|
|
|
#include "vtkObject.h"
|
|
#include "vtkPixelExtent.h" // for pixel extent
|
|
#include "vtkRenderingLICOpenGL2Module.h" // for export macro
|
|
#include <deque> // for deque
|
|
#include <vector> // for vector
|
|
|
|
class vtkFloatArray;
|
|
class vtkOpenGLRenderWindow;
|
|
class vtkTextureObject;
|
|
class vtkPainterCommunicator;
|
|
|
|
class VTKRENDERINGLICOPENGL2_EXPORT vtkSurfaceLICComposite : public vtkObject
|
|
{
|
|
public:
|
|
static vtkSurfaceLICComposite* New();
|
|
vtkTypeMacro(vtkSurfaceLICComposite, vtkObject);
|
|
void PrintSelf(ostream& os, vtkIndent indent) override;
|
|
|
|
/**
|
|
* Initialize the object based on the following description of the
|
|
* blocks projected onto the render window. wholeExt describes the
|
|
* window size, originalExts describe each block's extent in window
|
|
* coords. stepSize is the window coordinate integration step size.
|
|
* when inplace is true compositing happens on the original extent.
|
|
*/
|
|
void Initialize(const vtkPixelExtent& winExt, const std::deque<vtkPixelExtent>& blockExts,
|
|
int strategy, double stepSize, int nSteps, int normalizeVectors, int enhancedLIC,
|
|
int anitalias);
|
|
|
|
/**
|
|
* Control the screen space decomposition. The available modes are:
|
|
|
|
* INPLACE
|
|
* use the block decomp. This may result in LIC being computed
|
|
* many times for the same pixels and an excessive amount of
|
|
* IPC during compositing if any of the block extents cover
|
|
* or intersect a number of block extents. The input data
|
|
* needs to be shuffled but not unshuffled since for overlapping
|
|
* regions LIC is computed by all processes that overlap.
|
|
* If there is very little overlap between block extents
|
|
* then this method is superior since no unshuffle is needed.
|
|
|
|
* INPLACE_DISJOINT
|
|
* use a disjoint version of the block decomp. This will leave
|
|
* non-overlapping data in place, reasigning overlapping regions
|
|
* so that LIC is computed once for each pixel on the screen.
|
|
* An unshuffle step to move data in overlapping region to all
|
|
* processes that overlap.
|
|
|
|
* BALANCED
|
|
* move to a new decomp where each rank gets an equal number
|
|
* of pixels. This ensures the best load balancing during LIC
|
|
* and that LIC is computed once for each pixel. In the worst
|
|
* case each pixel will be shuffled and unshuffled.
|
|
|
|
* AUTO
|
|
* Use a heuristic to select the mode.
|
|
*/
|
|
enum
|
|
{
|
|
COMPOSITE_INPLACE = 0,
|
|
COMPOSITE_INPLACE_DISJOINT,
|
|
COMPOSITE_BALANCED,
|
|
COMPOSITE_AUTO
|
|
};
|
|
void SetStrategy(int val) { this->Strategy = val; }
|
|
int GetStrategy() { return this->Strategy; }
|
|
|
|
/**
|
|
* Get the number of new extents assigned to this rank after
|
|
* the decomposition.
|
|
*/
|
|
int GetNumberOfCompositeExtents() const { return static_cast<int>(this->CompositeExt.size()); }
|
|
|
|
/**
|
|
* Get the extent of the domain over which to compute the LIC. This can
|
|
* be querried only after the Composite takes place.
|
|
*/
|
|
const vtkPixelExtent& GetGuardExtent(int i = 0) const { return this->GuardExt[i]; }
|
|
|
|
const std::deque<vtkPixelExtent>& GetGuardExtents() const { return this->GuardExt; }
|
|
|
|
/**
|
|
* Get the extent of the domain over which to compute the LIC. This can
|
|
* be querried only after the Composite takes place.
|
|
*/
|
|
const vtkPixelExtent& GetDisjointGuardExtent(int i = 0) const
|
|
{
|
|
return this->DisjointGuardExt[i];
|
|
}
|
|
|
|
const std::deque<vtkPixelExtent>& GetDisjointGuardExtents() const { return this->GuardExt; }
|
|
|
|
/**
|
|
* Get the extent of the domain over which to compute the LIC. This can
|
|
* be querried only after the Composite takes place.
|
|
*/
|
|
const vtkPixelExtent& GetCompositeExtent(int i = 0) const { return this->CompositeExt[i]; }
|
|
|
|
const std::deque<vtkPixelExtent>& GetCompositeExtents() const { return this->CompositeExt; }
|
|
|
|
/**
|
|
* Get the whole dataset extent (all blocks).
|
|
*/
|
|
const vtkPixelExtent& GetDataSetExtent() const { return this->DataSetExt; }
|
|
|
|
/**
|
|
* Get the whole window extent.
|
|
*/
|
|
const vtkPixelExtent& GetWindowExtent() const { return this->WindowExt; }
|
|
|
|
/**
|
|
* Set up for a serial run, makes the decomp disjoint and adds
|
|
* requisite guard pixles.
|
|
*/
|
|
int InitializeCompositeExtents(float* vectors);
|
|
|
|
/**
|
|
* Set the rendering context. Must set prior to use. Reference is not
|
|
* held, so caller must ensure the renderer is not destroyed during
|
|
* use.
|
|
*/
|
|
virtual void SetContext(vtkOpenGLRenderWindow*) {}
|
|
virtual vtkOpenGLRenderWindow* GetContext() { return nullptr; }
|
|
|
|
/**
|
|
* Set the communicator for parallel communication. A duplicate
|
|
* is not made. It is up to the caller to manage the life of
|
|
* the communicator such that it is around while this class
|
|
* needs it and is released after.
|
|
*/
|
|
virtual void SetCommunicator(vtkPainterCommunicator*) {}
|
|
|
|
/**
|
|
* Set the communicator to the default communicator
|
|
*/
|
|
virtual void RestoreDefaultCommunicator() {}
|
|
|
|
/**
|
|
* Build programs to move data to the new decomp
|
|
* In parallel THIS IS A COLLECTIVE OPERATION
|
|
*/
|
|
virtual int BuildProgram(float*) { return -1; }
|
|
|
|
/**
|
|
* Move a single buffer from the geometry decomp to the LIC decomp.
|
|
* THIS IS A COLLECTIVE OPERATION
|
|
*/
|
|
virtual int Gather(void*, int, int, vtkTextureObject*&) { return -1; }
|
|
|
|
/**
|
|
* Move a single buffer from the LIC decomp to the geometry decomp
|
|
* In parallel THIS IS A COLLECTIVE OPERATION
|
|
*/
|
|
virtual int Scatter(void*, int, int, vtkTextureObject*&) { return -1; }
|
|
|
|
/**
|
|
* Make a decomposition disjoint with respect to itself. Extents are
|
|
* removed from the input array and disjoint extents are appended onto
|
|
* the output array. This is a local operation.
|
|
*/
|
|
static int MakeDecompDisjoint(std::deque<vtkPixelExtent>& in, std::deque<vtkPixelExtent>& out);
|
|
|
|
protected:
|
|
vtkSurfaceLICComposite();
|
|
~vtkSurfaceLICComposite() override;
|
|
|
|
/**
|
|
* For serial run. Make a decomposition disjoint. Sorts extents and
|
|
* processes largest to smallest , repeatedly subtracting smaller
|
|
* remaining blocks from the largest remaining. Each extent in the
|
|
* new disjoint set is shrunk to tightly bound the vector data,
|
|
* extents with empty vectors are removed. This is a local operation
|
|
* since vector field is local.
|
|
*/
|
|
int MakeDecompDisjoint(
|
|
const std::deque<vtkPixelExtent>& in, std::deque<vtkPixelExtent>& out, float* vectors);
|
|
|
|
/**
|
|
* Compute max(V) on the given extent.
|
|
*/
|
|
float VectorMax(const vtkPixelExtent& ext, float* vectors);
|
|
|
|
/**
|
|
* Compute max(V) on a set of extents. Neighboring extents are
|
|
* including in the computation.
|
|
*/
|
|
int VectorMax(const std::deque<vtkPixelExtent>& exts, float* vectors, std::vector<float>& vMax);
|
|
|
|
/**
|
|
* Add guard pixels (Serial run)
|
|
*/
|
|
int AddGuardPixels(const std::deque<vtkPixelExtent>& exts, std::deque<vtkPixelExtent>& guardExts,
|
|
std::deque<vtkPixelExtent>& disjointGuardExts, float* vectors);
|
|
|
|
/**
|
|
* shrink pixel extent based on non-zero alpha channel values
|
|
*/
|
|
void GetPixelBounds(float* rgba, int ni, vtkPixelExtent& ext);
|
|
|
|
/**
|
|
* factor for determining extra padding for guard pixels.
|
|
* depends on window aspect ratio because of anisotropic
|
|
* transform to texture space. see note in implementation.
|
|
*/
|
|
float GetFudgeFactor(int nx[2]);
|
|
|
|
protected:
|
|
int Pass; // id for mpi tagging
|
|
|
|
vtkPixelExtent WindowExt; // screen extent (screen size)
|
|
vtkPixelExtent DataSetExt; // screen extent of the dataset
|
|
std::deque<vtkPixelExtent> BlockExts; // screen extents of blocks
|
|
|
|
std::deque<vtkPixelExtent> CompositeExt; // screen extents after decomp
|
|
std::deque<vtkPixelExtent> GuardExt; // screen extents w/ guard cells
|
|
std::deque<vtkPixelExtent> DisjointGuardExt; // screen extents w/ guard cells
|
|
|
|
int Strategy; // control for parallel composite
|
|
|
|
double StepSize; // window coordinates step size
|
|
int NumberOfSteps; // number of integration steps
|
|
int NormalizeVectors; // does integrator normailze
|
|
int NumberOfGuardLevels; // 1.5 if enhanced LIC 1 otherwise
|
|
int NumberOfEEGuardPixels; // 1 if enhanced LIC 0 otherwise
|
|
int NumberOfAAGuardPixels; // n antialias passes
|
|
|
|
private:
|
|
vtkSurfaceLICComposite(const vtkSurfaceLICComposite&) = delete;
|
|
void operator=(const vtkSurfaceLICComposite&) = delete;
|
|
|
|
friend ostream& operator<<(ostream& os, vtkSurfaceLICComposite& ss);
|
|
};
|
|
|
|
ostream& operator<<(ostream& os, vtkSurfaceLICComposite& ss);
|
|
|
|
#endif
|