From 8cee40b22a49af0677de4eb063fccdeb309bc5bd Mon Sep 17 00:00:00 2001 From: Achim Gsell Date: Fri, 22 Feb 2008 13:45:25 +0000 Subject: [PATCH] reading of vertices and tets added --- src/h5/t_readwrite.c | 520 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 429 insertions(+), 91 deletions(-) diff --git a/src/h5/t_readwrite.c b/src/h5/t_readwrite.c index fa4e6f0..6df1ec5 100644 --- a/src/h5/t_readwrite.c +++ b/src/h5/t_readwrite.c @@ -152,7 +152,7 @@ _write_vertices ( struct h5t_fdata *t = &f->t; h5_err_t h5err; - if ( t->num_vertices <= 0 ) return H5_SUCCESS; + if ( t->num_vertices <= 0 ) return H5_SUCCESS; /* ???? */ if ( t->coord_gid < 0 ) { h5err = _open_coord_group ( f ); @@ -245,6 +245,7 @@ _write_data ( h5_err_t h5err; if ( t->num_levels <= 0 ) return 0; + if ( t->new_mesh < 0 ) return 0; if ( t->topo_gid < 0 ) { h5err = _open_topo_group ( f ); @@ -320,22 +321,6 @@ _h5t_close_step ( return H5_SUCCESS; } -h5_err_t -_h5t_create_mesh ( - h5_file *f /*!< file handle */ - ) { - - struct h5t_fdata *t = &f->t; - h5_err_t h5err = H5_SUCCESS; - - h5err = _open_mesh_group ( f ); - if ( h5err < 0 ) return h5err; - - t->num_levels = 0; - - return h5err; -} - h5_err_t _h5t_close_mesh ( h5_file *f /*!< file handle */ @@ -361,65 +346,106 @@ h5_size_t H5t_get_num_meshes ( h5_file * f ) { - return -1; -} - -h5_err_t -H5t_set_mesh ( - h5_file * f, - const h5_id_t id - ) { - return -1; -} - -h5_id_t -H5t_add_mesh ( - h5_file * f - ) { - struct h5t_fdata *t = &f->t; - h5_err_t h5err = H5_SUCCESS; - - /* - - close current mesh - - count number of objects in /TOPO - this is the number of stored - meshes. - - create new group - */ - h5err = _h5t_close_mesh ( f ); - if ( h5err < 0 ) return h5err; - - h5err = _open_topo_group ( f ); - if ( h5err < 0 ) return h5err; - - t->cur_mesh = (h5_id_t)H5_get_num_objects ( + return (h5_size_t)H5_get_num_objects ( f->root_gid, H5T_CONTAINER_GRPNAME, H5G_GROUP ); - if ( t->cur_mesh < 0 ) return t->cur_mesh; - if ( t->new_mesh < 0 ) - t->new_mesh = t->cur_mesh; - - snprintf ( t->mesh_name, sizeof ( t->mesh_name ), "Mesh#%d", t->cur_mesh ); - - h5err = _h5t_create_mesh ( f ); - if ( h5err < 0 ) return h5err; - - return t->cur_mesh; } +/* + If the value of parameter \c id is \c -1, a new mesh will be appended. + After calling this function, the number of levels is stored in the + file structure. +*/ +h5_err_t +H5t_open_mesh ( + h5_file * f, + h5_id_t id + ) { + struct h5t_fdata *t = &f->t; + + h5_err_t h5err = _h5t_close_mesh ( f ); + if ( h5err < 0 ) return h5err; + + if ( t->num_meshes < 0 ) { + h5_size_t result = H5t_get_num_meshes ( f ); + t->num_meshes = ( result > 0 ? result : 0 ); + } + if ( (id < -1) || (id >= t->num_meshes) ) { + return HANDLE_H5_OUT_OF_RANGE_ERR( "mesh", id ); + } + if ( id == -1 ) { /* append new mesh */ + id = t->num_meshes; + } + snprintf ( t->mesh_name, sizeof (t->mesh_name), "Mesh#%d", id ); + + h5err = _open_mesh_group ( f ); + if ( h5err < 0 ) return h5err; + + t->cur_mesh = id; + + if ( id != t->num_meshes ) { /* open existing */ + t->num_levels = H5t_get_num_levels ( f ); + if ( t->num_levels < 0 ) return t->num_levels; + } else { /* append new */ + t->num_meshes++; + if ( t->new_mesh < 0 ) + t->new_mesh = id; + t->num_levels = 0; + } + + return H5_SUCCESS; +} + +/* + Number of levels: Number of elements in dataset H5T_COORD3D_NUM_ELEMS_DSNAME + */ h5_size_t H5t_get_num_levels ( h5_file * f ) { - return -1; + struct h5t_fdata *t = &f->t; + h5_err_t h5err; + + if ( t->num_levels >= 0 ) return t->num_levels; + if ( t->cur_mesh < 0 ) { + return HANDLE_H5_UNDEF_MESH_ERR; + } + if ( t->coord_gid < 0 ) { + h5err = _open_coord_group ( f ); + if ( h5err < 0 ) return h5err; + } + hid_t dset_id = H5Dopen ( t->coord_gid, H5T_COORD3D_NUM_ELEMS_DSNAME ); + if ( dset_id < 0 ) + return HANDLE_H5D_OPEN_ERR ( H5T_COORD3D_NUM_ELEMS_DSNAME ); + hid_t space_id = H5Dget_space( dset_id ); + if ( space_id < 0 ) + return HANDLE_H5D_GET_SPACE_ERR; + hssize_t size = H5Sget_simple_extent_npoints ( space_id ); + if ( size < 0 ) + return HANDLE_H5S_GET_SIMPLE_EXTENT_NPOINTS_ERR; + + herr_t herr = H5Sclose ( space_id ); + if ( herr < 0 ) + return HANDLE_H5S_CLOSE_ERR; + t->num_levels = size; + return size; } h5_err_t -H5t_set_level ( +H5t_open_level ( h5_file * f, const h5_id_t id ) { - return -1; + struct h5t_fdata *t = &f->t; + + if ( (id < 0) || (id >= t->num_levels) ) + return HANDLE_H5_OUT_OF_RANGE_ERR ( "Level", id ); + t->cur_level = id; + t->last_retrieved_vertex_id = -1; + t->last_retrieved_tet_id = -1; + + return H5_SUCCESS; } h5_id_t @@ -469,11 +495,10 @@ H5t_add_num_vertices ( } ssize_t num_elems = (t->cur_level > 0 ? t->num_vertices[t->cur_level-1] + num : num); - t->num_vertices[t->cur_level] = num_elems; - t->vertices = realloc ( - t->vertices, num_elems*sizeof ( t->vertices[0] ) ); - + ssize_t num_bytes = num_elems*sizeof ( t->vertices[0] ); + H5_debug ( "Allocating %ld bytes.", num_bytes ); + t->vertices = realloc ( t->vertices, num_bytes ); if ( t->vertices == NULL ) { return HANDLE_H5_NOMEM_ERR; } @@ -481,6 +506,108 @@ H5t_add_num_vertices ( return num; } +/* + read everything with this function !? +*/ +static h5_err_t +_read_dataset ( + h5_file * f, + hid_t group_id, + const char dataset_name[], + hid_t type_id, + hid_t (*open_mem_space)(h5_file*,hid_t), + hid_t (*open_file_space)(h5_file*,hid_t), + void * const data ) { + + hid_t dataset_id = H5Dopen ( group_id, dataset_name ); + if ( dataset_id < 0 ) return HANDLE_H5D_OPEN_ERR ( dataset_name ); + + hid_t mem_space_id = (*open_mem_space)( f, dataset_id ); + if ( mem_space_id < 0 ) return mem_space_id; + hid_t file_space_id = (*open_file_space)( f, dataset_id ); + if ( file_space_id < 0 ) return file_space_id; + + herr_t herr = H5Dread ( + dataset_id, + type_id, + mem_space_id, + file_space_id, + f->xfer_prop, + data ); + if ( herr < 0 ) + return HANDLE_H5D_READ_ERR ( H5_get_objname ( dataset_id ) ); + + if ( file_space_id != H5S_ALL ) { + herr = H5Sclose ( file_space_id ); + if ( herr < 0 ) return HANDLE_H5S_CLOSE_ERR; + } + + if ( mem_space_id != H5S_ALL ) + herr = H5Sclose ( mem_space_id ); + if ( herr < 0 ) return HANDLE_H5S_CLOSE_ERR; + + herr = H5Dclose ( dataset_id ); + if ( herr < 0 ) return HANDLE_H5D_CLOSE_ERR; + + return H5_SUCCESS; +} + +static hid_t +_open_mem_space_vertices ( + h5_file * f, + hid_t dataset_id + ) { + return H5S_ALL; +} + +static hid_t +_open_file_space_vertices ( + h5_file * f, + hid_t dataset_id + ) { + return H5S_ALL; +} + +static hid_t +_open_space_all ( + h5_file * f, + hid_t dataset_id + ) { + return H5S_ALL; +} + +static h5_err_t +_read_num_vertices ( + h5_file * f + ) { + h5_err_t h5err; + struct h5t_fdata *t = &f->t; + + if ( t->cur_level < 0 ) + return HANDLE_H5_UNDEF_LEVEL_ERR; + + if ( t->coord_gid < 0 ) { + h5err = _open_coord_group ( f ); + if ( h5err < 0 ) return h5err; + } + ssize_t num_bytes = t->num_levels*sizeof ( t->num_vertices[0] ); + H5_debug ( "Allocating %ld bytes.", num_bytes ); + t->num_vertices = realloc ( t->num_vertices, num_bytes ); + if ( t->num_vertices == NULL ) + return HANDLE_H5_NOMEM_ERR; + h5err = _read_dataset ( + f, + t->coord_gid, + H5T_COORD3D_NUM_ELEMS_DSNAME, + H5T_NATIVE_INT32, + _open_space_all, + _open_space_all, + t->num_vertices ); + if ( h5err < 0 ) return h5err; + + return H5_SUCCESS; +} + static h5_err_t _read_vertices ( h5_file * f @@ -488,18 +615,35 @@ _read_vertices ( h5_err_t h5err; struct h5t_fdata *t = &f->t; - if ( t->topo_gid < 0 ) { - h5err = _open_topo_group ( f ); - if ( h5err < 0 ) return h5err; - } + if ( t->cur_level < 0 ) + return HANDLE_H5_UNDEF_LEVEL_ERR; + if ( t->coord_gid < 0 ) { h5err = _open_coord_group ( f ); if ( h5err < 0 ) return h5err; } - /* - get number of levels - */ + if ( t->num_vertices == NULL ) { + h5err = _read_num_vertices ( f ); + if ( h5err < 0 ) return h5err; + } + + ssize_t num_elems = t->num_vertices[t->num_levels-1]; + ssize_t num_bytes = num_elems*sizeof ( t->vertices[0] ); + H5_debug ( "Allocating %ld bytes.", num_bytes ); + t->vertices = realloc ( t->vertices, num_bytes ); + if ( t->vertices == NULL ) + return HANDLE_H5_NOMEM_ERR; + h5err = _read_dataset ( + f, + t->coord_gid, + H5T_COORD3D_DSNAME, + t->vertex_tid, + _open_mem_space_vertices, + _open_file_space_vertices, + t->vertices ); + if ( h5err < 0 ) return h5err; + return H5_SUCCESS; } @@ -515,8 +659,8 @@ H5t_get_num_vertices ( if ( t->cur_level < 0 ) { return HANDLE_H5_UNDEF_LEVEL_ERR; } - if ( t->vertices == NULL ) { - h5_err_t h5err = _read_vertices ( f ); + if ( t->num_vertices == NULL ) { + h5_err_t h5err = _read_num_vertices ( f ); if ( h5err < 0 ) return h5err; } return t->num_vertices[t->cur_level]; @@ -530,11 +674,31 @@ H5t_store_vertex ( ) { struct h5t_fdata *t = &f->t; - if ( t->cur_level < 0 ) - return H5_ERR_INVAL; + /* + more than allocated + */ + if ( t->last_stored_vertex_id+1 >= t->num_vertices[t->cur_level] ) + return HANDLE_H5_OVERFLOW_ERR( "vertex", + t->num_vertices[t->cur_level] ); - if ( t->last_stored_vertex_id+1 >= t->num_vertices[t->cur_level] ) - return H5_ERR_INVAL; + /* + missing call to add the first level + */ + if ( t->cur_level < 0 ) + return HANDLE_H5_UNDEF_LEVEL_ERR; + + /* + check id + */ + if ( (t->cur_level == 0) && ( + (id < 0) || (id >= t->num_vertices[0]) ) ) { + return HANDLE_H5_OUT_OF_RANGE_ERR( "vertex", id ); + } + if ( (t->cur_level > 0) && ( + (id < t->num_vertices[t->cur_level-1]) || + (id >= t->num_vertices[t->cur_level]) ) ) { + return HANDLE_H5_OUT_OF_RANGE_ERR( "vertex", id ); + } h5_vertex *vertex = &t->vertices[++t->last_stored_vertex_id]; vertex->id = id; @@ -555,10 +719,24 @@ H5t_get_vertex_ids ( h5_id_t H5t_get_vertex ( h5_file * f, /*!< file handle */ - h5_id_t * const id, /*!< global vertex id or -1 */ - h5_float64_t * const P[3] /*!< coordinates */ + h5_id_t * const id, /*!< global vertex */ + h5_float64_t P[3] /*!< coordinates */ ) { - return -1; + struct h5t_fdata *t = &f->t; + + if ( t->vertices == NULL ) { + h5_err_t h5err = _read_vertices ( f ); + if ( h5err < 0 ) return h5err; + } + if ( t->last_retrieved_vertex_id+1 >= t->num_vertices[t->cur_level] ) { + H5_warn ( "Trying to read more tets than available!" ); + return -1; + } + h5_vertex *vertex = &t->vertices[++t->last_retrieved_vertex_id]; + *id = vertex->id; + memcpy ( P, &vertex->P, sizeof ( vertex->P ) ); + + return t->last_retrieved_vertex_id; } h5_size_t @@ -576,7 +754,7 @@ H5t_add_num_tets ( num + t->num_tets_on_level[t->cur_level-1] : num; ssize_t num_bytes = num_tets*sizeof ( t->tets[0] ); - H5_debug ( "Allocating %d bytes.", num_bytes ); + H5_debug ( "Allocating %ld bytes.", num_bytes ); t->tets = realloc ( t->tets, num_bytes ); if ( t->tets == NULL ) { return H5_ERR_NOMEM; @@ -589,12 +767,6 @@ H5t_add_num_tets ( return num; } -h5_size_t -H5t_get_num_tets ( - h5_file * f - ) { - return -1; -} h5_id_t H5t_store_tet ( @@ -663,13 +835,179 @@ H5t_store_tet ( return t->last_stored_vertex_id; } +static h5_err_t +_read_num_tets ( + h5_file * f + ) { + + + h5_err_t h5err; + struct h5t_fdata *t = &f->t; + + if ( t->cur_level < 0 ) + return HANDLE_H5_UNDEF_LEVEL_ERR; + + if ( t->vmesh_gid < 0 ) { + h5err = _open_vmesh_group ( f ); + if ( h5err < 0 ) return h5err; + } + ssize_t num_bytes = t->num_levels*sizeof ( t->num_tets[0] ); + H5_debug ( "Allocating %ld bytes.", num_bytes ); + t->num_tets = realloc ( t->num_tets, num_bytes ); + if ( t->num_tets == NULL ) + return HANDLE_H5_NOMEM_ERR; + h5err = _read_dataset ( + f, + t->vmesh_gid, + H5T_TETMESH_NUM_ELEMS_DSNAME, + H5T_NATIVE_INT32, + _open_space_all, + _open_space_all, + t->num_tets ); + if ( h5err < 0 ) return h5err; + + return H5_SUCCESS; +} + +static h5_err_t +_read_num_tets_on_level ( + h5_file * f + ) { + + h5_err_t h5err; + struct h5t_fdata *t = &f->t; + + if ( t->cur_level < 0 ) + return HANDLE_H5_UNDEF_LEVEL_ERR; + + if ( t->vmesh_gid < 0 ) { + h5err = _open_vmesh_group ( f ); + if ( h5err < 0 ) return h5err; + } + ssize_t num_bytes = t->num_levels*sizeof ( t->num_tets_on_level[0] ); + H5_debug ( "Allocating %ld bytes.", num_bytes ); + t->num_tets_on_level = realloc ( t->num_tets_on_level, num_bytes ); + if ( t->num_tets_on_level == NULL ) + return HANDLE_H5_NOMEM_ERR; + h5err = _read_dataset ( + f, + t->vmesh_gid, + H5T_TETMESH_NUM_ELEMS_ON_LEVEL_DSNAME, + H5T_NATIVE_INT32, + _open_space_all, + _open_space_all, + t->num_tets_on_level ); + if ( h5err < 0 ) return h5err; + + return H5_SUCCESS; +} + +static hid_t +_open_mem_space_tets ( + h5_file * f, + hid_t dataset_id + ) { + return H5S_ALL; +} + +static hid_t +_open_file_space_tets ( + h5_file * f, + hid_t dataset_id + ) { + return H5S_ALL; +} + +static h5_err_t +_read_tets ( + h5_file * f + ) { + h5_err_t h5err; + struct h5t_fdata *t = &f->t; + + if ( t->cur_level < 0 ) + return HANDLE_H5_UNDEF_LEVEL_ERR; + + if ( t->vmesh_gid < 0 ) { + h5err = _open_vmesh_group ( f ); + if ( h5err < 0 ) return h5err; + } + + if ( t->num_tets == NULL ) { + h5err = _read_num_tets ( f ); + if ( h5err < 0 ) return h5err; + } + + ssize_t num_elems = t->num_tets[t->num_levels-1]; + ssize_t num_bytes = num_elems*sizeof ( t->tets[0] ); + H5_debug ( "Allocating %ld bytes.", num_bytes ); + t->tets = realloc ( t->tets, num_bytes ); + if ( t->tets == NULL ) + return HANDLE_H5_NOMEM_ERR; + h5err = _read_dataset ( + f, + t->vmesh_gid, + H5T_TETMESH_DSNAME, + t->tet_tid, + _open_mem_space_tets, + _open_file_space_tets, + t->tets ); + if ( h5err < 0 ) return h5err; + + return H5_SUCCESS; +} + +h5_size_t +H5t_get_num_tets ( + h5_file * f + ) { + struct h5t_fdata *t = &f->t; + + if ( t->cur_mesh < 0 ) { + return HANDLE_H5_UNDEF_MESH_ERR; + } + if ( t->cur_level < 0 ) { + return HANDLE_H5_UNDEF_LEVEL_ERR; + } + if ( t->num_tets_on_level == NULL ) { + h5_err_t h5err = _read_num_tets_on_level ( f ); + if ( h5err < 0 ) return h5err; + } + return t->num_tets_on_level[t->cur_level]; +} + h5_id_t H5t_get_tet ( h5_file * f, - h5_id_t * const tet_id, /*!< global tetrahedron id */ + h5_id_t * const id, /*!< global tetrahedron id */ h5_id_t * const parent_id, /*!< global parent id if level \c >0 else \c -1 */ - h5_id_t * const vertex_ids[4] /*!< tuple with vertex id's */ + h5_id_t ids[4] /*!< tuple with vertex id's */ ) { - return -1; + struct h5t_fdata *t = &f->t; + + if ( t->tets == NULL ) { + h5_err_t h5err = _read_tets ( f ); + if ( h5err < 0 ) return h5err; + } + if ( t->last_retrieved_tet_id+1 >= t->num_tets[t->cur_level] ) { + H5_warn ( "Trying to read more tets than available!" ); + return -1; + } + h5_tetrahedron *tet = &t->tets[++t->last_retrieved_tet_id]; + + while ( (tet->refined_on_level != -1) && + (tet->refined_on_level <= t->cur_level) ){ + tet++; + t->last_retrieved_tet_id++; + if ( t->last_retrieved_tet_id >= t->num_tets[t->cur_level] ) { + return HANDLE_H5_INTERNAL_ERR; + } + } + + *id = tet->id; + *parent_id = tet->parent_id; + memcpy ( ids, &tet->vertex_ids, sizeof ( tet->vertex_ids ) ); + + return t->last_retrieved_tet_id; }