Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MDAL version 1.3.0 #59354

Merged
merged 7 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions external/mdal/api/mdal.h
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,14 @@ MDAL_EXPORT MDAL_DatasetGroupH MDAL_M_addDatasetGroup(
MDAL_DriverH driver,
const char *datasetGroupFile );

/**
* Removes DatasetGroup from Mesh based on it's index. On error see MDAL_LastStatus
* for error type.
*
* \since MDAL 1.3.0
*/
MDAL_EXPORT void MDAL_M_RemoveDatasetGroup( MDAL_MeshH mesh, int index );

/**
* Returns name of MDAL driver
* not thread-safe and valid only till next call
Expand Down Expand Up @@ -587,6 +595,13 @@ MDAL_EXPORT void MDAL_G_setMetadata( MDAL_DatasetGroupH group, const char *key,
*/
MDAL_EXPORT const char *MDAL_G_name( MDAL_DatasetGroupH group );

/**
* Sets dataset group name
*
* \since MDAL 1.3.0
*/
MDAL_EXPORT void MDAL_G_setName( MDAL_DatasetGroupH group, const char *name );

/**
* Returns name of MDAL driver
* not thread-safe and valid only till next call
Expand Down
2 changes: 1 addition & 1 deletion external/mdal/frmts/mdal_2dm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ void MDAL::Driver2dm::save( const std::string &fileName, const std::string &, MD
for ( size_t j = 0; j < 2; ++j )
{
line.append( " " );
line.append( MDAL::coordinateToString( vertex[j] ) );
line.append( MDAL::doubleToString( vertex[j], 8, true ) );
}
line.append( " " );
line.append( MDAL::doubleToString( vertex[2] ) );
Expand Down
253 changes: 251 additions & 2 deletions external/mdal/frmts/mdal_xmdf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ size_t MDAL::XmdfDataset::activeData( size_t indexStart, size_t count, int *buff
MDAL::DriverXmdf::DriverXmdf()
: Driver( "XMDF",
"TUFLOW XMDF",
"*.xmdf",
Capability::ReadDatasets )
"*.xmdf;;*.h5",
Capability::ReadDatasets | Capability::ReadMesh )
{
}

Expand Down Expand Up @@ -206,6 +206,17 @@ void MDAL::DriverXmdf::addDatasetGroupsFromXmdfGroup( DatasetGroups &groups,
size_t vertexCount,
size_t faceCount ) const
{
// check if this root group can be loaded as a dataset group and if so, then load it
std::vector<std::string> gDataNames = rootGroup.datasets();
if ( MDAL::contains( gDataNames, "Times" ) &&
MDAL::contains( gDataNames, "Values" ) &&
MDAL::contains( gDataNames, "Mins" ) &&
MDAL::contains( gDataNames, "Maxs" ) )
{
std::shared_ptr<DatasetGroup> ds = readXmdfGroupAsDatasetGroup( rootGroup, rootGroup.name() + nameSuffix, vertexCount, faceCount );
groups.push_back( ds );
}

for ( const std::string &groupName : rootGroup.groups() )
{
HdfGroup g = rootGroup.group( groupName );
Expand Down Expand Up @@ -331,3 +342,241 @@ std::shared_ptr<MDAL::DatasetGroup> MDAL::DriverXmdf::readXmdfGroupAsDatasetGrou

return group;
}

bool MDAL::DriverXmdf::canReadMesh( const std::string &uri )
{
HdfFile file( uri, HdfFile::ReadOnly );
if ( !file.isValid() )
{
return false;
}

HdfDataset dsFileType = file.dataset( "/File Type" );
if ( dsFileType.readString() != "Xmdf" )
{
return false;
}

std::vector<std::string> meshPaths = meshGroupPaths( file );

return !meshPaths.empty();
}

std::string MDAL::DriverXmdf::buildUri( const std::string &meshFile )
{
mDatFile = meshFile;

std::vector<std::string> meshNames = findMeshesNames();

return MDAL::buildAndMergeMeshUris( meshFile, meshNames, name() );
}

std::vector<std::string> MDAL::DriverXmdf::findMeshesNames() const
{
std::vector<std::string> meshesInFile;

HdfFile file( mDatFile, HdfFile::ReadOnly );
if ( !file.isValid() )
{
return meshesInFile;
}

meshesInFile = meshGroupPaths( file );

return meshesInFile;
}

std::vector<std::string> MDAL::DriverXmdf::meshGroupPaths( const HdfFile &file ) const
{
std::vector<std::string> meshPaths;

std::vector<std::string> rootGroups = file.groups();

for ( const std::string &groupName : rootGroups )
{
HdfGroup g = file.group( groupName );
std::vector<std::string> paths = meshGroupPaths( g );
meshPaths.insert( meshPaths.end(), paths.begin(), paths.end() );
}

return meshPaths;
}

std::vector<std::string> MDAL::DriverXmdf::meshGroupPaths( const HdfGroup &group ) const
{
std::vector<std::string> meshPaths;

std::vector<std::string> gDataNames = group.groups();

if ( MDAL::contains( gDataNames, "Nodes" ) ||
MDAL::contains( gDataNames, "Elements" ) )
{
meshPaths.push_back( group.name() );
}

for ( const std::string &groupName : gDataNames )
{
HdfGroup g = group.group( groupName );
std::vector<std::string> paths = meshGroupPaths( g );
meshPaths.insert( meshPaths.end(), paths.begin(), paths.end() );
}

return meshPaths;
}

std::unique_ptr< MDAL::Mesh > MDAL::DriverXmdf::load( const std::string &meshFile, const std::string &meshName )
{
mDatFile = meshFile;

MDAL::Log::resetLastStatus();

HdfFile file( mDatFile, HdfFile::ReadOnly );
if ( !file.isValid() )
{
MDAL::Log::error( MDAL_Status::Err_UnknownFormat, name(), "File " + mDatFile + " is not valid" );
return nullptr;
}

HdfDataset dsFileType = file.dataset( "/File Type" );
if ( dsFileType.readString() != "Xmdf" )
{
MDAL::Log::error( MDAL_Status::Err_UnknownFormat, name(), "Unknown dataset file type" );
return nullptr;
}

std::vector<std::string> meshNames = findMeshesNames();

if ( meshNames.empty() )
{
MDAL::Log::error( MDAL_Status::Err_IncompatibleMesh, name(), "No meshes found in file " + mDatFile );
return nullptr;
}

std::string meshNameToLoad = meshName;

if ( meshNameToLoad.empty() )
{
meshNameToLoad = meshNames[0];
}

if ( !MDAL::contains( meshNames, meshNameToLoad ) )
{
MDAL::Log::error( MDAL_Status::Err_IncompatibleMesh, name(), "No meshes with name " + meshNameToLoad + " found in file " + mDatFile );
return nullptr;
}

HdfGroup groupMeshModule = file.group( meshNameToLoad );

std::vector<std::string> gDataNames = groupMeshModule.groups();

HdfGroup gNodes = groupMeshModule.group( "Nodes" );

std::vector<std::string> namesNodes = gNodes.datasets();
HdfDataset nodes = gNodes.dataset( namesNodes[0] );

std::vector<hsize_t> nodesDims = nodes.dims();
hsize_t nodesRows = nodesDims[0];
size_t vertexDims = nodesDims[1];

if ( vertexDims < 2 || vertexDims > 3 )
{
MDAL::Log::error( MDAL_Status::Err_IncompatibleMesh, name(), "Vertices have unsupported number of dimensions " + std::to_string( vertexDims ) + " only 2 (X,Y) or 3 (X, Y, Z) dimensions are allowed." );
return nullptr;
}

std::vector<double> nodesData = nodes.readArrayDouble();

Vertices vertices( nodesRows );

size_t currentVertexIndex = 0;
size_t i = 0;
while ( i < nodesData.size() )
{
Vertex &vertex = vertices[currentVertexIndex];

vertex.x = nodesData[i];
i++;
vertex.y = nodesData[i];
i++;
if ( vertexDims == 3 )
{
vertex.z = nodesData[i];
i++;
}
currentVertexIndex++;
}

nodesData.clear();

HdfGroup gElements = groupMeshModule.group( "Elements" );

std::vector<std::string> namesElements = gElements.datasets();
HdfDataset elements = gElements.dataset( namesElements[0] );

std::vector<hsize_t> elementsDims = elements.dims();
hsize_t elementsRows = elementsDims[0];
hsize_t elementsRowsDims = elementsDims[1];

std::vector<int> facesData = elements.readArrayInt();

Faces faces( elementsRows );
size_t maxVerticesPerFace = 0;

size_t currentFaceIndex = 0;
i = 0;
while ( i < facesData.size() )
{
std::vector<size_t> tempFace;
for ( hsize_t j = 0; j < elementsRowsDims; j++ )
{
int vertexIndex = facesData[i];
if ( vertexIndex > 0 )
{
// XMDF is 1-based, MDAL is 0-based
tempFace.push_back( facesData[i] - 1 );
}
i++;
}

// only store faces with more than 2 vertices
if ( tempFace.size() > static_cast<size_t>( 2 ) )
{
Face &face = faces[currentFaceIndex];
std::copy( tempFace.begin(), tempFace.end(), std::back_inserter( face ) );

if ( tempFace.size() > maxVerticesPerFace )
{
maxVerticesPerFace = tempFace.size();
}

currentFaceIndex++;
}
}

facesData.clear();

// copy only the faces that have been properly filled
faces = Faces( faces.begin(), faces.begin() + static_cast<long>( currentFaceIndex ) );

// create the mesh and set the required data
std::unique_ptr< MemoryMesh > mesh(
new MemoryMesh(
name(),
maxVerticesPerFace,
mDatFile
)
);

std::vector<double> values( vertices.size() );
for ( size_t i = 0; i < vertices.size(); ++i )
{
values[i] = vertices[i].z;
}

mesh->setFaces( std::move( faces ) );
mesh->setVertices( std::move( vertices ) );

addVertexScalarDatasetGroup( mesh.get(), values, "Z-Values" );

return mesh;
}
8 changes: 8 additions & 0 deletions external/mdal/frmts/mdal_xmdf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ namespace MDAL
bool canReadDatasets( const std::string &uri ) override;
void load( const std::string &datFile, Mesh *mesh ) override;

bool canReadMesh( const std::string &uri ) override;
std::unique_ptr< Mesh > load( const std::string &meshFile, const std::string &meshName = "" ) override;

private:
MDAL::Mesh *mMesh = nullptr;
std::string mDatFile;
Expand All @@ -111,6 +114,11 @@ namespace MDAL
size_t vertexCount,
size_t faceCount ) const;

std::string buildUri( const std::string &meshFile ) override;
std::vector<std::string> findMeshesNames() const;

std::vector<std::string> meshGroupPaths( const HdfGroup &group ) const;
std::vector<std::string> meshGroupPaths( const HdfFile &file ) const;
};

} // namespace MDAL
Expand Down
42 changes: 41 additions & 1 deletion external/mdal/mdal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ static const char *EMPTY_STR = "";

const char *MDAL_Version()
{
return "1.2.0";
return "1.3.0";
}

MDAL_Status MDAL_LastStatus()
Expand Down Expand Up @@ -580,6 +580,34 @@ MDAL_DatasetGroupH MDAL_M_addDatasetGroup(
return nullptr;
}

void MDAL_M_RemoveDatasetGroup( MDAL_MeshH mesh, int index )
{
MDAL::Log::resetLastStatus();

if ( !mesh )
{
MDAL::Log::error( MDAL_Status::Err_IncompatibleMesh, "Mesh is not valid (null)" );
return;
}

if ( index < 0 )
{
MDAL::Log::error( MDAL_Status::Err_IncompatibleMesh, "Requested index is not valid: " + std::to_string( index ) );
return;
}

MDAL::Mesh *m = static_cast< MDAL::Mesh * >( mesh );
int len = static_cast<int>( m->datasetGroups.size() );
if ( len <= index )
{
MDAL::Log::error( MDAL_Status::Err_IncompatibleMesh, "Requested index " + std::to_string( index ) + " is bigger than datasets count" );
return;
}
size_t i = static_cast<size_t>( index );

m->datasetGroups.erase( m->datasetGroups.begin() + static_cast<long>( i ) );
}

const char *MDAL_M_driverName( MDAL_MeshH mesh )
{
if ( !mesh )
Expand Down Expand Up @@ -847,6 +875,18 @@ const char *MDAL_G_name( MDAL_DatasetGroupH group )
return _return_str( g->name() );
}

void MDAL_G_setName( MDAL_DatasetGroupH group, const char *name )
{
if ( !group )
{
MDAL::Log::error( MDAL_Status::Err_IncompatibleDataset, "Dataset Group is not valid (null)" );
return;
}

MDAL::DatasetGroup *g = static_cast< MDAL::DatasetGroup * >( group );
g->setName( name );
}

bool MDAL_G_hasScalarData( MDAL_DatasetGroupH group )
{
if ( !group )
Expand Down
Loading