QGIS/external/mdal/mdal_memory_data_model.hpp
Peter Petrik 9f49c0d1fa
MDAL update & FLO-2D bug fix (#45349)
API for edges edits
data on volumes for dynamic drivers
WRITE support for PLY

Fix loading FLO-2D
2021-10-05 08:59:38 -04:00

376 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
MDAL - Mesh Data Abstraction Library (MIT License)
Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com)
*/
#ifndef MDAL_MEMORY_DATA_MODEL_HPP
#define MDAL_MEMORY_DATA_MODEL_HPP
#include <stddef.h>
#include <assert.h>
#include <vector>
#include <memory>
#include <map>
#include <string>
#include "mdal.h"
#include "mdal_data_model.hpp"
namespace MDAL
{
class MemoryMesh;
typedef struct VertexType
{
double x = std::numeric_limits<double>::quiet_NaN();
double y = std::numeric_limits<double>::quiet_NaN();
double z = 0.0; // Bed elevation
} Vertex;
typedef struct
{
size_t startVertex;
size_t endVertex;
} Edge;
typedef std::vector<size_t> Face;
typedef std::vector<Vertex> Vertices;
typedef std::vector<Edge> Edges;
typedef std::vector<Face> Faces;
/**
* The MemoryDataset stores all the data in the memory
*/
class MemoryDataset2D: public Dataset2D
{
public:
MemoryDataset2D( DatasetGroup *grp, bool hasActiveFlag = false );
~MemoryDataset2D() override;
size_t scalarData( size_t indexStart, size_t count, double *buffer ) override;
size_t vectorData( size_t indexStart, size_t count, double *buffer ) override;
//! Returns 0 for datasets that does not support active flags
size_t activeData( size_t indexStart, size_t count, int *buffer ) override;
/**
* Loop through all faces and activate those which has all 4 values on vertices valid
* Dataset must support active flags and be defined on vertices
*/
void activateFaces( MDAL::MemoryMesh *mesh );
/**
* Sets active flag for index
*
* \param stat 1 for active, 0 for non-active
* \param index index of the flag
*
* Dataset must support active flags
*/
void setActive( size_t index, int stat )
{
assert( supportsActiveFlag() );
assert( mActive.size() > index );
mActive[index] = stat;
}
void setActive( const int *activeBuffer );
int active( size_t index ) const
{
assert( supportsActiveFlag() );
assert( mActive.size() > index );
return mActive[index];
}
void setScalarValue( size_t index, double value )
{
assert( mValues.size() > index );
assert( group()->isScalar() );
mValues[index] = value;
}
void setVectorValue( size_t index, double x, double y )
{
assert( mValues.size() > 2 * index + 1 );
assert( !group()->isScalar() );
mValues[2 * index] = x;
mValues[2 * index + 1] = y;
}
void setValueX( size_t index, double x )
{
assert( mValues.size() > 2 * index );
assert( !group()->isScalar() );
mValues[2 * index] = x;
}
void setValueY( size_t index, double x )
{
assert( mValues.size() > 2 * index + 1 );
assert( !group()->isScalar() );
mValues[2 * index + 1] = x;
}
double valueX( size_t index ) const
{
assert( mValues.size() > 2 * index + 1 );
assert( !group()->isScalar() );
return mValues[2 * index];
}
double valueY( size_t index ) const
{
assert( mValues.size() > 2 * index + 1 );
assert( !group()->isScalar() );
return mValues[2 * index + 1];
}
double scalarValue( size_t index ) const
{
assert( mValues.size() > index );
assert( group()->isScalar() );
return mValues[index];
}
/**
* Returns pointer to internal buffer with values
* Never null, already allocated
* for vector datasets in form x1, y1, ..., xN, yN
*/
double *values()
{
return mValues.data();
}
private:
/**
* Stores vector2d/scalar data for dataset in form
* scalars: x1, x2, x3, ..., xN
* vector2D: x1, y1, x2, y2, x3, y3, .... , xN, yN
*
* all values are initialized to std::numerical_limits<double>::quiet_NaN ( == NODATA )
*
* size:
* - face count if isOnFaces & isScalar
* - vertex count if isOnVertices & isScalar
* - face count * 2 if isOnFaces & isVector
* - vertex count * 2 if isOnVertices & isVector
*/
std::vector<double> mValues;
/**
* Active flag, whether the face is active or not (disabled)
* Only make sense for dataset defined on vertices
* For dataset defined on faces, this is empty vector
*
* Values are initialized by default to 1 (active)
*/
std::vector<int> mActive;
};
class MemoryDataset3D: public Dataset3D
{
public:
MemoryDataset3D(
DatasetGroup *grp,
size_t volumes,
size_t maxVerticalLevelCount,
const int *verticalLevelCounts,
const double *verticalExtrusions
);
~MemoryDataset3D() override;
void setScalarValue( size_t index, double value )
{
assert( mValues.size() > index );
assert( group()->isScalar() );
mValues[index] = value;
}
void setVectorValue( size_t index, double x, double y )
{
assert( mValues.size() > 2 * index + 1 );
assert( !group()->isScalar() );
mValues[2 * index] = x;
mValues[2 * index + 1] = y;
}
void setValueX( size_t index, double x )
{
assert( mValues.size() > 2 * index );
assert( !group()->isScalar() );
mValues[2 * index] = x;
}
void setValueY( size_t index, double x )
{
assert( mValues.size() > 2 * index + 1 );
assert( !group()->isScalar() );
mValues[2 * index + 1] = x;
}
double valueX( size_t index ) const
{
assert( mValues.size() > 2 * index + 1 );
assert( !group()->isScalar() );
return mValues[2 * index];
}
double valueY( size_t index ) const
{
assert( mValues.size() > 2 * index + 1 );
assert( !group()->isScalar() );
return mValues[2 * index + 1];
}
double scalarValue( size_t index ) const
{
assert( mValues.size() > index );
assert( group()->isScalar() );
return mValues[index];
}
void updateIndices();
/**
* Returns pointer to internal buffer with values
* Never null, already allocated
* for vector datasets in form x1, y1, ..., xN, yN
*/
double *values()
{
return mValues.data();
}
size_t verticalLevelCountData( size_t indexStart, size_t count, int *buffer ) override;
size_t verticalLevelData( size_t indexStart, size_t count, double *buffer ) override;
size_t faceToVolumeData( size_t indexStart, size_t count, int *buffer ) override;
size_t scalarVolumesData( size_t indexStart, size_t count, double *buffer ) override;
size_t vectorVolumesData( size_t indexStart, size_t count, double *buffer ) override;
private:
/**
* Stores vector2d/scalar data for dataset in form
* scalars: x1, x2, x3, ..., xN
* vector2D: x1, y1, x2, y2, x3, y3, .... , xN, yN
*
* all values are initialized to std::numerical_limits<double>::quiet_NaN ( == NODATA )
*
*/
std::vector<double> mValues;
/**
* Stores the first index of 3D volume for particular meshs face in 3D Stacked Meshes
*
* All values are initialised to actual values
*/
std::vector<int> mFaceToVolume;
/**
* Stores number of vertical level for particular meshs face in 3D Stacked Meshes.
*
* All values are initialised to actual values
*/
std::vector<int> mVerticalLevelCounts;
/**
* Stores vertical level extrusion for particular meshs face in 3D Stacked Meshes.
*
* All values are initialised to actual values
*/
std::vector<double> mVerticalExtrusions;
};
class MemoryMesh: public Mesh
{
public:
//! Constructs an empty mesh
MemoryMesh( const std::string &driverName,
size_t faceVerticesMaximumCount,
const std::string &uri );
~MemoryMesh() override;
std::unique_ptr<MDAL::MeshVertexIterator> readVertices() override;
std::unique_ptr<MDAL::MeshEdgeIterator> readEdges() override;
std::unique_ptr<MDAL::MeshFaceIterator> readFaces() override;
const Vertices &vertices() const {return mVertices;}
const Faces &faces() const {return mFaces;}
const Edges &edges() const {return mEdges;}
//! Sets all vertices using std::move if possible
void setVertices( Vertices vertices );
//! Sets all faces using std::move if possible
void setFaces( Faces faces );
//! Sets all edges using std::move if possible
void setEdges( Edges edges );
size_t verticesCount() const override {return mVertices.size();}
size_t edgesCount() const override {return mEdges.size();}
size_t facesCount() const override {return mFaces.size();}
BBox extent() const override;
void addVertices( size_t vertexCount, double *coordinates ) override;
void addFaces( size_t faceCount, size_t driverMaxVerticesPerFace, int *faceSizes, int *vertexIndices ) override;
void addEdges( size_t edgeCount, int *startVertexIndices, int *endVertexIndices ) override;
bool isEditable() const override {return true;}
private:
BBox mExtent;
Vertices mVertices;
Faces mFaces;
Edges mEdges;
};
class MemoryMeshVertexIterator: public MeshVertexIterator
{
public:
MemoryMeshVertexIterator( const MemoryMesh *mesh );
~MemoryMeshVertexIterator() override;
size_t next( size_t vertexCount, double *coordinates ) override;
const MemoryMesh *mMemoryMesh;
size_t mLastVertexIndex = 0;
};
class MemoryMeshEdgeIterator: public MeshEdgeIterator
{
public:
MemoryMeshEdgeIterator( const MemoryMesh *mesh );
~MemoryMeshEdgeIterator() override;
size_t next( size_t edgeCount,
int *startVertexIndices,
int *endVertexIndices ) override;
const MemoryMesh *mMemoryMesh;
size_t mLastEdgeIndex = 0;
};
class MemoryMeshFaceIterator: public MeshFaceIterator
{
public:
MemoryMeshFaceIterator( const MemoryMesh *mesh );
~MemoryMeshFaceIterator() override;
size_t next( size_t faceOffsetsBufferLen,
int *faceOffsetsBuffer,
size_t vertexIndicesBufferLen,
int *vertexIndicesBuffer ) override;
const MemoryMesh *mMemoryMesh;
size_t mLastFaceIndex = 0;
};
} // namespace MDAL
#endif //MDAL_MEMORY_DATA_MODEL_HPP