MDAL
mdal_selafin.hpp
1 /*
2  MDAL - Mesh Data Abstraction Library (MIT License)
3  Copyright (C) 2019 Peter Petrik (zilolv at gmail dot com)
4 */
5 
6 #ifndef MDAL_SELAFIN_HPP
7 #define MDAL_SELAFIN_HPP
8 
9 #include <string>
10 #include <memory>
11 #include <map>
12 #include <iostream>
13 #include <fstream>
14 
15 #include "mdal_data_model.hpp"
16 #include "mdal_memory_data_model.hpp"
17 #include "mdal.h"
18 #include "mdal_driver.hpp"
19 
20 namespace MDAL
21 {
42  {
43  public:
45  SelafinFile( const std::string &fileName );
46 
48  static std::unique_ptr<Mesh> createMesh( const std::string &fileName );
50  static void populateDataset( Mesh *mesh, const std::string &fileName );
51 
53  std::string readHeader();
54 
56  bool addDatasetGroup( DatasetGroup *datasetGroup );
57 
58  private:
59 
61  void initialize();
62 
64  void parseFile();
65 
67  size_t verticesCount();
69  size_t facesCount();
71  size_t verticesPerFace();
72 
74  std::vector<double> datasetValues( size_t timeStepIndex, size_t variableIndex, size_t offset, size_t count );
76  std::vector<int> connectivityIndex( size_t offset, size_t count );
78  std::vector<double> vertices( size_t offset, size_t count );
79 
81  std::string readString( size_t len );
82 
87  std::vector<double> readDoubleArr( size_t len );
88 
93  std::vector<int> readIntArr( size_t len );
94 
99  std::vector<double> readDoubleArr( const std::streampos &position, size_t offset, size_t len );
100 
105  std::vector<int> readIntArr( const std::streampos &position, size_t offset, size_t len );
106 
108  bool checkIntArraySize( size_t len );
109 
111  bool checkDoubleArraySize( size_t len );
112 
114  size_t remainingBytes();
115 
120  std::streampos passThroughIntArray( size_t size );
121 
126  std::streampos passThroughDoubleArray( size_t size );
127 
128  double readDouble( );
129  int readInt( );
130  size_t readSizeT( );
131 
132  void ignoreArrayLength( );
133  std::string readStringWithoutLength( size_t len );
134  void ignore( int len );
135 
136  static void populateDataset( Mesh *mesh, std::shared_ptr<SelafinFile> reader );
137 
138  // ///////
139  // attribute updated by parseFile() method
140  // //////
141  std::vector<int> mParameters;
142  // Dataset
143  DateTime mReferenceTime;
144  std::vector<std::vector<std::streampos>> mVariableStreamPosition;
145  std::vector<RelativeTimestamp> mTimeSteps;
146  std::vector<std::string> mVariableNames;
147  // Mesh
148  size_t mVerticesCount;
149  size_t mFacesCount;
150  size_t mVerticesPerFace;
151  std::streampos mXStreamPosition;
152  std::streampos mYStreamPosition;
153  std::streampos mConnectivityStreamPosition;
154  std::streampos mIPOBOStreamPosition;
155  double mXOrigin;
156  double mYOrigin;
157 
158  std::string mFileName;
159  bool mStreamInFloatPrecision = true;
160  bool mChangeEndianness = true;
161  long long mFileSize = -1;
162 
163  std::ifstream mIn;
164  bool mParsed = false;
165 
166 
167  friend class MeshSelafin;
168  friend class MeshSelafinVertexIterator;
169  friend class MeshSelafinFaceIterator;
170  friend class DatasetSelafin;
171  };
172 
173  class DatasetSelafin : public Dataset2D
174  {
175  public:
185  DatasetSelafin( DatasetGroup *parent,
186  std::shared_ptr<SelafinFile> reader,
187  size_t timeStepIndex );
188 
189  size_t scalarData( size_t indexStart, size_t count, double *buffer ) override;
190  size_t vectorData( size_t indexStart, size_t count, double *buffer ) override;
191 
193  void setXVariableIndex( size_t index );
195  void setYVariableIndex( size_t index );
196 
197  private:
198  std::shared_ptr<SelafinFile> mReader;
199 
200  size_t mXVariableIndex = 0;
201  size_t mYVariableIndex = 0;
202  size_t mTimeStepIndex = 0;
203  };
204 
206  {
207  public:
214  MeshSelafinVertexIterator( std::shared_ptr<SelafinFile> reader );
215 
216  size_t next( size_t vertexCount, double *coordinates ) override;
217 
218  private:
219  std::shared_ptr<SelafinFile> mReader;
220  size_t mPosition = 0;
221  };
222 
224  {
225  public:
232  MeshSelafinFaceIterator( std::shared_ptr<SelafinFile> reader );
233 
234  size_t next( size_t faceOffsetsBufferLen, int *faceOffsetsBuffer, size_t vertexIndicesBufferLen, int *vertexIndicesBuffer ) override;
235 
236  private:
237  std::shared_ptr<SelafinFile> mReader;
238  size_t mPosition = 0;
239  };
240 
241  class MeshSelafin: public Mesh
242  {
243  public:
250  MeshSelafin( const std::string &uri,
251  std::shared_ptr<SelafinFile> reader );
252 
253  std::unique_ptr<MeshVertexIterator> readVertices() override;
254 
256  std::unique_ptr<MeshEdgeIterator> readEdges() override;
257 
258  std::unique_ptr<MeshFaceIterator> readFaces() override;
259 
260  size_t verticesCount() const override {return mReader->verticesCount();}
261  size_t edgesCount() const override {return 0;}
262  size_t facesCount() const override {return mReader->facesCount();}
263  BBox extent() const override;
264 
265  void closeSource() override;
266 
267  private:
268  mutable bool mIsExtentUpToDate = false;
269  mutable BBox mExtent;
270 
271  std::shared_ptr<SelafinFile> mReader;
272 
273  void calculateExtent() const;
274  };
275 
312  class DriverSelafin: public Driver
313  {
314  public:
315  DriverSelafin();
316  ~DriverSelafin() override;
317  DriverSelafin *create() override;
318 
319  bool canReadMesh( const std::string &uri ) override;
320  bool canReadDatasets( const std::string &uri ) override;
321 
322  std::unique_ptr< Mesh > load( const std::string &meshFile, const std::string &meshName = "" ) override;
323  void load( const std::string &datFile, Mesh *mesh ) override;
324 
325  bool persist( DatasetGroup *group ) override;
326 
327  int faceVerticesMaximumCount() const override {return 3;}
328  void save( const std::string &fileName, const std::string &meshName, Mesh *mesh ) override;
329 
330  std::string writeDatasetOnFileSuffix() const override;
331  std::string saveMeshOnFileSuffix() const override;
332 
333  private:
334  bool saveDatasetGroupOnFile( DatasetGroup *datasetGroup );
335  };
336 
337 } // namespace MDAL
338 #endif //MDAL_SELAFIN_HPP
Definition: mdal_data_model.hpp:97
Definition: mdal_data_model.hpp:137
Definition: mdal_selafin.hpp:174
void setYVariableIndex(size_t index)
Sets the position of the Y array in the stream.
Definition: mdal_selafin.cpp:918
size_t scalarData(size_t indexStart, size_t count, double *buffer) override
For DataOnVertices or DataOnFaces.
Definition: mdal_selafin.cpp:883
DatasetSelafin(DatasetGroup *parent, std::shared_ptr< SelafinFile > reader, size_t timeStepIndex)
Contructs a dataset with a SelafinFile object and the index of the time step.
Definition: mdal_selafin.cpp:875
size_t vectorData(size_t indexStart, size_t count, double *buffer) override
For DataOnVertices or DataOnFaces.
Definition: mdal_selafin.cpp:895
void setXVariableIndex(size_t index)
Sets the position of the X array in the stream.
Definition: mdal_selafin.cpp:913
Definition: mdal_datetime.hpp:48
Serafin format (also called Selafin)
Definition: mdal_selafin.hpp:313
int faceVerticesMaximumCount() const override
returns the maximum vertices per face
Definition: mdal_selafin.hpp:327
Definition: mdal_driver.hpp:28
Definition: mdal_data_model.hpp:227
Definition: mdal_selafin.hpp:224
MeshSelafinFaceIterator(std::shared_ptr< SelafinFile > reader)
Contructs a face iterator with a SerafinFile instance.
Definition: mdal_selafin.cpp:832
Definition: mdal_selafin.hpp:206
MeshSelafinVertexIterator(std::shared_ptr< SelafinFile > reader)
Contructs a vertex iterator with a SerafinFile instance.
Definition: mdal_selafin.cpp:812
Definition: mdal_selafin.hpp:242
std::unique_ptr< MeshEdgeIterator > readEdges() override
Selafin format doesn't support edges in MDAL, returns a void unique_ptr.
Definition: mdal_selafin.cpp:756
MeshSelafin(const std::string &uri, std::shared_ptr< SelafinFile > reader)
Contructs a dataset with a SerafinFile instance reader.
Definition: mdal_selafin.cpp:744
Definition: mdal_data_model.hpp:209
Definition: mdal_data_model.hpp:238
This class is used to read the selafin file format.
Definition: mdal_selafin.hpp:42
SelafinFile(const std::string &fileName)
Constructor.
Definition: mdal_selafin.cpp:32
bool addDatasetGroup(DatasetGroup *datasetGroup)
Add the dataset group to the file (persist), replace dataset in the new group by Selafindataset with ...
Definition: mdal_selafin.cpp:1138
std::string readHeader()
Read the header of the file and return the project name.
Definition: mdal_selafin.cpp:200
static void populateDataset(Mesh *mesh, const std::string &fileName)
Populates the mesh with dataset from the file.
Definition: mdal_selafin.cpp:262
static std::unique_ptr< Mesh > createMesh(const std::string &fileName)
Returns a mesh created with the file.
Definition: mdal_selafin.cpp:250
Definition: mdal_data_model.hpp:24