Mercurial > hg > minc-tools
changeset 2309:8e3050227a19
Add irregular dimension handling, nonspatial voxel-to-world transforms
author | bert <bert> |
---|---|
date | Mon, 04 Jul 2005 12:43:35 +0000 |
parents | 7db0db114a67 |
children | a438fa86baf0 |
files | volume_io/Volumes/input_mnc.c volume_io/Volumes/volumes.c |
diffstat | 2 files changed, 257 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/volume_io/Volumes/input_mnc.c +++ b/volume_io/Volumes/input_mnc.c @@ -16,7 +16,7 @@ #include <minc.h> #ifndef lint -static char rcsid[] = "$Header: /private-cvsroot/minc/volume_io/Volumes/input_mnc.c,v 1.65.2.1 2004-10-04 20:20:14 bert Exp $"; +static char rcsid[] = "$Header: /private-cvsroot/minc/volume_io/Volumes/input_mnc.c,v 1.65.2.2 2005-07-04 12:43:35 bert Exp $"; #endif #define INVALID_AXIS -1 @@ -131,6 +131,9 @@ int spatial_axis_indices[MAX_VAR_DIMS]; minc_input_options default_options; BOOLEAN no_volume_data_type; + char spacing_type[MI_MAX_ATTSTR_LEN+1]; + double *irr_starts[MAX_VAR_DIMS]; + double *irr_widths[MAX_VAR_DIMS]; ALLOC( file, 1 ); @@ -298,6 +301,9 @@ file_separations[d] = 1.0; start_position[d] = 0.0; + irr_starts[d] = NULL; + irr_widths[d] = NULL; + if( spatial_dim_flags[d] ) { dir_cosines[d][0] = 0.0; @@ -344,6 +350,43 @@ (void) strcpy( prev_space_type, space_type ); } } + else if (!strcmp(MItime, file->dim_names[d])) { + /* For the moment this is implemented for time dimensions + * only. + */ + miattgetstr(file->cdfid, dimvar, MIspacing, + MI_MAX_ATTSTR_LEN+1, spacing_type); + if (!strcmp(spacing_type, MI_IRREGULAR)) { + long start[1]; + long count[1]; + int i; + + irr_starts[d] = malloc(sizeof(Real) * file->sizes_in_file[d]); + irr_widths[d] = malloc(sizeof(Real) * file->sizes_in_file[d]); + + start[0] = 0; + count[0] = file->sizes_in_file[d]; + + mivarget(file->cdfid, dimvar, start, count, + NC_DOUBLE, MI_SIGNED, irr_starts[d]); + + dimvar = ncvarid(file->cdfid, MItime_width); + if (dimvar < 0) { + for (i = 0; i < count[0]; i++) { + irr_widths[d][i] = file_separations[d]; + } + } + else { + mivarget(file->cdfid, dimvar, start, count, + NC_DOUBLE, MI_SIGNED, irr_widths[d]); + } + } + else { + if( miattget1(file->cdfid, dimvar, MIstart, NC_DOUBLE, + (void *) (&start_position[d]) ) == MI_ERROR ) + start_position[d] = 0.0; + } + } } if( file->to_volume_index[d] == INVALID_AXIS ) @@ -362,6 +405,7 @@ set_volume_direction_unit_cosine( volume, file->to_volume_index[d], dir_cosines[d] ); } + } } @@ -410,6 +454,24 @@ set_volume_sizes( volume, sizes ); + for_less( d, 0, file->n_file_dimensions ) + { + if (file->to_volume_index[d] == INVALID_AXIS) { + continue; + } + + if (irr_starts[d] != NULL) { + set_volume_irregular_starts(volume, file->to_volume_index[d], + file->sizes_in_file[d], + irr_starts[d]); + } + if (irr_widths[d] != NULL) { + set_volume_irregular_widths(volume, file->to_volume_index[d], + file->sizes_in_file[d], + irr_widths[d]); + } + } + /* --- create the image conversion variable */ file->minc_icv = miicv_create();
--- a/volume_io/Volumes/volumes.c +++ b/volume_io/Volumes/volumes.c @@ -17,7 +17,7 @@ #include <float.h> #ifndef lint -static char rcsid[] = "$Header: /private-cvsroot/minc/volume_io/Volumes/volumes.c,v 1.72.2.1 2004-10-04 20:20:14 bert Exp $"; +static char rcsid[] = "$Header: /private-cvsroot/minc/volume_io/Volumes/volumes.c,v 1.72.2.2 2005-07-04 12:43:36 bert Exp $"; #endif STRING XYZ_dimension_names[] = { MIxspace, MIyspace, MIzspace }; @@ -187,6 +187,8 @@ volume->direction_cosines[i][X] = 0.0; volume->direction_cosines[i][Y] = 0.0; volume->direction_cosines[i][Z] = 0.0; + volume->irregular_starts[i] = NULL; + volume->irregular_widths[i] = NULL; sizes[i] = 0; @@ -2335,6 +2337,19 @@ set_volume_space_type( copy, volume->coordinate_system_name ); + for_less( c, 0, get_volume_n_dimensions(volume) ) + { + if (is_volume_dimension_irregular(volume, c)) { + Real *irr_starts = malloc(sizeof(Real) * sizes[c]); + Real *irr_widths = malloc(sizeof(Real) * sizes[c]); + get_volume_irregular_starts( volume, c, sizes[c], irr_starts); + set_volume_irregular_starts( volume, c, sizes[c], irr_starts); + + get_volume_irregular_widths( volume, c, sizes[c], irr_starts); + set_volume_irregular_widths( volume, c, sizes[c], irr_starts); + } + } + return( copy ); } @@ -2424,3 +2439,181 @@ return( copy ); } + +/* These are not public functions, so they are not VIOAPI yet */ +BOOLEAN +is_volume_dimension_irregular(Volume volume, int idim) +{ + if (idim > volume->array.n_dimensions) { + return (0); + } + return (volume->irregular_starts[idim] != NULL); +} + +int +get_volume_irregular_starts(Volume volume, int idim, int count, Real *starts) +{ + int i; + + if (idim >= volume->array.n_dimensions) { + return (0); + } + + if (volume->irregular_starts[idim] == NULL) { + return (0); + } + + if (count > volume->array.sizes[idim]) { + count = volume->array.sizes[idim]; + } + + for (i = 0; i < count; i++) { + starts[i] = volume->irregular_starts[idim][i]; + } + + return (count); +} + +int +get_volume_irregular_widths(Volume volume, int idim, int count, Real *widths) +{ + int i; + + if (idim >= volume->array.n_dimensions) { + return (0); + } + + if (volume->irregular_widths[idim] == NULL) { + return (0); + } + + if (count > volume->array.sizes[idim]) { + count = volume->array.sizes[idim]; + } + + for (i = 0; i < count; i++) { + widths[i] = volume->irregular_widths[idim][i]; + } + + return (count); +} + +int +set_volume_irregular_starts(Volume volume, int idim, int count, Real *starts) +{ + int i; + + if (idim >= volume->array.n_dimensions) { + return (0); + } + + if (volume->irregular_starts[idim] != NULL) { + free(volume->irregular_starts[idim]); + } + + if (starts == NULL) { + return (0); + } + + if (count > volume->array.sizes[idim]) { + count = volume->array.sizes[idim]; + } + + volume->irregular_starts[idim] = malloc(count * sizeof (Real)); + if (volume->irregular_starts[idim] == NULL) { + return (0); + } + + for (i = 0; i < count; i++) { + volume->irregular_starts[idim][i] = starts[i]; + } + + return (count); +} + +int +set_volume_irregular_widths(Volume volume, int idim, int count, Real *widths) +{ + int i; + + if (idim >= volume->array.n_dimensions) { + return (0); + } + + if (volume->irregular_widths[idim] != NULL) { + free(volume->irregular_widths[idim]); + } + + if (widths == NULL) { + return (0); + } + + if (count > volume->array.sizes[idim]) { + count = volume->array.sizes[idim]; + } + + volume->irregular_widths[idim] = malloc(count * sizeof (Real)); + if (volume->irregular_widths[idim] == NULL) { + return (0); + } + + for (i = 0; i < count; i++) { + volume->irregular_widths[idim][i] = widths[i]; + } + + return (count); +} + + +VIOAPI VIO_Real +nonspatial_voxel_to_world(Volume volume, int idim, int voxel) +{ + VIO_Real world; + + if (is_volume_dimension_irregular(volume, idim)) { + if (voxel < 0) { + world = 0.0; + } + else if (voxel >= volume->array.sizes[idim]) { + /* If we are asking for a position PAST the end of the axis, + * return the very last position on the axis, defined as the + * last start position plus the last width. + * NOTE! TODO: FIXME! We should take the axis alignment into + * account here. + */ + voxel = volume->array.sizes[idim] - 1; + + world = (volume->irregular_starts[idim][voxel] + + volume->irregular_widths[idim][voxel]); + } + else { + world = volume->irregular_starts[idim][voxel]; + } + } + else { + world = volume->starts[idim] + (voxel * volume->separations[idim]); + } + return (world); +} + +VIOAPI int +nonspatial_world_to_voxel(Volume volume, int idim, VIO_Real world) +{ + int voxel; + int i; + + if (is_volume_dimension_irregular(volume, idim)) { + voxel = volume->array.sizes[idim]; + for (i = 0; i < volume->array.sizes[idim]; i++) { + if (world < (volume->irregular_starts[idim][i] + + volume->irregular_widths[idim][i])) { + voxel = i; + break; + } + } + } + else { + voxel = ROUND((world - volume->starts[idim]) / volume->separations[idim]); + } + return (voxel); +}