// -*- 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 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