You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
447 lines
13 KiB
C++
447 lines
13 KiB
C++
// -*- c++ -*-
|
|
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkSLACReader.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.
|
|
|
|
=========================================================================*/
|
|
|
|
/*-------------------------------------------------------------------------
|
|
Copyright 2008 Sandia Corporation.
|
|
Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
|
the U.S. Government retains certain rights in this software.
|
|
-------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* @class vtkSLACReader
|
|
*
|
|
*
|
|
*
|
|
* A reader for a data format used by Omega3p, Tau3p, and several other tools
|
|
* used at the Standford Linear Accelerator Center (SLAC). The underlying
|
|
* format uses netCDF to store arrays, but also imposes several conventions
|
|
* to form an unstructured grid of elements.
|
|
*
|
|
*/
|
|
|
|
#ifndef vtkSLACReader_h
|
|
#define vtkSLACReader_h
|
|
|
|
#include "vtkIONetCDFModule.h" // For export macro
|
|
#include "vtkMultiBlockDataSetAlgorithm.h"
|
|
|
|
#include "vtkSmartPointer.h" // For internal method.
|
|
|
|
class vtkDataArraySelection;
|
|
class vtkDoubleArray;
|
|
class vtkIdTypeArray;
|
|
class vtkInformationIntegerKey;
|
|
class vtkInformationObjectBaseKey;
|
|
|
|
class VTKIONETCDF_EXPORT vtkSLACReader : public vtkMultiBlockDataSetAlgorithm
|
|
{
|
|
public:
|
|
vtkTypeMacro(vtkSLACReader, vtkMultiBlockDataSetAlgorithm);
|
|
static vtkSLACReader* New();
|
|
void PrintSelf(ostream& os, vtkIndent indent) override;
|
|
|
|
vtkGetStringMacro(MeshFileName);
|
|
vtkSetStringMacro(MeshFileName);
|
|
|
|
//@{
|
|
/**
|
|
* There may be one mode file (usually for actual modes) or multiple mode
|
|
* files (which usually actually represent time series). These methods
|
|
* set and clear the list of mode files (which can be a single mode file).
|
|
*/
|
|
virtual void AddModeFileName(const char* fname);
|
|
virtual void RemoveAllModeFileNames();
|
|
virtual unsigned int GetNumberOfModeFileNames();
|
|
virtual const char* GetModeFileName(unsigned int idx);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* If on, reads the internal volume of the data set. Set to off by default.
|
|
*/
|
|
vtkGetMacro(ReadInternalVolume, vtkTypeBool);
|
|
vtkSetMacro(ReadInternalVolume, vtkTypeBool);
|
|
vtkBooleanMacro(ReadInternalVolume, vtkTypeBool);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* If on, reads the external surfaces of the data set. Set to on by default.
|
|
*/
|
|
vtkGetMacro(ReadExternalSurface, vtkTypeBool);
|
|
vtkSetMacro(ReadExternalSurface, vtkTypeBool);
|
|
vtkBooleanMacro(ReadExternalSurface, vtkTypeBool);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* If on, reads midpoint information for external surfaces and builds
|
|
* quadratic surface triangles. Set to on by default.
|
|
*/
|
|
vtkGetMacro(ReadMidpoints, vtkTypeBool);
|
|
vtkSetMacro(ReadMidpoints, vtkTypeBool);
|
|
vtkBooleanMacro(ReadMidpoints, vtkTypeBool);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Variable array selection.
|
|
*/
|
|
virtual int GetNumberOfVariableArrays();
|
|
virtual const char* GetVariableArrayName(int idx);
|
|
virtual int GetVariableArrayStatus(const char* name);
|
|
virtual void SetVariableArrayStatus(const char* name, int status);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Sets the scale factor for each mode. Each scale factor is reset to 1.
|
|
*/
|
|
virtual void ResetFrequencyScales();
|
|
virtual void SetFrequencyScale(int index, double scale);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Sets the phase offset for each mode. Each shift is reset to 0.
|
|
*/
|
|
virtual void ResetPhaseShifts();
|
|
virtual void SetPhaseShift(int index, double shift);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* NOTE: This is not thread-safe.
|
|
*/
|
|
virtual vtkDoubleArray* GetFrequencyScales();
|
|
virtual vtkDoubleArray* GetPhaseShifts();
|
|
//@}
|
|
|
|
/**
|
|
* Returns true if the given file can be read by this reader.
|
|
*/
|
|
static int CanReadFile(const char* filename);
|
|
|
|
/**
|
|
* This key is attached to the metadata information of all data sets in the
|
|
* output that are part of the internal volume.
|
|
*/
|
|
static vtkInformationIntegerKey* IS_INTERNAL_VOLUME();
|
|
|
|
/**
|
|
* This key is attached to the metadata information of all data sets in the
|
|
* output that are part of the external surface.
|
|
*/
|
|
static vtkInformationIntegerKey* IS_EXTERNAL_SURFACE();
|
|
|
|
//@{
|
|
/**
|
|
* All the data sets stored in the multiblock output share the same point
|
|
* data. For convenience, the point coordinates (vtkPoints) and point data
|
|
* (vtkPointData) are saved under these keys in the vtkInformation of the
|
|
* output data set.
|
|
*/
|
|
static vtkInformationObjectBaseKey* POINTS();
|
|
static vtkInformationObjectBaseKey* POINT_DATA();
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Simple class used internally to define an edge based on the endpoints. The
|
|
* endpoints are canonically identified by the lower and higher values.
|
|
*/
|
|
class VTKIONETCDF_EXPORT EdgeEndpoints
|
|
{
|
|
public:
|
|
EdgeEndpoints()
|
|
: MinEndPoint(-1)
|
|
, MaxEndPoint(-1)
|
|
{
|
|
}
|
|
EdgeEndpoints(vtkIdType endpointA, vtkIdType endpointB)
|
|
{
|
|
if (endpointA < endpointB)
|
|
{
|
|
this->MinEndPoint = endpointA;
|
|
this->MaxEndPoint = endpointB;
|
|
}
|
|
else
|
|
{
|
|
this->MinEndPoint = endpointB;
|
|
this->MaxEndPoint = endpointA;
|
|
}
|
|
}
|
|
inline vtkIdType GetMinEndPoint() const { return this->MinEndPoint; }
|
|
inline vtkIdType GetMaxEndPoint() const { return this->MaxEndPoint; }
|
|
inline bool operator==(const EdgeEndpoints& other) const
|
|
{
|
|
return ((this->GetMinEndPoint() == other.GetMinEndPoint()) &&
|
|
(this->GetMaxEndPoint() == other.GetMaxEndPoint()));
|
|
}
|
|
|
|
protected:
|
|
vtkIdType MinEndPoint;
|
|
vtkIdType MaxEndPoint;
|
|
};
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Simple class used internally for holding midpoint information.
|
|
*/
|
|
class VTKIONETCDF_EXPORT MidpointCoordinates
|
|
{
|
|
public:
|
|
MidpointCoordinates() {}
|
|
MidpointCoordinates(const double coord[3], vtkIdType id)
|
|
{
|
|
this->Coordinate[0] = coord[0];
|
|
this->Coordinate[1] = coord[1];
|
|
this->Coordinate[2] = coord[2];
|
|
this->ID = id;
|
|
}
|
|
double Coordinate[3];
|
|
vtkIdType ID;
|
|
};
|
|
//@}
|
|
|
|
enum
|
|
{
|
|
SURFACE_OUTPUT = 0,
|
|
VOLUME_OUTPUT = 1,
|
|
NUM_OUTPUTS = 2
|
|
};
|
|
|
|
protected:
|
|
vtkSLACReader();
|
|
~vtkSLACReader() override;
|
|
|
|
class vtkInternal;
|
|
vtkInternal* Internal;
|
|
|
|
// Friend so vtkInternal can access MidpointIdMap
|
|
// (so Sun CC compiler doesn't complain).
|
|
friend class vtkInternal;
|
|
|
|
char* MeshFileName;
|
|
|
|
vtkTypeBool ReadInternalVolume;
|
|
vtkTypeBool ReadExternalSurface;
|
|
vtkTypeBool ReadMidpoints;
|
|
|
|
/**
|
|
* True if reading from a proper mode file. Set in RequestInformation.
|
|
*/
|
|
bool ReadModeData;
|
|
|
|
/**
|
|
* True if "mode" files are a sequence of time steps.
|
|
*/
|
|
bool TimeStepModes;
|
|
|
|
/**
|
|
* True if mode files describe vibrating fields.
|
|
*/
|
|
bool FrequencyModes;
|
|
|
|
int RequestInformation(vtkInformation* request, vtkInformationVector** inputVector,
|
|
vtkInformationVector* outputVector) override;
|
|
|
|
int RequestData(vtkInformation* request, vtkInformationVector** inputVector,
|
|
vtkInformationVector* outputVector) override;
|
|
|
|
/**
|
|
* Callback registered with the VariableArraySelection.
|
|
*/
|
|
static void SelectionModifiedCallback(
|
|
vtkObject* caller, unsigned long eid, void* clientdata, void* calldata);
|
|
|
|
/**
|
|
* Convenience function that checks the dimensions of a 2D netCDF array that
|
|
* is supposed to be a set of tuples. It makes sure that the number of
|
|
* dimensions is expected and that the number of components in each tuple
|
|
* agree with what is expected. It then returns the number of tuples. An
|
|
* error is emitted and 0 is returned if the checks fail.
|
|
*/
|
|
virtual vtkIdType GetNumTuplesInVariable(int ncFD, int varId, int expectedNumComponents);
|
|
|
|
/**
|
|
* Checks the winding of the tetrahedra in the mesh file. Returns 1 if
|
|
* the winding conforms to VTK, 0 if the winding needs to be corrected.
|
|
*/
|
|
virtual int CheckTetrahedraWinding(int meshFD);
|
|
|
|
/**
|
|
* Read the connectivity information from the mesh file. Returns 1 on
|
|
* success, 0 on failure.
|
|
*/
|
|
virtual int ReadConnectivity(
|
|
int meshFD, vtkMultiBlockDataSet* surfaceOutput, vtkMultiBlockDataSet* volumeOutput);
|
|
|
|
//@{
|
|
/**
|
|
* Reads tetrahedron connectivity arrays. Called by ReadConnectivity.
|
|
*/
|
|
virtual int ReadTetrahedronInteriorArray(int meshFD, vtkIdTypeArray* connectivity);
|
|
virtual int ReadTetrahedronExteriorArray(int meshFD, vtkIdTypeArray* connectivity);
|
|
//@}
|
|
|
|
/**
|
|
* Reads point data arrays. Called by ReadCoordinates and ReadFieldData.
|
|
*/
|
|
virtual vtkSmartPointer<vtkDataArray> ReadPointDataArray(int ncFD, int varId);
|
|
|
|
/**
|
|
* Helpful constants equal to the amount of identifiers per tet.
|
|
*/
|
|
enum
|
|
{
|
|
NumPerTetInt = 5,
|
|
NumPerTetExt = 9
|
|
};
|
|
|
|
//@{
|
|
/**
|
|
* Manages a map from edges to midpoint coordinates.
|
|
*/
|
|
class VTKIONETCDF_EXPORT MidpointCoordinateMap
|
|
{
|
|
public:
|
|
MidpointCoordinateMap();
|
|
~MidpointCoordinateMap();
|
|
//@}
|
|
|
|
void AddMidpoint(const EdgeEndpoints& edge, const MidpointCoordinates& midpoint);
|
|
void RemoveMidpoint(const EdgeEndpoints& edge);
|
|
void RemoveAllMidpoints();
|
|
vtkIdType GetNumberOfMidpoints() const;
|
|
|
|
/**
|
|
* Finds the coordinates for the given edge or returns nullptr if it
|
|
* does not exist.
|
|
*/
|
|
MidpointCoordinates* FindMidpoint(const EdgeEndpoints& edge);
|
|
|
|
protected:
|
|
class vtkInternal;
|
|
vtkInternal* Internal;
|
|
|
|
private:
|
|
// Too lazy to implement these.
|
|
MidpointCoordinateMap(const MidpointCoordinateMap&);
|
|
void operator=(const MidpointCoordinateMap&);
|
|
};
|
|
|
|
//@{
|
|
/**
|
|
* Manages a map from edges to the point id of the midpoint.
|
|
*/
|
|
class VTKIONETCDF_EXPORT MidpointIdMap
|
|
{
|
|
public:
|
|
MidpointIdMap();
|
|
~MidpointIdMap();
|
|
//@}
|
|
|
|
void AddMidpoint(const EdgeEndpoints& edge, vtkIdType midpoint);
|
|
void RemoveMidpoint(const EdgeEndpoints& edge);
|
|
void RemoveAllMidpoints();
|
|
vtkIdType GetNumberOfMidpoints() const;
|
|
|
|
/**
|
|
* Finds the id for the given edge or returns nullptr if it does not exist.
|
|
*/
|
|
vtkIdType* FindMidpoint(const EdgeEndpoints& edge);
|
|
|
|
/**
|
|
* Initialize iteration. The iteration can occur in any order.
|
|
*/
|
|
void InitTraversal();
|
|
/**
|
|
* Get the next midpoint in the iteration. Return 0 if the end is reached.
|
|
*/
|
|
bool GetNextMidpoint(EdgeEndpoints& edge, vtkIdType& midpoint);
|
|
|
|
protected:
|
|
class vtkInternal;
|
|
vtkInternal* Internal;
|
|
|
|
private:
|
|
// Too lazy to implement these.
|
|
MidpointIdMap(const MidpointIdMap&);
|
|
void operator=(const MidpointIdMap&);
|
|
};
|
|
|
|
/**
|
|
* Read in the point coordinate data from the mesh file. Returns 1 on
|
|
* success, 0 on failure.
|
|
*/
|
|
virtual int ReadCoordinates(int meshFD, vtkMultiBlockDataSet* output);
|
|
|
|
/**
|
|
* Reads in the midpoint coordinate data from the mesh file and returns a map
|
|
* from edges to midpoints. This method is called by ReadMidpointData.
|
|
* Returns 1 on success, 0 on failure.
|
|
*/
|
|
virtual int ReadMidpointCoordinates(
|
|
int meshFD, vtkMultiBlockDataSet* output, MidpointCoordinateMap& map);
|
|
|
|
/**
|
|
* Read in the midpoint data from the mesh file. Returns 1 on success,
|
|
* 0 on failure. Also fills a midpoint id map that will be passed into
|
|
* InterpolateMidpointFieldData.
|
|
*/
|
|
virtual int ReadMidpointData(int meshFD, vtkMultiBlockDataSet* output, MidpointIdMap& map);
|
|
|
|
/**
|
|
* Instead of reading data from the mesh file, restore the data from the
|
|
* previous mesh file read.
|
|
*/
|
|
virtual int RestoreMeshCache(vtkMultiBlockDataSet* surfaceOutput,
|
|
vtkMultiBlockDataSet* volumeOutput, vtkMultiBlockDataSet* compositeOutput);
|
|
|
|
/**
|
|
* Read in the field data from the mode file. Returns 1 on success, 0
|
|
* on failure.
|
|
*/
|
|
virtual int ReadFieldData(const int* modeFDArray, int numModeFDs, vtkMultiBlockDataSet* output);
|
|
|
|
/**
|
|
* Takes the data read on the fields and interpolates data for the midpoints.
|
|
* map is the same map that was created in ReadMidpointData.
|
|
*/
|
|
virtual int InterpolateMidpointData(vtkMultiBlockDataSet* output, MidpointIdMap& map);
|
|
|
|
/**
|
|
* A time stamp for the last time the mesh file was read. This is used to
|
|
* determine whether the mesh needs to be read in again or if we just need
|
|
* to read the mode data.
|
|
*/
|
|
vtkTimeStamp MeshReadTime;
|
|
|
|
/**
|
|
* Returns 1 if the mesh is up to date, 0 if the mesh needs to be read from
|
|
* disk.
|
|
*/
|
|
virtual int MeshUpToDate();
|
|
|
|
private:
|
|
vtkSLACReader(const vtkSLACReader&) = delete;
|
|
void operator=(const vtkSLACReader&) = delete;
|
|
};
|
|
|
|
#endif // vtkSLACReader_h
|