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 
00085                         inline void clear(unsigned int starting_size=1024)
00086                         {
00087                                 if ( data != 0 )
00088                                 {
00089                                         delete [] data;
00090                                         data = 0;
00091                                 }
00092                                 size = 0;
00093                                 elements = 0;
00094                                 resize(starting_size);
00095                         }
00096 
00103                         inline void resize(const unsigned int n)
00104                         {
00105                                 data = (type*)realloc(data, n*sizeof(type));
00106 
00107                                 for(unsigned int i = size; i < n; ++i) data[i] = 0;
00108                                 size = n;
00109                         }
00110 
00115                         inline void push_back(const type& t)
00116                         {
00117                                 if ( elements == size ) resize(2*size);
00118                                 data[elements] = t;
00119                                 ++elements;
00120                         }
00121 
00126                         inline void push_back_3(const type* const p)
00127                         {
00128                                 if ( elements+2 >= size ) resize(2*size);
00129                                 memcpy( &data[elements], p, 3*sizeof(type));
00130                                 elements = elements + 3;
00131                         }
00132 
00135                         inline void mult3(const type& v1, const type& v2, const type& v3)
00136                         {
00137                                 for(unsigned int i = 0; (i + 2) < elements; i += 3 ){
00138                                         data[i] *= v1;
00139                                         data[i+1] *= v2;
00140                                         data[i+2] *= v3;
00141                                 }
00142                         }
00143 
00150                         inline unsigned int elem() { return elements; }
00151 
00156                         inline type& operator[](const unsigned int idx)
00157                         {
00158                                 unsigned int csize = size;
00159                                 while (idx >= csize ) {
00160                                         csize *= 2;
00161                                 }
00162                                 if ( csize != size ) resize(csize);
00163                                 return data[idx];
00164                         }
00165 
00169                         inline type* get_data() { return data; }
00170 
00171                 private:
00173                         type* data;
00175                         unsigned int size;
00177                         unsigned int elements;
00178         };
00179 
00180         class MarchingCubes : public Isosurface {
00181                 friend class GLUtil;
00182         public:
00185                 MarchingCubes();
00186 
00191                 MarchingCubes(EMData * em);
00192                 virtual ~MarchingCubes();
00193 
00199                 void set_data(EMData* data);
00200 
00204                 void set_surface_value(const float value);
00205 
00209                 float get_surface_value() const { return _surf_value; }
00210 
00219                 void set_sampling(const int rate) { drawing_level = rate; }
00220 
00224                 int get_sampling() const { return drawing_level; }
00225 
00228                 int get_sampling_range() { return minvals.size()-1; }
00229 
00234                 Dict get_isosurface();
00235 
00236                 void surface_face_z();
00237         private:
00238                 map<int, int> point_map;
00239                 unsigned long _isodl;
00240 
00246                 bool calculate_min_max_vals();
00247                 
00248         
00252                 void clear_min_max_vals();
00253 
00255                 vector<EMData*> minvals, maxvals;
00256 
00258                 int drawing_level;
00259 
00269                 void draw_cube(const int x, const int y, const int z, const int cur_level );
00270 
00271 
00279                 void marching_cube(int fX, int fY, int fZ, const int cur_level);
00280 
00284                 void calculate_surface();
00285 
00294                 float get_offset(float fValue1, float fValue2, float fValueDesired);
00295 
00299                 int get_edge_num(int x, int y, int z, int edge);
00300 
00311                 void get_normal(Vector3 &normal, int fX, int fY, int fZ);
00312 
00314                 CustomVector<float> pp;
00315                 CustomVector<float> nn;
00316                 CustomVector<unsigned int> ff;
00317         };
00318 
00322 //      class CudaMarchingCubes : public Isosurface {
00323 //              public:
00324 //
00325 //                      /** Most commonly used constructor
00326 //                      * calls set_data(em)
00327 //                      * @param em the EMData object to generate triangles and normals for
00328 //                      */
00329 //                      CudaMarchingCubes(EMData * em);
00330 //                      virtual ~CudaMarchingCubes();
00331 //                      /**
00332 //                       * Set Isosurface value
00333 //                       */
00334 //                      virtual void set_surface_value(const float value);
00335 //
00336 //                      /** Sets Voxel data for Isosurface implementation
00337 //                      * Calls calculate_min_max_vals which generates the tree of data
00338 //                      * @param data the emdata object to be rendered in 3D
00339 //                      * @exception ImageDimensionException if the image z dimension is 1
00340 //                      */
00341 //                      void set_data(EMData* data);
00342 //
00343 //                      virtual float get_surface_value() const { return _surf_value; }
00344 //
00345 //                      /**
00346 //                       * Set Grid Size
00347 //                       */
00348 //                      virtual void set_sampling(const int size) {} ;
00349 //
00350 //                      virtual int get_sampling() const { return 0; };
00351 //
00352 //                      /** Get the number of feasible samplings
00353 //                      *
00354 //                       */
00355 //                      virtual int get_sampling_range() {return 0; }
00356 //
00357 //                      virtual Dict get_isosurface()  { return Dict;}
00358 //
00359 //      }
00360 
00363         class U3DWriter{
00364         public:
00365                 typedef unsigned int U32;
00366                 typedef long unsigned int U64;
00367                 typedef double F64;
00368                 typedef float F32;
00369                 typedef short int I16;
00370                 typedef short unsigned int U16;
00371                 typedef unsigned char U8;
00372 
00373 
00374 
00375                 U3DWriter();
00376                 ~U3DWriter();
00377 
00378                 int write(const string& filename);
00379 
00380                 ostream& write(ostream&);
00381 
00382         private:
00383                 unsigned int size_of_in_bytes();
00384 
00385                 void test_type_sizes();
00386 
00387                 ostream& write_header(ostream&);
00388                 ostream& write_clod_mesh_generator_node(ostream& os);
00389 
00390 
00391                 template<typename type>
00392                 ostream& write(ostream& os, const type& T) {
00393                         os.write( (char*)(&T), sizeof(type) );
00394                         return os;
00395                 }
00396 
00397 
00398 //              U8 reverse_bits_3d( U8 val ) {
00399 //                      U8 ret = 0;
00400 //                      U8 n_bits = sizeof ( val ) * CHAR_BIT;
00401 //
00402 //                      for ( unsigned i = 0; i < n_bits; ++i ) {
00403 //                              ret = ( ret << 1 ) | ( val & 1 );
00404 //                              val >>= 1;
00405 //                      }
00406 //
00407 //                      return ret;
00408 //              }
00409 
00410 //              U16 reverse_bits_u3d( U16 val ) {
00411 //                      bool is_big_endian = ByteOrder::is_host_big_endian();
00412 //
00413 //                      U16 ret = 0;
00414 //
00415 //                      U8* pu8 = (U8*)&val;
00416 //                      U8* pu8ret = (U8*)&ret;
00417 //                      U8 high_order = 0;
00418 //                      U8 low_order = 0;
00419 //                      if (is_big_endian) {
00420 //                              high_order = pu8[0];
00421 //                              low_order = pu8[1];
00422 //                      }
00423 //                      else {
00424 //                              high_order = pu8[1];
00425 //                              low_order = pu8[0];
00426 //                      }
00427 //
00428 //                      pu8ret[0] = low_order;
00429 //                      pu8ret[1] = higher_order;
00430 //
00431 //                      high_order = reverse_bits_u3d(high_order);
00432 //                      low_order = reverse_bits_u3d(low_order);
00433 //
00434 //                      return ret;
00435 //
00436 //              }
00437 //
00438 //              U32 reverse_bits_u3d( U32 val ) {
00439 //                      bool is_big_endian = ByteOrder::is_host_big_endian();
00440 //
00441 //                      U32 ret = 0;
00442 //
00443 //                      U16 * pu16 = (U16*)&val;
00444 //                      U16* pu16ret = (U16*)&ret;
00445 //                      U16 high_order = 0;
00446 //                      U16 low_order = 0;
00447 //                      if (is_big_endian) {
00448 //                              high_order = pu16[0];
00449 //                              low_order = pu16[1];
00450 //                      }
00451 //                      else {
00452 //                              high_order = pu16[1];
00453 //                              low_order = pu16[0];
00454 //                      }
00455 //
00456 //                      high_order = reverse_bits_u3d(high_order);
00457 //                      low_order = reverse_bits_u3d(low_order);
00458 //
00459 //                      pu16ret[0] = low_order;
00460 //                      pu16ret[1] = higher_order;
00461 //
00462 //                      return ret;
00463 //
00464 //              }
00465 //
00466 
00467                 U32 DIFFUSE_COLOR_COUNT;
00468                 U32 SPECULAR_COLOR_COUNT;
00469 
00470 
00471                 CustomVector<F32> pp;
00472                 CustomVector<F32> nn;
00473                 CustomVector<unsigned int> ff;
00474         };
00475 
00476         // Template specialization. Have to be careful when dealing with strings
00477         template<> ostream& U3DWriter::write(ostream& os, const string& );
00478 
00479 //      class U3DBitStreamWriter {
00480 //      public:
00481 //              typedef unsigned int U32;
00482 //              typedef long unsigned int U64;
00483 //              typedef double F64;
00484 //              typedef float F32;
00485 //              typedef short int I16;
00486 //              typedef short unsigned int U16;
00487 //              typedef unsigned char U8;
00488 //
00489 //
00490 //              U3D_BitStreamWriter();
00491 //              ~U3D_BitStreamWriter();
00492 //
00493 //              // We could do this kind of thing with templates,  but
00494 //              // we would have to specialize each function anyhow,
00495 //              // so it makes sense just to do it the C way.
00496 //              void writeU8( U8 value );
00497 //              void writeU16( U16 value );
00498 //              void writeU32( U32 value );
00499 //              void writeU64( U64 value );
00500 //              void writeI32( I32 value );
00501 //              void writeF32( F32 value );
00502 //              void writeF64( F64 value );
00503 //
00504 //              void WriteCompressedU32( U32 context, U32 value );
00505 //              void WriteCompressedU16( U32 context, U32 value );
00506 //              void WriteCompressedU8( U32 context, U32 value );
00507 //
00508 //      };
00509 
00510 
00511 
00512 }
00513 
00514 #endif

Generated on Fri Apr 30 15:38:52 2010 for EMAN2 by  doxygen 1.3.9.1