2018-12-04 17:28:05 +01:00
|
|
|
/*
|
|
|
|
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>
|
2019-12-11 14:04:34 +01:00
|
|
|
#include <assert.h>
|
2018-12-04 17:28:05 +01:00
|
|
|
#include <vector>
|
|
|
|
#include <memory>
|
|
|
|
#include <map>
|
|
|
|
#include <string>
|
|
|
|
#include "mdal.h"
|
|
|
|
#include "mdal_data_model.hpp"
|
|
|
|
|
|
|
|
namespace MDAL
|
|
|
|
{
|
2019-12-11 14:04:34 +01:00
|
|
|
class MemoryMesh;
|
|
|
|
|
2018-12-04 17:28:05 +01:00
|
|
|
typedef struct
|
|
|
|
{
|
2020-08-10 15:49:19 +02:00
|
|
|
double x = std::numeric_limits<double>::quiet_NaN();
|
|
|
|
double y = std::numeric_limits<double>::quiet_NaN();
|
2020-03-09 05:59:51 +01:00
|
|
|
double z = 0.0; // Bed elevation
|
2018-12-14 14:59:53 +01:00
|
|
|
|
2018-12-04 17:28:05 +01:00
|
|
|
} Vertex;
|
|
|
|
|
2020-03-09 05:59:51 +01:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
size_t startVertex;
|
|
|
|
size_t endVertex;
|
|
|
|
} Edge;
|
|
|
|
|
2018-12-04 17:28:05 +01:00
|
|
|
typedef std::vector<size_t> Face;
|
|
|
|
typedef std::vector<Vertex> Vertices;
|
2020-03-09 05:59:51 +01:00
|
|
|
typedef std::vector<Edge> Edges;
|
2018-12-04 17:28:05 +01:00
|
|
|
typedef std::vector<Face> Faces;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The MemoryDataset stores all the data in the memory
|
|
|
|
*/
|
2019-11-29 15:15:01 +01:00
|
|
|
class MemoryDataset2D: public Dataset2D
|
2018-12-04 17:28:05 +01:00
|
|
|
{
|
|
|
|
public:
|
2019-12-11 14:04:34 +01:00
|
|
|
MemoryDataset2D( DatasetGroup *grp, bool hasActiveFlag = false );
|
2019-11-29 15:15:01 +01:00
|
|
|
~MemoryDataset2D() override;
|
2018-12-04 17:28:05 +01:00
|
|
|
|
|
|
|
size_t scalarData( size_t indexStart, size_t count, double *buffer ) override;
|
|
|
|
size_t vectorData( size_t indexStart, size_t count, double *buffer ) override;
|
2019-12-11 14:04:34 +01:00
|
|
|
|
|
|
|
//! Returns 0 for datasets that does not support active flags
|
2018-12-04 17:28:05 +01:00
|
|
|
size_t activeData( size_t indexStart, size_t count, int *buffer ) override;
|
|
|
|
|
|
|
|
/**
|
2019-12-11 14:04:34 +01:00
|
|
|
* 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
|
2018-12-04 17:28:05 +01:00
|
|
|
*/
|
2019-12-11 14:04:34 +01:00
|
|
|
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];
|
|
|
|
}
|
2018-12-04 17:28:05 +01:00
|
|
|
|
2019-12-11 14:04:34 +01:00
|
|
|
//! 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();
|
|
|
|
}
|
2018-12-04 17:28:05 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
/**
|
|
|
|
* Stores vector2d/scalar data for dataset in form
|
|
|
|
* scalars: x1, x2, x3, ..., xN
|
|
|
|
* vector2D: x1, y1, x2, y2, x3, y3, .... , xN, yN
|
|
|
|
*
|
2019-12-11 14:04:34 +01:00
|
|
|
* all values are initialized to std::numerical_limits<double>::quiet_NaN ( == NODATA )
|
2018-12-04 17:28:05 +01:00
|
|
|
*
|
|
|
|
* 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;
|
2019-11-29 15:15:01 +01:00
|
|
|
|
2018-12-04 17:28:05 +01:00
|
|
|
/**
|
|
|
|
* Active flag, whether the face is active or not (disabled)
|
2019-12-11 14:04:34 +01:00
|
|
|
* Only make sense for dataset defined on vertices
|
2018-12-04 17:28:05 +01:00
|
|
|
* For dataset defined on faces, this is empty vector
|
|
|
|
*
|
|
|
|
* Values are initialized by default to 1 (active)
|
|
|
|
*/
|
|
|
|
std::vector<int> mActive;
|
|
|
|
};
|
|
|
|
|
|
|
|
class MemoryMesh: public Mesh
|
|
|
|
{
|
|
|
|
public:
|
2020-07-01 04:18:27 -04:00
|
|
|
//! Constructs an empty mesh
|
2019-01-04 18:18:34 +01:00
|
|
|
MemoryMesh( const std::string &driverName,
|
2018-12-04 17:28:05 +01:00
|
|
|
size_t faceVerticesMaximumCount,
|
|
|
|
const std::string &uri );
|
2020-07-01 04:18:27 -04:00
|
|
|
|
2018-12-04 17:28:05 +01:00
|
|
|
~MemoryMesh() override;
|
|
|
|
|
|
|
|
std::unique_ptr<MDAL::MeshVertexIterator> readVertices() override;
|
2020-03-09 05:59:51 +01:00
|
|
|
std::unique_ptr<MDAL::MeshEdgeIterator> readEdges() override;
|
2018-12-04 17:28:05 +01:00
|
|
|
std::unique_ptr<MDAL::MeshFaceIterator> readFaces() override;
|
|
|
|
|
2020-07-01 04:18:27 -04:00
|
|
|
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;
|
|
|
|
|
|
|
|
private:
|
|
|
|
BBox mExtent;
|
|
|
|
Vertices mVertices;
|
|
|
|
Faces mFaces;
|
|
|
|
Edges mEdges;
|
2018-12-04 17:28:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
2020-03-09 05:59:51 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
class MemoryMeshEdgeIterator: public MeshEdgeIterator
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
MemoryMeshEdgeIterator( const MemoryMesh *mesh );
|
|
|
|
~MemoryMeshEdgeIterator() override;
|
|
|
|
|
|
|
|
size_t next( size_t edgeCount,
|
|
|
|
int *startVertexIndices,
|
|
|
|
int *endVertexIndices ) override;
|
2018-12-04 17:28:05 +01:00
|
|
|
|
2020-03-09 05:59:51 +01:00
|
|
|
const MemoryMesh *mMemoryMesh;
|
|
|
|
size_t mLastEdgeIndex = 0;
|
2018-12-04 17:28:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
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
|