1 /*
2 MDAL - Mesh Data Abstraction Library (MIT License)
3 Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com)
4 */
5
6 #include "gtest/gtest.h"
7
8 #include "mdal_testutils.hpp"
9 #include "mdal_config.hpp"
10 #include "mdal_utils.hpp"
11 #include <vector>
12 #include <math.h>
13 #include <assert.h>
14 #include <fstream>
15 #include <stdio.h>
16
data_path()17 const char *data_path()
18 {
19 return TESTDATA;
20 }
21
drivers_path()22 const char *drivers_path()
23 {
24 return DRIVERS_PATH;
25 }
26
27
test_file(std::string basename)28 std::string test_file( std::string basename )
29 {
30 std::string path( data_path() );
31 path += basename;
32 return path;
33 }
34
tmp_file(std::string basename)35 std::string tmp_file( std::string basename )
36 {
37 std::string path( data_path() + std::string( "/tmp" ) );
38 path += basename;
39 return path;
40 }
41
copy(const std::string & src,const std::string & dest)42 void copy( const std::string &src, const std::string &dest )
43 {
44 std::ifstream srcS;
45 std::ofstream dstS;
46
47 srcS.open( src, std::ios::in | std::ios::binary );
48 dstS.open( dest, std::ios::out | std::ios::binary );
49 dstS << srcS.rdbuf();
50 }
51
deleteFile(const std::string & path)52 void deleteFile( const std::string &path )
53 {
54 if ( fileExists( path ) )
55 remove( path.c_str() );
56 }
57
fileExists(const std::string & filename)58 bool fileExists( const std::string &filename )
59 {
60 std::ifstream in( filename );
61 return in.good();
62 }
63
getActive(MDAL_DatasetH dataset,int index)64 int getActive( MDAL_DatasetH dataset, int index )
65 {
66 bool hasFlag = MDAL_D_hasActiveFlagCapability( dataset );
67 if ( hasFlag )
68 {
69 int active;
70 int nValuesRead = MDAL_D_data( dataset, index, 1, MDAL_DataType::ACTIVE_INTEGER, &active );
71 if ( nValuesRead != 1 )
72 return -2;
73 return static_cast<bool>( active );
74 }
75 else
76 {
77 return -1;
78 }
79 }
80
getValue(MDAL_DatasetH dataset,int index)81 double getValue( MDAL_DatasetH dataset, int index )
82 {
83 double val;
84 int nValuesRead = MDAL_D_data( dataset, index, 1, MDAL_DataType::SCALAR_DOUBLE, &val );
85 if ( nValuesRead != 1 )
86 return 0;
87
88 return val;
89 }
90
getValueX(MDAL_DatasetH dataset,int index)91 double getValueX( MDAL_DatasetH dataset, int index )
92 {
93 double val[2];
94 int nValuesRead = MDAL_D_data( dataset, index, 1, MDAL_DataType::VECTOR_2D_DOUBLE, &val );
95 if ( nValuesRead != 1 )
96 return 0;
97
98 return val[0];
99 }
100
getValueY(MDAL_DatasetH dataset,int index)101 double getValueY( MDAL_DatasetH dataset, int index )
102 {
103 double val[2];
104 int nValuesRead = MDAL_D_data( dataset, index, 1, MDAL_DataType::VECTOR_2D_DOUBLE, &val );
105 if ( nValuesRead != 1 )
106 return 0;
107
108 return val[1];
109 }
110
getLevelsCount3D(MDAL_DatasetH dataset,int index)111 int getLevelsCount3D( MDAL_DatasetH dataset, int index )
112 {
113 int count;
114 int nValuesRead = MDAL_D_data( dataset, index, 1, MDAL_DataType::VERTICAL_LEVEL_COUNT_INTEGER, &count );
115 if ( nValuesRead != 1 )
116 return -1;
117
118 return count;
119 }
120
getLevelZ3D(MDAL_DatasetH dataset,int index)121 double getLevelZ3D( MDAL_DatasetH dataset, int index )
122 {
123 double z;
124 int nValuesRead = MDAL_D_data( dataset, index, 1, MDAL_DataType::VERTICAL_LEVEL_DOUBLE, &z );
125 if ( nValuesRead != 1 )
126 return -1;
127
128 return z;
129 }
130
getValue3D(MDAL_DatasetH dataset,int index)131 double getValue3D( MDAL_DatasetH dataset, int index )
132 {
133 double val;
134 int nValuesRead = MDAL_D_data( dataset, index, 1, MDAL_DataType::SCALAR_VOLUMES_DOUBLE, &val );
135 if ( nValuesRead != 1 )
136 return 0;
137
138 return val;
139 }
140
getValue3DX(MDAL_DatasetH dataset,int index)141 double getValue3DX( MDAL_DatasetH dataset, int index )
142 {
143 double val[2];
144 int nValuesRead = MDAL_D_data( dataset, index, 1, MDAL_DataType::VECTOR_2D_VOLUMES_DOUBLE, &val );
145 if ( nValuesRead != 1 )
146 return 0;
147
148 return val[0];
149 }
150
getValue3DY(MDAL_DatasetH dataset,int index)151 double getValue3DY( MDAL_DatasetH dataset, int index )
152 {
153 double val[2];
154 int nValuesRead = MDAL_D_data( dataset, index, 1, MDAL_DataType::VECTOR_2D_VOLUMES_DOUBLE, &val );
155 if ( nValuesRead != 1 )
156 return 0;
157
158 return val[1];
159 }
160
get3DFrom2D(MDAL_DatasetH dataset,int index)161 int get3DFrom2D( MDAL_DatasetH dataset, int index )
162 {
163 int index3d;
164 int nValuesRead = MDAL_D_data( dataset, index, 1, MDAL_DataType::FACE_INDEX_TO_VOLUME_INDEX_INTEGER, &index3d );
165 if ( nValuesRead != 1 )
166 return -1;
167
168 return index3d;
169 }
170
compareVectors(const std::vector<int> & a,const std::vector<int> & b)171 bool compareVectors( const std::vector<int> &a, const std::vector<int> &b )
172 {
173 if ( a.size() != b.size() )
174 return false;
175
176 for ( size_t i = 0; i < a.size(); ++i )
177 if ( a[i] != b[i] )
178 return false;
179
180 return true;
181 }
182
compareVectors(const std::vector<double> & a,const std::vector<double> & b)183 bool compareVectors( const std::vector<double> &a, const std::vector<double> &b )
184 {
185 double eps = 1e-4;
186 if ( a.size() != b.size() )
187 return false;
188
189 for ( size_t i = 0; i < a.size(); ++i )
190 if ( fabs( a[i] - b[i] ) > eps )
191 return false;
192
193 return true;
194 }
195
compareMeshFrames(MDAL_MeshH meshA,MDAL_MeshH meshB)196 void compareMeshFrames( MDAL_MeshH meshA, MDAL_MeshH meshB )
197 {
198 // Vertices
199 int orignal_v_count = MDAL_M_vertexCount( meshA );
200 int saved_v_count = MDAL_M_vertexCount( meshB );
201 EXPECT_EQ( orignal_v_count, saved_v_count );
202
203 std::vector<double> coordsA = getCoordinates( meshA, orignal_v_count );
204 std::vector<double> coordsB = getCoordinates( meshB, saved_v_count );
205 EXPECT_TRUE( compareVectors( coordsA, coordsB ) );
206
207 // Edges
208 int orignal_e_count = MDAL_M_edgeCount( meshA );
209 int saved_e_count = MDAL_M_edgeCount( meshB );
210 EXPECT_EQ( orignal_e_count, saved_e_count );
211
212 std::vector<int> original_start;
213 std::vector<int> original_end;
214 std::vector<int> saved_start;
215 std::vector<int> saved_end;
216
217 getEdgeVertexIndices( meshA, orignal_e_count, original_start, original_end );
218 getEdgeVertexIndices( meshB, saved_e_count, saved_start, saved_end );
219
220 EXPECT_TRUE( compareVectors( original_start, saved_start ) );
221 EXPECT_TRUE( compareVectors( original_end, saved_end ) );
222
223 // Faces
224 int orignal_f_count = MDAL_M_faceCount( meshA );
225 int saved_f_count = MDAL_M_faceCount( meshB );
226 EXPECT_EQ( orignal_f_count, saved_f_count );
227
228 std::vector<int> verticesA = faceVertexIndices( meshA, orignal_f_count );
229 std::vector<int> verticesB = faceVertexIndices( meshB, saved_f_count );
230 EXPECT_TRUE( compareVectors( verticesA, verticesB ) );
231 }
232
getCoordinates(MDAL_MeshH mesh,int verticesCount)233 std::vector<double> getCoordinates( MDAL_MeshH mesh, int verticesCount )
234 {
235 MDAL_MeshVertexIteratorH iterator = MDAL_M_vertexIterator( mesh );
236 std::vector<double> coordinates( static_cast<size_t>( 3 * verticesCount ) );
237 MDAL_VI_next( iterator, verticesCount, coordinates.data() );
238 MDAL_VI_close( iterator );
239 return coordinates;
240 }
241
getEdgeVertexIndices(MDAL_MeshH mesh,int edgesCount,std::vector<int> & start,std::vector<int> & end)242 void getEdgeVertexIndices( MDAL_MeshH mesh, int edgesCount, std::vector<int> &start, std::vector<int> &end )
243 {
244 MDAL_MeshEdgeIteratorH iterator = MDAL_M_edgeIterator( mesh );
245 start.clear();
246 start.resize( static_cast<size_t>( edgesCount ) );
247 end.clear();
248 end.resize( static_cast<size_t>( edgesCount ) );
249 MDAL_EI_next( iterator, edgesCount, start.data(), end.data() );
250 MDAL_EI_close( iterator );
251 }
252
_getVertexCoordinatesAt(MDAL_MeshH mesh,int index,int coordIndex)253 double _getVertexCoordinatesAt( MDAL_MeshH mesh, int index, int coordIndex )
254 {
255 // coordIndex = 0 x
256 // coordIndex = 1 y
257 // coordIndex = 2 z
258 std::vector<double> coordinates = getCoordinates( mesh, index + 1 );
259 double val = coordinates[static_cast<size_t>( index * 3 + coordIndex )];
260 return val;
261 }
262
getVertexXCoordinatesAt(MDAL_MeshH mesh,int index)263 double getVertexXCoordinatesAt( MDAL_MeshH mesh, int index )
264 {
265 return _getVertexCoordinatesAt( mesh, index, 0 );
266 }
267
getVertexYCoordinatesAt(MDAL_MeshH mesh,int index)268 double getVertexYCoordinatesAt( MDAL_MeshH mesh, int index )
269 {
270 return _getVertexCoordinatesAt( mesh, index, 1 );
271 }
272
getVertexZCoordinatesAt(MDAL_MeshH mesh,int index)273 double getVertexZCoordinatesAt( MDAL_MeshH mesh, int index )
274 {
275 return _getVertexCoordinatesAt( mesh, index, 2 );
276 }
277
faceVertexIndices(MDAL_MeshH mesh,int faceCount)278 std::vector<int> faceVertexIndices( MDAL_MeshH mesh, int faceCount )
279 {
280 MDAL_MeshFaceIteratorH iterator = MDAL_M_faceIterator( mesh );
281 int faceOffsetsBufferLen = faceCount + 1;
282 int vertexIndicesBufferLen = faceOffsetsBufferLen * MDAL_M_faceVerticesMaximumCount( mesh );
283 std::vector<int> faceOffsetsBuffer( static_cast<size_t>( faceOffsetsBufferLen ) );
284 std::vector<int> vertexIndicesBuffer( static_cast<size_t>( vertexIndicesBufferLen ) );
285 MDAL_FI_next( iterator, faceOffsetsBufferLen, faceOffsetsBuffer.data(),
286 vertexIndicesBufferLen, vertexIndicesBuffer.data() );
287 MDAL_FI_close( iterator );
288 return vertexIndicesBuffer;
289 }
290
getFaceVerticesCountAt(MDAL_MeshH mesh,int faceIndex)291 int getFaceVerticesCountAt( MDAL_MeshH mesh, int faceIndex )
292 {
293 MDAL_MeshFaceIteratorH iterator = MDAL_M_faceIterator( mesh );
294 int faceOffsetsBufferLen = faceIndex + 1;
295 int vertexIndicesBufferLen = faceOffsetsBufferLen * MDAL_M_faceVerticesMaximumCount( mesh );
296 std::vector<int> faceOffsetsBuffer( static_cast<size_t>( faceOffsetsBufferLen ) );
297 std::vector<int> vertexIndicesBuffer( static_cast<size_t>( vertexIndicesBufferLen ) );
298 MDAL_FI_next( iterator, faceOffsetsBufferLen, faceOffsetsBuffer.data(),
299 vertexIndicesBufferLen, vertexIndicesBuffer.data() );
300 MDAL_FI_close( iterator );
301 int count;
302 if ( faceIndex == 0 )
303 {
304 count = faceOffsetsBuffer[static_cast<size_t>( faceIndex )];
305 }
306 else
307 {
308 count = faceOffsetsBuffer[static_cast<size_t>( faceIndex )] - faceOffsetsBuffer[static_cast<size_t>( faceIndex - 1 )];
309 }
310 return count;
311 }
312
getFaceVerticesIndexAt(MDAL_MeshH mesh,int faceIndex,int index)313 int getFaceVerticesIndexAt( MDAL_MeshH mesh, int faceIndex, int index )
314 {
315 MDAL_MeshFaceIteratorH iterator = MDAL_M_faceIterator( mesh );
316 int faceOffsetsBufferLen = faceIndex + 1;
317 int vertexIndicesBufferLen = faceOffsetsBufferLen * MDAL_M_faceVerticesMaximumCount( mesh );
318 std::vector<int> faceOffsetsBuffer( static_cast<size_t>( faceOffsetsBufferLen ) );
319 std::vector<int> vertexIndicesBuffer( static_cast<size_t>( vertexIndicesBufferLen ) );
320 MDAL_FI_next( iterator, faceOffsetsBufferLen, faceOffsetsBuffer.data(),
321 vertexIndicesBufferLen, vertexIndicesBuffer.data() );
322 MDAL_FI_close( iterator );
323 int id;
324 if ( faceIndex == 0 )
325 {
326 id = index;
327 }
328 else
329 {
330 id = faceOffsetsBuffer[static_cast<size_t>( faceIndex - 1 )] + index;
331 }
332
333 int faceVertexIndex = vertexIndicesBuffer[static_cast<size_t>( id )];
334 return faceVertexIndex;
335 }
336
set_mdal_driver_path(const std::string & dirname)337 void set_mdal_driver_path( const std::string &dirname )
338 {
339 std::string fullPath = std::string( drivers_path() ) + "/" + dirname;
340 #ifdef WIN32
341 size_t requiredSize = 0;
342 getenv_s( &requiredSize, NULL, 0, "MDAL_DRIVER_PATH" );
343 if ( requiredSize == 0 )
344 {
345 _putenv_s( "MDAL_DRIVER_PATH", fullPath.c_str() );
346 }
347 #endif
348
349 #ifndef WIN32
350 setenv( "MDAL_DRIVER_PATH", fullPath.c_str(), 0 );
351 #endif
352 }
353
init_test()354 void init_test()
355 {
356 }
357
finalize_test()358 void finalize_test()
359 {
360 }
361
compareDurationInHours(double h1,double h2)362 bool compareDurationInHours( double h1, double h2 )
363 {
364 return fabs( h1 - h2 ) < 1.0 / 3600 / 1000;
365 }
366
hasReferenceTime(MDAL_DatasetGroupH group)367 bool hasReferenceTime( MDAL_DatasetGroupH group )
368 {
369 return std::strcmp( MDAL_G_referenceTime( group ), "" ) != 0;
370 }
371
compareReferenceTime(MDAL_DatasetGroupH group,const char * referenceTime)372 bool compareReferenceTime( MDAL_DatasetGroupH group, const char *referenceTime )
373 {
374 return std::strcmp( MDAL_G_referenceTime( group ), referenceTime ) == 0;
375 }
376
saveAndCompareMesh(const std::string & filename,const std::string & savedFile,const std::string & driver,const std::string & meshName)377 void saveAndCompareMesh( const std::string &filename, const std::string &savedFile, const std::string &driver, const std::string &meshName )
378 {
379 //test driver capability
380 EXPECT_TRUE( MDAL_DR_saveMeshCapability( MDAL_driverFromName( driver.c_str() ) ) );
381
382 std::string uri( filename );
383
384 std::string savedUri = driver + ":\"" + savedFile + "\"";
385
386 if ( !meshName.empty() )
387 {
388 uri = "\"" + uri + "\":" + meshName;
389 savedUri = savedUri + ":" + meshName;
390 }
391
392 // Open mesh
393 MDAL_MeshH meshToSave = MDAL_LoadMesh( uri.c_str() );
394 EXPECT_NE( meshToSave, nullptr );
395 MDAL_Status s = MDAL_LastStatus();
396 ASSERT_EQ( MDAL_Status::None, s );
397
398 // Save the mesh
399 MDAL_SaveMeshWithUri( meshToSave, savedUri.c_str() );
400 s = MDAL_LastStatus();
401 ASSERT_EQ( MDAL_Status::None, s );
402
403 // Load saved mesh
404 MDAL_MeshH savedMesh = MDAL_LoadMesh( savedFile.c_str() );
405 EXPECT_NE( savedMesh, nullptr );
406 s = MDAL_LastStatus();
407 ASSERT_EQ( MDAL_Status::None, s );
408
409 // Compare saved with the original mesh
410 compareMeshFrames( meshToSave, savedMesh );
411
412 MDAL_CloseMesh( savedMesh );
413
414 // Again but with other API method
415 MDAL_SaveMesh( meshToSave, savedFile.c_str(), driver.c_str() );
416 s = MDAL_LastStatus();
417 ASSERT_EQ( MDAL_Status::None, s );
418
419 // Load saved mesh
420 savedMesh = MDAL_LoadMesh( savedFile.c_str() );
421 EXPECT_NE( savedMesh, nullptr );
422 s = MDAL_LastStatus();
423 ASSERT_EQ( MDAL_Status::None, s );
424
425 // Close meshed and delete all the files
426 MDAL_CloseMesh( meshToSave );
427 MDAL_CloseMesh( savedMesh );
428 std::remove( savedFile.c_str() );
429 }
430