Skip to content

Commit

Permalink
[MDAL] update MDAL to 0.1.0 (new API)
Browse files Browse the repository at this point in the history
  • Loading branch information
PeterPetrik committed Dec 7, 2018
1 parent d6701f2 commit d43f637
Show file tree
Hide file tree
Showing 23 changed files with 1,928 additions and 699 deletions.
138 changes: 105 additions & 33 deletions external/mdal/api/mdal.h
Expand Up @@ -63,8 +63,9 @@ enum MDAL_Status
Warn_NodeNotUnique
};

//! Mesh
typedef void *MeshH;
typedef void *MeshVertexIteratorH;
typedef void *MeshFaceIteratorH;
typedef void *DatasetGroupH;
typedef void *DatasetH;

Expand All @@ -78,7 +79,10 @@ MDAL_EXPORT MDAL_Status MDAL_LastStatus();
/// MESH
///////////////////////////////////////////////////////////////////////////////////////

//! Loads mesh file. On error see MDAL_LastStatus for error type This effectively loads whole mesh in-memory
/**
* Loads mesh file. On error see MDAL_LastStatus for error type
* This may effectively load whole mesh in-memory for some providers
*/
MDAL_EXPORT MeshH MDAL_LoadMesh( const char *meshFile );
//! Closes mesh, frees the memory
MDAL_EXPORT void MDAL_CloseMesh( MeshH mesh );
Expand All @@ -88,20 +92,18 @@ MDAL_EXPORT void MDAL_CloseMesh( MeshH mesh );
* not thread-safe and valid only till next call
*/
MDAL_EXPORT const char *MDAL_M_projection( MeshH mesh );

/**
* Returns mesh extent in native projection
* Returns NaN on error
*/
MDAL_EXPORT void MDAL_M_extent( MeshH mesh, double *minX, double *maxX, double *minY, double *maxY );
//! Returns vertex count for the mesh
MDAL_EXPORT int MDAL_M_vertexCount( MeshH mesh );
//! Returns vertex X coord for the mesh
MDAL_EXPORT double MDAL_M_vertexXCoordinatesAt( MeshH mesh, int index );
//! Returns vertex Y coord for the mesh
MDAL_EXPORT double MDAL_M_vertexYCoordinatesAt( MeshH mesh, int index );
//! Returns vertex Z coord for the mesh
MDAL_EXPORT double MDAL_M_vertexZCoordinatesAt( MeshH mesh, int index );
//! Returns face count for the mesh
MDAL_EXPORT int MDAL_M_faceCount( MeshH mesh );
//! Returns number of vertices face consist of, e.g. 3 for triangle
MDAL_EXPORT int MDAL_M_faceVerticesCountAt( MeshH mesh, int index );
//! Returns vertex index for face
MDAL_EXPORT int MDAL_M_faceVerticesIndexAt( MeshH mesh, int face_index, int vertex_index );
//! Returns maximum number of vertices face can consist of, e.g. 4 for regular quad mesh
MDAL_EXPORT int MDAL_M_faceVerticesMaximumCount( MeshH mesh );

/**
* Loads dataset file. On error see MDAL_LastStatus for error type.
Expand All @@ -110,17 +112,74 @@ MDAL_EXPORT int MDAL_M_faceVerticesIndexAt( MeshH mesh, int face_index, int vert
* can be freed manually with MDAL_CloseDataset if needed
*/
MDAL_EXPORT void MDAL_M_LoadDatasets( MeshH mesh, const char *datasetFile );

//! Returns dataset groups count
MDAL_EXPORT int MDAL_M_datasetGroupCount( MeshH mesh );

//! Returns dataset group handle
MDAL_EXPORT DatasetGroupH MDAL_M_datasetGroup( MeshH mesh, int index );

///////////////////////////////////////////////////////////////////////////////////////
/// MESH VERTICES
///////////////////////////////////////////////////////////////////////////////////////

/**
* Returns iterator to the mesh vertices
* For some formats this may effectively load all vertices in-memory until iterator is closed
*/
MDAL_EXPORT MeshVertexIteratorH MDAL_M_vertexIterator( MeshH mesh );

