#pragma once #include <math.h> #include <fstream> #include "DS_cube.h" #include "DS_slice.h" #include "Vect3usi.h" #include "file_IO_lib.h" class DS_1b_cube { public: typedef int (DS_1b_cube::*setSpotPtr)(unsigned short, unsigned short, unsigned short); typedef int (DS_1b_cube::*setSpotVectPtr)(Vect3usi); // ---------------------------------------------------------------------------------------- // Constructors and destructor // ---------------------------------------------------------------------------------------- DS_1b_cube(unsigned short nwZ, unsigned short nwY, unsigned short nwX); DS_1b_cube(char* BIN_file, int type, unsigned short swZ, unsigned short nwZ, unsigned short nwY, unsigned short nwX); DS_1b_cube(DS_cube* orig_cube); ~DS_1b_cube(void); // ---------------------------------------------------------------------------------------- // INLINED location getter/setter funcions // ---------------------------------------------------------------------------------------- bool get_spot(unsigned short zL, unsigned short yL, unsigned short xL); bool get_spot(Vect3usi &coord); void set_spot(unsigned short zL, unsigned short yL, unsigned short xL, bool value); void set_spot(Vect3usi &coord, bool value); bool set_spot_1(unsigned short zL, unsigned short yL, unsigned short xL); bool set_spot_1(Vect3usi &coord); bool set_spot_0(unsigned short zL, unsigned short yL, unsigned short xL); bool set_spot_0(Vect3usi &coord); bool get_memory(unsigned long long indx); bool set_memory_1(unsigned long long indx); bool set_memory_0(unsigned long long indx); // ---------------------------------------------------------------------------------------- // Additional operations // ---------------------------------------------------------------------------------------- DS_1b_cube* rotate_XY_to_YZ(); DS_1b_cube* rotate_XY_to_ZX(); bool writeToFile(char* out_file, bool auto_append_extension = false); bool readFromFile( char *file_name ); DS_1b_cube* duplicate(); void invert(); void to_DS_cube(DS_cube * new_cube, unsigned short first_slice, unsigned short last_slice); void to_DS_slice(DS_slice * slice, unsigned short z_index); void clear(); void setall(); void add_outside_layer(bool b_val); // ---------------------------------------------------------------------------------------- // Drawing operations (see DS_1b_cube_draw.c) // ---------------------------------------------------------------------------------------- void drawLine6Connected( Vect3usi &start_coord, Vect3usi &end_coord, bool draw_value ); void drawSolidBox( Vect3usi &corner_coord, Vect3usi &dimensions, bool fill_value ); void drawSolidSphere( Vect3usi ¢er_coord, unsigned short inn_diam, unsigned short out_diam, bool fill_value); private: // ---------------------------------------------------------------------------------------- // Private functions // ---------------------------------------------------------------------------------------- void AllocateMemory(); // This requires all size variables to be initialized // ---------------------------------------------------------------------------------------- // Public variables // ---------------------------------------------------------------------------------------- public: unsigned short wZ, wY, wX; unsigned short cwX; Vect3usi dimensions; // Same as wZ, wY, wX, but in single structure form unsigned long long wI; unsigned char ***data; // This is a 3d array unsigned char **rows; // This is memory for each slice pointers unsigned char *memory; // This is memory for actual data }; // ======================================================================================== // INLINED METHOD IMPLEMENTATIONS // // ---------------------------------------------------------------------------------------- // Obtains a single bit location from the data cube // ---------------------------------------------------------------------------------------- inline bool DS_1b_cube::get_spot(unsigned short zL, unsigned short yL, unsigned short xL) { return ( ( (unsigned char)(data[zL][yL][xL/8] << (xL%8)) > 0x7F) ? (true) : (false) ); }; inline bool DS_1b_cube::get_spot(Vect3usi &coord) { return get_spot(coord.z, coord.y, coord.x); }; // ---------------------------------------------------------------------------------------- // Sets a single bit location in the data cube, no return value // ---------------------------------------------------------------------------------------- inline void DS_1b_cube::set_spot(unsigned short zL, unsigned short yL, unsigned short xL, bool value) { // These are used multiple times, so do calc only once unsigned char charLoc = (unsigned char)(xL%8); unsigned short int charOff = xL/8; if ( value ) { data[zL][yL][charOff] |= (unsigned char)(0x80 >> charLoc); } else { data[zL][yL][charOff] &= (unsigned char)(~(0x80 >> charLoc)); } }; inline void DS_1b_cube::set_spot(Vect3usi &coord, bool value) { set_spot(coord.z, coord.y, coord.x, value); }; // ---------------------------------------------------------------------------------------- // Sets a single bit location in the data cube, returns true if bit was flipped // ---------------------------------------------------------------------------------------- inline bool DS_1b_cube::set_spot_1(unsigned short zL, unsigned short yL, unsigned short xL) { // These are used multiple times, so do calc only once unsigned char charLoc = (unsigned char)(xL%8); unsigned short int charOff = xL/8; // Need to shift to bring the desired location to the most significant spot. // If the spot is not HIGH, then set it HIGH if ( (unsigned char)(data[zL][yL][charOff] << charLoc) < 0x80) { //OR the original byte with the shifted '1' to set the desired bit HIGH data[zL][yL][charOff] |= (unsigned char)(0x80 >> charLoc); return true; } else { return false; } }; inline bool DS_1b_cube::set_spot_1(Vect3usi &coord) { return set_spot_1(coord.z, coord.y, coord.x); }; // ---------------------------------------------------------------------------------------- // Clears a single bit location in the data cube, returns true if bit was flipped // ---------------------------------------------------------------------------------------- inline bool DS_1b_cube::set_spot_0(unsigned short int zL, unsigned short int yL, unsigned short int xL) { /* this is used multiple times, so do calc only once */ unsigned char charLoc = (unsigned char)(xL%8); unsigned short int charOff = xL/8; /* might need to shift to bring the desired location to the most significant spot */ /* if the spot is not LOW, then set it LOW */ if ( (unsigned char)(data[zL][yL][charOff] << charLoc) > 127) { //shift a '1' into position of bit that needs to be set LOW, and invert //AND the original byte with the shifted '0' to set the desired bit LOW data[zL][yL][charOff] &= (unsigned char)(~(0x80 >> charLoc)); return true; } else return false; }; inline bool DS_1b_cube::set_spot_0(Vect3usi &coord) { return set_spot_0(coord.z, coord.y, coord.x); }; // ---------------------------------------------------------------------------------------- // Operations for single bit index in the data cube seen as a single long array // ---------------------------------------------------------------------------------------- inline bool DS_1b_cube::get_memory(unsigned long long indx) { return ( ( (unsigned char)(memory[indx/8]<<(indx%8)) > 0x7F) ? (true):(false) ); }; inline bool DS_1b_cube::set_memory_1(unsigned long long indx) { memory[indx/8] |= (0x80>>(indx%8)); }; inline bool DS_1b_cube::set_memory_0(unsigned long long indx) { memory[indx/8] &= (~(0x80>>(indx%8))); };