Skip to content

Commit 61f84ce

Browse files
authored
Merge pull request #7008 from PeterPetrik/qgsmeshlayer_2_scalar_vector_datasets
[mesh] Rendering of scalar and vector datasets
2 parents dde895d + 882d8ed commit 61f84ce

File tree

53 files changed

+4419
-196
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+4419
-196
lines changed

external/mdal/api/mdal.h

+70-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
#ifndef MDAL_H
77
#define MDAL_H
88

9+
/**********************************************************************/
10+
/**********************************************************************/
11+
/* API is considered EXPERIMENTAL and can be changed without a notice */
12+
/**********************************************************************/
13+
/**********************************************************************/
14+
915
#ifdef MDAL_STATIC
1016
# define MDAL_EXPORT
1117
#else
@@ -46,6 +52,7 @@ enum MDAL_Status
4652
Err_UnknownFormat,
4753
Err_IncompatibleMesh,
4854
Err_InvalidData,
55+
Err_IncompatibleDataset,
4956
Err_MissingDriver,
5057
// Warnings
5158
Warn_UnsupportedElement,
@@ -57,6 +64,7 @@ enum MDAL_Status
5764

5865
//! Mesh
5966
typedef void *MeshH;
67+
typedef void *DatasetH;
6068

6169
//! Return MDAL version
6270
MDAL_EXPORT const char *MDAL_Version();
@@ -68,7 +76,6 @@ MDAL_EXPORT MDAL_Status MDAL_LastStatus();
6876
MDAL_EXPORT MeshH MDAL_LoadMesh( const char *meshFile );
6977
//! Close mesh, free the memory
7078
MDAL_EXPORT void MDAL_CloseMesh( MeshH mesh );
71-
7279
//! Return vertex count for the mesh
7380
MDAL_EXPORT int MDAL_M_vertexCount( MeshH mesh );
7481
//! Return vertex X coord for the mesh
@@ -82,6 +89,68 @@ MDAL_EXPORT int MDAL_M_faceVerticesCountAt( MeshH mesh, int index );
8289
//! Return vertex index for face
8390
MDAL_EXPORT int MDAL_M_faceVerticesIndexAt( MeshH mesh, int face_index, int vertex_index );
8491

92+
/**
93+
* Load dataset file. On error see MDAL_LastStatus for error type.
94+
* This may effectively load whole dataset in-memory for some providers
95+
* Datasets will be closed automatically on mesh destruction or memory
96+
* can be freed manually with MDAL_CloseDataset if needed
97+
*/
98+
MDAL_EXPORT void MDAL_M_LoadDatasets( MeshH mesh, const char *datasetFile );
99+
100+
//! Free the memory used to get dataset values
101+
MDAL_EXPORT void MDAL_M_CloseDataset( DatasetH dataset );
102+
103+
//! Return dataset count
104+
MDAL_EXPORT int MDAL_M_datasetCount( MeshH mesh );
105+
106+
//! Return dataset handle
107+
MDAL_EXPORT DatasetH MDAL_M_dataset( MeshH mesh, int index );
108+
109+
//! Whether dataset has scalar data associated
110+
MDAL_EXPORT bool MDAL_D_hasScalarData( DatasetH dataset );
111+
112+
//! Whether dataset is on vertices
113+
MDAL_EXPORT bool MDAL_D_isOnVertices( DatasetH dataset );
114+
115+
//! Return number of metadata values
116+
MDAL_EXPORT int MDAL_D_metadataCount( DatasetH dataset );
117+
118+
//! Return dataset metadata key
119+
MDAL_EXPORT const char *MDAL_D_metadataKey( DatasetH dataset, int index );
120+
121+
//! Return dataset metadata value
122+
MDAL_EXPORT const char *MDAL_D_metadataValue( DatasetH dataset, int index );
123+
124+
//! Return number of values
125+
MDAL_EXPORT int MDAL_D_valueCount( DatasetH dataset );
126+
127+
/**
128+
* Return scalar value associated with the index from the dataset
129+
* for nodata return numeric_limits<double>:quiet_NaN
130+
*/
131+
MDAL_EXPORT double MDAL_D_value( DatasetH dataset, int valueIndex );
132+
133+
/**
134+
* Return X value associated with the index from the vector dataset
135+
* for nodata return numeric_limits<double>:quiet_NaN
136+
*/
137+
MDAL_EXPORT double MDAL_D_valueX( DatasetH dataset, int valueIndex );
138+
139+
/**
140+
* Return Y value associated with the index from the vector dataset
141+
* for nodata return numeric_limits<double>:quiet_NaN
142+
*/
143+
MDAL_EXPORT double MDAL_D_valueY( DatasetH dataset, int valueIndex );
144+
145+
/**
146+
* Whether element is active - should be taken into account
147+
* Some formats support switching off the element for particular timestep
148+
*/
149+
MDAL_EXPORT bool MDAL_D_active( DatasetH dataset, int faceIndex );
150+
151+
//! Return whether dataset is valid
152+
MDAL_EXPORT bool MDAL_D_isValid( DatasetH dataset );
153+
85154
#ifdef __cplusplus
86155
}
87156
#endif

external/mdal/frmts/mdal_2dm.cpp

+44-41
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
MDAL - Mesh Data Abstraction Library (MIT License)
3-
Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com)
3+
Copyright (C) 2018 Lutra Consulting Ltd.
44
*/
55

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

25-
MDAL::Mesh *MDAL::Loader2dm::load( MDAL_Status *status )
25+
std::unique_ptr<MDAL::Mesh> MDAL::Loader2dm::load( MDAL_Status *status )
2626
{
2727
if ( status ) *status = MDAL_Status::None;
2828

2929
if ( !MDAL::fileExists( mMeshFile ) )
3030
{
3131
if ( status ) *status = MDAL_Status::Err_FileNotFound;
32-
return 0;
32+
return nullptr;
3333
}
3434

3535
std::ifstream in( mMeshFile, std::ifstream::in );
3636
std::string line;
3737
if ( !std::getline( in, line ) || !startsWith( line, "MESH2D" ) )
3838
{
3939
if ( status ) *status = MDAL_Status::Err_UnknownFormat;
40-
return 0;
40+
return nullptr;
4141
}
4242

43-
size_t elemCount = 0;
44-
size_t nodeCount = 0;
43+
size_t faceCount = 0;
44+
size_t vertexCount = 0;
4545

4646
// Find out how many nodes and elements are contained in the .2dm mesh file
4747
while ( std::getline( in, line ) )
4848
{
4949
if ( startsWith( line, "E4Q" ) ||
5050
startsWith( line, "E3T" ) )
5151
{
52-
elemCount++;
52+
faceCount++;
5353
}
5454
else if ( startsWith( line, "ND" ) )
5555
{
56-
nodeCount++;
56+
vertexCount++;
5757
}
5858
else if ( startsWith( line, "E2L" ) ||
5959
startsWith( line, "E3L" ) ||
@@ -62,71 +62,71 @@ MDAL::Mesh *MDAL::Loader2dm::load( MDAL_Status *status )
6262
startsWith( line, "E9Q" ) )
6363
{
6464
if ( status ) *status = MDAL_Status::Warn_UnsupportedElement;
65-
elemCount += 1; // We still count them as elements
65+
faceCount += 1; // We still count them as elements
6666
}
6767
}
6868

6969
// Allocate memory
70-
std::vector<Vertex> vertices( nodeCount );
71-
std::vector<Face> faces( elemCount );
70+
std::vector<Vertex> vertices( vertexCount );
71+
std::vector<Face> faces( faceCount );
7272

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

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

78-
size_t elemIndex = 0;
79-
size_t nodeIndex = 0;
80-
std::map<size_t, size_t> elemIDtoIndex;
81-
std::map<size_t, size_t> nodeIDtoIndex;
78+
size_t faceIndex = 0;
79+
size_t vertexIndex = 0;
80+
std::map<size_t, size_t> faceIDtoIndex;
81+
std::map<size_t, size_t> vertexIDtoIndex;
8282

8383
while ( std::getline( in, line ) )
8484
{
8585
if ( startsWith( line, "E4Q" ) )
8686
{
8787
chunks = split( line, " ", SplitBehaviour::SkipEmptyParts );
88-
assert( elemIndex < elemCount );
88+
assert( faceIndex < faceCount );
8989

9090
size_t elemID = toSizeT( chunks[1] );
9191

92-
std::map<size_t, size_t>::iterator search = elemIDtoIndex.find( elemID );
93-
if ( search != elemIDtoIndex.end() )
92+
std::map<size_t, size_t>::iterator search = faceIDtoIndex.find( elemID );
93+
if ( search != faceIDtoIndex.end() )
9494
{
9595
if ( status ) *status = MDAL_Status::Warn_ElementNotUnique;
9696
continue;
9797
}
98-
elemIDtoIndex[elemID] = elemIndex;
99-
Face &face = faces[elemIndex];
98+
faceIDtoIndex[elemID] = faceIndex;
99+
Face &face = faces[faceIndex];
100100
face.resize( 4 );
101101
// Right now we just store node IDs here - we will convert them to node indices afterwards
102102
for ( size_t i = 0; i < 4; ++i )
103103
face[i] = toSizeT( chunks[i + 2] );
104104

105-
elemIndex++;
105+
faceIndex++;
106106
}
107107
else if ( startsWith( line, "E3T" ) )
108108
{
109109
chunks = split( line, " ", SplitBehaviour::SkipEmptyParts );
110-
assert( elemIndex < elemCount );
110+
assert( faceIndex < faceCount );
111111

112112
size_t elemID = toSizeT( chunks[1] );
113113

114-
std::map<size_t, size_t>::iterator search = elemIDtoIndex.find( elemID );
115-
if ( search != elemIDtoIndex.end() )
114+
std::map<size_t, size_t>::iterator search = faceIDtoIndex.find( elemID );
115+
if ( search != faceIDtoIndex.end() )
116116
{
117117
if ( status ) *status = MDAL_Status::Warn_ElementNotUnique;
118118
continue;
119119
}
120-
elemIDtoIndex[elemID] = elemIndex;
121-
Face &face = faces[elemIndex];
120+
faceIDtoIndex[elemID] = faceIndex;
121+
Face &face = faces[faceIndex];
122122
face.resize( 3 );
123123
// Right now we just store node IDs here - we will convert them to node indices afterwards
124124
for ( size_t i = 0; i < 3; ++i )
125125
{
126126
face[i] = toSizeT( chunks[i + 2] );
127127
}
128128

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

141141
size_t elemID = toSizeT( chunks[1] );
142142

143-
std::map<size_t, size_t>::iterator search = elemIDtoIndex.find( elemID );
144-
if ( search != elemIDtoIndex.end() )
143+
std::map<size_t, size_t>::iterator search = faceIDtoIndex.find( elemID );
144+
if ( search != faceIDtoIndex.end() )
145145
{
146146
if ( status ) *status = MDAL_Status::Warn_ElementNotUnique;
147147
continue;
148148
}
149-
elemIDtoIndex[elemID] = elemIndex;
149+
faceIDtoIndex[elemID] = faceIndex;
150150
assert( false ); //TODO mark element as unusable
151151

152-
elemIndex++;
152+
faceIndex++;
153153
}
154154
else if ( startsWith( line, "ND" ) )
155155
{
156156
chunks = split( line, " ", SplitBehaviour::SkipEmptyParts );
157157
size_t nodeID = toSizeT( chunks[1] );
158158

159-
std::map<size_t, size_t>::iterator search = nodeIDtoIndex.find( nodeID );
160-
if ( search != nodeIDtoIndex.end() )
159+
std::map<size_t, size_t>::iterator search = vertexIDtoIndex.find( nodeID );
160+
if ( search != vertexIDtoIndex.end() )
161161
{
162162
if ( status ) *status = MDAL_Status::Warn_NodeNotUnique;
163163
continue;
164164
}
165-
nodeIDtoIndex[nodeID] = nodeIndex;
166-
assert( nodeIndex < nodeCount );
167-
Vertex &vertex = vertices[nodeIndex];
165+
vertexIDtoIndex[nodeID] = vertexIndex;
166+
assert( vertexIndex < vertexCount );
167+
Vertex &vertex = vertices[vertexIndex];
168168
vertex.x = toDouble( chunks[2] );
169169
vertex.y = toDouble( chunks[3] );
170170

171-
nodeIndex++;
171+
vertexIndex++;
172172
}
173173
}
174174

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

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

199-
Mesh *mesh = new Mesh;
199+
std::unique_ptr< Mesh > mesh( new Mesh );
200+
mesh->uri = mMeshFile;
200201
mesh->faces = faces;
201202
mesh->vertices = vertices;
203+
mesh->faceIDtoIndex = faceIDtoIndex;
204+
mesh->vertexIDtoIndex = vertexIDtoIndex;
202205

203206
return mesh;
204207
}

external/mdal/frmts/mdal_2dm.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define MDAL_2DM_HPP
88

99
#include <string>
10+
#include <memory>
1011

1112
#include "mdal_defines.hpp"
1213
#include "mdal.h"
@@ -18,7 +19,7 @@ namespace MDAL
1819
{
1920
public:
2021
Loader2dm( const std::string &meshFile );
21-
Mesh *load( MDAL_Status *status );
22+
std::unique_ptr< Mesh > load( MDAL_Status *status );
2223

2324
private:
2425
std::string mMeshFile;

0 commit comments

Comments
 (0)