/**
* Returns vertices from iterator for the mesh
* \param iterator mesh data iterator
* \param verticesCount maximum number or vertices to be written to buffer
* \param coordinates must be allocated to 3* verticesCount items to store x1, y1, z1, ..., xN, yN, zN coordinates
* \returns number of vertices written in the buffer
*/
MDAL_EXPORT int MDAL_VI_next( MeshVertexIteratorH iterator, int verticesCount, double *coordinates );

//! Closes mesh data iterator, frees the memory
MDAL_EXPORT void MDAL_VI_close( MeshVertexIteratorH iterator );

///////////////////////////////////////////////////////////////////////////////////////
/// MESH FACES
///////////////////////////////////////////////////////////////////////////////////////

/**
* Returns iterator to the mesh faces
* For some formats this may effectively load all faces in-memory until iterator is closed
*/
MDAL_EXPORT MeshFaceIteratorH MDAL_M_faceIterator( MeshH mesh );

/**
* Returns next faces from iterator for the mesh
*
* Reading stops when vertexIndicesBuffer capacity is full / faceOffsetsBuffer
* capacity is full / end of faces is reached, whatever comes first
*
* \param iterator mesh data iterator
* \param faceOffsetsBufferLen size of faceOffsetsBuffer, minimum 1
* \param faceOffsetsBuffer allocated array to store face offset in vertexIndicesBuffer for given face.
* To find number of vertices of face i, calculate faceOffsetsBuffer[i] - faceOffsetsBuffer[i-1]
* \param vertexIndicesBufferLen size of vertexIndicesBuffer, minimum is MDAL_M_faceVerticesMaximumCount()
* \param vertexIndicesBuffer writes vertex indexes for faces
* faceOffsetsBuffer[i-1] is index where the vertices for face i begins,
* \returns number of faces written in the buffer
*/
MDAL_EXPORT int MDAL_FI_next( MeshFaceIteratorH iterator,
int faceOffsetsBufferLen,
int *faceOffsetsBuffer,
int vertexIndicesBufferLen,
int *vertexIndicesBuffer );

//! Closes mesh data iterator, frees the memory
MDAL_EXPORT void MDAL_FI_close( MeshFaceIteratorH iterator );

///////////////////////////////////////////////////////////////////////////////////////
/// DATASET GROUPS
///////////////////////////////////////////////////////////////////////////////////////

//! Returns dataset parent mesh
MDAL_EXPORT MeshH MDAL_G_mesh( DatasetGroupH group );

//! Returns dataset count in group
MDAL_EXPORT int MDAL_G_datasetCount( DatasetGroupH group );

Expand Down Expand Up @@ -154,6 +213,12 @@ MDAL_EXPORT bool MDAL_G_hasScalarData( DatasetGroupH group );
//! Whether dataset is on vertices
MDAL_EXPORT bool MDAL_G_isOnVertices( DatasetGroupH group );

/**
* Returns the min and max values of the group
* Returns NaN on error
*/
MDAL_EXPORT void MDAL_G_minimumMaximum( DatasetGroupH group, double *min, double *max );

///////////////////////////////////////////////////////////////////////////////////////
/// DATASETS
///////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -167,32 +232,39 @@ MDAL_EXPORT double MDAL_D_time( DatasetH dataset );
//! Returns number of values
MDAL_EXPORT int MDAL_D_valueCount( DatasetH dataset );

/**
* Returns scalar value associated with the index from the dataset
* for nodata return numeric_limits<double>:quiet_NaN
*/
MDAL_EXPORT double MDAL_D_value( DatasetH dataset, int valueIndex );
//! Returns whether dataset is valid
MDAL_EXPORT bool MDAL_D_isValid( DatasetH dataset );

/**
* Returns X value associated with the index from the vector dataset
* for nodata return numeric_limits<double>:quiet_NaN
*/
MDAL_EXPORT double MDAL_D_valueX( DatasetH dataset, int valueIndex );
//! Data type to be returned by MDAL_D_data
enum MDAL_DataType
{
SCALAR_DOUBLE, //!< Double value for scalar datasets
VECTOR_2D_DOUBLE, //!< Double, double value for vector datasets
ACTIVE_INTEGER //!< Integer, active flag for dataset faces. Some formats support switching off the element for particular timestep.
};

