#pragma once #include "DS_1b_cube.h" #include "LinkedList.h" #include "GroupedLists.h" #include "vect3usi.h" #include "useful_inlined_functions.h" // ======================================================================================== // Compile time flags for distance transforms. // ======================================================================================== // Provides stats on how large lists get during SS transforms #define DT_KEEP_TRACK_OF_STATS 0 // ======================================================================================== // TEMPLATE CLASS FOR ANY TYPE OF DISTANCE TRANSFORM // // Note: No logging is performed by any of these functions for performance reasons. // As a side effect, returned status should probably be examined and acted on if needed. // // ======================================================================================== // ---------------------------------------------------------------------------------------- // Options for distance xfrms typedef unsigned int dt_options; #define DT_NORMAL_XFRM 0x0000 // for ALL xfrms, including eraseSS() #define DT_INIT_INPUT 0x0001 // Erases entire cube before doing xfrm // for SS xfrm only #define DT_FACE_ONLY 0x0002 // Prevents diagonal movements (edge and corner), also works for eraseSS #define DT_STOP_AT_HIT 0x0004 // SS finished when 'dt_end_value' reached // for BS xfrm only #define DT_BOUNDARY_IS_SOLID 0x0008 // Mirror by default // ---------------------------------------------------------------------------------------- // Return codes typedef enum dt_ret_code { DT_NO_ERROR = 0, DT_MISMATCHED_SIZES, // Boundary cube size does not match xfmr cube size DT_OVERFLOW_LIKELY, // Returned if 'infinity' or 'unmarked' values are reached DT_STOPPED_AT_HIT // We have reached a coordinate containing 'dt_end_value' } dt_ret_code; // ---------------------------------------------------------------------------------------- // Transform class definition template <class T> class DistanceXfrm { public: DistanceXfrm(DS_1b_cube *boundary_cube, CProgressCtrl *PBarPtr=NULL); ~DistanceXfrm(void); // Functions for changing default constant values. void changePoreValue( bool new_pore_value ); // Default is '0'/false void changeFECValues(T face, T edge, T corner); // Default is 3,4,5 void changeEndValueForSS(T end_value); // Default is infinity-1 void changeInfinityValue(T infinity); // Default is all bits set to 1 (except MSb if signed). // Functions for getting current constant values. void getFECValues(T &face, T &edge, T &corner); T getFaceValue(); T getEndValueForSS(); T getInfinityValue(); bool getPoreValue(); // Main work functions (see implementations for details) dt_ret_code runBS(DSt_cube<T> *cube_to_xfrm, dt_options options=0); dt_ret_code runSS(DSt_cube<T> *cube_to_xfrm, Vect3usi &start_pt, dt_options options=0); dt_ret_code eraseSS(DSt_cube<T> *cube_to_erase, Vect3usi &start_pt, T erase_value, dt_options options=0); dt_ret_code initXfrmCube( DSt_cube<T> *cube_to_xfrm ); private: // Support functions dt_ret_code runFastSS( DSt_cube<T> *cube_to_xfrm, Vect3usi &start_pt, dt_options options=0 ); dt_ret_code runFullSS( DSt_cube<T> *cube_to_xfrm, Vect3usi &start_pt, dt_options options=0 ); private: // External input pointers DS_1b_cube *bound_cube; CProgressCtrl *progress_bar_ptr; // Value for pore in boundary_cube (defaults to '0') bool pore_value; // Face-Edge-Corner values T dt_face; T dt_edge; T dt_corner; // End point trigger, and infinity value (used as 'unmarked'). T dt_end_value; T dt_infinity; // Lists that get preserved once allocated in case of multiple calls LinkedList<Vect3usi> *queue_cur; LinkedList<Vect3usi> *queue_nxt; GroupedLists<T,Vect3usi> *list_of_queues; // Stat tracking #if DT_KEEP_TRACK_OF_STATS unsigned int ss_full_max_queue_size; unsigned int ss_full_double_traveled; unsigned int ss_fast_max_queue_size; #endif }; //==================================================================================== // Constructor and destructor //==================================================================================== template <class T> DistanceXfrm<T>::DistanceXfrm(DS_1b_cube *boundary_cube, CProgressCtrl *PBarPtr/*=NULL*/) { bound_cube = boundary_cube; pore_value = false; dt_face = (T) 3; dt_edge = (T) 4; dt_corner = (T) 5; progress_bar_ptr = PBarPtr; // Initialize all queues to NULL queue_cur = NULL; queue_nxt = NULL; list_of_queues = NULL; // Obtain infinity value for 'T', and set defaults using it FindUsefulTypeProperties<T> find_inf; dt_infinity = find_inf.getInfinity(); dt_end_value = dt_infinity - 1; #if DT_KEEP_TRACK_OF_STATS ss_full_max_queue_size = 0; ss_fast_max_queue_size = 0; ss_full_double_traveled = 0; #endif }; template <class T> DistanceXfrm<T>::~DistanceXfrm(void) { if ( queue_cur ) delete queue_cur; if ( queue_nxt ) delete queue_nxt; if ( list_of_queues ) delete list_of_queues; }; //==================================================================================== // Access Functions //==================================================================================== template <class T> void DistanceXfrm<T>::getFECValues(T &face, T &edge, T &corner) { face = dt_face; edge = dt_edge; corner = dt_corner; }; template <class T> T DistanceXfrm<T>::getFaceValue( ) { return dt_face; }; template <class T> T DistanceXfrm<T>::getInfinityValue( ) { return dt_infinity; }; template <class T> T DistanceXfrm<T>::getEndValueForSS( ) { return dt_end_value; }; template <class T> bool DistanceXfrm<T>::getPoreValue( ) { return pore_value; }; //==================================================================================== // Setter Functions //==================================================================================== template <class T> void DistanceXfrm<T>::changeFECValues(T face, T edge, T corner) { dt_face = face; dt_edge = edge; dt_corner = corner; }; template <class T> void DistanceXfrm<T>::changeInfinityValue( T infinity ) { dt_infinity = infinity; }; template <class T> void DistanceXfrm<T>::changeEndValueForSS( T end_value ) { dt_end_value = end_value; }; template <class T> void DistanceXfrm<T>::changePoreValue( bool new_pore_value ) { pore_value = new_pore_value; }; //==================================================================================== //======================= REST OF FUNCTIONS ===================================== //==================================================================================== #include "DistanceTransform.hpp" //==================================================================================== //======================= END OF FILE ===================================== //====================================================================================