⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 marchingcubes.cpp

📁 RBF平台
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/** * @file    MarchingCubes.cpp * @author  Thomas Lewiner <thomas.lewiner@polytechnique.org> * @author  Math Dept, PUC-Rio * @version 0.2 * @date    12/08/2002 * * @brief   MarchingCubes Algorithm *///________________________________________________//#ifndef WIN32//#pragma implementation//#endif // WIN32
#include "stdafx.h"#include <math.h>#include <time.h>#include <memory.h>#include <float.h>#include "MarchingCubes.h"#include "ply_tk.h"#include "LookUpTable.h"// step size of the arrays of vertices and triangles#define ALLOC_SIZE 65536//_____________________________________________________________________________// print cube for debugvoid MarchingCubes::print_cube() { printf( "\t%f %f %f %f %f %f %f %f\n", _cube[0], _cube[1], _cube[2], _cube[3], _cube[4], _cube[5], _cube[6], _cube[7]) ; }//_____________________________________________________________________________//_____________________________________________________________________________// ConstructorMarchingCubes::MarchingCubes( const int size_x /*= -1*/, const int size_y /*= -1*/, const int size_z /*= -1*/ ) ://-----------------------------------------------------------------------------  _originalMC(false),  _size_x    (size_x),  _size_y    (size_y),  _size_z    (size_z),  _data      ((float*)NULL),  _x_verts   (( int *)NULL),  _y_verts   (( int *)NULL),  _z_verts   (( int *)NULL),  _nverts    (0),  _ntrigs    (0),  _Nverts    (0),  _Ntrigs    (0),  _vertices  (( Vertex_mc *)NULL),  _triangles ((Triangle*)NULL){}//_____________________________________________________________________________//_____________________________________________________________________________// DestructorMarchingCubes::~MarchingCubes()//-----------------------------------------------------------------------------{  clean_all() ;}//_____________________________________________________________________________//_____________________________________________________________________________// main algorithmvoid MarchingCubes::run()//-----------------------------------------------------------------------------{  printf("Marching Cubes begin: cpu %ld\n", clock() ) ;  compute_intersection_points( ) ;  for( _k = 0 ; _k < _size_z-1 ; _k++ )  for( _j = 0 ; _j < _size_y-1 ; _j++ )  for( _i = 0 ; _i < _size_x-1 ; _i++ )  {    _lut_entry = 0 ;    for( int p = 0 ; p < 8 ; ++p )    {      _cube[p] = get_data( _i+((p^(p>>1))&1), _j+((p>>1)&1), _k+((p>>2)&1) ) ;      if( fabs( _cube[p] ) < FLT_EPSILON ) _cube[p] = FLT_EPSILON ;      if( _cube[p] > 0 ) _lut_entry += 1 << p ;    }/*    if( ( _cube[0] = get_data( _i , _j , _k ) ) > 0 ) _lut_entry +=   1 ;    if( ( _cube[1] = get_data(_i+1, _j , _k ) ) > 0 ) _lut_entry +=   2 ;    if( ( _cube[2] = get_data(_i+1,_j+1, _k ) ) > 0 ) _lut_entry +=   4 ;    if( ( _cube[3] = get_data( _i ,_j+1, _k ) ) > 0 ) _lut_entry +=   8 ;    if( ( _cube[4] = get_data( _i , _j ,_k+1) ) > 0 ) _lut_entry +=  16 ;    if( ( _cube[5] = get_data(_i+1, _j ,_k+1) ) > 0 ) _lut_entry +=  32 ;    if( ( _cube[6] = get_data(_i+1,_j+1,_k+1) ) > 0 ) _lut_entry +=  64 ;    if( ( _cube[7] = get_data( _i ,_j+1,_k+1) ) > 0 ) _lut_entry += 128 ;*/    process_cube( ) ;  }  printf("Marching Cubes end: cpu %ld\n", clock() ) ;  for( _i = 0 ; _i < 15 ; _i++ )  {    printf("  %7d cases %d\n", _N[_i], _i ) ;  }}//_____________________________________________________________________________//_____________________________________________________________________________// init temporary structures (must set sizes before call)void MarchingCubes::init_temps()//-----------------------------------------------------------------------------{  _data    = new float[_size_x * _size_y * _size_z] ;  _x_verts = new int  [_size_x * _size_y * _size_z] ;  _y_verts = new int  [_size_x * _size_y * _size_z] ;  _z_verts = new int  [_size_x * _size_y * _size_z] ;  memset( _x_verts, -1, _size_x * _size_y * _size_z * sizeof( int ) ) ;  memset( _y_verts, -1, _size_x * _size_y * _size_z * sizeof( int ) ) ;  memset( _z_verts, -1, _size_x * _size_y * _size_z * sizeof( int ) ) ;  memset( _N, 0, 15 * sizeof(int) ) ;}//_____________________________________________________________________________//_____________________________________________________________________________// init all structures (must set sizes before call)void MarchingCubes::init_all ()//-----------------------------------------------------------------------------{  init_temps() ;  _nverts = _ntrigs = 0 ;  _Nverts = _Ntrigs = ALLOC_SIZE ;  _vertices  = new Vertex_mc  [_Nverts];  _triangles = new Triangle[_Ntrigs];}//_____________________________________________________________________________//_____________________________________________________________________________// clean temporary structuresvoid MarchingCubes::clean_temps()//-----------------------------------------------------------------------------{  delete [] _data;  delete [] _x_verts;  delete [] _y_verts;  delete [] _z_verts;  _data     = (float*)NULL ;  _x_verts  = (int*)NULL ;  _y_verts  = (int*)NULL ;  _z_verts  = (int*)NULL ;}//_____________________________________________________________________________//_____________________________________________________________________________// clean all structuresvoid MarchingCubes::clean_all()//-----------------------------------------------------------------------------{  clean_temps() ;  delete [] _vertices  ;  delete [] _triangles ;  _vertices  = (Vertex_mc   *)NULL ;  _triangles = (Triangle *)NULL ;  _nverts = _ntrigs = 0 ;  _Nverts = _Ntrigs = 0 ;  _size_x = _size_y = _size_z = -1 ;}//_____________________________________________________________________________//_____________________________________________________________________________//_____________________________________________________________________________//_____________________________________________________________________________// Compute the intersection pointsvoid MarchingCubes::compute_intersection_points( )//-----------------------------------------------------------------------------{  for( _k = 0 ; _k < _size_z ; _k++ )  for( _j = 0 ; _j < _size_y ; _j++ )  for( _i = 0 ; _i < _size_x ; _i++ )  {    _cube[0] = get_data( _i, _j, _k ) ;    if( _i < _size_x - 1 ) _cube[1] = get_data(_i+1, _j , _k ) ;    else                 _cube[1] = _cube[0] ;    if( _j < _size_y - 1 ) _cube[3] = get_data( _i ,_j+1, _k ) ;    else                 _cube[3] = _cube[0] ;    if( _k < _size_z - 1 ) _cube[4] = get_data( _i , _j ,_k+1) ;    else                 _cube[4] = _cube[0] ;    if( fabs( _cube[0] ) < FLT_EPSILON ) _cube[0] = FLT_EPSILON ;    if( fabs( _cube[1] ) < FLT_EPSILON ) _cube[1] = FLT_EPSILON ;    if( fabs( _cube[3] ) < FLT_EPSILON ) _cube[3] = FLT_EPSILON ;    if( fabs( _cube[4] ) < FLT_EPSILON ) _cube[4] = FLT_EPSILON ;    if( _cube[0] < 0 )    {      if( _cube[1] > 0 ) set_x_vert( add_x_vertex( ), _i,_j,_k ) ;      if( _cube[3] > 0 ) set_y_vert( add_y_vertex( ), _i,_j,_k ) ;      if( _cube[4] > 0 ) set_z_vert( add_z_vertex( ), _i,_j,_k ) ;    }    else    {      if( _cube[1] < 0 ) set_x_vert( add_x_vertex( ), _i,_j,_k ) ;      if( _cube[3] < 0 ) set_y_vert( add_y_vertex( ), _i,_j,_k ) ;      if( _cube[4] < 0 ) set_z_vert( add_z_vertex( ), _i,_j,_k ) ;    }  }}//_____________________________________________________________________________//_____________________________________________________________________________// Test a face// if face>0 return true if the face contains a part of the surfacebool MarchingCubes::test_face( schar face )//-----------------------------------------------------------------------------{  float A,B,C,D ;  switch( face )  {  case -1 : case 1 :  A = _cube[0] ;  B = _cube[4] ;  C = _cube[5] ;  D = _cube[1] ;  break ;  case -2 : case 2 :  A = _cube[1] ;  B = _cube[5] ;  C = _cube[6] ;  D = _cube[2] ;  break ;  case -3 : case 3 :  A = _cube[2] ;  B = _cube[6] ;  C = _cube[7] ;  D = _cube[3] ;  break ;  case -4 : case 4 :  A = _cube[3] ;  B = _cube[7] ;  C = _cube[4] ;  D = _cube[0] ;  break ;  case -5 : case 5 :  A = _cube[0] ;  B = _cube[3] ;  C = _cube[2] ;  D = _cube[1] ;  break ;  case -6 : case 6 :  A = _cube[4] ;  B = _cube[7] ;  C = _cube[6] ;  D = _cube[5] ;  break ;  default : printf( "Invalid face code %d\n", face ) ;  print_cube() ;  A = B = C = D = 0 ;  };  return face * A * ( A*C - B*D ) >= 0  ;  // face and A invert signs}//_____________________________________________________________________________//_____________________________________________________________________________// Test the interior of a cube// if s == 7, return true  if the interior is empty// if s ==-7, return false if the interior is emptybool MarchingCubes::test_interior( schar s )//-----------------------------------------------------------------------------{  float t, At=0, Bt=0, Ct=0, Dt=0, a, b ;  char  test =  0 ;  char  edge = -1 ; // reference edge of the triangulation  switch( _case )  {  case  4 :  case 10 :    a = ( _cube[4] - _cube[0] ) * ( _cube[6] - _cube[2] ) - ( _cube[7] - _cube[3] ) * ( _cube[5] - _cube[1] ) ;    b =  _cube[2] * ( _cube[4] - _cube[0] ) + _cube[0] * ( _cube[6] - _cube[2] )             - _cube[1] * ( _cube[7] - _cube[3] ) - _cube[3] * ( _cube[5] - _cube[1] ) ;    t = - b / (2*a) ;    if( t<0 || t>1 ) return s>0 ;    At = _cube[0] + ( _cube[4] - _cube[0] ) * t ;    Bt = _cube[3] + ( _cube[7] - _cube[3] ) * t ;    Ct = _cube[2] + ( _cube[6] - _cube[2] ) * t ;    Dt = _cube[1] + ( _cube[5] - _cube[1] ) * t ;    break ;  case  6 :  case  7 :  case 12 :  case 13 :    switch( _case )    {    case  6 : edge = test6 [_config][2] ; break ;    case  7 : edge = test7 [_config][4] ; break ;    case 12 : edge = test12[_config][3] ; break ;    case 13 : edge = tiling13_5_1[_config][_subconfig][0] ; break ;    }    switch( edge )    {    case  0 :      t  = _cube[0] / ( _cube[0] - _cube[1] ) ;      At = 0 ;      Bt = _cube[3] + ( _cube[2] - _cube[3] ) * t ;      Ct = _cube[7] + ( _cube[6] - _cube[7] ) * t ;      Dt = _cube[4] + ( _cube[5] - _cube[4] ) * t ;      break ;    case  1 :      t  = _cube[1] / ( _cube[1] - _cube[2] ) ;      At = 0 ;      Bt = _cube[0] + ( _cube[3] - _cube[0] ) * t ;      Ct = _cube[4] + ( _cube[7] - _cube[4] ) * t ;      Dt = _cube[5] + ( _cube[6] - _cube[5] ) * t ;      break ;    case  2 :      t  = _cube[2] / ( _cube[2] - _cube[3] ) ;      At = 0 ;      Bt = _cube[1] + ( _cube[0] - _cube[1] ) * t ;      Ct = _cube[5] + ( _cube[4] - _cube[5] ) * t ;      Dt = _cube[6] + ( _cube[7] - _cube[6] ) * t ;      break ;    case  3 :      t  = _cube[3] / ( _cube[3] - _cube[0] ) ;      At = 0 ;      Bt = _cube[2] + ( _cube[1] - _cube[2] ) * t ;      Ct = _cube[6] + ( _cube[5] - _cube[6] ) * t ;      Dt = _cube[7] + ( _cube[4] - _cube[7] ) * t ;      break ;    case  4 :      t  = _cube[4] / ( _cube[4] - _cube[5] ) ;      At = 0 ;      Bt = _cube[7] + ( _cube[6] - _cube[7] ) * t ;      Ct = _cube[3] + ( _cube[2] - _cube[3] ) * t ;      Dt = _cube[0] + ( _cube[1] - _cube[0] ) * t ;      break ;    case  5 :      t  = _cube[5] / ( _cube[5] - _cube[6] ) ;      At = 0 ;      Bt = _cube[4] + ( _cube[7] - _cube[4] ) * t ;      Ct = _cube[0] + ( _cube[3] - _cube[0] ) * t ;      Dt = _cube[1] + ( _cube[2] - _cube[1] ) * t ;      break ;    case  6 :      t  = _cube[6] / ( _cube[6] - _cube[7] ) ;      At = 0 ;      Bt = _cube[5] + ( _cube[4] - _cube[5] ) * t ;      Ct = _cube[1] + ( _cube[0] - _cube[1] ) * t ;      Dt = _cube[2] + ( _cube[3] - _cube[2] ) * t ;      break ;    case  7 :      t  = _cube[7] / ( _cube[7] - _cube[4] ) ;      At = 0 ;      Bt = _cube[6] + ( _cube[5] - _cube[6] ) * t ;      Ct = _cube[2] + ( _cube[1] - _cube[2] ) * t ;      Dt = _cube[3] + ( _cube[0] - _cube[3] ) * t ;      break ;    case  8 :      t  = _cube[0] / ( _cube[0] - _cube[4] ) ;      At = 0 ;      Bt = _cube[3] + ( _cube[7] - _cube[3] ) * t ;      Ct = _cube[2] + ( _cube[6] - _cube[2] ) * t ;      Dt = _cube[1] + ( _cube[5] - _cube[1] ) * t ;      break ;    case  9 :      t  = _cube[1] / ( _cube[1] - _cube[5] ) ;      At = 0 ;      Bt = _cube[0] + ( _cube[4] - _cube[0] ) * t ;      Ct = _cube[3] + ( _cube[7] - _cube[3] ) * t ;      Dt = _cube[2] + ( _cube[6] - _cube[2] ) * t ;      break ;    case 10 :      t  = _cube[2] / ( _cube[2] - _cube[6] ) ;      At = 0 ;      Bt = _cube[1] + ( _cube[5] - _cube[1] ) * t ;      Ct = _cube[0] + ( _cube[4] - _cube[0] ) * t ;      Dt = _cube[3] + ( _cube[7] - _cube[3] ) * t ;      break ;    case 11 :      t  = _cube[3] / ( _cube[3] - _cube[7] ) ;      At = 0 ;      Bt = _cube[2] + ( _cube[6] - _cube[2] ) * t ;      Ct = _cube[1] + ( _cube[5] - _cube[1] ) * t ;      Dt = _cube[0] + ( _cube[4] - _cube[0] ) * t ;      break ;    default : printf( "Invalid edge %d\n", edge ) ;  print_cube() ;  break ;    }    break ;  default : printf( "Invalid ambiguous case %d\n", _case ) ;  print_cube() ;  break ;  }  if( At >= 0 ) test ++ ;  if( Bt >= 0 ) test += 2 ;  if( Ct >= 0 ) test += 4 ;  if( Dt >= 0 ) test += 8 ;  switch( test )  {  case  0 : return s>0 ;  case  1 : return s>0 ;  case  2 : return s>0 ;  case  3 : return s>0 ;  case  4 : return s>0 ;  case  5 : if( At * Ct <  Bt * Dt ) return s>0 ; break ;  case  6 : return s>0 ;  case  7 : return s<0 ;  case  8 : return s>0 ;  case  9 : return s>0 ;  case 10 : if( At * Ct >= Bt * Dt ) return s>0 ; break ;  case 11 : return s<0 ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -