Skip to content

Commit

Permalink
Merge pull request #7008 from PeterPetrik/qgsmeshlayer_2_scalar_vecto…
Browse files Browse the repository at this point in the history
…r_datasets

[mesh] Rendering of scalar and vector datasets
  • Loading branch information
wonder-sk authored May 24, 2018
2 parents dde895d + 882d8ed commit 61f84ce
Show file tree
Hide file tree
Showing 53 changed files with 4,419 additions and 196 deletions.
71 changes: 70 additions & 1 deletion external/mdal/api/mdal.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
#ifndef MDAL_H
#define MDAL_H

/**********************************************************************/
/**********************************************************************/
/* API is considered EXPERIMENTAL and can be changed without a notice */
/**********************************************************************/
/**********************************************************************/

#ifdef MDAL_STATIC
# define MDAL_EXPORT
#else
Expand Down Expand Up @@ -46,6 +52,7 @@ enum MDAL_Status
Err_UnknownFormat,
Err_IncompatibleMesh,
Err_InvalidData,
Err_IncompatibleDataset,
Err_MissingDriver,
// Warnings
Warn_UnsupportedElement,
Expand All @@ -57,6 +64,7 @@ enum MDAL_Status

//! Mesh
typedef void *MeshH;
typedef void *DatasetH;

//! Return MDAL version
MDAL_EXPORT const char *MDAL_Version();
Expand All @@ -68,7 +76,6 @@ MDAL_EXPORT MDAL_Status MDAL_LastStatus();
MDAL_EXPORT MeshH MDAL_LoadMesh( const char *meshFile );
//! Close mesh, free the memory
MDAL_EXPORT void MDAL_CloseMesh( MeshH mesh );

//! Return vertex count for the mesh
MDAL_EXPORT int MDAL_M_vertexCount( MeshH mesh );
//! Return vertex X coord for the mesh
Expand All @@ -82,6 +89,68 @@ MDAL_EXPORT int MDAL_M_faceVerticesCountAt( MeshH mesh, int index );
//! Return vertex index for face
MDAL_EXPORT int MDAL_M_faceVerticesIndexAt( MeshH mesh, int face_index, int vertex_index );

/**
* Load dataset file. On error see MDAL_LastStatus for error type.
* This may effectively load whole dataset in-memory for some providers
* Datasets will be closed automatically on mesh destruction or memory
* can be freed manually with MDAL_CloseDataset if needed
*/
MDAL_EXPORT void MDAL_M_LoadDatasets( MeshH mesh, const char *datasetFile );

//! Free the memory used to get dataset values
MDAL_EXPORT void MDAL_M_CloseDataset( DatasetH dataset );

//! Return dataset count
MDAL_EXPORT int MDAL_M_datasetCount( MeshH mesh );

//! Return dataset handle
MDAL_EXPORT DatasetH MDAL_M_dataset( MeshH mesh, int index );

//! Whether dataset has scalar data associated
MDAL_EXPORT bool MDAL_D_hasScalarData( DatasetH dataset );

//! Whether dataset is on vertices
MDAL_EXPORT bool MDAL_D_isOnVertices( DatasetH dataset );

//! Return number of metadata values
MDAL_EXPORT int MDAL_D_metadataCount( DatasetH dataset );

//! Return dataset metadata key
MDAL_EXPORT const char *MDAL_D_metadataKey( DatasetH dataset, int index );

//! Return dataset metadata value
MDAL_EXPORT const char *MDAL_D_metadataValue( DatasetH dataset, int index );

//! Return number of values
MDAL_EXPORT int MDAL_D_valueCount( DatasetH dataset );

/**
* Return 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 );

/**
* Return 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 );

/**
* Return Y value associated with the index from the vector dataset
* for nodata return numeric_limits<double>:quiet_NaN
*/
MDAL_EXPORT double MDAL_D_valueY( DatasetH dataset, int valueIndex );

/**
* Whether element is active - should be taken into account
* Some formats support switching off the element for particular timestep
*/
MDAL_EXPORT bool MDAL_D_active( DatasetH dataset, int faceIndex );

//! Return whether dataset is valid
MDAL_EXPORT bool MDAL_D_isValid( DatasetH dataset );

#ifdef __cplusplus
}
#endif
Expand Down
85 changes: 44 additions & 41 deletions external/mdal/frmts/mdal_2dm.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
MDAL - Mesh Data Abstraction Library (MIT License)
Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com)
Copyright (C) 2018 Lutra Consulting Ltd.
*/

#include <stddef.h>
Expand All @@ -22,38 +22,38 @@ MDAL::Loader2dm::Loader2dm( const std::string &meshFile ):
{
}

MDAL::Mesh *MDAL::Loader2dm::load( MDAL_Status *status )
std::unique_ptr<MDAL::Mesh> MDAL::Loader2dm::load( MDAL_Status *status )
{
if ( status ) *status = MDAL_Status::None;

if ( !MDAL::fileExists( mMeshFile ) )
{
if ( status ) *status = MDAL_Status::Err_FileNotFound;
return 0;
return nullptr;
}

std::ifstream in( mMeshFile, std::ifstream::in );
std::string line;
if ( !std::getline( in, line ) || !startsWith( line, "MESH2D" ) )
{
if ( status ) *status = MDAL_Status::Err_UnknownFormat;
return 0;
return nullptr;
}

size_t elemCount = 0;
size_t nodeCount = 0;
size_t faceCount = 0;
size_t vertexCount = 0;

// Find out how many nodes and elements are contained in the .2dm mesh file
while ( std::getline( in, line ) )
{
if ( startsWith( line, "E4Q" ) ||
startsWith( line, "E3T" ) )
{
elemCount++;
faceCount++;
}
else if ( startsWith( line, "ND" ) )
{
nodeCount++;
vertexCount++;
}
else if ( startsWith( line, "E2L" ) ||
startsWith( line, "E3L" ) ||
Expand All @@ -62,71 +62,71 @@ MDAL::Mesh *MDAL::Loader2dm::load( MDAL_Status *status )
startsWith( line, "E9Q" ) )
{
if ( status ) *status = MDAL_Status::Warn_UnsupportedElement;
elemCount += 1; // We still count them as elements
faceCount += 1; // We still count them as elements
}
}

// Allocate memory
std::vector<Vertex> vertices( nodeCount );
std::vector<Face> faces( elemCount );
std::vector<Vertex> vertices( vertexCount );
std::vector<Face> faces( faceCount );

in.clear();
in.seekg( 0, std::ios::beg );

std::vector<std::string> chunks;

size_t elemIndex = 0;
size_t nodeIndex = 0;
std::map<size_t, size_t> elemIDtoIndex;
std::map<size_t, size_t> nodeIDtoIndex;
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 ) )
{
if ( startsWith( line, "E4Q" ) )
{
chunks = split( line, " ", SplitBehaviour::SkipEmptyParts );
assert( elemIndex < elemCount );
assert( faceIndex < faceCount );

size_t elemID = toSizeT( chunks[1] );

std::map<size_t, size_t>::iterator search = elemIDtoIndex.find( elemID );
if ( search != elemIDtoIndex.end() )
std::map<size_t, size_t>::iterator search = faceIDtoIndex.find( elemID );
if ( search != faceIDtoIndex.end() )
{
if ( status ) *status = MDAL_Status::Warn_ElementNotUnique;
continue;
}
elemIDtoIndex[elemID] = elemIndex;
Face &face = faces[elemIndex];
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] );

elemIndex++;
faceIndex++;
}
else if ( startsWith( line, "E3T" ) )
{
chunks = split( line, " ", SplitBehaviour::SkipEmptyParts );
assert( elemIndex < elemCount );
assert( faceIndex < faceCount );

size_t elemID = toSizeT( chunks[1] );

std::map<size_t, size_t>::iterator search = elemIDtoIndex.find( elemID );
if ( search != elemIDtoIndex.end() )
std::map<size_t, size_t>::iterator search = faceIDtoIndex.find( elemID );
if ( search != faceIDtoIndex.end() )
{
if ( status ) *status = MDAL_Status::Warn_ElementNotUnique;
continue;
}
elemIDtoIndex[elemID] = elemIndex;
Face &face = faces[elemIndex];
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] );
}

elemIndex++;
faceIndex++;
}
else if ( startsWith( line, "E2L" ) ||
startsWith( line, "E3L" ) ||
Expand All @@ -136,39 +136,39 @@ MDAL::Mesh *MDAL::Loader2dm::load( MDAL_Status *status )
{
// We do not yet support these elements
chunks = split( line, " ", SplitBehaviour::SkipEmptyParts );
assert( elemIndex < elemCount );
assert( faceIndex < faceCount );

size_t elemID = toSizeT( chunks[1] );

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

elemIndex++;
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 = nodeIDtoIndex.find( nodeID );
if ( search != nodeIDtoIndex.end() )
std::map<size_t, size_t>::iterator search = vertexIDtoIndex.find( nodeID );
if ( search != vertexIDtoIndex.end() )
{
if ( status ) *status = MDAL_Status::Warn_NodeNotUnique;
continue;
}
nodeIDtoIndex[nodeID] = nodeIndex;
assert( nodeIndex < nodeCount );
Vertex &vertex = vertices[nodeIndex];
vertexIDtoIndex[nodeID] = vertexIndex;
assert( vertexIndex < vertexCount );
Vertex &vertex = vertices[vertexIndex];
vertex.x = toDouble( chunks[2] );
vertex.y = toDouble( chunks[3] );

nodeIndex++;
vertexIndex++;
}
}

Expand All @@ -179,8 +179,8 @@ MDAL::Mesh *MDAL::Loader2dm::load( MDAL_Status *status )
{
size_t nodeID = face[nd];

std::map<size_t, size_t>::iterator ni2i = nodeIDtoIndex.find( nodeID );
if ( ni2i != nodeIDtoIndex.end() )
std::map<size_t, size_t>::iterator ni2i = vertexIDtoIndex.find( nodeID );
if ( ni2i != vertexIDtoIndex.end() )
{
face[nd] = ni2i->second; // convert from ID to index
}
Expand All @@ -196,9 +196,12 @@ MDAL::Mesh *MDAL::Loader2dm::load( MDAL_Status *status )
//check that we have distinct nodes
}

Mesh *mesh = new Mesh;
std::unique_ptr< Mesh > mesh( new Mesh );
mesh->uri = mMeshFile;
mesh->faces = faces;
mesh->vertices = vertices;
mesh->faceIDtoIndex = faceIDtoIndex;
mesh->vertexIDtoIndex = vertexIDtoIndex;

return mesh;
}
3 changes: 2 additions & 1 deletion external/mdal/frmts/mdal_2dm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define MDAL_2DM_HPP

#include <string>
#include <memory>

#include "mdal_defines.hpp"
#include "mdal.h"
Expand All @@ -18,7 +19,7 @@ namespace MDAL
{
public:
Loader2dm( const std::string &meshFile );
Mesh *load( MDAL_Status *status );
std::unique_ptr< Mesh > load( MDAL_Status *status );

private:
std::string mMeshFile;
Expand Down
Loading

0 comments on commit 61f84ce

Please sign in to comment.