int main(int argc, char *argv[]) { VIO_General_transform transform, *grid_transform_ptr, forward_transform; VIO_Volume target_vol, volume; volume_input_struct input_info; VIO_Real voxel[VIO_MAX_DIMENSIONS], steps[VIO_MAX_DIMENSIONS], start[VIO_N_DIMENSIONS], target_steps[VIO_MAX_DIMENSIONS], wx,wy,wz, inv_x, inv_y, inv_z, def_values[VIO_MAX_DIMENSIONS]; static int clobber_flag = FALSE, verbose = TRUE, debug = FALSE; static char *target_file; int parse_flag, prog_count, sizes[VIO_MAX_DIMENSIONS], target_sizes[VIO_MAX_DIMENSIONS], xyzv[VIO_MAX_DIMENSIONS], target_xyzv[VIO_MAX_DIMENSIONS], index[VIO_MAX_DIMENSIONS], i, trans_count; VIO_progress_struct progress; static ArgvInfo argTable[] = { {"-like", ARGV_STRING, (char *) 0, (char *) &target_file, "Specify target volume sampling information."}, {"-no_clobber", ARGV_CONSTANT, (char *) FALSE, (char *) &clobber_flag, "Do not overwrite output file (default)."}, {"-clobber", ARGV_CONSTANT, (char *) TRUE, (char *) &clobber_flag, "Overwrite output file."}, {"-verbose", ARGV_CONSTANT, (char *) TRUE, (char *) &verbose, "Write messages indicating progress (default)"}, {"-quiet", ARGV_CONSTANT, (char *) FALSE, (char *) &verbose, "Do not write log messages"}, {"-debug", ARGV_CONSTANT, (char *) TRUE, (char *) &debug, "Print out debug info."}, {NULL, ARGV_END, NULL, NULL, NULL} }; prog_name = argv[0]; target_file = malloc(1024); strcpy(target_file,""); /* Call ParseArgv to interpret all command line args (returns TRUE if error) */ parse_flag = ParseArgv(&argc, argv, argTable, 0); /* Check remaining arguments */ if (parse_flag || argc != 3) print_usage_and_exit(prog_name); /* Read in file that has a def field to invert */ if (input_transform_file(argv[1], &transform) != OK) { (void) fprintf(stderr, "%s: Error reading transform file %s\n", argv[0], argv[1]); exit(EXIT_FAILURE); } for(trans_count=0; trans_count<get_n_concated_transforms(&transform); trans_count++ ) { grid_transform_ptr = get_nth_general_transform(&transform, trans_count ); if (grid_transform_ptr->type == GRID_TRANSFORM) { copy_general_transform(grid_transform_ptr, &forward_transform); /* this is the call that should be made with the latest version of internal_libvolume_io invert_general_transform(&forward_transform); */ forward_transform.inverse_flag = !(forward_transform.inverse_flag); volume = grid_transform_ptr->displacement_volume; if (strlen(target_file)!=0) { if (debug) print ("Def field will be resampled like %s\n",target_file); if (!file_exists( target_file ) ) { (void) fprintf(stderr, "%s: Target file '%s' does not exist\n", prog_name,target_file); exit(EXIT_FAILURE); } start_volume_input(target_file, 3, (char **)NULL, NC_UNSPECIFIED, FALSE, 0.0, 0.0, TRUE, &target_vol, (minc_input_options *)NULL, &input_info); get_volume_XYZV_indices(volume, xyzv); get_volume_separations (volume, steps); get_volume_sizes (volume, sizes); get_volume_XYZV_indices(target_vol, target_xyzv); get_volume_separations (target_vol, target_steps); get_volume_sizes (target_vol, target_sizes); for(i=0; i<VIO_MAX_DIMENSIONS; i++) { index[i] = 0; voxel[i] = 0.0; } convert_voxel_to_world(target_vol, voxel, &start[VIO_X], &start[VIO_Y], &start[VIO_Z]); if( volume != (void *) NULL ){ free_volume_data( volume ); } for(i=VIO_X; i<=VIO_Z; i++) { steps[ xyzv[i] ] = target_steps[ target_xyzv[i] ] ; sizes[ xyzv[i] ] = target_sizes[ target_xyzv[i] ] ; } set_volume_separations(volume, steps); set_volume_sizes( volume, sizes); set_volume_starts(volume, start); alloc_volume_data( volume ); } get_volume_sizes(volume, sizes); get_volume_XYZV_indices(volume,xyzv); for(i=0; i<VIO_MAX_DIMENSIONS; i++){ index[i] = 0; } if (verbose){ initialize_progress_report(&progress, FALSE, sizes[xyzv[VIO_X]]*sizes[xyzv[VIO_Y]]*sizes[xyzv[VIO_Z]]+1, "Inverting def field"); } prog_count = 0; for(index[xyzv[VIO_X]]=0; index[xyzv[VIO_X]]<sizes[xyzv[VIO_X]]; index[xyzv[VIO_X]]++) for(index[xyzv[VIO_Y]]=0; index[xyzv[VIO_Y]]<sizes[xyzv[VIO_Y]]; index[xyzv[VIO_Y]]++) for(index[xyzv[VIO_Z]]=0; index[xyzv[VIO_Z]]<sizes[xyzv[VIO_Z]]; index[xyzv[VIO_Z]]++) { index[ xyzv[VIO_Z+1] ] = 0; for(i=0; i<VIO_MAX_DIMENSIONS; i++) voxel[i] = (VIO_Real)index[i]; convert_voxel_to_world(volume, voxel, &wx, &wy, &wz); if (sizes[ xyzv[VIO_Z] ] ==1) general_inverse_transform_point_in_trans_plane(&forward_transform, wx, wy, wz, &inv_x, &inv_y, &inv_z); else grid_inverse_transform_point(&forward_transform, wx, wy, wz, &inv_x, &inv_y, &inv_z); def_values[VIO_X] = inv_x - wx; def_values[VIO_Y] = inv_y - wy; def_values[VIO_Z] = inv_z - wz; for(index[xyzv[VIO_Z+1]]=0; index[xyzv[VIO_Z+1]]<3; index[xyzv[VIO_Z+1]]++) set_volume_real_value(volume, index[0],index[1],index[2],index[3],index[4], def_values[ index[ xyzv[VIO_Z+1] ]]); prog_count++; if (verbose) update_progress_report(&progress, prog_count); } if (verbose) terminate_progress_report(&progress); delete_general_transform(&forward_transform); grid_transform_ptr->inverse_flag = !(grid_transform_ptr->inverse_flag); } } /* Write out the transform */ if (output_transform_file(argv[2], NULL, &transform) != OK) { (void) fprintf(stderr, "%s: Error writing transform file %s\n", argv[0], argv[2]); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
static void transform_or_inverse_point_in_trans_plane(VIO_General_transform *transform, VIO_BOOL inverse_flag, VIO_Real x, VIO_Real y, VIO_Real z, VIO_Real *x_transformed, VIO_Real *y_transformed, VIO_Real *z_transformed) { int trans; switch( transform->type ) { case LINEAR: if( inverse_flag ) transform_point( transform->inverse_linear_transform, x, y, z, x_transformed, y_transformed, z_transformed ); else transform_point( transform->linear_transform, x, y, z, x_transformed, y_transformed, z_transformed ); break; case THIN_PLATE_SPLINE: if( inverse_flag ) { thin_plate_spline_inverse_transform( transform->n_dimensions, transform->n_points, transform->points, transform->displacements, x, y, z, x_transformed, y_transformed, z_transformed ); } else { thin_plate_spline_transform( transform->n_dimensions, transform->n_points, transform->points, transform->displacements, x, y, z, x_transformed, y_transformed, z_transformed ); } break; case GRID_TRANSFORM: if( inverse_flag ) { grid_inverse_transform_point_in_trans_plane( transform, x, y, z, x_transformed, y_transformed, z_transformed ); } else { grid_transform_point_in_trans_plane( transform, x, y, z, x_transformed, y_transformed, z_transformed ); } break; case USER_TRANSFORM: if( inverse_flag ) { transform->user_inverse_transform_function( transform->user_data, x, y, z, x_transformed, y_transformed, z_transformed ); } else { transform->user_transform_function( transform->user_data, x, y, z, x_transformed, y_transformed, z_transformed ); } break; case CONCATENATED_TRANSFORM: *x_transformed = x; *y_transformed = y; *z_transformed = z; if( transform->inverse_flag ) inverse_flag = !inverse_flag; if( inverse_flag ) { for( trans = transform->n_transforms-1; trans >= 0; --trans ) { general_inverse_transform_point_in_trans_plane(&transform->transforms[trans], *x_transformed, *y_transformed, *z_transformed, x_transformed, y_transformed, z_transformed ); } } else { for(trans=0; trans<transform->n_transforms; trans++) { general_transform_point_in_trans_plane( &transform->transforms[trans], *x_transformed, *y_transformed, *z_transformed, x_transformed, y_transformed, z_transformed ); } } break; default: handle_internal_error( "transform_or_invert_point" ); break; } }