#include "StdAfx.h" #include "MA_Voxel_Coding.h" // ---------------------------------------------------------------------------------------- // // Description - // ---------------------------------------------------------------------------------------- void MA_VoxelCoding::writeToFileBS( char *output_prefix, ma_options save_options ) { char output_file[MAX_FILE_STR_LEN]; // Check if it needs to be saved or not if ( save_options & MA_SAVE_BS_GRAY ) { sprintf(output_file, "%s_BS_xfrm", output_prefix); progress_win_ptr->SetWindowText("Saving BS xfrm (Gray)..."); BS_cube->writeToFile( output_file, DST_UPDATE_FILE_NAME ); write_to_log("MA_VoxelCoding::writeToFileBS - Saving BS cube to %s.", output_file); } if ( save_options & MA_SAVE_BS_RGB ) { sprintf(output_file, "%s_BS_xfrm", output_prefix); progress_win_ptr->SetWindowText("Saving BS xfrm (RGB)..."); BS_cube->writeToFileRGB( output_file, 0, DST_UPDATE_FILE_NAME, progress_bar_ptr ); write_to_log("MA_VoxelCoding::writeToFileBS - Saving BS cube to %s.", output_file); } } // ---------------------------------------------------------------------------------------- // // Description - // ---------------------------------------------------------------------------------------- void MA_VoxelCoding::writeToFileSS( char *output_prefix, ma_options save_options ) { char output_file[MAX_FILE_STR_LEN]; // Check if SS cube needs to be saved or not if ( save_options & MA_SAVE_SS_GRAY ) { sprintf(output_file, "%s_SS_xfrm", output_prefix); progress_win_ptr->SetWindowText("Saving SS xfrm (Gray)..."); SS_cube->writeToFile( output_file, DST_UPDATE_FILE_NAME ); write_to_log("MA_VoxelCoding::writeToFileSS - Saved SS cube (GRAY) to %s.", output_file); } if ( save_options & MA_SAVE_SS_RGB ) { sprintf(output_file, "%s_SS_xfrm", output_prefix); progress_win_ptr->SetWindowText("Saving SS xfrm (RGB)..."); SS_cube->writeToFileRGB( output_file, 0, DST_UPDATE_FILE_NAME, progress_bar_ptr ); write_to_log("MA_VoxelCoding::writeToFileSS - Saved SS cube (RGB) to %s.", output_file); } } // ---------------------------------------------------------------------------------------- // // Description - // ---------------------------------------------------------------------------------------- void MA_VoxelCoding::writeToFileCL( char *output_prefix, ma_options save_options ) { char output_file[MAX_FILE_STR_LEN]; // Check if SS cube needs to be saved or not if ( save_options & MA_SAVE_CL_GRAY ) { sprintf(output_file, "%s_CL_cube", output_prefix); progress_win_ptr->SetWindowText("Saving CL cube (Gray)..."); CL_cube->writeToFile( output_file, DST_UPDATE_FILE_NAME ); write_to_log("MA_VoxelCoding::writeToFileCL - Saved CL cube (GRAY) to %s.", output_file); } if ( save_options & MA_SAVE_CL_RGB ) { sprintf(output_file, "%s_CL_cube", output_prefix); progress_win_ptr->SetWindowText("Saving CL cube (RGB)..."); CL_cube->writeToFileRGB( output_file, 0, DST_UPDATE_FILE_NAME, progress_bar_ptr ); write_to_log("MA_VoxelCoding::writeToFileCL - Saved CL cube (RGB) to %s.", output_file); } // Special request to mark all special clusters and all maximum points if ( save_options & MA_SAVE_CL_MARKED ) { // Values used in marking the 8-bit cube enum { pore = 0, mark_local_max = 100, mark_dividing = 110, mark_dividing_and_merging = 120, mark_merging = 130, mark_rp = 140, mark_clust_bs_max = 150, fiber = 0xFF }; progress_win_ptr->SetWindowText("Preparing CL mark cube..."); // First save current cluster to disc in temporary file, and allocate // a temporary 8 bit cube. char temp_file[MAX_FILE_STR_LEN]; sprintf(temp_file, "%s_CL____temp____", output_prefix); CL_cube->writeToFile( output_file, DST_UPDATE_FILE_NAME ); delete CL_cube; out_marked_cube = new DSt_cube<unsigned char>(boundary_cube->wZ, boundary_cube->wY, boundary_cube->wX); // Now initialize the cube to match input Vect3usi cur_coord; FOR_wZwYwX_LOOP(boundary_cube, cur_coord.z, cur_coord.y, cur_coord.x) { if ( boundary_cube->get_spot(cur_coord) ) { out_marked_cube->datac(cur_coord, fiber); } else { out_marked_cube->datac(cur_coord, pore); } } // Go through all cluster nodes, and mark appropriately LinkedListNode<Vect3usi> *cur_list_node_ptr; for ( cl_t i = 0; i < number_of_clusters; i++ ) { if ( cluster_nodes_array[i].cluster_type == (CLUSTER_TYPE_MERGING | CLUSTER_TYPE_DIVIDING) ) { // Cluster is merging and dividing type current_mark_value = mark_dividing_and_merging; recurseOnAllNeighbors( cluster_nodes_array[i].max_coord_list_ptr->getHeadPtr()->item, &MA_VoxelCoding::markSingleClusterInMarkCube ); } else if ( cluster_nodes_array[i].cluster_type == CLUSTER_TYPE_DIVIDING ) { // Cluster is dividing type current_mark_value = mark_dividing; recurseOnAllNeighbors( cluster_nodes_array[i].max_coord_list_ptr->getHeadPtr()->item, &MA_VoxelCoding::markSingleClusterInMarkCube ); } else if ( cluster_nodes_array[i].cluster_type == CLUSTER_TYPE_MERGING ) { // Cluster is merging type current_mark_value = mark_merging; recurseOnAllNeighbors( cluster_nodes_array[i].max_coord_list_ptr->getHeadPtr()->item, &MA_VoxelCoding::markSingleClusterInMarkCube ); } else if ( cluster_nodes_array[i].cluster_type == CLUSTER_TYPE_LOCAL_MAX ) { // Cluster is local maximum type current_mark_value = mark_local_max; recurseOnAllNeighbors( cluster_nodes_array[i].max_coord_list_ptr->getHeadPtr()->item, &MA_VoxelCoding::markSingleClusterInMarkCube ); // Skip marking max points, since it might only be a single coordinate continue; } else if ( cluster_nodes_array[i].cluster_type == CLUSTER_TYPE_RP ) { // Cluster is rp type current_mark_value = mark_rp; recurseOnAllNeighbors( cluster_nodes_array[i].max_coord_list_ptr->getHeadPtr()->item, &MA_VoxelCoding::markSingleClusterInMarkCube ); // Skip marking max points, since it IS only a single coordinate continue; } // Now mark all maximums belonging to the cluster cur_list_node_ptr = cluster_nodes_array[i].max_coord_list_ptr->getHeadPtr(); while ( cur_list_node_ptr ) { out_marked_cube->datac( cur_list_node_ptr->item, mark_clust_bs_max ); cur_list_node_ptr = cur_list_node_ptr->next; } } // Write out the marked cube if ( save_options & MA_SAVE_CL_GRAY ) { sprintf(output_file, "%s_CL_marked", output_prefix); progress_win_ptr->SetWindowText("Saving CL marked cube (Gray)..."); out_marked_cube->writeToFile( output_file, DST_UPDATE_FILE_NAME ); write_to_log("MA_VoxelCoding::writeToFileCL - Saved marked CL cube (GRAY) to %s.", output_file); } if ( save_options & MA_SAVE_CL_RGB ) { sprintf(output_file, "%s_CL_marked", output_prefix); progress_win_ptr->SetWindowText("Saving CL marked cube (RGB)..."); out_marked_cube->writeToFileRGB( output_file, mark_clust_bs_max, DST_UPDATE_FILE_NAME, progress_bar_ptr ); write_to_log("MA_VoxelCoding::writeToFileCL - Saved marked CL cube (RGB) to %s.", output_file); } // Can now delete the marked cube delete out_marked_cube; // Re-allocate CL cube and read back in CL_cube = new DSt_cube<cl_t>(boundary_cube->wZ, boundary_cube->wY, boundary_cube->wX); CL_cube->readFromFile( temp_file ); DeleteFile( temp_file ); } } // ---------------------------------------------------------------------------------------- // // Description: A work function called from RecurseOnAllNeighbors(), that will clear // all NOT_LM and IN_QUEUE spots belonging to current cluster. // ---------------------------------------------------------------------------------------- bool MA_VoxelCoding::markSingleClusterInMarkCube( Vect3usi &cur_coord, Vect3usi &nxt_coord ) { if ( (SS_cube->datac(cur_coord) == SS_cube->datac(nxt_coord)) && (out_marked_cube->datac(nxt_coord) == 0) ) { // Mark the cluster voxel and return true to indicate new spot needs to be recursed on out_marked_cube->datac(nxt_coord, (unsigned char)current_mark_value); return true; } else { // Return false, indicating invalid spot return false; } } // ---------------------------------------------------------------------------------------- // // Description - Note: Uses MARK_cube[0] for buffer // ---------------------------------------------------------------------------------------- void MA_VoxelCoding::writeToFileShortestPaths( char *output_prefix, ma_options save_options ) { // Check if SP cube needs to be saved or not if ( save_options & MA_SAVE_SP_CUBE ) { char output_file[MAX_FILE_STR_LEN]; // Trace the shortest path in MARK_cubes[0] MARK_cubes[0]->clear(); for ( unsigned int j = 0; j < number_of_volumes; j++ ) { for ( unsigned int i = 0; i < medial_path_volumes[j].number_of_medial_paths; i++ ) { markPathInCube( medial_path_volumes[j].medial_paths_array[i], MARK_cubes[0], true ); } } // Write to file sprintf(output_file, "%s_SP_cube", output_prefix); progress_win_ptr->SetWindowText("Saving SP cube (1 bit)..."); MARK_cubes[0]->writeToFile( output_file, true ); write_to_log("MA_VoxelCoding::writeToFileShortestPaths - Saved SP cube to %s.", output_file); MARK_cubes[0]->clear(); } } // ---------------------------------------------------------------------------------------- // // Description - Note: Uses MARK_cube[0] for buffer if MA_CUBE, and SS_cube if MA_DETAILED // ---------------------------------------------------------------------------------------- void MA_VoxelCoding::writeToFileMedialPaths( char *output_prefix, ma_options save_options ) { // Check if SP cube needs to be saved or not if ( save_options & MA_SAVE_MA_CUBE ) { progress_win_ptr->SetWindowText("Saving MA cube (1 bit)..."); // Note that MA cube needs to be inverted before writing MARK_cubes[FINAL_MA]->invert(); // Write to file char output_file[MAX_FILE_STR_LEN]; sprintf(output_file, "%s_MA_cube", output_prefix); MARK_cubes[FINAL_MA]->writeToFile( output_file, true ); write_to_log("MA_VoxelCoding::writeToFileMedialPaths - Saved MA cube to %s.", output_file); MARK_cubes[FINAL_MA]->invert(); } if ( save_options & MA_SAVE_MA_DETAILED ) { progress_win_ptr->SetWindowText("Saving detailed MA cube..."); LinkedListNode<PathNode> *cur_node_ptr; char output_file[MAX_FILE_STR_LEN]; char cur_pattern; // Reset SS_cube SS_Xfrm->initXfrmCube( SS_cube ); // Write a pattern for the path: 2 voxels for path number, 1 voxel for volume number for ( unsigned int j = 0; j < number_of_volumes; j++ ) { for ( unsigned int i = 0; i < medial_path_volumes[j].number_of_medial_paths; i++ ) { cur_node_ptr = medial_path_volumes[j].medial_paths_array[i]->getHeadPtr(); cur_pattern = 0; while ( cur_node_ptr ) { if ( cur_node_ptr->item.type == COORD_NODE ) { SS_cube->datac( cur_node_ptr->item.coordinate, (ss_t)((cur_pattern>1)?(j):(i)) ); cur_pattern = (++cur_pattern)%3; } cur_node_ptr = cur_node_ptr->next; } } } // Write to file sprintf(output_file, "%s_MA_detailed", output_prefix); SS_cube->writeToFile( output_file ); write_to_log("MA_VoxelCoding::writeToFileMedialPaths - Saved detailed MA cube to %s.", output_file); } }