/**
* Returns Y value associated with the index from the vector dataset
* for nodata return numeric_limits<double>:quiet_NaN
* Populates buffer with values from the dataset
* for nodata, returned is numeric_limits<double>::quiet_NaN
*
* \param dataset handle to dataset
* \param indexStart index of face/vertex to start reading of values to the buffer
* \param count number of values to be written to the buffer
* \param dataType type of values to be written to the buffer
* \param buffer output array to be populated with the values. must be already allocated
* For SCALAR_DOUBLE, the minimum size must be valuesCount * size_of(double)
* For VECTOR_2D_DOUBLE, the minimum size must be valuesCount * 2 * size_of(double).
* Values are returned as x1, y1, x2, y2, ..., xN, yN
* For ACTIVE_INTEGER, the minimum size must be valuesCount * size_of(int)
* \returns number of values written to buffer. If return value != count requested, see MDAL_LastStatus() for error type
*/
MDAL_EXPORT double MDAL_D_valueY( DatasetH dataset, int valueIndex );
MDAL_EXPORT int MDAL_D_data( DatasetH dataset, int indexStart, int count, MDAL_DataType dataType, void *buffer );

/**
* Whether element is active - should be taken into account
* Some formats support switching off the element for particular timestep
* Returns the min and max values of the dataset
* Returns NaN on error
*/
MDAL_EXPORT bool MDAL_D_active( DatasetH dataset, int faceIndex );

//! Returns whether dataset is valid
MDAL_EXPORT bool MDAL_D_isValid( DatasetH dataset );
MDAL_EXPORT void MDAL_D_minimumMaximum( DatasetH dataset, double *min, double *max );

#ifdef __cplusplus
}
Expand Down
105 changes: 57 additions & 48 deletions external/mdal/frmts/mdal_2dm.cpp
Expand Up @@ -17,6 +17,46 @@
#include "mdal.h"
#include "mdal_utils.hpp"

MDAL::Mesh2dm::Mesh2dm( size_t verticesCount,
size_t facesCount,
size_t faceVerticesMaximumCount,
MDAL::BBox extent,
const std::string &uri,
const std::map<size_t, size_t> vertexIDtoIndex )
: MemoryMesh( verticesCount, facesCount, faceVerticesMaximumCount, extent, uri )
, mVertexIDtoIndex( vertexIDtoIndex )
{
}

MDAL::Mesh2dm::~Mesh2dm() = default;

bool _parse_vertex_id_gaps( std::map<size_t, size_t> &vertexIDtoIndex, size_t vertexIndex, size_t vertexID, MDAL_Status *status )
{
if ( vertexIndex == vertexID )
return false;

std::map<size_t, size_t>::iterator search = vertexIDtoIndex.find( vertexID );
if ( search != vertexIDtoIndex.end() )
{
if ( status ) *status = MDAL_Status::Warn_ElementNotUnique;
return true;
}

vertexIDtoIndex[vertexID] = vertexIndex;
return false;
}

size_t MDAL::Mesh2dm::vertexIndex( size_t vertexID ) const
{
auto ni2i = mVertexIDtoIndex.find( vertexID );
if ( ni2i != mVertexIDtoIndex.end() )
{
return ni2i->second; // convert from ID to index
}
return vertexID;
}


MDAL::Loader2dm::Loader2dm( const std::string &meshFile ):
mMeshFile( meshFile )
{
Expand Down Expand Up @@ -71,7 +111,6 @@ std::unique_ptr<MDAL::Mesh> MDAL::Loader2dm::load( MDAL_Status *status )

size_t faceIndex = 0;
size_t vertexIndex = 0;
std::map<size_t, size_t> faceIDtoIndex;
std::map<size_t, size_t> vertexIDtoIndex;

while ( std::getline( in, line ) )
Expand All @@ -81,20 +120,11 @@ std::unique_ptr<MDAL::Mesh> MDAL::Loader2dm::load( MDAL_Status *status )
chunks = split( line, " ", SplitBehaviour::SkipEmptyParts );
assert( faceIndex < faceCount );

size_t elemID = toSizeT( chunks[1] );

std::map<size_t, size_t>::iterator search = faceIDtoIndex.find( elemID );
if ( search != faceIDtoIndex.end() )
{
if ( status ) *status = MDAL_Status::Warn_ElementNotUnique;
continue;
}
faceIDtoIndex[elemID] = faceIndex;
Face &face = faces[faceIndex];
face.resize( 4 );
// Right now we just store node IDs here - we will convert them to node indices afterwards
for ( size_t i = 0; i < 4; ++i )
face[i] = toSizeT( chunks[i + 2] );
face[i] = toSizeT( chunks[i + 2] ) - 1; // 2dm is numbered from 1

faceIndex++;
}
Expand All @@ -103,21 +133,12 @@ std::unique_ptr<MDAL::Mesh> MDAL::Loader2dm::load( MDAL_Status *status )
chunks = split( line, " ", SplitBehaviour::SkipEmptyParts );
assert( faceIndex < faceCount );

