#include "StdAfx.h" #include "SphereGrowth.h" #include "DistanceTransform.h" using namespace std; /* SPHERE GROWTH */ //Vasa's version //constructor SphereGrowth::SphereGrowth(DS_1b_cube* ds_cube_ptr, CEdit *prog_text, CProgressCtrl *prog_bar) { distance_xfrm = NULL; sphere_map = NULL; output_prefix = NULL; cur_state = 0; FindUsefulTypeProperties<sg_xfrm_type> properties; inf_radius = properties.getInfinity()/2; //set pointers to used objects ds_cube = ds_cube_ptr; progress_txt = prog_text; progress_bar = prog_bar; //precompute all possible sqrts (cuts run time in half), they are used many many times progress_txt->SetWindowText("Precomputing square root table..."); sqrt_table_last_precomputed = SG_SQRT_TABLE_BYTES/sizeof(unsigned short); sqrt_table = new unsigned short [ sqrt_table_last_precomputed+1 ]; for (unsigned int i = 0; i <= sqrt_table_last_precomputed; i++) { sqrt_table[i] = (unsigned short) sqrt( (float)i ); } } SphereGrowth::~SphereGrowth() { if (sqrt_table) delete [] sqrt_table; if (distance_xfrm) delete distance_xfrm; if (sphere_map) delete sphere_map; } sg_status SphereGrowth::PrepareMemoryForRun() { // If needed, allocate memory for distance xfrm cube. If cube is valid from last run // no need to reallocate memory, since it will be same size if ( !(cur_state&SG_STATE_XFRM_DONE) ) { // Delete previous cube if it exists (likely 3 slice buffer if it does) if ( distance_xfrm ) { delete distance_xfrm; } // Allocate distance xfrm cube distance_xfrm = new DSt_cube<sg_xfrm_type>( ds_cube->wZ, ds_cube->wY, ds_cube->wX ); if (distance_xfrm == NULL) { // Error occured during memory allocation write_to_log("SphereGrowth::PrepareMemoryForRun - Error allocating 'distance_xfrm' cube of size (%d, %d, %d).", ds_cube->wX, ds_cube->wY, ds_cube->wZ); return SG_ERR_MEMORY_ALLOC; } } // Mark current cube as invalid... it is just a chunk of memory cur_state &= (~SG_STATE_XFRM_DONE); // If conserve memory option is NOT enabled, allocate memory right away. Otherwise, memory will be // allocated in GrowAllFromMinToMaxDiameter(), once distance xfrm cube is deleted to free up memory. if ( !(cur_setting & SG_CONSERVE_MEMORY) ) { sphere_map = new DSt_cube<sg_sphr_type>(ds_cube->wZ, ds_cube->wY, ds_cube->wX); if (sphere_map == NULL) { // Error occured during memory allocation write_to_log("SphereGrowth::PrepareMemoryForRun - Error allocating 'sphere_map' cube of size (%d, %d, %d).", ds_cube->wX, ds_cube->wY, ds_cube->wZ); return SG_ERR_MEMORY_ALLOC; } } return SG_NO_ERROR; } sg_status SphereGrowth::RunSphereGrowth(sg_options options, char *outfile_prefix, dist_xfrm_vals *dt_params/*=NULL*/) { sg_status status = SG_NO_ERROR; char file_str[MAX_FILE_STR_LEN]; // Log start of Sphere run write_to_log("SphereGrowth::RunSphereGrowth - Started sphere run (settings = %d).", options); // Update current settings and output prefix cur_setting = options; output_prefix = outfile_prefix; // Allocate memory for this run status = PrepareMemoryForRun(); if (status != SG_NO_ERROR) { // Error occured while allocating memory, see run log for details return status; } // If quick xfrm option is set, reset or update face/edge/corner values if ( cur_setting & SG_QUICK_DIST_XFRM ) { if ( dt_params ) { cur_FEC.face = dt_params->face; cur_FEC.edge = dt_params->edge; cur_FEC.corner = dt_params->corner; } else {// 3, 4, 5 by default cur_FEC.face = 3; cur_FEC.edge = 4; cur_FEC.corner = 5; } } // Generate diameter map (a.k.a distance xfrm) status = GetDiameterMap(); if ( status != SG_NO_ERROR ) { // An error occured during distance xfrm creation return SG_ERR_XFRM_CREATION; } // Save xfrm cube as gray scale image if ( cur_setting & SG_SAVE_DIST_GRAY) { progress_txt->SetWindowText("Saving gray scale diameter map..."); // Give appropriate description to output file if ( cur_setting & SG_QUICK_DIST_XFRM ) { sprintf(file_str, "%s_Diameter_Map_%d-%d-%d-Xfrm", output_prefix, (int)cur_FEC.face, \ (int)cur_FEC.edge, (int)cur_FEC.corner ); } else { sprintf(file_str, "%s_Diameter_Map_Grown", output_prefix); } if ( distance_xfrm->writeToFile(file_str, DST_UPDATE_FILE_NAME) != DST_NO_ERROR ) { // This is not a fatal error, simply log it status = SG_ERR_FILE_IO; write_to_log("SphereGrowth::RunSphereGrowth - Error outputting gray scale diameter map to %s.", file_str); } } // Save xfrm cube as RBG image if ( cur_setting & SG_SAVE_DIST_RGB) { progress_txt->SetWindowText("Saving RGB scale diameter map..."); // Give appropriate description to output file if ( cur_setting & SG_QUICK_DIST_XFRM ) { sprintf(file_str, "%s_Diameter_Map_%d-%d-%d-Xfrm", output_prefix, (int)cur_FEC.face, \ (int)cur_FEC.edge, (int)cur_FEC.corner ); } else { sprintf(file_str, "%s_Diameter_Map_Grown", output_prefix); } if ( distance_xfrm->writeToFileRGB(file_str, max_diameter, DST_UPDATE_FILE_NAME, progress_bar) != DST_NO_ERROR ) { // This is not a fatal error, simply log it status = SG_ERR_FILE_IO; write_to_log("SphereGrowth::RunSphereGrowth - Error outputting RBG scale diameter map to %s.", file_str); } } // Check if option to stop after Distance Xfrm is set if ( cur_setting & SG_STOP_AFTER_DISTANCE ) { write_to_log("SphereGrowth::RunSphereGrowth - Run was requested to stop after distance transform.", options); return status; } // Perform Sphere growth from minimum diamter to maximum diameter status = GrowAllFromMinToMaxDiameter(); if ( status != SG_NO_ERROR ) { // An error occured during distance xfrm creation write_to_log("SphereGrowth::RunSphereGrowth - There was an ERROR with sphere creation.", options); return SG_ERR_SPHERE_CREATION; } // Save xfrm cube as gray scale image if ( cur_setting & SG_SAVE_GROWN_GRAY ) { progress_txt->SetWindowText("Saving gray scale sphere map..."); // Give appropriate description to output file if ( cur_setting & SG_QUICK_DIST_XFRM ) { sprintf(file_str, "%s_Sphere_Map_%d-%d-%d-Xfrm" , output_prefix, (int)cur_FEC.face, \ (int)cur_FEC.edge, (int)cur_FEC.corner ); } else { sprintf(file_str, "%s_Sphere_Map_Grown", output_prefix); } if ( sphere_map->writeToFile(file_str, DST_UPDATE_FILE_NAME) != DST_NO_ERROR ) { // This is not a fatal error, simply log it status = SG_ERR_FILE_IO; write_to_log("SphereGrowth::RunSphereGrowth - Error outputting gray scale sphere map to %s.", file_str); } } // Save xfrm cube as RBG image if ( cur_setting & SG_SAVE_GROWN_RGB) { progress_txt->SetWindowText("Saving RGB scale sphere map..."); // Give appropriate description to output file if ( cur_setting & SG_QUICK_DIST_XFRM ) { sprintf(file_str, "%s_Sphere_Map_%d-%d-%d-Xfrm", output_prefix, (int)cur_FEC.face, \ (int)cur_FEC.edge, (int)cur_FEC.corner ); } else { sprintf(file_str, "%s_Sphere_Map_Grown", output_prefix); } if ( sphere_map->writeToFileRGB(file_str, max_diameter, DST_UPDATE_FILE_NAME, progress_bar) != DST_NO_ERROR ) { // This is not a fatal error, simply log it and set status status = SG_ERR_FILE_IO; write_to_log("SphereGrowth::RunSphereGrowth - Error outputting RBG scale sphere map to %s.", file_str); } } // Done, log and return status write_to_log("SphereGrowth::RunSphereGrowth - Done with full run.", options); return status; }