mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-15 00:07:25 -05:00
update MDAL 0.7.91 (beta release for QGIS 3.18)
This commit is contained in:
parent
fe6cf6090b
commit
8f5583eb51
64
external/mdal/frmts/mdal_2dm.cpp
vendored
64
external/mdal/frmts/mdal_2dm.cpp
vendored
@ -34,7 +34,7 @@ MDAL::Mesh2dm::Mesh2dm( size_t faceVerticesMaximumCount,
|
||||
|
||||
MDAL::Mesh2dm::~Mesh2dm() = default;
|
||||
|
||||
bool _parse_vertex_id_gaps( std::map<size_t, size_t> &vertexIDtoIndex, size_t vertexIndex, size_t vertexID )
|
||||
static bool _parse_vertex_id_gaps( std::map<size_t, size_t> &vertexIDtoIndex, size_t vertexIndex, size_t vertexID )
|
||||
{
|
||||
if ( vertexIndex == vertexID )
|
||||
return false;
|
||||
@ -50,6 +50,21 @@ bool _parse_vertex_id_gaps( std::map<size_t, size_t> &vertexIDtoIndex, size_t ve
|
||||
return false;
|
||||
}
|
||||
|
||||
static void _persist_native_index( std::vector<double> &arr, size_t nativeID, size_t ourId, size_t maxOurId )
|
||||
{
|
||||
if ( !arr.empty() || ( nativeID != ourId + 1 ) )
|
||||
{
|
||||
// we have gaps in face indexing
|
||||
if ( arr.empty() )
|
||||
{
|
||||
arr.resize( maxOurId );
|
||||
for ( size_t i = 0; i < ourId; ++i )
|
||||
arr[i] = static_cast<double>( i + 1 );
|
||||
}
|
||||
arr[ourId] = static_cast<double>( nativeID );
|
||||
}
|
||||
}
|
||||
|
||||
size_t MDAL::Mesh2dm::vertexIndex( size_t vertexID ) const
|
||||
{
|
||||
auto ni2i = mVertexIDtoIndex.find( vertexID );
|
||||
@ -120,11 +135,16 @@ std::unique_ptr<MDAL::Mesh> MDAL::Driver2dm::load( const std::string &meshFile,
|
||||
size_t materialCount = 0;
|
||||
bool hasMaterialsDefinitionsForElements = false;
|
||||
|
||||
std::vector<double> nativeVertexIds;
|
||||
std::vector<double> nativeFaceIds;
|
||||
std::vector<double> nativeEdgeIds;
|
||||
|
||||
// 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" ) )
|
||||
startsWith( line, "E3T" ) ||
|
||||
startsWith( line, "E6T" ) )
|
||||
{
|
||||
faceCount++;
|
||||
}
|
||||
@ -137,7 +157,6 @@ std::unique_ptr<MDAL::Mesh> MDAL::Driver2dm::load( const std::string &meshFile,
|
||||
edgesCount++;
|
||||
}
|
||||
else if ( startsWith( line, "E3L" ) ||
|
||||
startsWith( line, "E6T" ) ||
|
||||
startsWith( line, "E8Q" ) ||
|
||||
startsWith( line, "E9Q" ) )
|
||||
{
|
||||
@ -156,6 +175,7 @@ std::unique_ptr<MDAL::Mesh> MDAL::Driver2dm::load( const std::string &meshFile,
|
||||
Vertices vertices( vertexCount );
|
||||
Edges edges( edgesCount );
|
||||
Faces faces( faceCount );
|
||||
size_t maxVerticesPerFace = 2;
|
||||
|
||||
// .2dm mesh files may have any number of material ID columns
|
||||
std::vector<std::vector<double>> faceMaterials;
|
||||
@ -174,24 +194,31 @@ std::unique_ptr<MDAL::Mesh> MDAL::Driver2dm::load( const std::string &meshFile,
|
||||
while ( std::getline( in, line ) )
|
||||
{
|
||||
if ( startsWith( line, "E4Q" ) ||
|
||||
startsWith( line, "E3T" )
|
||||
startsWith( line, "E3T" ) ||
|
||||
startsWith( line, "E6T" )
|
||||
)
|
||||
{
|
||||
chunks = split( line, ' ' );
|
||||
assert( faceIndex < faceCount );
|
||||
|
||||
const size_t faceVertexCount = MDAL::toSizeT( line[1] );
|
||||
assert( ( faceVertexCount == 3 ) || ( faceVertexCount == 4 ) );
|
||||
assert( ( faceVertexCount == 3 ) || ( faceVertexCount == 4 ) || ( faceVertexCount == 6 ) );
|
||||
if ( maxVerticesPerFace < faceVertexCount )
|
||||
maxVerticesPerFace = faceVertexCount;
|
||||
|
||||
Face &face = faces[faceIndex];
|
||||
face.resize( faceVertexCount );
|
||||
|
||||
// chunks format here
|
||||
// E** id vertex_id1, vertex_id2, vertex_id3, material_id [, aux_column_1, aux_column_2, ...]
|
||||
// E** id vertex_id1, vertex_id2, vertex_id3, ..., material_id [, aux_column_1, aux_column_2, ...]
|
||||
// vertex ids are numbered from 1
|
||||
// Right now we just store node IDs here - we will convert them to node indices afterwards
|
||||
assert( chunks.size() > faceVertexCount + 1 );
|
||||
|
||||
// in case we have gaps/reorders in native indexes, store it
|
||||
size_t nativeID = MDAL::toSizeT( chunks[1] );
|
||||
_persist_native_index( nativeFaceIds, nativeID, faceIndex, faceCount );
|
||||
|
||||
for ( size_t i = 0; i < faceVertexCount; ++i )
|
||||
face[i] = MDAL::toSizeT( chunks[i + 2] ) - 1; // 2dm is numbered from 1
|
||||
|
||||
@ -237,6 +264,10 @@ std::unique_ptr<MDAL::Mesh> MDAL::Driver2dm::load( const std::string &meshFile,
|
||||
chunks = split( line, ' ' );
|
||||
assert( edgeIndex < edgesCount );
|
||||
assert( chunks.size() > 4 );
|
||||
// in case we have gaps/reorders in native indexes, store it
|
||||
size_t nativeID = MDAL::toSizeT( chunks[1] );
|
||||
_persist_native_index( nativeEdgeIds, nativeID, edgeIndex, edgesCount );
|
||||
|
||||
size_t startVertexIndex = MDAL::toSizeT( chunks[2] ) - 1; // 2dm is numbered from 1
|
||||
size_t endVertexIndex = MDAL::toSizeT( chunks[3] ) - 1; // 2dm is numbered from 1
|
||||
Edge &edge = edges[edgeIndex];
|
||||
@ -261,9 +292,11 @@ std::unique_ptr<MDAL::Mesh> MDAL::Driver2dm::load( const std::string &meshFile,
|
||||
}
|
||||
lastVertexID = nodeID;
|
||||
}
|
||||
nodeID -= 1; // 2dm is numbered from 1
|
||||
|
||||
_parse_vertex_id_gaps( vertexIDtoIndex, vertexIndex, nodeID );
|
||||
// in case we have gaps/reorders in native indexes, store it
|
||||
_persist_native_index( nativeVertexIds, nodeID, vertexIndex, vertexCount );
|
||||
_parse_vertex_id_gaps( vertexIDtoIndex, vertexIndex, nodeID - 1 );
|
||||
|
||||
assert( vertexIndex < vertexCount );
|
||||
Vertex &vertex = vertices[vertexIndex];
|
||||
vertex.x = toDouble( chunks[2] );
|
||||
@ -296,7 +329,7 @@ std::unique_ptr<MDAL::Mesh> MDAL::Driver2dm::load( const std::string &meshFile,
|
||||
|
||||
std::unique_ptr< Mesh2dm > mesh(
|
||||
new Mesh2dm(
|
||||
MAX_VERTICES_PER_FACE_2DM,
|
||||
maxVerticesPerFace,
|
||||
mMeshFile,
|
||||
vertexIDtoIndex
|
||||
)
|
||||
@ -308,6 +341,13 @@ std::unique_ptr<MDAL::Mesh> MDAL::Driver2dm::load( const std::string &meshFile,
|
||||
// Add Bed Elevation
|
||||
MDAL::addBedElevationDatasetGroup( mesh.get(), mesh->vertices() );
|
||||
|
||||
if ( !nativeFaceIds.empty() )
|
||||
MDAL::addFaceScalarDatasetGroup( mesh.get(), nativeFaceIds, "NativeFaceIds" );
|
||||
if ( !nativeVertexIds.empty() )
|
||||
MDAL::addVertexScalarDatasetGroup( mesh.get(), nativeVertexIds, "NativeVertexIds" );
|
||||
if ( !nativeEdgeIds.empty() )
|
||||
MDAL::addEdgeScalarDatasetGroup( mesh.get(), nativeEdgeIds, "NativeEdgeIds" );
|
||||
|
||||
// Add material IDs
|
||||
if ( hasMaterialsDefinitionsForElements )
|
||||
{
|
||||
@ -367,12 +407,12 @@ void MDAL::Driver2dm::save( const std::string &uri, MDAL::Mesh *mesh )
|
||||
}
|
||||
|
||||
// write faces
|
||||
std::vector<int> vertexIndices( mesh->faceVerticesMaximumCount() );
|
||||
std::unique_ptr<MDAL::MeshFaceIterator> faceIterator = mesh->readFaces();
|
||||
for ( size_t i = 0; i < mesh->facesCount(); ++i )
|
||||
{
|
||||
int faceOffsets[1];
|
||||
int vertexIndices[MAX_VERTICES_PER_FACE_2DM];
|
||||
faceIterator->next( 1, faceOffsets, 4, vertexIndices );
|
||||
faceIterator->next( 1, faceOffsets, 4, vertexIndices.data() );
|
||||
|
||||
if ( faceOffsets[0] > 2 && faceOffsets[0] < 5 )
|
||||
{
|
||||
@ -380,6 +420,8 @@ void MDAL::Driver2dm::save( const std::string &uri, MDAL::Mesh *mesh )
|
||||
line = "E3T ";
|
||||
if ( faceOffsets[0] == 4 )
|
||||
line = "E4Q ";
|
||||
if ( faceOffsets[0] == 6 )
|
||||
line = "E6T ";
|
||||
|
||||
line.append( std::to_string( i + 1 ) );
|
||||
|
||||
|
||||
6
external/mdal/frmts/mdal_2dm.hpp
vendored
6
external/mdal/frmts/mdal_2dm.hpp
vendored
@ -14,9 +14,6 @@
|
||||
#include "mdal.h"
|
||||
#include "mdal_driver.hpp"
|
||||
|
||||
|
||||
#define MAX_VERTICES_PER_FACE_2DM 4
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
class Mesh2dm: public MemoryMesh
|
||||
@ -86,8 +83,7 @@ namespace MDAL
|
||||
~Driver2dm() override;
|
||||
Driver2dm *create() override;
|
||||
|
||||
int faceVerticesMaximumCount() const override
|
||||
{return MAX_VERTICES_PER_FACE_2DM;}
|
||||
int faceVerticesMaximumCount() const override {return 6;}
|
||||
|
||||
bool canReadMesh( const std::string &uri ) override;
|
||||
std::unique_ptr< Mesh > load( const std::string &meshFile, const std::string &meshName = "" ) override;
|
||||
|
||||
2
external/mdal/frmts/mdal_ascii_dat.cpp
vendored
2
external/mdal/frmts/mdal_ascii_dat.cpp
vendored
@ -485,7 +485,7 @@ bool MDAL::DriverAsciiDat::persist( MDAL::DatasetGroup *group )
|
||||
if ( !MDAL::contains( uri, "_els" ) && group->dataLocation() != MDAL_DataLocation::DataOnVertices )
|
||||
{
|
||||
// Should contain _els in name for edges/faces dataset but it does not
|
||||
int pos = uri.size() - 4;
|
||||
int pos = MDAL::toInt( uri.size() ) - 4;
|
||||
uri.insert( std::max( 0, pos ), "_els" );
|
||||
group->replaceUri( uri );
|
||||
}
|
||||
|
||||
457
external/mdal/frmts/mdal_dynamic_driver.cpp
vendored
Executable file
457
external/mdal/frmts/mdal_dynamic_driver.cpp
vendored
Executable file
@ -0,0 +1,457 @@
|
||||
/*
|
||||
MDAL - Mesh Data Abstraction Library (MIT License)
|
||||
Copyright (C) 2020 Vincent Cloarec (vcloarec at gmail dot com)
|
||||
*/
|
||||
|
||||
|
||||
#include "mdal_dynamic_driver.hpp"
|
||||
#include "mdal_logger.hpp"
|
||||
#if not defined (WIN32)
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
MDAL::DriverDynamic::DriverDynamic( const std::string &name, const std::string &longName, const std::string &filters, int capabilityFlags, int maxVertexPerFace, const MDAL::Library &lib ):
|
||||
Driver( name, longName, filters, capabilityFlags ),
|
||||
mLibrary( lib ),
|
||||
mCapabilityFlags( capabilityFlags ),
|
||||
mMaxVertexPerFace( maxVertexPerFace )
|
||||
{}
|
||||
|
||||
MDAL::Driver *MDAL::DriverDynamic::create()
|
||||
{
|
||||
std::unique_ptr<MDAL::DriverDynamic> driver( new DriverDynamic( name(), longName(), filters(), mCapabilityFlags, mMaxVertexPerFace, mLibrary ) );
|
||||
if ( driver->loadSymbols() )
|
||||
return driver.release();
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool MDAL::DriverDynamic::canReadMesh( const std::string &uri )
|
||||
{
|
||||
if ( mCanReadMeshFunction )
|
||||
{
|
||||
return mCanReadMeshFunction( uri.c_str() );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<MDAL::Mesh> MDAL::DriverDynamic::load( const std::string &uri, const std::string &meshName )
|
||||
{
|
||||
if ( !mOpenMeshFunction )
|
||||
return std::unique_ptr<MDAL::Mesh>();
|
||||
|
||||
int meshId = mOpenMeshFunction( uri.c_str(), meshName.c_str() );
|
||||
if ( meshId != -1 )
|
||||
{
|
||||
if ( mMeshIds.find( meshId ) == mMeshIds.end() )
|
||||
{
|
||||
std::unique_ptr<MDAL::MeshDynamicDriver> mesh( new MeshDynamicDriver( name(), mMaxVertexPerFace, uri, mLibrary, meshId ) );
|
||||
if ( mesh->loadSymbol() )
|
||||
{
|
||||
mMeshIds.insert( meshId );
|
||||
mesh->setProjection();
|
||||
if ( mesh->populateDatasetGroups() )
|
||||
return mesh;
|
||||
}
|
||||
}
|
||||
}
|
||||
MDAL::Log::error( MDAL_Status::Err_UnknownFormat, name(), "Unable to load the mesh" );
|
||||
return std::unique_ptr<MDAL::Mesh>();
|
||||
}
|
||||
|
||||
MDAL::Driver *MDAL::DriverDynamic::create( const std::string &libFile )
|
||||
{
|
||||
Library library( libFile );
|
||||
|
||||
std::function<const char *()> driverNameFunction = library.getSymbol<const char *>( "MDAL_DRIVER_driverName" );
|
||||
std::function<const char *()> driverLongNameFunction = library.getSymbol<const char *>( "MDAL_DRIVER_driverLongName" );
|
||||
std::function<const char *()> driverFiltersFunction = library.getSymbol<const char *>( "MDAL_DRIVER_filters" );
|
||||
std::function<int()> driverCapabilitiesFunction = library.getSymbol<int>( "MDAL_DRIVER_capabilities" );
|
||||
std::function<int()> driverMaxVertexPerFaceFunction = library.getSymbol<int>( "MDAL_DRIVER_maxVertexPerFace" );
|
||||
|
||||
if ( !driverNameFunction ||
|
||||
!driverLongNameFunction ||
|
||||
!driverFiltersFunction ||
|
||||
!driverCapabilitiesFunction ||
|
||||
!driverMaxVertexPerFaceFunction )
|
||||
{
|
||||
// No log error here because MDAL can try any files to find the good one
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string name( driverNameFunction() );
|
||||
std::string longName( driverLongNameFunction() );
|
||||
std::string filters( driverFiltersFunction() );
|
||||
MDAL::Capability capabilities = static_cast<MDAL::Capability>( driverCapabilitiesFunction() );
|
||||
int maxVertexPerFace = driverMaxVertexPerFaceFunction();
|
||||
|
||||
std::unique_ptr<DriverDynamic> driver( new DriverDynamic( name, longName, filters, capabilities, maxVertexPerFace, library ) );
|
||||
|
||||
if ( !driver->loadSymbols() )
|
||||
{
|
||||
//Log error created by loadSymbols()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return driver.release();
|
||||
}
|
||||
|
||||
bool MDAL::DriverDynamic::loadSymbols()
|
||||
{
|
||||
mCanReadMeshFunction = mLibrary.getSymbol<bool, const char *>( "MDAL_DRIVER_canReadMesh" );
|
||||
mOpenMeshFunction = mLibrary.getSymbol<int, const char *, const char *>( "MDAL_DRIVER_openMesh" );
|
||||
|
||||
if ( mCanReadMeshFunction == nullptr ||
|
||||
mOpenMeshFunction == nullptr )
|
||||
{
|
||||
MDAL::Log::error( MDAL_Status::Err_MissingDriver, name(), "External driver is not valid" );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
MDAL::MeshDynamicDriver::MeshDynamicDriver( const std::string &driverName,
|
||||
size_t faceVerticesMaximumCount,
|
||||
const std::string &uri,
|
||||
const MDAL::Library &library,
|
||||
int meshId ):
|
||||
Mesh( driverName, faceVerticesMaximumCount, uri ),
|
||||
mLibrary( library ),
|
||||
mId( meshId )
|
||||
{}
|
||||
|
||||
MDAL::MeshDynamicDriver::~MeshDynamicDriver()
|
||||
{
|
||||
mCloseMeshFunction( mId );
|
||||
}
|
||||
|
||||
static int elementCount( int meshId, const std::function<int ( int )> &countFunction, const std::string &driverName )
|
||||
{
|
||||
if ( countFunction )
|
||||
{
|
||||
int count = countFunction( meshId );
|
||||
if ( count >= 0 )
|
||||
return count;
|
||||
|
||||
MDAL::Log::error( MDAL_Status::Err_InvalidData, driverName, "Invalid mesh" );
|
||||
}
|
||||
else
|
||||
MDAL::Log::error( MDAL_Status::Err_MissingDriver, driverName, "Driver is not valid" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t MDAL::MeshDynamicDriver::verticesCount() const
|
||||
{
|
||||
return elementCount( mId, mMeshVertexCountFunction, driverName() );
|
||||
}
|
||||
|
||||
size_t MDAL::MeshDynamicDriver::facesCount() const
|
||||
{
|
||||
return elementCount( mId, mMeshFaceCountFunction, driverName() );
|
||||
}
|
||||
|
||||
size_t MDAL::MeshDynamicDriver::edgesCount() const
|
||||
{
|
||||
return elementCount( mId, mMeshEdgeCountFunction, driverName() );
|
||||
}
|
||||
|
||||
MDAL::BBox MDAL::MeshDynamicDriver::extent() const
|
||||
{
|
||||
if ( mMeshExtentFunction )
|
||||
{
|
||||
double xMin, xMax, yMin, yMax;
|
||||
mMeshExtentFunction( mId, &xMin, &xMax, &yMin, &yMax );
|
||||
return BBox( xMin, xMax, yMin, yMax );
|
||||
}
|
||||
|
||||
return BBox( std::numeric_limits<double>::quiet_NaN(),
|
||||
std::numeric_limits<double>::quiet_NaN(),
|
||||
std::numeric_limits<double>::quiet_NaN(),
|
||||
std::numeric_limits<double>::quiet_NaN() );
|
||||
}
|
||||
|
||||
void MDAL::MeshDynamicDriver::setProjection()
|
||||
{
|
||||
if ( !mMeshProjectionFunction )
|
||||
return;
|
||||
|
||||
std::string projection = mMeshProjectionFunction( mId );
|
||||
setSourceCrs( projection );
|
||||
}
|
||||
|
||||
bool MDAL::MeshDynamicDriver::populateDatasetGroups()
|
||||
{
|
||||
if ( !mMeshDatasetGroupsCountFunction )
|
||||
return false;
|
||||
|
||||
int datasetGroupCount = mMeshDatasetGroupsCountFunction( mId );
|
||||
|
||||
for ( int i = 0; i < datasetGroupCount; ++i )
|
||||
{
|
||||
const char *groupName = mDatasetgroupNameFunction( mId, i );
|
||||
const char *referenceTime = mDatasetGroupReferencetimeFunction( mId, i );
|
||||
bool isScalar = true;
|
||||
int dataLocation = 0;
|
||||
int datasetCount = 0;
|
||||
if ( !mDatasetDescriptionFunction( mId, i, &isScalar, &dataLocation, &datasetCount ) )
|
||||
return false;
|
||||
std::shared_ptr<DatasetGroup> group = std::make_shared<DatasetGroup>( driverName(), this, uri() );
|
||||
if ( groupName )
|
||||
group->setName( groupName );
|
||||
if ( referenceTime )
|
||||
{
|
||||
std::string referenceTimeIso8701 = referenceTime;
|
||||
group->setReferenceTime( referenceTimeIso8701 );
|
||||
}
|
||||
group->setIsScalar( isScalar );
|
||||
switch ( dataLocation )
|
||||
{
|
||||
case 1:
|
||||
group->setDataLocation( MDAL_DataLocation::DataOnVertices );
|
||||
break;
|
||||
case 2:
|
||||
group->setDataLocation( MDAL_DataLocation::DataOnFaces );
|
||||
break;
|
||||
case 3:
|
||||
group->setDataLocation( MDAL_DataLocation::DataOnEdges );
|
||||
break;
|
||||
default:
|
||||
group->setDataLocation( MDAL_DataLocation::DataInvalidLocation );
|
||||
break;
|
||||
}
|
||||
|
||||
int metadataCount = mDatasetGroupMetadataCountFunction( mId, i );
|
||||
if ( metadataCount > 0 )
|
||||
{
|
||||
for ( int metaIndex = 0; metaIndex < metadataCount; ++metaIndex )
|
||||
{
|
||||
std::string key( mDatasetGroupMetadataKeyFunction( mId, i, metaIndex ) );
|
||||
std::string value( mDatasetGroupMetadataValueFunction( mId, i, metaIndex ) );
|
||||
group->setMetadata( key, value );
|
||||
}
|
||||
}
|
||||
|
||||
for ( int d = 0; d < datasetCount ; ++d )
|
||||
{
|
||||
std::shared_ptr<DatasetDynamicDriver> dataset = std::make_shared<DatasetDynamicDriver>( group.get(), mId, i, d, mLibrary );
|
||||
dataset->setSupportsActiveFlag( mDatasetSupportActiveFlagFunction( mId, i, d ) );
|
||||
if ( !dataset->loadSymbol() )
|
||||
return false;
|
||||
|
||||
bool ok = true;
|
||||
double time = mDatasetTimeFunction( mId, i, d, &ok );
|
||||
if ( !ok )
|
||||
return false;
|
||||
dataset->setTime( RelativeTimestamp( time, RelativeTimestamp::hours ) );
|
||||
|
||||
dataset->setStatistics( MDAL::calculateStatistics( dataset ) );
|
||||
dataset->unloadData();
|
||||
|
||||
group->datasets.push_back( dataset );
|
||||
}
|
||||
|
||||
group->setStatistics( MDAL::calculateStatistics( group ) );
|
||||
datasetGroups.push_back( group );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MDAL::MeshDynamicDriver::loadSymbol()
|
||||
{
|
||||
mMeshVertexCountFunction = mLibrary.getSymbol<int, int>( "MDAL_DRIVER_M_vertexCount" ) ;
|
||||
mMeshFaceCountFunction = mLibrary.getSymbol<int, int>( "MDAL_DRIVER_M_faceCount" ) ;
|
||||
mMeshEdgeCountFunction = mLibrary.getSymbol<int, int>( "MDAL_DRIVER_M_edgeCount" ) ;
|
||||
mMeshExtentFunction = mLibrary.getSymbol<void, int, double *, double *, double *, double *>( "MDAL_DRIVER_M_extent" );
|
||||
mMeshProjectionFunction = mLibrary.getSymbol<const char *, int>( "MDAL_DRIVER_M_projection" ) ;
|
||||
mMeshDatasetGroupsCountFunction = mLibrary.getSymbol<int, int>( "MDAL_DRIVER_M_datasetGroupCount" );
|
||||
mDatasetgroupNameFunction = mLibrary.getSymbol<const char *, int, int>( "MDAL_DRIVER_G_groupName" );
|
||||
mDatasetGroupReferencetimeFunction = mLibrary.getSymbol<const char *, int, int>( "MDAL_DRIVER_G_referenceTime" );
|
||||
mDatasetGroupMetadataCountFunction = mLibrary.getSymbol<int, int, int>( "MDAL_DRIVER_G_metadataCount" );
|
||||
mDatasetGroupMetadataKeyFunction = mLibrary.getSymbol<const char *, int, int, int>( "MDAL_DRIVER_G_metadataKey" );
|
||||
mDatasetGroupMetadataValueFunction = mLibrary.getSymbol<const char *, int, int, int>( "MDAL_DRIVER_G_metadataValue" );
|
||||
mDatasetTimeFunction = mLibrary.getSymbol<double, int, int, int, bool *>( "MDAL_DRIVER_D_time" );
|
||||
mDatasetDescriptionFunction = mLibrary.getSymbol<bool, int, int, bool *, int *, int *>( "MDAL_DRIVER_G_datasetsDescription" );
|
||||
mDatasetSupportActiveFlagFunction = mLibrary.getSymbol<bool, int, int, int>( "MDAL_DRIVER_D_hasActiveFlagCapability" );
|
||||
mCloseMeshFunction = mLibrary.getSymbol<void, int>( "MDAL_DRIVER_closeMesh" );
|
||||
|
||||
if ( mMeshVertexCountFunction == nullptr ||
|
||||
mMeshFaceCountFunction == nullptr ||
|
||||
mMeshEdgeCountFunction == nullptr ||
|
||||
mMeshExtentFunction == nullptr ||
|
||||
mMeshProjectionFunction == nullptr ||
|
||||
mMeshDatasetGroupsCountFunction == nullptr ||
|
||||
mDatasetgroupNameFunction == nullptr ||
|
||||
mDatasetGroupReferencetimeFunction == nullptr ||
|
||||
mDatasetGroupMetadataCountFunction == nullptr ||
|
||||
mDatasetGroupMetadataKeyFunction == nullptr ||
|
||||
mDatasetGroupMetadataValueFunction == nullptr ||
|
||||
mDatasetDescriptionFunction == nullptr ||
|
||||
mDatasetTimeFunction == nullptr ||
|
||||
mDatasetSupportActiveFlagFunction == nullptr ||
|
||||
mCloseMeshFunction == nullptr )
|
||||
{
|
||||
MDAL::Log::error( MDAL_Status::Err_MissingDriver, driverName(), "Driver is not valid, unable to load mesh access functions" );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<MDAL::MeshVertexIterator> MDAL::MeshDynamicDriver::readVertices()
|
||||
{
|
||||
return std::unique_ptr<MeshVertexIteratorDynamicDriver>( new MeshVertexIteratorDynamicDriver( mLibrary, mId ) );
|
||||
}
|
||||
|
||||
std::unique_ptr<MDAL::MeshEdgeIterator> MDAL::MeshDynamicDriver::readEdges()
|
||||
{
|
||||
return std::unique_ptr<MeshEdgeIterator>( new MeshEdgeIteratorDynamicDriver( mLibrary, mId ) );
|
||||
}
|
||||
|
||||
std::unique_ptr<MDAL::MeshFaceIterator> MDAL::MeshDynamicDriver::readFaces()
|
||||
{
|
||||
return std::unique_ptr<MeshFaceIterator>( new MeshFaceIteratorDynamicDriver( mLibrary, mId ) );
|
||||
}
|
||||
|
||||
|
||||
MDAL::MeshVertexIteratorDynamicDriver::MeshVertexIteratorDynamicDriver( const Library &library, int meshId ):
|
||||
mLibrary( library ),
|
||||
mMeshId( meshId )
|
||||
{}
|
||||
|
||||
size_t MDAL::MeshVertexIteratorDynamicDriver::next( size_t vertexCount, double *coordinates )
|
||||
{
|
||||
if ( !mVerticesFunction )
|
||||
{
|
||||
mVerticesFunction = mLibrary.getSymbol<int, int, int, int, double *>( "MDAL_DRIVER_M_vertices" );
|
||||
if ( !mVerticesFunction )
|
||||
return 0;
|
||||
}
|
||||
|
||||
int effectiveVerticesCount = mVerticesFunction( mMeshId, mPosition, MDAL::toInt( vertexCount ), coordinates );
|
||||
if ( effectiveVerticesCount < 0 )
|
||||
{
|
||||
MDAL::Log::error( MDAL_Status::Err_InvalidData, "Invalid mesh, unable to read vertices" );
|
||||
return 0;
|
||||
}
|
||||
mPosition += effectiveVerticesCount;
|
||||
|
||||
return effectiveVerticesCount;
|
||||
}
|
||||
|
||||
MDAL::MeshFaceIteratorDynamicDriver::MeshFaceIteratorDynamicDriver( const MDAL::Library &library, int meshId ):
|
||||
mLibrary( library ),
|
||||
mMeshId( meshId )
|
||||
{}
|
||||
|
||||
size_t MDAL::MeshFaceIteratorDynamicDriver::next( size_t faceOffsetsBufferLen, int *faceOffsetsBuffer, size_t vertexIndicesBufferLen, int *vertexIndicesBuffer )
|
||||
{
|
||||
if ( !mFacesFunction )
|
||||
{
|
||||
mFacesFunction = mLibrary.getSymbol<int, int, int, int, int *, int, int *>( "MDAL_DRIVER_M_faces" );
|
||||
if ( !mFacesFunction )
|
||||
return 0;
|
||||
}
|
||||
|
||||
int effectiveFacesCount = mFacesFunction( mMeshId, mPosition, MDAL::toInt( faceOffsetsBufferLen ), faceOffsetsBuffer, MDAL::toInt( vertexIndicesBufferLen ), vertexIndicesBuffer );
|
||||
if ( effectiveFacesCount < 0 )
|
||||
{
|
||||
MDAL::Log::error( MDAL_Status::Err_InvalidData, "Invalid mesh, unable to read faces" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
mPosition += effectiveFacesCount;
|
||||
return effectiveFacesCount;
|
||||
}
|
||||
|
||||
MDAL::MeshEdgeIteratorDynamicDriver::MeshEdgeIteratorDynamicDriver( const MDAL::Library &library, int meshId ):
|
||||
mLibrary( library ),
|
||||
mMeshId( meshId )
|
||||
{}
|
||||
|
||||
size_t MDAL::MeshEdgeIteratorDynamicDriver::next( size_t edgeCount, int *startVertexIndices, int *endVertexIndices )
|
||||
{
|
||||
if ( !mEdgesFunction )
|
||||
{
|
||||
mEdgesFunction = mLibrary.getSymbol<int, int, int, int, int *, int *>( "MDAL_DRIVER_M_edges" );
|
||||
if ( !mEdgesFunction )
|
||||
return 0;
|
||||
}
|
||||
|
||||
int effectiveEdgesCount = mEdgesFunction( mMeshId, mPosition, MDAL::toInt( edgeCount ), startVertexIndices, endVertexIndices );
|
||||
|
||||
if ( effectiveEdgesCount < 0 )
|
||||
{
|
||||
MDAL::Log::error( MDAL_Status::Err_InvalidData, "Invalid mesh, unable to read edges" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
mPosition += effectiveEdgesCount;
|
||||
return effectiveEdgesCount;
|
||||
}
|
||||
|
||||
MDAL::DatasetDynamicDriver::DatasetDynamicDriver( MDAL::DatasetGroup *parentGroup, int meshId, int groupIndex, int datasetIndex, const MDAL::Library &library ):
|
||||
Dataset2D( parentGroup )
|
||||
, mMeshId( meshId )
|
||||
, mGroupIndex( groupIndex )
|
||||
, mDatasetIndex( datasetIndex )
|
||||
, mLibrary( library )
|
||||
{}
|
||||
|
||||
size_t MDAL::DatasetDynamicDriver::scalarData( size_t indexStart, size_t count, double *buffer )
|
||||
{
|
||||
if ( !mDataFunction )
|
||||
return 0;
|
||||
|
||||
return mDataFunction( mMeshId, mGroupIndex, mDatasetIndex, MDAL::toInt( indexStart ), MDAL::toInt( count ), buffer );
|
||||
}
|
||||
|
||||
size_t MDAL::DatasetDynamicDriver::vectorData( size_t indexStart, size_t count, double *buffer )
|
||||
{
|
||||
if ( !mDataFunction )
|
||||
return 0;
|
||||
|
||||
return mDataFunction( mMeshId, mGroupIndex, mDatasetIndex, MDAL::toInt( indexStart ), MDAL::toInt( count ), buffer );
|
||||
}
|
||||
|
||||
size_t MDAL::DatasetDynamicDriver::activeData( size_t indexStart, size_t count, int *buffer )
|
||||
{
|
||||
if ( !supportsActiveFlag() )
|
||||
return Dataset2D::activeData( indexStart, count, buffer );
|
||||
|
||||
if ( !mActiveFlagsFunction )
|
||||
return 0;
|
||||
|
||||
return mActiveFlagsFunction( mMeshId, mGroupIndex, mDatasetIndex, MDAL::toInt( indexStart ), MDAL::toInt( count ), buffer );
|
||||
}
|
||||
|
||||
bool MDAL::DatasetDynamicDriver::loadSymbol()
|
||||
{
|
||||
mDataFunction = mLibrary.getSymbol<int, int, int, int, int, int, double *>( "MDAL_DRIVER_D_data" );
|
||||
mUnloadFunction = mLibrary.getSymbol<void, int, int, int>( "MDAL_DRIVER_D_unload" );
|
||||
if ( supportsActiveFlag() )
|
||||
mActiveFlagsFunction = mLibrary.getSymbol<int, int, int, int, int, int, int *>( "MDAL_DRIVER_D_activeFlags" );
|
||||
|
||||
if ( mDataFunction == nullptr ||
|
||||
mUnloadFunction == nullptr ||
|
||||
( supportsActiveFlag() && mActiveFlagsFunction == nullptr ) )
|
||||
{
|
||||
MDAL::Log::error( MDAL_Status::Err_MissingDriver, "Driver is not valid" );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MDAL::DatasetDynamicDriver::unloadData()
|
||||
{
|
||||
if ( !mUnloadFunction )
|
||||
return;
|
||||
|
||||
mUnloadFunction( mMeshId, mGroupIndex, mDatasetIndex );
|
||||
}
|
||||
187
external/mdal/frmts/mdal_dynamic_driver.hpp
vendored
Executable file
187
external/mdal/frmts/mdal_dynamic_driver.hpp
vendored
Executable file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
MDAL - Mesh Data Abstraction Library (MIT License)
|
||||
Copyright (C) 2020 Vincent Cloarec (vcloarec at gmail dot com)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MDAL_DYNAMIC_DRIVER_H
|
||||
#define MDAL_DYNAMIC_DRIVER_H
|
||||
|
||||
#include "mdal_driver.hpp"
|
||||
#include "mdal_utils.hpp"
|
||||
#include "mdal.h"
|
||||
|
||||
#include <functional>
|
||||
#include <set>
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
class DriverDynamic: public Driver
|
||||
{
|
||||
|
||||
public:
|
||||
~DriverDynamic() = default;
|
||||
|
||||
Driver *create() override;
|
||||
bool canReadMesh( const std::string &uri ) override;
|
||||
std::unique_ptr<Mesh> load( const std::string &uri, const std::string &meshName ) override;
|
||||
|
||||
//! Creates a dynamic driver from a library file
|
||||
static Driver *create( const std::string &libFile );
|
||||
|
||||
private:
|
||||
|
||||
DriverDynamic( const std::string &name,
|
||||
const std::string &longName,
|
||||
const std::string &filters,
|
||||
int capabilityFlags,
|
||||
int maxVertexPerFace,
|
||||
const Library &lib );
|
||||
|
||||
bool loadSymbols();
|
||||
Library mLibrary;
|
||||
int mCapabilityFlags = 0;
|
||||
int mMaxVertexPerFace = std::numeric_limits<int>::max();
|
||||
|
||||
std::set<int> mMeshIds;
|
||||
|
||||
//************************************
|
||||
std::function<bool ( const char * )> mCanReadMeshFunction;
|
||||
std::function<int ( const char *, const char * )> mOpenMeshFunction;
|
||||
};
|
||||
|
||||
class MeshDynamicDriver;
|
||||
|
||||
class MeshVertexIteratorDynamicDriver: public MeshVertexIterator
|
||||
{
|
||||
public:
|
||||
MeshVertexIteratorDynamicDriver( const Library &library, int meshId );
|
||||
|
||||
size_t next( size_t vertexCount, double *coordinates ) override;
|
||||
private:
|
||||
Library mLibrary;
|
||||
int mMeshId;
|
||||
int mPosition = 0;
|
||||
|
||||
//************************************
|
||||
std::function<int ( int, int, int, double * )> mVerticesFunction;
|
||||
};
|
||||
|
||||
class MeshFaceIteratorDynamicDriver: public MeshFaceIterator
|
||||
{
|
||||
public:
|
||||
MeshFaceIteratorDynamicDriver( const Library &library, int meshId );
|
||||
|
||||
size_t next( size_t faceOffsetsBufferLen,
|
||||
int *faceOffsetsBuffer,
|
||||
size_t vertexIndicesBufferLen,
|
||||
int *vertexIndicesBuffer ) override;
|
||||
private:
|
||||
Library mLibrary;
|
||||
int mMeshId;
|
||||
int mPosition = 0;
|
||||
|
||||
//************************************
|
||||
std::function<int ( int, int, int, int *, int, int * )> mFacesFunction;
|
||||
};
|
||||
|
||||
class MeshEdgeIteratorDynamicDriver: public MeshEdgeIterator
|
||||
{
|
||||
public:
|
||||
MeshEdgeIteratorDynamicDriver( const Library &library, int meshId );
|
||||
|
||||
size_t next( size_t edgeCount,
|
||||
int *startVertexIndices,
|
||||
int *endVertexIndices );
|
||||
private:
|
||||
Library mLibrary;
|
||||
int mMeshId;
|
||||
int mPosition = 0;
|
||||
|
||||
//************************************
|
||||
std::function<int ( int, int, int, int *, int * )> mEdgesFunction;
|
||||
};
|
||||
|
||||
class DatasetDynamicDriver: public Dataset2D
|
||||
{
|
||||
public:
|
||||
DatasetDynamicDriver( DatasetGroup *parentGroup,
|
||||
int meshId,
|
||||
int groupIndex,
|
||||
int datasetIndex,
|
||||
const Library &library );
|
||||
|
||||
size_t scalarData( size_t indexStart, size_t count, double *buffer ) override;
|
||||
size_t vectorData( size_t indexStart, size_t count, double *buffer ) override;
|
||||
size_t activeData( size_t indexStart, size_t count, int *buffer ) override;
|
||||
|
||||
bool loadSymbol();
|
||||
|
||||
//! Removes stored data in memory (for drivers that support lazy loading)
|
||||
void unloadData();
|
||||
|
||||
private:
|
||||
int mMeshId = -1;
|
||||
int mGroupIndex = -1;
|
||||
int mDatasetIndex = -1;
|
||||
Library mLibrary;
|
||||
|
||||
//************************************
|
||||
std::function<int ( int, int, int, int, int, double * )> mDataFunction;
|
||||
std::function<int ( int, int, int, int, int, int * )> mActiveFlagsFunction;
|
||||
std::function<void( int, int, int )> mUnloadFunction;
|
||||
};
|
||||
|
||||
class MeshDynamicDriver: public Mesh
|
||||
{
|
||||
public:
|
||||
MeshDynamicDriver( const std::string &driverName,
|
||||
size_t faceVerticesMaximumCount,
|
||||
const std::string &uri,
|
||||
const Library &library,
|
||||
int meshId );
|
||||
~MeshDynamicDriver();
|
||||
|
||||
std::unique_ptr<MeshVertexIterator> readVertices() override;
|
||||
std::unique_ptr<MeshEdgeIterator> readEdges() override;
|
||||
std::unique_ptr<MeshFaceIterator> readFaces() override;
|
||||
size_t verticesCount() const override;
|
||||
size_t edgesCount() const override;
|
||||
size_t facesCount() const override;
|
||||
BBox extent() const override;
|
||||
|
||||
//! Set the projection from the source
|
||||
void setProjection();
|
||||
|
||||
bool populateDatasetGroups();
|
||||
|
||||
//! Returns whether all the symbols have been loaded
|
||||
bool loadSymbol();
|
||||
|
||||
private:
|
||||
Library mLibrary;
|
||||
int mId = -1;
|
||||
|
||||
//************************************
|
||||
std::function<int ( int )> mMeshVertexCountFunction;
|
||||
std::function<int ( int )> mMeshFaceCountFunction;
|
||||
std::function<int ( int )> mMeshEdgeCountFunction;
|
||||
std::function<void ( int, double *, double *, double *, double * )> mMeshExtentFunction;
|
||||
std::function<const char *( int )> mMeshProjectionFunction;
|
||||
std::function<int ( int )> mMeshDatasetGroupsCountFunction;
|
||||
|
||||
std::function<const char *( int, int )> mDatasetgroupNameFunction;
|
||||
std::function<const char *( int, int )> mDatasetGroupReferencetimeFunction;
|
||||
std::function<int ( int, int )> mDatasetGroupMetadataCountFunction;
|
||||
std::function<const char *( int, int, int )> mDatasetGroupMetadataKeyFunction;
|
||||
std::function<const char *( int, int, int )> mDatasetGroupMetadataValueFunction;
|
||||
std::function < bool ( int, int, bool *, int *, int * )> mDatasetDescriptionFunction;
|
||||
std::function < double( int, int, int, bool * )> mDatasetTimeFunction;
|
||||
std::function<bool ( int, int, int )> mDatasetSupportActiveFlagFunction;
|
||||
|
||||
std::function<void ( int )> mCloseMeshFunction;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif // MDAL_DYNAMIC_DRIVER_H
|
||||
18
external/mdal/frmts/mdal_flo2d.cpp
vendored
18
external/mdal/frmts/mdal_flo2d.cpp
vendored
@ -144,8 +144,8 @@ void MDAL::DriverFlo2D::parseCHANBANKFile( const std::string &datFileName,
|
||||
{
|
||||
throw MDAL::Error( MDAL_Status::Err_UnknownFormat, "Error while loading CHANBANK file, wrong lineparts count (2)" );
|
||||
}
|
||||
int leftBank = MDAL::toSizeT( lineParts[0] ) - 1; //numbered from 1
|
||||
int rightBank = MDAL::toSizeT( lineParts[1] ) - 1;
|
||||
int leftBank = MDAL::toInt( MDAL::toSizeT( lineParts[0] ) ) - 1; //numbered from 1
|
||||
int rightBank = MDAL::toInt( MDAL::toSizeT( lineParts[1] ) ) - 1;
|
||||
|
||||
std::map<size_t, size_t>::const_iterator it = cellIdToVertices.find( rightBank );
|
||||
if ( it != cellIdToVertices.end() )
|
||||
@ -197,7 +197,7 @@ void MDAL::DriverFlo2D::parseCHANFile( const std::string &datFileName, const std
|
||||
{
|
||||
throw MDAL::Error( MDAL_Status::Err_UnknownFormat, "Error while loading CHAN file, wrong chanel element line" );
|
||||
}
|
||||
int currentCellId = MDAL::toSizeT( lineParts[1] ) - 1;
|
||||
int currentCellId = MDAL::toInt( MDAL::toSizeT( lineParts[1] ) ) - 1;
|
||||
if ( previousCellId >= 0 )
|
||||
{
|
||||
std::map<size_t, size_t>::const_iterator it1 = cellIdToVertices.find( previousCellId );
|
||||
@ -818,8 +818,8 @@ void MDAL::DriverFlo2D::createMesh2d( const std::vector<CellCenter> &cells, cons
|
||||
cellCenterExtent.minY - half_cell_size,
|
||||
cellCenterExtent.maxY + half_cell_size );
|
||||
|
||||
size_t width = ( vertexExtent.maxX - vertexExtent.minX ) / cell_size + 1;
|
||||
size_t heigh = ( vertexExtent.maxY - vertexExtent.minY ) / cell_size + 1;
|
||||
size_t width = MDAL::toSizeT( ( vertexExtent.maxX - vertexExtent.minX ) / cell_size + 1 );
|
||||
size_t heigh = MDAL::toSizeT( ( vertexExtent.maxY - vertexExtent.minY ) / cell_size + 1 );
|
||||
std::vector<std::vector<size_t>> vertexGrid( width, std::vector<size_t>( heigh, INVALID_INDEX ) );
|
||||
|
||||
Vertices vertices;
|
||||
@ -828,13 +828,13 @@ void MDAL::DriverFlo2D::createMesh2d( const std::vector<CellCenter> &cells, cons
|
||||
{
|
||||
Face &e = faces[i];
|
||||
|
||||
size_t xVertexIdx = ( cells[i].x - vertexExtent.minX ) / cell_size;
|
||||
size_t yVertexIdx = ( cells[i].y - vertexExtent.minY ) / cell_size;
|
||||
size_t xVertexIdx = MDAL::toSizeT( ( cells[i].x - vertexExtent.minX ) / cell_size );
|
||||
size_t yVertexIdx = MDAL::toSizeT( ( cells[i].y - vertexExtent.minY ) / cell_size );
|
||||
|
||||
for ( size_t position = 0; position < 4; ++position )
|
||||
{
|
||||
size_t xPos;
|
||||
size_t yPos;
|
||||
size_t xPos = 0;
|
||||
size_t yPos = 0;
|
||||
|
||||
switch ( position )
|
||||
{
|
||||
|
||||
2
external/mdal/frmts/mdal_hdf5.cpp
vendored
2
external/mdal/frmts/mdal_hdf5.cpp
vendored
@ -186,7 +186,7 @@ HdfDataset::HdfDataset( hid_t file, const std::string &path )
|
||||
|
||||
HdfDataset::~HdfDataset() = default;
|
||||
|
||||
bool HdfDataset::isValid() const { return d->id >= 0; }
|
||||
bool HdfDataset::isValid() const { return d && d->id >= 0; }
|
||||
|
||||
hid_t HdfDataset::id() const { return d->id; }
|
||||
|
||||
|
||||
10
external/mdal/frmts/mdal_hdf5.hpp
vendored
10
external/mdal/frmts/mdal_hdf5.hpp
vendored
@ -193,9 +193,12 @@ class HdfDataset
|
||||
public:
|
||||
typedef HdfH<H5I_DATASET> Handle;
|
||||
|
||||
//! Create new, simple 1 dimensional dataset
|
||||
//! creates invalid dataset
|
||||
HdfDataset() = default;
|
||||
|
||||
//! Creates new, simple 1 dimensional dataset
|
||||
HdfDataset( hid_t file, const std::string &path, HdfDataType dtype, size_t nItems = 1 );
|
||||
//! Create new dataset with custom dimensions
|
||||
//! Creates new dataset with custom dimensions
|
||||
HdfDataset( hid_t file, const std::string &path, HdfDataType dtype, HdfDataspace dataspace );
|
||||
//! Opens dataset for reading
|
||||
HdfDataset( hid_t file, const std::string &path );
|
||||
@ -286,9 +289,6 @@ class HdfDataset
|
||||
|
||||
protected:
|
||||
std::shared_ptr<Handle> d;
|
||||
hid_t m_fileId;
|
||||
std::string m_path;
|
||||
|
||||
HdfDataType mType; // when in write mode
|
||||
};
|
||||
|
||||
|
||||
122
external/mdal/frmts/mdal_hec2d.cpp
vendored
122
external/mdal/frmts/mdal_hec2d.cpp
vendored
@ -202,21 +202,6 @@ static std::vector<MDAL::RelativeTimestamp> readTimes( const HdfFile &hdfFile )
|
||||
return convertTimeData( times, dataTimeUnits );
|
||||
}
|
||||
|
||||
static std::vector<int> readFace2Cells( const HdfFile &hdfFile, const std::string &flowAreaName, size_t *nFaces )
|
||||
{
|
||||
// First read face to node mapping
|
||||
HdfGroup gGeom = openHdfGroup( hdfFile, "Geometry" );
|
||||
HdfGroup gGeom2DFlowAreas = openHdfGroup( gGeom, "2D Flow Areas" );
|
||||
HdfGroup gArea = openHdfGroup( gGeom2DFlowAreas, flowAreaName );
|
||||
HdfDataset dsFace2Cells = openHdfDataset( gArea, "Faces Cell Indexes" );
|
||||
|
||||
std::vector<hsize_t> fdims = dsFace2Cells.dims();
|
||||
std::vector<int> face2Cells = dsFace2Cells.readArrayInt(); //2x nFaces
|
||||
|
||||
*nFaces = fdims[0];
|
||||
return face2Cells;
|
||||
}
|
||||
|
||||
void MDAL::DriverHec2D::readFaceOutput( const HdfFile &hdfFile,
|
||||
const HdfGroup &rootGroup,
|
||||
const std::vector<size_t> &areaElemStartIndex,
|
||||
@ -226,8 +211,6 @@ void MDAL::DriverHec2D::readFaceOutput( const HdfFile &hdfFile,
|
||||
const std::vector<RelativeTimestamp> ×,
|
||||
const DateTime &referenceTime )
|
||||
{
|
||||
double eps = std::numeric_limits<double>::min();
|
||||
|
||||
std::shared_ptr<DatasetGroup> group = std::make_shared< DatasetGroup >(
|
||||
name(),
|
||||
mMesh.get(),
|
||||
@ -235,7 +218,7 @@ void MDAL::DriverHec2D::readFaceOutput( const HdfFile &hdfFile,
|
||||
datasetName
|
||||
);
|
||||
group->setDataLocation( MDAL_DataLocation::DataOnFaces );
|
||||
group->setIsScalar( true );
|
||||
group->setIsScalar( false );
|
||||
group->setReferenceTime( referenceTime );
|
||||
|
||||
std::vector<std::shared_ptr<MDAL::MemoryDataset2D>> datasets;
|
||||
@ -253,34 +236,99 @@ void MDAL::DriverHec2D::readFaceOutput( const HdfFile &hdfFile,
|
||||
{
|
||||
std::string flowAreaName = flowAreaNames[nArea];
|
||||
|
||||
size_t nFaces;
|
||||
std::vector<int> face2Cells = readFace2Cells( hdfFile, flowAreaName, &nFaces );
|
||||
|
||||
HdfGroup gFlowAreaRes = openHdfGroup( rootGroup, flowAreaName );
|
||||
HdfDataset dsVals = openHdfDataset( gFlowAreaRes, rawDatasetName );
|
||||
std::vector<float> vals = dsVals.readArray();
|
||||
|
||||
HdfGroup gGeom = openHdfGroup( hdfFile, "Geometry" );
|
||||
HdfGroup gGeom2DFlowAreas = openHdfGroup( gGeom, "2D Flow Areas" );
|
||||
HdfGroup gArea = openHdfGroup( gGeom2DFlowAreas, flowAreaName );
|
||||
HdfDataset dsCellFaceInfo = openHdfDataset( gArea, "Cells Face and Orientation Info" );
|
||||
std::vector<hsize_t> celldims = dsCellFaceInfo.dims();
|
||||
std::vector<int> cellFaceInfo = dsCellFaceInfo.readArrayInt();
|
||||
|
||||
HdfDataset dsCellFaceOrValues = openHdfDataset( gArea, "Cells Face and Orientation Values" );
|
||||
std::vector<int> cellFaceOrValues = dsCellFaceOrValues.readArrayInt();
|
||||
|
||||
HdfDataset dsFacePointIndex = openHdfDataset( gArea, "Faces FacePoint Indexes" );
|
||||
std::vector<hsize_t> fdims = dsFacePointIndex.dims();
|
||||
size_t nFaces = static_cast<size_t>( fdims[0] );
|
||||
std::vector<int> facePointIndex = dsFacePointIndex.readArrayInt();
|
||||
|
||||
HdfDataset dsCoords = openHdfDataset( gArea, "FacePoints Coordinate" );
|
||||
std::vector<hsize_t> cdims = dsCoords.dims();
|
||||
std::vector<double> coords = dsCoords.readArrayDouble(); //2xnNodes matrix in array
|
||||
|
||||
for ( size_t tidx = 0; tidx < times.size(); ++tidx )
|
||||
{
|
||||
std::shared_ptr<MDAL::MemoryDataset2D> dataset = datasets[tidx];
|
||||
double *values = dataset->values();
|
||||
|
||||
for ( size_t i = 0; i < nFaces; ++i )
|
||||
for ( size_t cell_idx = 0; cell_idx < celldims.at( 0 ); ++cell_idx )
|
||||
{
|
||||
size_t idx = tidx * nFaces + i;
|
||||
double val = static_cast<double>( vals[idx] ); // This is value on face!
|
||||
|
||||
if ( !std::isnan( val ) && fabs( val ) > eps ) //not nan and not 0
|
||||
size_t cell_mdal_idx = cell_idx + areaElemStartIndex[nArea];
|
||||
double valx = 0;
|
||||
double valy = 0;
|
||||
size_t consideredValueCount = 0;
|
||||
size_t firstPosition = static_cast<size_t>( cellFaceInfo[cell_idx * 2] );
|
||||
size_t faceCount = static_cast<size_t>( cellFaceInfo[cell_idx * 2 + 1] );
|
||||
for ( size_t f = 0; f < faceCount; ++f )
|
||||
{
|
||||
for ( size_t c = 0; c < 2; ++c )
|
||||
//get face indexes
|
||||
size_t faceIndex1 = static_cast<size_t>( cellFaceOrValues[( firstPosition + f ) * 2] );
|
||||
size_t faceIndex2 = static_cast<size_t>( cellFaceOrValues[( firstPosition + ( f + 1 ) % faceCount ) * 2] );
|
||||
double val1 = static_cast<double>( vals[faceIndex1 + tidx * nFaces] );
|
||||
double val2 = static_cast<double>( vals[faceIndex2 + tidx * nFaces] );
|
||||
if ( std::isnan( val1 ) || std::isnan( val2 ) )
|
||||
continue;
|
||||
|
||||
size_t indexPoint11 = facePointIndex[faceIndex1 * 2];
|
||||
size_t indexPoint12 = facePointIndex[faceIndex1 * 2 + 1];
|
||||
size_t indexPoint21 = facePointIndex[faceIndex2 * 2];
|
||||
size_t indexPoint22 = facePointIndex[faceIndex2 * 2 + 1];
|
||||
bool commonIndex = ( indexPoint11 == indexPoint21 ||
|
||||
indexPoint11 == indexPoint22 ||
|
||||
indexPoint12 == indexPoint21 ||
|
||||
indexPoint12 == indexPoint22 );
|
||||
if ( !commonIndex )
|
||||
{
|
||||
size_t cell_idx = static_cast<size_t>( face2Cells[2 * i + c] ) + areaElemStartIndex[nArea];
|
||||
// Take just maximum
|
||||
if ( std::isnan( values[cell_idx] ) || values[cell_idx] < val )
|
||||
{
|
||||
values[cell_idx] = val;
|
||||
}
|
||||
// should not happen, but better to prevent
|
||||
continue;
|
||||
}
|
||||
|
||||
double dx1 = coords[indexPoint11 * 2] - coords[indexPoint12 * 2];
|
||||
double dy1 = coords[indexPoint11 * 2 + 1] - coords[indexPoint12 * 2 + 1];
|
||||
double dx2 = coords[indexPoint21 * 2] - coords[indexPoint22 * 2];
|
||||
double dy2 = coords[indexPoint21 * 2 + 1] - coords[indexPoint22 * 2 + 1];
|
||||
double l1 = sqrt( dx1 * dx1 + dy1 * dy1 );
|
||||
double l2 = sqrt( dx2 * dx2 + dy2 * dy2 );
|
||||
if ( l1 == 0 || l2 == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
double nx1 = -dy1 / l1;
|
||||
double ny1 = dx1 / l1;
|
||||
double nx2 = -dy2 / l2;
|
||||
double ny2 = dx2 / l2;
|
||||
|
||||
double deter = nx1 * ny2 - nx2 * ny1;
|
||||
if ( deter == 0 ) //colinear face, forbidden by hecras, but better to prevent
|
||||
continue;
|
||||
valx += ( ny2 * val1 - ny1 * val2 ) / deter;
|
||||
valy += ( nx1 * val2 - nx2 * val1 ) / deter;
|
||||
consideredValueCount++;
|
||||
}
|
||||
if ( consideredValueCount != 0 )
|
||||
{
|
||||
valx /= consideredValueCount;
|
||||
valy /= consideredValueCount;
|
||||
values[cell_mdal_idx * 2] = valx;
|
||||
values[cell_mdal_idx * 2 + 1] = valy;
|
||||
}
|
||||
else
|
||||
{
|
||||
values[cell_mdal_idx * 2] = std::numeric_limits<double>::quiet_NaN();
|
||||
values[cell_mdal_idx * 2 + 1] = std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -302,15 +350,15 @@ void MDAL::DriverHec2D::readFaceResults( const HdfFile &hdfFile,
|
||||
// UNSTEADY
|
||||
HdfGroup flowGroup = get2DFlowAreasGroup( hdfFile, "Unsteady Time Series" );
|
||||
MDAL::DateTime referenceDateTime = readReferenceDateTime( hdfFile );
|
||||
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Face Shear Stress", "Face Shear Stress", mTimes, referenceDateTime );
|
||||
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Face Velocity", "Face Velocity", mTimes, referenceDateTime );
|
||||
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Face Shear Stress", "Shear Stress", mTimes, referenceDateTime );
|
||||
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Face Velocity", "Velocity", mTimes, referenceDateTime );
|
||||
|
||||
// SUMMARY
|
||||
flowGroup = get2DFlowAreasGroup( hdfFile, "Summary Output" );
|
||||
std::vector<MDAL::RelativeTimestamp> dummyTimes( 1, MDAL::RelativeTimestamp() );
|
||||
|
||||
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Maximum Face Shear Stress", "Face Shear Stress/Maximums", dummyTimes, referenceDateTime );
|
||||
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Maximum Face Velocity", "Face Velocity/Maximums", dummyTimes, referenceDateTime );
|
||||
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Maximum Face Shear Stress", "Shear Stress/Maximums", dummyTimes, referenceDateTime );
|
||||
readFaceOutput( hdfFile, flowGroup, areaElemStartIndex, flowAreaNames, "Maximum Face Velocity", "Velocity/Maximums", dummyTimes, referenceDateTime );
|
||||
}
|
||||
|
||||
|
||||
|
||||
60
external/mdal/frmts/mdal_selafin.cpp
vendored
60
external/mdal/frmts/mdal_selafin.cpp
vendored
@ -863,7 +863,7 @@ size_t MDAL::MeshSelafinFaceIterator::next( size_t faceOffsetsBufferLen, int *fa
|
||||
throw MDAL::Error( MDAL_Status::Err_UnknownFormat, "File format problem while reading faces" );
|
||||
vertexIndicesBuffer[vertexLocalIndex + j] = indexes[j + i * verticesPerFace] - 1;
|
||||
}
|
||||
vertexLocalIndex += verticesPerFace;
|
||||
vertexLocalIndex += MDAL::toInt( verticesPerFace );
|
||||
faceOffsetsBuffer[i] = vertexLocalIndex;
|
||||
}
|
||||
|
||||
@ -936,9 +936,9 @@ static void writeInt( std::ofstream &file, int i )
|
||||
|
||||
static void writeStringRecord( std::ofstream &file, const std::string &str )
|
||||
{
|
||||
writeInt( file, str.size() );
|
||||
writeInt( file, MDAL::toInt( str.size() ) );
|
||||
file.write( str.data(), str.size() );
|
||||
writeInt( file, str.size() );
|
||||
writeInt( file, MDAL::toInt( str.size() ) );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -1011,9 +1011,9 @@ void MDAL::DriverSelafin::save( const std::string &uri, MDAL::Mesh *mesh )
|
||||
size_t verticesCount = mesh->verticesCount();
|
||||
size_t facesCount = mesh->facesCount();
|
||||
std::vector<int> elem( 4 );
|
||||
elem[0] = facesCount;
|
||||
elem[1] = verticesCount;
|
||||
elem[2] = verticesPerFace;
|
||||
elem[0] = MDAL::toInt( facesCount );
|
||||
elem[1] = MDAL::toInt( verticesCount );
|
||||
elem[2] = MDAL::toInt( verticesPerFace );
|
||||
elem[3] = 1;
|
||||
writeValueArrayRecord( file, elem );
|
||||
|
||||
@ -1022,7 +1022,7 @@ void MDAL::DriverSelafin::save( const std::string &uri, MDAL::Mesh *mesh )
|
||||
std::vector<int> faceOffsetBuffer( bufferSize );
|
||||
std::unique_ptr<MeshFaceIterator> faceIter = mesh->readFaces();
|
||||
size_t count = 0;
|
||||
writeInt( file, facesCount * verticesPerFace * 4 );
|
||||
writeInt( file, MDAL::toInt( facesCount * verticesPerFace * 4 ) );
|
||||
do
|
||||
{
|
||||
std::vector<int> inkle( bufferSize * verticesPerFace );
|
||||
@ -1034,7 +1034,7 @@ void MDAL::DriverSelafin::save( const std::string &uri, MDAL::Mesh *mesh )
|
||||
writeValueArray( file, inkle );
|
||||
}
|
||||
while ( count != 0 );
|
||||
writeInt( file, facesCount * verticesPerFace * 4 );
|
||||
writeInt( file, MDAL::toInt( facesCount * verticesPerFace * 4 ) );
|
||||
|
||||
// IPOBO filled with 0
|
||||
writeValueArrayRecord( file, std::vector<int>( verticesCount, 0 ) );
|
||||
@ -1077,9 +1077,9 @@ static void writeScalarDataset( std::ofstream &file, MDAL::Dataset *dataset, boo
|
||||
{
|
||||
size_t valuesCount = dataset->valuesCount();
|
||||
size_t bufferSize = BUFFER_SIZE;
|
||||
int count = 0;
|
||||
int indexStart = 0;
|
||||
writeInt( file, valuesCount * ( isFloat ? 4 : 8 ) );
|
||||
size_t count = 0;
|
||||
size_t indexStart = 0;
|
||||
writeInt( file, MDAL::toInt( valuesCount * ( isFloat ? 4 : 8 ) ) );
|
||||
do
|
||||
{
|
||||
std::vector<double> values( bufferSize );
|
||||
@ -1088,8 +1088,8 @@ static void writeScalarDataset( std::ofstream &file, MDAL::Dataset *dataset, boo
|
||||
if ( isFloat )
|
||||
{
|
||||
std::vector<float> floatValues( count );
|
||||
for ( int i = 0; i < count; ++i )
|
||||
floatValues[i] = values[i];
|
||||
for ( int i = 0; i < MDAL::toInt( count ); ++i )
|
||||
floatValues[i] = static_cast<float>( values[i] );
|
||||
writeValueArray( file, floatValues );
|
||||
}
|
||||
else
|
||||
@ -1098,7 +1098,7 @@ static void writeScalarDataset( std::ofstream &file, MDAL::Dataset *dataset, boo
|
||||
indexStart += count;
|
||||
}
|
||||
while ( count != 0 );
|
||||
writeInt( file, valuesCount * ( isFloat ? 4 : 8 ) );
|
||||
writeInt( file, MDAL::toInt( valuesCount * ( isFloat ? 4 : 8 ) ) );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -1109,17 +1109,17 @@ static void writeVectorDataset( std::ofstream &file, MDAL::Dataset *dataset )
|
||||
std::vector<T> valuesX( valuesCount );
|
||||
std::vector<T> valuesY( valuesCount );
|
||||
size_t bufferSize = BUFFER_SIZE;
|
||||
int count = 0;
|
||||
int indexStart = 0;
|
||||
size_t count = 0;
|
||||
size_t indexStart = 0;
|
||||
do
|
||||
{
|
||||
std::vector<double> values( bufferSize * 2 );
|
||||
count = dataset->vectorData( indexStart, bufferSize, values.data() );
|
||||
values.resize( count * 2 );
|
||||
for ( int i = 0; i < count; ++i )
|
||||
for ( int i = 0; i < MDAL::toInt( count ); ++i )
|
||||
{
|
||||
valuesX[indexStart + i] = values[i * 2];
|
||||
valuesY[indexStart + i] = values[i * 2 + 1];
|
||||
valuesX[indexStart + i] = static_cast< T >( values[i * 2] );
|
||||
valuesY[indexStart + i] = static_cast< T >( values[i * 2 + 1] );
|
||||
}
|
||||
indexStart += count;
|
||||
}
|
||||
@ -1224,24 +1224,24 @@ bool MDAL::SelafinFile::addDatasetGroup( MDAL::DatasetGroup *datasetGroup )
|
||||
writeValueArrayRecord( out, std::vector<int> {int( mFacesCount ), int( mVerticesCount ), int( mVerticesPerFace ), 1} );
|
||||
|
||||
//IKLE
|
||||
writeInt( out, mFacesCount * mVerticesPerFace * 4 );
|
||||
writeInt( out, MDAL::toInt( mFacesCount * mVerticesPerFace * 4 ) );
|
||||
streamToStream( out, mIn, mConnectivityStreamPosition, mFacesCount * mVerticesPerFace * 4, BUFFER_SIZE );
|
||||
writeInt( out, mFacesCount * mVerticesPerFace * 4 );
|
||||
writeInt( out, MDAL::toInt( mFacesCount * mVerticesPerFace * 4 ) );
|
||||
//vertices
|
||||
|
||||
//IPOBO
|
||||
writeInt( out, mVerticesCount * 4 );
|
||||
writeInt( out, MDAL::toInt( mVerticesCount * 4 ) );
|
||||
streamToStream( out, mIn, mIPOBOStreamPosition, mVerticesCount * 4, BUFFER_SIZE );
|
||||
writeInt( out, mVerticesCount * 4 );
|
||||
writeInt( out, MDAL::toInt( mVerticesCount * 4 ) );
|
||||
|
||||
//X Vertices
|
||||
writeInt( out, mVerticesCount * realSize );
|
||||
writeInt( out, MDAL::toInt( mVerticesCount * realSize ) );
|
||||
streamToStream( out, mIn, mXStreamPosition, mVerticesCount * realSize, BUFFER_SIZE );
|
||||
writeInt( out, mVerticesCount * realSize );
|
||||
writeInt( out, MDAL::toInt( mVerticesCount * realSize ) );
|
||||
//Y Vertices
|
||||
writeInt( out, mVerticesCount * realSize );
|
||||
writeInt( out, MDAL::toInt( mVerticesCount * realSize ) );
|
||||
streamToStream( out, mIn, mYStreamPosition, mVerticesCount * realSize, BUFFER_SIZE );
|
||||
writeInt( out, mVerticesCount * realSize );
|
||||
writeInt( out, MDAL::toInt( mVerticesCount * realSize ) );
|
||||
|
||||
// Write datasets
|
||||
for ( size_t nT = 0; nT < mTimeSteps.size(); nT++ )
|
||||
@ -1249,7 +1249,7 @@ bool MDAL::SelafinFile::addDatasetGroup( MDAL::DatasetGroup *datasetGroup )
|
||||
// Time step
|
||||
if ( mStreamInFloatPrecision )
|
||||
{
|
||||
std::vector<float> time( 1, mTimeSteps.at( nT ).value( RelativeTimestamp::seconds ) );
|
||||
std::vector<float> time( 1, static_cast<float>( mTimeSteps.at( nT ).value( RelativeTimestamp::seconds ) ) );
|
||||
writeValueArrayRecord( out, time );
|
||||
}
|
||||
else
|
||||
@ -1261,9 +1261,9 @@ bool MDAL::SelafinFile::addDatasetGroup( MDAL::DatasetGroup *datasetGroup )
|
||||
// First, prexisting datasets from the original file
|
||||
for ( int i = 0; i < nbv[0] - addedVariable; ++i )
|
||||
{
|
||||
writeInt( out, mVerticesCount * realSize );
|
||||
writeInt( out, MDAL::toInt( mVerticesCount * realSize ) );
|
||||
streamToStream( out, mIn, mVariableStreamPosition[i][nT], realSize * mVerticesCount, BUFFER_SIZE );
|
||||
writeInt( out, mVerticesCount * realSize );
|
||||
writeInt( out, MDAL::toInt( mVerticesCount * realSize ) );
|
||||
}
|
||||
|
||||
// Then, new datasets from the new dataset group
|
||||
|
||||
4
external/mdal/frmts/mdal_ugrid.cpp
vendored
4
external/mdal/frmts/mdal_ugrid.cpp
vendored
@ -315,8 +315,8 @@ void MDAL::DriverUgrid::populateEdges( MDAL::Edges &edges )
|
||||
for ( size_t i = 0; i < edgesCount; ++i )
|
||||
{
|
||||
|
||||
int startEdgeIx = i * 2;
|
||||
int endEdgeIx = i * 2 + 1;
|
||||
int startEdgeIx = MDAL::toInt( i ) * 2;
|
||||
int endEdgeIx = MDAL::toInt( i ) * 2 + 1;
|
||||
|
||||
edges[i].startVertex = edgeNodesIdxs[startEdgeIx] - startIndex;
|
||||
edges[i].endVertex = edgeNodesIdxs[endEdgeIx] - startIndex;
|
||||
|
||||
72
external/mdal/frmts/mdal_xmdf.cpp
vendored
72
external/mdal/frmts/mdal_xmdf.cpp
vendored
@ -74,6 +74,8 @@ size_t MDAL::XmdfDataset::vectorData( size_t indexStart, size_t count, double *b
|
||||
|
||||
size_t MDAL::XmdfDataset::activeData( size_t indexStart, size_t count, int *buffer )
|
||||
{
|
||||
if ( !dsActive().isValid() )
|
||||
return 0;
|
||||
std::vector<hsize_t> offsets = {timeIndex(), indexStart};
|
||||
std::vector<hsize_t> counts = {1, count};
|
||||
std::vector<uchar> active = dsActive().readArrayUint8( offsets, counts );
|
||||
@ -117,6 +119,27 @@ bool MDAL::DriverXmdf::canReadDatasets( const std::string &uri )
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MDAL::DriverXmdf::readGroupsTree( HdfFile &file, const std::string &name, MDAL::DatasetGroups &groups, size_t vertexCount, size_t faceCount ) const
|
||||
{
|
||||
HdfGroup gMesh = file.group( name );
|
||||
for ( const std::string &groupName : gMesh.groups() )
|
||||
{
|
||||
HdfGroup gGroup = gMesh.group( groupName );
|
||||
if ( gGroup.isValid() )
|
||||
{
|
||||
if ( groupName == "Maximums" )
|
||||
{
|
||||
addDatasetGroupsFromXmdfGroup( groups, gGroup, "/Maximums", vertexCount, faceCount );
|
||||
}
|
||||
else
|
||||
{
|
||||
addDatasetGroupsFromXmdfGroup( groups, gGroup, "", vertexCount, faceCount );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MDAL::DriverXmdf::load( const std::string &datFile, MDAL::Mesh *mesh )
|
||||
{
|
||||
mDatFile = datFile;
|
||||
@ -143,26 +166,25 @@ void MDAL::DriverXmdf::load( const std::string &datFile, MDAL::Mesh *mesh )
|
||||
size_t faceCount = mesh->facesCount();
|
||||
|
||||
std::vector<std::string> rootGroups = file.groups();
|
||||
if ( rootGroups.size() != 1 )
|
||||
if ( rootGroups.empty() )
|
||||
{
|
||||
MDAL::Log::error( MDAL_Status::Err_UnknownFormat, name(), "Expecting exactly one root group for the mesh data" );
|
||||
MDAL::Log::error( MDAL_Status::Err_UnknownFormat, name(), "Expecting at least one root group for the mesh data" );
|
||||
return;
|
||||
}
|
||||
HdfGroup gMesh = file.group( rootGroups[0] );
|
||||
|
||||
DatasetGroups groups; // DAT outputs data
|
||||
|
||||
for ( const std::string &groupName : gMesh.groups() )
|
||||
for ( std::string &name : rootGroups )
|
||||
{
|
||||
HdfGroup gGroup = gMesh.group( groupName );
|
||||
if ( gGroup.isValid() )
|
||||
HdfGroup rootGroup = file.group( name );
|
||||
if ( rootGroup.groups().size() > 0 )
|
||||
readGroupsTree( file, name, groups, vertexCount, faceCount );
|
||||
else
|
||||
{
|
||||
if ( groupName == "Maximums" )
|
||||
std::shared_ptr<DatasetGroup> ds = readXmdfGroupAsDatasetGroup( rootGroup, name, vertexCount, faceCount );
|
||||
if ( ds && ds->datasets.size() > 0 )
|
||||
{
|
||||
addDatasetGroupsFromXmdfGroup( groups, gGroup, "/Maximums", vertexCount, faceCount );
|
||||
}
|
||||
else
|
||||
{
|
||||
addDatasetGroupsFromXmdfGroup( groups, gGroup, "", vertexCount, faceCount );
|
||||
groups.push_back( ds );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -178,7 +200,7 @@ void MDAL::DriverXmdf::addDatasetGroupsFromXmdfGroup( DatasetGroups &groups,
|
||||
const HdfGroup &rootGroup,
|
||||
const std::string &nameSuffix,
|
||||
size_t vertexCount,
|
||||
size_t faceCount )
|
||||
size_t faceCount ) const
|
||||
{
|
||||
for ( const std::string &groupName : rootGroup.groups() )
|
||||
{
|
||||
@ -193,13 +215,12 @@ void MDAL::DriverXmdf::addDatasetGroupsFromXmdfGroup( DatasetGroups &groups,
|
||||
|
||||
|
||||
std::shared_ptr<MDAL::DatasetGroup> MDAL::DriverXmdf::readXmdfGroupAsDatasetGroup(
|
||||
const HdfGroup &rootGroup, const std::string &groupName, size_t vertexCount, size_t faceCount )
|
||||
const HdfGroup &rootGroup, const std::string &groupName, size_t vertexCount, size_t faceCount ) const
|
||||
{
|
||||
std::shared_ptr<DatasetGroup> group;
|
||||
std::vector<std::string> gDataNames = rootGroup.datasets();
|
||||
if ( !MDAL::contains( gDataNames, "Times" ) ||
|
||||
!MDAL::contains( gDataNames, "Values" ) ||
|
||||
!MDAL::contains( gDataNames, "Active" ) ||
|
||||
!MDAL::contains( gDataNames, "Mins" ) ||
|
||||
!MDAL::contains( gDataNames, "Maxs" ) )
|
||||
{
|
||||
@ -207,21 +228,29 @@ std::shared_ptr<MDAL::DatasetGroup> MDAL::DriverXmdf::readXmdfGroupAsDatasetGrou
|
||||
return group;
|
||||
}
|
||||
|
||||
bool activeFlagSupported = MDAL::contains( gDataNames, "Active" );
|
||||
|
||||
HdfDataset dsTimes = rootGroup.dataset( "Times" );
|
||||
HdfDataset dsValues = rootGroup.dataset( "Values" );
|
||||
HdfDataset dsActive = rootGroup.dataset( "Active" );
|
||||
HdfDataset dsMins = rootGroup.dataset( "Mins" );
|
||||
HdfDataset dsMaxs = rootGroup.dataset( "Maxs" );
|
||||
|
||||
std::vector<hsize_t> dimTimes = dsTimes.dims();
|
||||
std::vector<hsize_t> dimValues = dsValues.dims();
|
||||
std::vector<hsize_t> dimActive = dsActive.dims();
|
||||
std::vector<hsize_t> dimMins = dsMins.dims();
|
||||
std::vector<hsize_t> dimActive;
|
||||
std::vector<hsize_t> dimMaxs = dsMaxs.dims();
|
||||
|
||||
HdfDataset dsActive;
|
||||
if ( activeFlagSupported )
|
||||
{
|
||||
dsActive = rootGroup.dataset( "Active" );
|
||||
dimActive = dsActive.dims();
|
||||
}
|
||||
|
||||
if ( dimTimes.size() != 1 ||
|
||||
( dimValues.size() != 2 && dimValues.size() != 3 ) ||
|
||||
dimActive.size() != 2 ||
|
||||
( activeFlagSupported && dimActive.size() != 2 ) ||
|
||||
dimMins.size() != 1 ||
|
||||
dimMaxs.size() != 1
|
||||
)
|
||||
@ -232,14 +261,15 @@ std::shared_ptr<MDAL::DatasetGroup> MDAL::DriverXmdf::readXmdfGroupAsDatasetGrou
|
||||
hsize_t nTimeSteps = dimTimes[0];
|
||||
|
||||
if ( dimValues[0] != nTimeSteps ||
|
||||
dimActive[0] != nTimeSteps ||
|
||||
( activeFlagSupported && dimActive[0] != nTimeSteps ) ||
|
||||
dimMins[0] != nTimeSteps ||
|
||||
dimMaxs[0] != nTimeSteps )
|
||||
{
|
||||
MDAL::Log::debug( "ignoring dataset " + groupName + " - arrays not having correct dimension sizes" );
|
||||
return group;
|
||||
}
|
||||
if ( dimValues[1] != vertexCount || dimActive[1] != faceCount )
|
||||
|
||||
if ( dimValues[1] != vertexCount || ( activeFlagSupported && dimActive[1] != faceCount ) )
|
||||
{
|
||||
MDAL::Log::debug( "ignoring dataset " + groupName + " - not aligned with the used mesh" );
|
||||
return group;
|
||||
@ -252,6 +282,7 @@ std::shared_ptr<MDAL::DatasetGroup> MDAL::DriverXmdf::readXmdfGroupAsDatasetGrou
|
||||
mDatFile,
|
||||
groupName
|
||||
);
|
||||
|
||||
bool isVector = dimValues.size() == 3;
|
||||
group->setIsScalar( !isVector );
|
||||
group->setDataLocation( MDAL_DataLocation::DataOnVertices );
|
||||
@ -286,6 +317,7 @@ std::shared_ptr<MDAL::DatasetGroup> MDAL::DriverXmdf::readXmdfGroupAsDatasetGrou
|
||||
{
|
||||
std::shared_ptr<XmdfDataset> dataset = std::make_shared< XmdfDataset >( group.get(), dsValues, dsActive, i );
|
||||
dataset->setTime( times[i], timeUnit );
|
||||
dataset->setSupportsActiveFlag( activeFlagSupported );
|
||||
Statistics stats;
|
||||
stats.minimum = static_cast<double>( mins[i] );
|
||||
stats.maximum = static_cast<double>( maxs[i] );
|
||||
|
||||
21
external/mdal/frmts/mdal_xmdf.hpp
vendored
21
external/mdal/frmts/mdal_xmdf.hpp
vendored
@ -23,13 +23,17 @@ namespace MDAL
|
||||
|
||||
/**
|
||||
* The XmdfDataset reads the data directly from HDF5 file
|
||||
* by usage of hyperslabs retrieval
|
||||
*
|
||||
* by usage of hyperslabs retrieval. This format is used by TUFLOW and HYDRO_AS-2D
|
||||
* basically all (timesteps) data for one particular dataset groups
|
||||
* are stored in single
|
||||
* 3D arrays (time, x, y) for vector datasets
|
||||
* 2D arrays (time, x) for scalar datasets
|
||||
* 2D arrays (time, active) for active flags
|
||||
* 2D arrays (time, active) for active flags (optional, supported by default)
|
||||
*
|
||||
* For TUFLOW, the dataset groups are structured with a tree starting from a unique group and datasets support active flag value.
|
||||
*
|
||||
* For HYDRO_AS-2D, all the groups are on the root of the file and the datasets don't support active flag value.
|
||||
*
|
||||
*/
|
||||
class XmdfDataset: public Dataset2D
|
||||
{
|
||||
@ -92,14 +96,21 @@ namespace MDAL
|
||||
const HdfGroup &rootGroup,
|
||||
const std::string &groupName,
|
||||
size_t vertexCount,
|
||||
size_t faceCount );
|
||||
size_t faceCount ) const;
|
||||
|
||||
void addDatasetGroupsFromXmdfGroup(
|
||||
DatasetGroups &groups,
|
||||
const HdfGroup &rootGroup,
|
||||
const std::string &nameSuffix,
|
||||
size_t vertexCount,
|
||||
size_t faceCount );
|
||||
size_t faceCount ) const;
|
||||
|
||||
void readGroupsTree( HdfFile &file,
|
||||
const std::string &name,
|
||||
MDAL::DatasetGroups &groups,
|
||||
size_t vertexCount,
|
||||
size_t faceCount ) const;
|
||||
|
||||
};
|
||||
|
||||
} // namespace MDAL
|
||||
|
||||
2
external/mdal/mdal.cpp
vendored
2
external/mdal/mdal.cpp
vendored
@ -21,7 +21,7 @@ static const char *EMPTY_STR = "";
|
||||
|
||||
const char *MDAL_Version()
|
||||
{
|
||||
return "0.7.1";
|
||||
return "0.7.91";
|
||||
}
|
||||
|
||||
MDAL_Status MDAL_LastStatus()
|
||||
|
||||
2
external/mdal/mdal_data_model.hpp
vendored
2
external/mdal/mdal_data_model.hpp
vendored
@ -31,7 +31,7 @@ namespace MDAL
|
||||
double maxY = -std::numeric_limits<double>::max();
|
||||
};
|
||||
|
||||
typedef struct
|
||||
typedef struct StatisticsType
|
||||
{
|
||||
double minimum = std::numeric_limits<double>::quiet_NaN();
|
||||
double maximum = std::numeric_limits<double>::quiet_NaN();
|
||||
|
||||
21
external/mdal/mdal_driver_manager.cpp
vendored
21
external/mdal/mdal_driver_manager.cpp
vendored
@ -12,6 +12,7 @@
|
||||
#include "frmts/mdal_selafin.hpp"
|
||||
#include "frmts/mdal_esri_tin.hpp"
|
||||
#include "frmts/mdal_ply.hpp"
|
||||
#include "frmts/mdal_dynamic_driver.hpp"
|
||||
#include "mdal_utils.hpp"
|
||||
|
||||
#ifdef HAVE_HDF5
|
||||
@ -240,5 +241,25 @@ MDAL::DriverManager::DriverManager()
|
||||
#if defined HAVE_HDF5 && defined HAVE_XML
|
||||
mDrivers.push_back( std::make_shared<MDAL::DriverXdmf>() );
|
||||
#endif
|
||||
|
||||
loadDynamicDrivers();
|
||||
}
|
||||
|
||||
void MDAL::DriverManager::loadDynamicDrivers()
|
||||
{
|
||||
std::string dirPath = MDAL::getEnvVar( "MDAL_DRIVER_PATH" );
|
||||
if ( dirPath.empty() )
|
||||
return;
|
||||
dirPath += '/';
|
||||
std::vector<std::string> libList = MDAL::Library::libraryFilesInDir( dirPath );
|
||||
for ( const std::string &libFile : libList )
|
||||
{
|
||||
std::shared_ptr<MDAL::Driver> driver( MDAL::DriverDynamic::create( dirPath + libFile ) );
|
||||
|
||||
if ( driver )
|
||||
mDrivers.push_back( driver );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
2
external/mdal/mdal_driver_manager.hpp
vendored
2
external/mdal/mdal_driver_manager.hpp
vendored
@ -44,6 +44,8 @@ namespace MDAL
|
||||
std::shared_ptr<MDAL::Driver> driver( const std::string &driverName ) const;
|
||||
std::shared_ptr<MDAL::Driver> driver( size_t index ) const;
|
||||
|
||||
void loadDynamicDrivers();
|
||||
|
||||
private:
|
||||
DriverManager();
|
||||
|
||||
|
||||
4
external/mdal/mdal_memory_data_model.cpp
vendored
4
external/mdal/mdal_memory_data_model.cpp
vendored
@ -308,8 +308,8 @@ size_t MDAL::MemoryMeshEdgeIterator::next( size_t edgeCount,
|
||||
break;
|
||||
|
||||
const Edge &e = edges[mLastEdgeIndex + i];
|
||||
startVertexIndices[i] = e.startVertex;
|
||||
endVertexIndices[i] = e.endVertex;
|
||||
startVertexIndices[i] = MDAL::toInt( e.startVertex );
|
||||
endVertexIndices[i] = MDAL::toInt( e.endVertex );
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
2
external/mdal/mdal_memory_data_model.hpp
vendored
2
external/mdal/mdal_memory_data_model.hpp
vendored
@ -19,7 +19,7 @@ namespace MDAL
|
||||
{
|
||||
class MemoryMesh;
|
||||
|
||||
typedef struct
|
||||
typedef struct VertexType
|
||||
{
|
||||
double x = std::numeric_limits<double>::quiet_NaN();
|
||||
double y = std::numeric_limits<double>::quiet_NaN();
|
||||
|
||||
240
external/mdal/mdal_utils.cpp
vendored
240
external/mdal/mdal_utils.cpp
vendored
@ -14,6 +14,33 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctime>
|
||||
#include <stdlib.h>
|
||||
|
||||
std::string MDAL::getEnvVar( const std::string &varname, const std::string &defaultVal )
|
||||
{
|
||||
if ( varname.empty() )
|
||||
return std::string();
|
||||
|
||||
char *envVarC = nullptr;
|
||||
#ifdef WIN32
|
||||
size_t requiredSize = 0;
|
||||
getenv_s( &requiredSize, NULL, 0, varname.c_str() );
|
||||
if ( requiredSize != 0 )
|
||||
{
|
||||
envVarC = ( char * )malloc( requiredSize * sizeof( char ) );
|
||||
getenv_s( &requiredSize, envVarC, requiredSize, varname.c_str() );
|
||||
}
|
||||
else
|
||||
envVarC = nullptr;
|
||||
#else
|
||||
envVarC = getenv( varname.c_str() );
|
||||
#endif
|
||||
|
||||
if ( !envVarC )
|
||||
return defaultVal;
|
||||
else
|
||||
return std::string( envVarC );
|
||||
}
|
||||
|
||||
bool MDAL::fileExists( const std::string &filename )
|
||||
{
|
||||
@ -119,6 +146,23 @@ size_t MDAL::toSizeT( const char &str )
|
||||
return static_cast< size_t >( i );
|
||||
}
|
||||
|
||||
size_t MDAL::toSizeT( const double value )
|
||||
{
|
||||
return static_cast<size_t>( value );
|
||||
}
|
||||
|
||||
int MDAL::toInt( const size_t value )
|
||||
{
|
||||
if ( value > std::numeric_limits<int>::max() )
|
||||
throw std::runtime_error( "Invalid cast" );
|
||||
return static_cast< int >( value );
|
||||
}
|
||||
|
||||
double MDAL::toDouble( const size_t value )
|
||||
{
|
||||
return static_cast< double >( value );
|
||||
}
|
||||
|
||||
double MDAL::toDouble( const std::string &str )
|
||||
{
|
||||
return atof( str.c_str() );
|
||||
@ -430,7 +474,7 @@ std::string MDAL::getCurrentTimeStamp()
|
||||
return s;
|
||||
}
|
||||
|
||||
MDAL::Statistics _calculateStatistics( const std::vector<double> &values, size_t count, bool isVector )
|
||||
MDAL::Statistics _calculateStatistics( const std::vector<double> &values, size_t count, bool isVector, const std::vector<int> &active )
|
||||
{
|
||||
MDAL::Statistics ret;
|
||||
|
||||
@ -440,6 +484,9 @@ MDAL::Statistics _calculateStatistics( const std::vector<double> &values, size_t
|
||||
|
||||
for ( size_t i = 0; i < count; ++i )
|
||||
{
|
||||
if ( !active.empty() && active.at( i ) == 0 )
|
||||
continue;
|
||||
|
||||
double magnitude;
|
||||
if ( isVector )
|
||||
{
|
||||
@ -510,6 +557,11 @@ MDAL::Statistics MDAL::calculateStatistics( std::shared_ptr<Dataset> dataset )
|
||||
bool is3D = dataset->group()->dataLocation() == MDAL_DataLocation::DataOnVolumes;
|
||||
size_t bufLen = 2000;
|
||||
std::vector<double> buffer( isVector ? bufLen * 2 : bufLen );
|
||||
std::vector<int> activeBuffer;
|
||||
bool activeFaceFlag = dataset->group()->dataLocation() == MDAL_DataLocation::DataOnFaces && dataset->supportsActiveFlag();
|
||||
|
||||
if ( activeFaceFlag )
|
||||
activeBuffer.resize( bufLen );
|
||||
|
||||
size_t i = 0;
|
||||
while ( i < dataset->valuesCount() )
|
||||
@ -536,11 +588,14 @@ MDAL::Statistics MDAL::calculateStatistics( std::shared_ptr<Dataset> dataset )
|
||||
{
|
||||
valsRead = dataset->scalarData( i, bufLen, buffer.data() );
|
||||
}
|
||||
|
||||
if ( activeFaceFlag )
|
||||
dataset->activeData( i, bufLen, activeBuffer.data() );
|
||||
}
|
||||
if ( valsRead == 0 )
|
||||
return ret;
|
||||
|
||||
MDAL::Statistics dsStats = _calculateStatistics( buffer, valsRead, isVector );
|
||||
MDAL::Statistics dsStats = _calculateStatistics( buffer, valsRead, isVector, activeBuffer );
|
||||
combineStatistics( ret, dsStats );
|
||||
i += valsRead;
|
||||
}
|
||||
@ -565,58 +620,51 @@ void MDAL::combineStatistics( MDAL::Statistics &main, const MDAL::Statistics &ot
|
||||
|
||||
void MDAL::addBedElevationDatasetGroup( MDAL::Mesh *mesh, const Vertices &vertices )
|
||||
{
|
||||
if ( !mesh )
|
||||
return;
|
||||
|
||||
if ( 0 == mesh->verticesCount() )
|
||||
return;
|
||||
|
||||
std::shared_ptr<DatasetGroup> group = std::make_shared< DatasetGroup >(
|
||||
mesh->driverName(),
|
||||
mesh,
|
||||
mesh->uri(),
|
||||
"Bed Elevation"
|
||||
);
|
||||
group->setDataLocation( MDAL_DataLocation::DataOnVertices );
|
||||
group->setIsScalar( true );
|
||||
|
||||
std::shared_ptr<MDAL::MemoryDataset2D> dataset = std::make_shared< MemoryDataset2D >( group.get() );
|
||||
dataset->setTime( 0.0 );
|
||||
std::vector<double> values( mesh->verticesCount() );
|
||||
for ( size_t i = 0; i < vertices.size(); ++i )
|
||||
{
|
||||
dataset->setScalarValue( i, vertices[i].z );
|
||||
values[i] = vertices[i].z;
|
||||
}
|
||||
dataset->setStatistics( MDAL::calculateStatistics( dataset ) );
|
||||
group->datasets.push_back( dataset );
|
||||
group->setStatistics( MDAL::calculateStatistics( group ) );
|
||||
mesh->datasetGroups.push_back( group );
|
||||
addVertexScalarDatasetGroup( mesh, values, "Bed Elevation" );
|
||||
}
|
||||
|
||||
void MDAL::addFaceScalarDatasetGroup( MDAL::Mesh *mesh,
|
||||
const std::vector<double> &values,
|
||||
const std::string &name )
|
||||
static void _addScalarDatasetGroup( MDAL::Mesh *mesh,
|
||||
const std::vector<double> &values,
|
||||
const std::string &name,
|
||||
MDAL_DataLocation location
|
||||
)
|
||||
{
|
||||
if ( !mesh )
|
||||
return;
|
||||
|
||||
size_t maxCount = 0;
|
||||
switch ( location )
|
||||
{
|
||||
case MDAL_DataLocation::DataOnVertices: maxCount = mesh->verticesCount(); break;
|
||||
case MDAL_DataLocation::DataOnFaces: maxCount = mesh->facesCount(); break;
|
||||
case MDAL_DataLocation::DataOnEdges: maxCount = mesh->edgesCount(); break;
|
||||
default:
|
||||
assert( false );
|
||||
}
|
||||
|
||||
if ( values.empty() )
|
||||
return;
|
||||
|
||||
if ( mesh->facesCount() == 0 )
|
||||
if ( maxCount == 0 )
|
||||
return;
|
||||
|
||||
assert( values.size() == mesh->facesCount() );
|
||||
assert( values.size() == maxCount );
|
||||
|
||||
std::shared_ptr<DatasetGroup> group = std::make_shared< DatasetGroup >(
|
||||
mesh->driverName(),
|
||||
mesh,
|
||||
mesh->uri(),
|
||||
name
|
||||
);
|
||||
group->setDataLocation( MDAL_DataLocation::DataOnFaces );
|
||||
std::shared_ptr<MDAL::DatasetGroup> group = std::make_shared< MDAL::DatasetGroup >(
|
||||
mesh->driverName(),
|
||||
mesh,
|
||||
mesh->uri(),
|
||||
name
|
||||
);
|
||||
group->setDataLocation( location );
|
||||
group->setIsScalar( true );
|
||||
|
||||
std::shared_ptr<MDAL::MemoryDataset2D> dataset = std::make_shared< MemoryDataset2D >( group.get() );
|
||||
std::shared_ptr<MDAL::MemoryDataset2D> dataset = std::make_shared< MDAL::MemoryDataset2D >( group.get() );
|
||||
dataset->setTime( 0.0 );
|
||||
memcpy( dataset->values(), values.data(), sizeof( double )*values.size() );
|
||||
dataset->setStatistics( MDAL::calculateStatistics( dataset ) );
|
||||
@ -625,6 +673,24 @@ void MDAL::addFaceScalarDatasetGroup( MDAL::Mesh *mesh,
|
||||
mesh->datasetGroups.push_back( group );
|
||||
}
|
||||
|
||||
|
||||
void MDAL::addFaceScalarDatasetGroup( MDAL::Mesh *mesh,
|
||||
const std::vector<double> &values,
|
||||
const std::string &name )
|
||||
{
|
||||
_addScalarDatasetGroup( mesh, values, name, MDAL_DataLocation::DataOnFaces );
|
||||
}
|
||||
|
||||
void MDAL::addVertexScalarDatasetGroup( MDAL::Mesh *mesh, const std::vector<double> &values, const std::string &name )
|
||||
{
|
||||
_addScalarDatasetGroup( mesh, values, name, MDAL_DataLocation::DataOnVertices );
|
||||
}
|
||||
|
||||
void MDAL::addEdgeScalarDatasetGroup( MDAL::Mesh *mesh, const std::vector<double> &values, const std::string &name )
|
||||
{
|
||||
_addScalarDatasetGroup( mesh, values, name, MDAL_DataLocation::DataOnEdges );
|
||||
}
|
||||
|
||||
bool MDAL::isNativeLittleEndian()
|
||||
{
|
||||
// https://stackoverflow.com/a/4181991/2838364
|
||||
@ -644,7 +710,6 @@ std::string MDAL::coordinateToString( double coordinate, int precision )
|
||||
oss << coordinate;
|
||||
|
||||
std::string returnString = oss.str();
|
||||
returnString.back();
|
||||
|
||||
//remove unnecessary '0' or '.'
|
||||
if ( returnString.size() > 0 )
|
||||
@ -919,3 +984,102 @@ std::string MDAL::buildAndMergeMeshUris( const std::string &meshFile, const std:
|
||||
|
||||
return mergedUris;
|
||||
}
|
||||
|
||||
MDAL::Library::Library( std::string libraryFile )
|
||||
{
|
||||
d = new Data;
|
||||
d->mLibraryFile = libraryFile;
|
||||
}
|
||||
|
||||
MDAL::Library::~Library()
|
||||
{
|
||||
d->mRef--;
|
||||
#ifdef WIN32
|
||||
if ( d->mLibrary && d->mRef == 0 )
|
||||
FreeLibrary( d->mLibrary );
|
||||
#else
|
||||
if ( d->mLibrary && d->mRef == 0 )
|
||||
dlclose( d->mLibrary );
|
||||
#endif
|
||||
}
|
||||
|
||||
MDAL::Library::Library( const MDAL::Library &other )
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
MDAL::Library &MDAL::Library::operator=( const MDAL::Library &other )
|
||||
{
|
||||
d = other.d;
|
||||
d->mRef++;
|
||||
|
||||
return ( *this );
|
||||
}
|
||||
|
||||
bool MDAL::Library::isValid()
|
||||
{
|
||||
if ( !d->mLibrary )
|
||||
loadLibrary();
|
||||
|
||||
return d->mLibrary != nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::string> MDAL::Library::libraryFilesInDir( const std::string &dirPath )
|
||||
{
|
||||
std::vector<std::string> filesList;
|
||||
#if defined(WIN32)
|
||||
WIN32_FIND_DATA data;
|
||||
HANDLE hFind;
|
||||
std::string pattern = dirPath;
|
||||
pattern.push_back( '*' );
|
||||
|
||||
hFind = FindFirstFile( pattern.c_str(), &data );
|
||||
|
||||
if ( hFind == INVALID_HANDLE_VALUE )
|
||||
return filesList;
|
||||
|
||||
do
|
||||
{
|
||||
std::string fileName( data.cFileName );
|
||||
if ( !fileName.empty() && fileExtension( fileName ) == ".dll" )
|
||||
filesList.push_back( fileName );
|
||||
}
|
||||
while ( FindNextFile( hFind, &data ) != 0 );
|
||||
|
||||
FindClose( hFind );
|
||||
#else
|
||||
DIR *dir = opendir( dirPath.c_str() );
|
||||
struct dirent *de = readdir( dir );
|
||||
while ( de != nullptr )
|
||||
{
|
||||
std::string fileName( de->d_name );
|
||||
if ( !fileName.empty() )
|
||||
{
|
||||
std::string extentsion = fileExtension( fileName );
|
||||
if ( extentsion == ".so" || extentsion == ".dylib" )
|
||||
filesList.push_back( fileName );
|
||||
}
|
||||
de = readdir( dir );
|
||||
}
|
||||
|
||||
closedir( dir );
|
||||
#endif
|
||||
return filesList;
|
||||
}
|
||||
|
||||
bool MDAL::Library::loadLibrary()
|
||||
{
|
||||
//should we allow only one successful loading?
|
||||
if ( d->mLibrary )
|
||||
return false;
|
||||
#ifdef WIN32
|
||||
UINT uOldErrorMode =
|
||||
SetErrorMode( SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS );
|
||||
d->mLibrary = LoadLibrary( d->mLibraryFile.c_str() );
|
||||
SetErrorMode( uOldErrorMode );
|
||||
#else
|
||||
d->mLibrary = dlopen( d->mLibraryFile.c_str(), RTLD_LAZY );
|
||||
#endif
|
||||
|
||||
return d->mLibrary != nullptr;
|
||||
}
|
||||
|
||||
92
external/mdal/mdal_utils.hpp
vendored
92
external/mdal/mdal_utils.hpp
vendored
@ -13,6 +13,16 @@
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
|
||||
#if defined (WIN32)
|
||||
#include <windows.h>
|
||||
#undef min
|
||||
#undef max
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -30,6 +40,9 @@
|
||||
|
||||
namespace MDAL
|
||||
{
|
||||
|
||||
std::string getEnvVar( const std::string &varname, const std::string &defaultVal = std::string() );
|
||||
|
||||
// endianness
|
||||
bool isNativeLittleEndian();
|
||||
|
||||
@ -75,8 +88,11 @@ namespace MDAL
|
||||
/** Return 0 if not possible to convert */
|
||||
size_t toSizeT( const std::string &str );
|
||||
size_t toSizeT( const char &str );
|
||||
size_t toSizeT( const double value );
|
||||
int toInt( const std::string &str );
|
||||
int toInt( const size_t value );
|
||||
double toDouble( const std::string &str );
|
||||
double toDouble( const size_t value );
|
||||
bool toBool( const std::string &str );
|
||||
|
||||
//! Returns the string with a adapted format to coordinate
|
||||
@ -136,8 +152,12 @@ namespace MDAL
|
||||
// mesh & datasets
|
||||
//! Adds bed elevatiom dataset group to mesh
|
||||
void addBedElevationDatasetGroup( MDAL::Mesh *mesh, const Vertices &vertices );
|
||||
//! Adds altitude dataset group to mesh
|
||||
//! Adds a scalar face dataset group with 1 timestep to mesh
|
||||
void addFaceScalarDatasetGroup( MDAL::Mesh *mesh, const std::vector<double> &values, const std::string &name );
|
||||
//! Adds a scalar vertex dataset group with 1 timestep to mesh
|
||||
void addVertexScalarDatasetGroup( MDAL::Mesh *mesh, const std::vector<double> &values, const std::string &name );
|
||||
//! Adds a scalar edge dataset group with 1 timestep to mesh
|
||||
void addEdgeScalarDatasetGroup( MDAL::Mesh *mesh, const std::vector<double> &values, const std::string &name );
|
||||
|
||||
//! Reads all of type of value. Option to change the endianness is provided
|
||||
template<typename T>
|
||||
@ -222,5 +242,75 @@ namespace MDAL
|
||||
std::string mssg;
|
||||
std::string driver;
|
||||
};
|
||||
|
||||
//! Class to handle dynamic library. The loaded library is implicity shared when copying this object
|
||||
class Library
|
||||
{
|
||||
public:
|
||||
//! Creater a instance from a library file
|
||||
Library( std::string libraryFile );
|
||||
~Library();
|
||||
Library( const Library &other );
|
||||
Library &operator=( const Library &other );
|
||||
|
||||
//! Returns whether the library is valid after loading the file if needed
|
||||
bool isValid();
|
||||
|
||||
//! Returns a list of library file in the folder \a dirPath
|
||||
static std::vector<std::string> libraryFilesInDir( const std::string &dirPath );
|
||||
|
||||
/**
|
||||
* Returns a function from a symbol name. Caller needs to define what are the types of the arguments and of the returned value :
|
||||
* <Type of the returned Value, Type of arg1, Type of arg2, ...>
|
||||
*/
|
||||
template<typename T, typename ... Ts>
|
||||
std::function<T( Ts ... args )> getSymbol( const std::string &symbolName )
|
||||
{
|
||||
if ( !isValid() )
|
||||
return std::function<T( Ts ... args )>();
|
||||
#ifdef WIN32
|
||||
FARPROC proc = GetProcAddress( d->mLibrary, symbolName.c_str() );
|
||||
|
||||
if ( !proc )
|
||||
return std::function<T( Ts ... args )>();
|
||||
|
||||
std::function<T( Ts ... args )> symbol = reinterpret_cast<T( * )( Ts ... args )>( proc );
|
||||
#else
|
||||
std::function<T( Ts ... args )> symbol =
|
||||
reinterpret_cast<T( * )( Ts ... args )>( dlsym( d->mLibrary, symbolName.c_str() ) );
|
||||
|
||||
#if (defined(__APPLE__) && defined(__MACH__))
|
||||
/* On mach-o systems, C symbols have a leading underscore and depending
|
||||
* on how dlcompat is configured it may or may not add the leading
|
||||
* underscore. If dlsym() fails, add an underscore and try again.
|
||||
*/
|
||||
if ( symbol == nullptr )
|
||||
{
|
||||
char withUnder[256] = {};
|
||||
snprintf( withUnder, sizeof( withUnder ), "_%s", symbolName.c_str() );
|
||||
std::function<T( Ts ... args )> symbol = reinterpret_cast<T( * )( Ts ... args )>( dlsym( d->mLibrary, withUnder ) );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return symbol;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
struct Data
|
||||
{
|
||||
#ifdef WIN32
|
||||
HINSTANCE mLibrary = nullptr;
|
||||
#else
|
||||
void *mLibrary = nullptr;
|
||||
#endif
|
||||
mutable int mRef = 1;
|
||||
std::string mLibraryFile;
|
||||
};
|
||||
|
||||
Data *d;
|
||||
|
||||
bool loadLibrary();
|
||||
};
|
||||
} // namespace MDAL
|
||||
#endif //MDAL_UTILS_HPP
|
||||
|
||||
@ -40,6 +40,7 @@ if (WITH_INTERNAL_MDAL)
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/mdal_logger.cpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/mdal_logger.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_driver.cpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_dynamic_driver.cpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_2dm.cpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_ascii_dat.cpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_binary_dat.cpp
|
||||
@ -57,6 +58,7 @@ if (WITH_INTERNAL_MDAL)
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/mdal_memory_data_model.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/mdal_driver_manager.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_driver.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_dynamic_driver.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_2dm.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_ascii_dat.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_binary_dat.hpp
|
||||
@ -79,7 +81,6 @@ if (WITH_INTERNAL_MDAL)
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_hec2d.hpp
|
||||
${CMAKE_SOURCE_DIR}/external/mdal/frmts/mdal_flo2d.hpp
|
||||
)
|
||||
set(MDAL_DEPS ${MDAL_DEPS} )
|
||||
set (HAVE_HDF5 TRUE)
|
||||
endif()
|
||||
|
||||
@ -191,6 +192,10 @@ target_link_libraries (mdalprovider
|
||||
${MDAL_LIBRARY}
|
||||
)
|
||||
|
||||
if (WITH_INTERNAL_MDAL)
|
||||
target_link_libraries(mdalprovider ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
||||
if (WITH_GUI)
|
||||
target_link_libraries (mdalprovider
|
||||
qgis_gui
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user