Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

marchingcubes.h

Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Tao Ju, 5/16/2007 <taoju@cs.wustl.edu>, code ported by Grant Tang
00007  * Copyright (c) 2000-2006 Baylor College of Medicine
00008  *
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  *
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  *
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  *
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  *
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00033  *
00034  * */
00035 
00036 #ifndef _MARCHING_CUBES_H_
00037 #define _MARCHING_CUBES_H_
00038 
00039 #include <vector>
00040 using std::vector;
00041 
00042 #include "vecmath.h"
00043 #include "isosurface.h"
00044 
00045 // Marching cubes debug will turn on debug and timing information
00046 #define MARCHING_CUBES_DEBUG 0
00047 
00048 #include <ostream>
00049 using std::ostream;
00050 
00051 #include <climits>
00052 // for CHAR_BIT
00053 
00054 namespace EMAN
00055 {
00069         template<typename type>
00070         class CustomVector
00071         {
00072                 public:
00076                         explicit CustomVector(unsigned int starting_size=1024) : data(0), size(0), elements(0)
00077                         {
00078                                 resize(starting_size);
00079                         }
00080 
00081                         ~CustomVector()
00082                         {
00083                                 if(data) {free(data); data=0;}
00084                         }
00085 
00090                         inline void clear(unsigned int starting_size=1024)
00091                         {
00092                                 if (data) {free(data); data = 0;}
00093                                 size = 0;
00094                                 elements = 0;
00095                                 resize(starting_size);
00096                         }
00097 
00104                         inline void resize(const unsigned int n)
00105                         {
00106                                 data = (type*)realloc(data, n*sizeof(type));
00107 
00108                                 for(unsigned int i = size; i < n; ++i) data[i] = 0;
00109                                 size = n;
00110                         }
00111 
00116                         inline void push_back(const type& t)
00117                         {
00118                                 if ( elements == size ) resize(2*size);
00119                                 data[elements] = t;
00120                                 ++elements;
00121                         }
00122 
00127                         inline void push_back_3(const type* const p)
00128                         {
00129                                 if ( elements+2 >= size ) resize(2*size);
00130                                 memcpy( &data[elements], p, 3*sizeof(type));
00131                                 elements = elements + 3;
00132                         }
00133 
00136                         inline void mult3(const type& v1, const type& v2, const type& v3)
00137                         {
00138                                 for(unsigned int i = 0; (i + 2) < elements; i += 3 ){
00139                                         data[i] *= v1;
00140                                         data[i+1] *= v2;
00141                                         data[i+2] *= v3;
00142                                 }
00143                         }
00144 
00151                         inline unsigned int elem() { return elements; }
00152 
00157                         inline type& operator[](const unsigned int idx)
00158                         {
00159                                 unsigned int csize = size;
00160                                 while (idx >= csize ) {
00161                                         csize *= 2;
00162                                 }
00163                                 if ( csize != size ) resize(csize);
00164                                 return data[idx];
00165                         }
00166 
00170                         inline type* get_data() { return data; }
00171 
00172                 private:
00174                         type* data;
00176                         unsigned int size;
00178                         unsigned int elements;
00179         };
00180 
00181         class MarchingCubes : public Isosurface {
00182                 friend class GLUtil;
00183         public:
00186                 MarchingCubes();
00187 
00192                 MarchingCubes(EMData * em);
00193                 virtual ~MarchingCubes();
00194 
00200                 void set_data(EMData* data);
00201 
00205                 void set_surface_value(const float value);
00206 
00210                 float get_surface_value() const { return _surf_value; }
00211 
00220                 void set_sampling(const int rate) { drawing_level = rate; }
00221 
00225                 int get_sampling() const { return drawing_level; }
00226 
00229                 int get_sampling_range() { return minvals.size()-1; }
00230 
00235                 Dict get_isosurface();
00236 
00237                 void surface_face_z();
00238         private:
00239                 map<int, int> point_map;
00240                 unsigned long _isodl;
00241 
00247                 bool calculate_min_max_vals();
00248                 
00249         
00253                 void clear_min_max_vals();
00254 
00256                 vector<EMData*> minvals, maxvals;
00257 
00259                 int drawing_level;
00260 
00270                 void draw_cube(const int x, const int y, const int z, const int cur_level );
00271 
00272 
00280                 void marching_cube(int fX, int fY, int fZ, const int cur_level);
00281 
00285                 void calculate_surface();
00286 
00295                 float get_offset(float fValue1, float fValue2, float fValueDesired);
00296 
00300                 int get_edge_num(int x, int y, int z, int edge);
00301 
00312                 void get_normal(Vector3 &normal, int fX, int fY, int fZ);
00313 
00315                 CustomVector<float> pp;
00316                 CustomVector<float> nn;
00317                 CustomVector<unsigned int> ff;
00318         };
00319 
00323 //      class CudaMarchingCubes : public Isosurface {
00324 //              public:
00325 //
00326 //                      /** Most commonly used constructor
00327 //                      * calls set_data(em)
00328 //                      * @param em the EMData object to generate triangles and normals for
00329 //                      */
00330 //                      CudaMarchingCubes(EMData * em);
00331 //                      virtual ~CudaMarchingCubes();
00332 //                      /**
00333 //                       * Set Isosurface value
00334 //                       */
00335 //                      virtual void set_surface_value(const float value);
00336 //
00337 //                      /** Sets Voxel data for Isosurface implementation
00338 //                      * Calls calculate_min_max_vals which generates the tree of data
00339 //                      * @param data the emdata object to be rendered in 3D
00340 //                      * @exception ImageDimensionException if the image z dimension is 1
00341 //                      */
00342 //                      void set_data(EMData* data);
00343 //
00344 //                      virtual float get_surface_value() const { return _surf_value; }
00345 //
00346 //                      /**
00347 //                       * Set Grid Size
00348 //                       */
00349 //                      virtual void set_sampling(const int size) {} ;
00350 //
00351 //                      virtual int get_sampling() const { return 0; };
00352 //
00353 //                      /** Get the number of feasible samplings
00354 //                      *
00355 //                       */
00356 //                      virtual int get_sampling_range() {return 0; }
00357 //
00358 //                      virtual Dict get_isosurface()  { return Dict;}
00359 //
00360 //      }
00361 
00364         class U3DWriter{
00365         public:
00366                 typedef unsigned int U32;
00367                 typedef long unsigned int U64;
00368                 typedef double F64;
00369                 typedef float F32;
00370                 typedef short int I16;
00371                 typedef short unsigned int U16;
00372                 typedef unsigned char U8;
00373 
00374 
00375 
00376                 U3DWriter();
00377                 ~U3DWriter();
00378 
00379                 int write(const string& filename);
00380 
00381                 ostream& write(ostream&);
00382 
00383         private:
00384                 unsigned int size_of_in_bytes();
00385 
00386                 void test_type_sizes();
00387 
00388                 ostream& write_header(ostream&);
00389                 ostream& write_clod_mesh_generator_node(ostream& os);
00390 
00391 
00392                 template<typename type>
00393                 ostream& write(ostream& os, const type& T) {
00394                         os.write( (const char*)(&T), sizeof(type) );
00395                         return os;
00396                 }
00397 
00398 
00399 //              U8 reverse_bits_3d( U8 val ) {
00400 //                      U8 ret = 0;
00401 //                      U8 n_bits = sizeof ( val ) * CHAR_BIT;
00402 //
00403 //                      for ( unsigned i = 0; i < n_bits; ++i ) {
00404 //                              ret = ( ret << 1 ) | ( val & 1 );
00405 //                              val >>= 1;
00406 //                      }
00407 //
00408 //                      return ret;
00409 //              }
00410 
00411 //              U16 reverse_bits_u3d( U16 val ) {
00412 //                      bool is_big_endian = ByteOrder::is_host_big_endian();
00413 //
00414 //                      U16 ret = 0;
00415 //
00416 //                      U8* pu8 = (U8*)&val;
00417 //                      U8* pu8ret = (U8*)&ret;
00418 //                      U8 high_order = 0;
00419 //                      U8 low_order = 0;
00420 //                      if (is_big_endian) {
00421 //                              high_order = pu8[0];
00422 //                              low_order = pu8[1];
00423 //                      }
00424 //                      else {
00425 //                              high_order = pu8[1];
00426 //                              low_order = pu8[0];
00427 //                      }
00428 //
00429 //                      pu8ret[0] = low_order;
00430 //                      pu8ret[1] = higher_order;
00431 //
00432 //                      high_order = reverse_bits_u3d(high_order);
00433 //                      low_order = reverse_bits_u3d(low_order);
00434 //
00435 //                      return ret;
00436 //
00437 //              }
00438 //
00439 //              U32 reverse_bits_u3d( U32 val ) {
00440 //                      bool is_big_endian = ByteOrder::is_host_big_endian();
00441 //
00442 //                      U32 ret = 0;
00443 //
00444 //                      U16 * pu16 = (U16*)&val;
00445 //                      U16* pu16ret = (U16*)&ret;
00446 //                      U16 high_order = 0;
00447 //                      U16 low_order = 0;
00448 //                      if (is_big_endian) {
00449 //                              high_order = pu16[0];
00450 //                              low_order = pu16[1];
00451 //                      }
00452 //                      else {
00453 //                              high_order = pu16[1];
00454 //                              low_order = pu16[0];
00455 //                      }
00456 //
00457 //                      high_order = reverse_bits_u3d(high_order);
00458 //                      low_order = reverse_bits_u3d(low_order);
00459 //
00460 //                      pu16ret[0] = low_order;
00461 //                      pu16ret[1] = higher_order;
00462 //
00463 //                      return ret;
00464 //
00465 //              }
00466 //
00467 
00468                 U32 DIFFUSE_COLOR_COUNT;
00469                 U32 SPECULAR_COLOR_COUNT;
00470 
00471 
00472                 CustomVector<F32> pp;
00473                 CustomVector<F32> nn;
00474                 CustomVector<unsigned int> ff;
00475         };
00476 
00477         // Template specialization. Have to be careful when dealing with strings
00478         template<> ostream& U3DWriter::write(ostream& os, const string& );
00479 
00480 //      class U3DBitStreamWriter {
00481 //      public:
00482 //              typedef unsigned int U32;
00483 //              typedef long unsigned int U64;
00484 //              typedef double F64;
00485 //              typedef float F32;
00486 //              typedef short int I16;
00487 //              typedef short unsigned int U16;
00488 //              typedef unsigned char U8;
00489 //
00490 //
00491 //              U3D_BitStreamWriter();
00492 //              ~U3D_BitStreamWriter();
00493 //
00494 //              // We could do this kind of thing with templates,  but
00495 //              // we would have to specialize each function anyhow,
00496 //              // so it makes sense just to do it the C way.
00497 //              void writeU8( U8 value );
00498 //              void writeU16( U16 value );
00499 //              void writeU32( U32 value );
00500 //              void writeU64( U64 value );
00501 //              void writeI32( I32 value );
00502 //              void writeF32( F32 value );
00503 //              void writeF64( F64 value );
00504 //
00505 //              void WriteCompressedU32( U32 context, U32 value );
00506 //              void WriteCompressedU16( U32 context, U32 value );
00507 //              void WriteCompressedU8( U32 context, U32 value );
00508 //
00509 //      };
00510 
00511 
00512 
00513 }
00514 
00515 #endif

Generated on Thu Nov 17 12:43:46 2011 for EMAN2 by  doxygen 1.3.9.1