size_t elemID = toSizeT( chunks[1] );

std::map<size_t, size_t>::iterator search = faceIDtoIndex.find( elemID );
if ( search != faceIDtoIndex.end() )
{
if ( status ) *status = MDAL_Status::Warn_ElementNotUnique;
continue;
}
faceIDtoIndex[elemID] = faceIndex;
Face &face = faces[faceIndex];
face.resize( 3 );
// Right now we just store node IDs here - we will convert them to node indices afterwards
for ( size_t i = 0; i < 3; ++i )
{
face[i] = toSizeT( chunks[i + 2] );
face[i] = toSizeT( chunks[i + 2] ) - 1; // 2dm is numbered from 1
}

faceIndex++;
Expand All @@ -132,31 +153,16 @@ std::unique_ptr<MDAL::Mesh> MDAL::Loader2dm::load( MDAL_Status *status )
chunks = split( line, " ", SplitBehaviour::SkipEmptyParts );
assert( faceIndex < faceCount );

size_t elemID = toSizeT( chunks[1] );

std::map<size_t, size_t>::iterator search = faceIDtoIndex.find( elemID );
if ( search != faceIDtoIndex.end() )
{
if ( status ) *status = MDAL_Status::Warn_ElementNotUnique;
continue;
}
faceIDtoIndex[elemID] = faceIndex;
//size_t elemID = toSizeT( chunks[1] );
assert( false ); //TODO mark element as unusable

faceIndex++;
}
else if ( startsWith( line, "ND" ) )
{
chunks = split( line, " ", SplitBehaviour::SkipEmptyParts );
size_t nodeID = toSizeT( chunks[1] );

std::map<size_t, size_t>::iterator search = vertexIDtoIndex.find( nodeID );
if ( search != vertexIDtoIndex.end() )
{
if ( status ) *status = MDAL_Status::Warn_NodeNotUnique;
continue;
}
vertexIDtoIndex[nodeID] = vertexIndex;
size_t nodeID = toSizeT( chunks[1] ) - 1; // 2dm is numbered from 1
_parse_vertex_id_gaps( vertexIDtoIndex, vertexIndex, nodeID, status );
assert( vertexIndex < vertexCount );
Vertex &vertex = vertices[vertexIndex];
vertex.x = toDouble( chunks[2] );
Expand All @@ -178,25 +184,28 @@ std::unique_ptr<MDAL::Mesh> MDAL::Loader2dm::load( MDAL_Status *status )
{
face[nd] = ni2i->second; // convert from ID to index
}
else
else if ( vertices.size() < nodeID )
{
assert( false ); //TODO mark element as unusable

if ( status ) *status = MDAL_Status::Warn_ElementWithInvalidNode;
}
}

//TODO check validity of the face
//check that we have distinct nodes
}

std::unique_ptr< Mesh > mesh( new Mesh );
mesh->uri = mMeshFile;
std::unique_ptr< MemoryMesh > mesh(
new Mesh2dm(
vertices.size(),
faces.size(),
4, //maximum quads
computeExtent( vertices ),
mMeshFile,
vertexIDtoIndex
)
);
mesh->faces = faces;
mesh->vertices = vertices;
mesh->faceIDtoIndex = faceIDtoIndex;
mesh->vertexIDtoIndex = vertexIDtoIndex;
mesh->addBedElevationDataset();
mesh->addBedElevationDataset( vertices, faces );

return mesh;
}

0 comments on commit d43f637

Please sign in to comment.