An Implementation of the Marching Cubes Algorithm
1.0
|
00001 00024 #include <iostream> // std::cout, std::endl, std::cerr 00025 #include <cstdlib> // EXIT_SUCCESS, EXIT_FAILURE 00026 00027 #include "grid.hpp" // mc::Grid 00028 #include "surfbuilder.hpp" // mc::SurfBuilder 00029 #include "3dvector.hpp" // common::t3DVector 00030 00031 00032 using mc::Grid ; 00033 using mc::SurfBuilder ; 00034 using common::t3DVector ; 00035 00036 00037 // ------------------------------------------------------------------- 00038 // 00039 // Auxiliary functions. 00040 // 00041 // ------------------------------------------------------------------- 00042 00056 bool check_grid( const Grid& g ) 00057 { 00058 unsigned sx = g.get_size_x() ; 00059 unsigned sy = g.get_size_y() ; 00060 unsigned sz = g.get_size_z() ; 00061 00062 for ( unsigned j = 0 ; j < sy ; j++ ) { 00063 for ( unsigned i = 0 ; i < sx ; i++ ) { 00064 if ( 00065 ( g.get_value( i , j , 0 ) <= 0 ) || 00066 ( g.get_value( i , j , sz - 1 ) <= 0 ) 00067 ) 00068 { 00069 return false ; 00070 } 00071 } 00072 } 00073 00074 for ( unsigned k = 0 ; k < sz ; k++ ) { 00075 for ( unsigned i = 0 ; i < sx ; i++ ) { 00076 if ( 00077 ( g.get_value( i , 0 , k ) <= 0 ) || 00078 ( g.get_value( i , sy - 1 , k ) <= 0 ) 00079 ) 00080 { 00081 return false ; 00082 } 00083 } 00084 } 00085 00086 for ( unsigned k = 0 ; k < sz ; k++ ) { 00087 for ( unsigned j = 0 ; j < sy ; j++ ) { 00088 if ( 00089 ( g.get_value( 0 , j , k ) <= 0 ) || 00090 ( g.get_value( sx - 1, j , k ) <= 0 ) 00091 ) 00092 { 00093 return false ; 00094 } 00095 } 00096 } 00097 00098 return true ; 00099 } 00100 00101 00115 double torus( 00116 double x , 00117 double y , 00118 double z 00119 ) 00120 { 00121 double x2 = x * x ; 00122 double y2 = y * y ; 00123 double z2 = z * z ; 00124 00125 double ff = 4 - sqrt( x2 + y2 ) ; 00126 00127 ff *= ff ; 00128 00129 ff += ( z2 - 4 ) ; 00130 00131 return ff ; 00132 } 00133 00134 00135 00136 // ------------------------------------------------------------------ 00137 // 00138 // Main function starts below: 00139 // 00140 // ------------------------------------------------------------------ 00141 00149 int main() 00150 { 00151 // 00152 // Create a 3D grid. 00153 // 00154 00155 std::cerr << "Create a 3D grid..." 00156 << std::endl ; 00157 00158 Grid g( 00159 26 , // Number of points in the X direction. 00160 26 , // Number of points in the Y direction. 00161 26 , // Number of points in the Z direction. 00162 t3DVector( -7.00 , -7.00 , -7.00 ) , // Grid origin. 00163 t3DVector( 0.56 , 0.56 , 0.56 ) // Length of the edges in each direction. 00164 ) ; 00165 00166 // 00167 // Assign value to each grid point. 00168 // 00169 00170 std::cerr << "Compute function values at the grid vertices..." 00171 << std::endl ; 00172 00173 unsigned sx = g.get_size_x() ; 00174 unsigned sy = g.get_size_y() ; 00175 unsigned sz = g.get_size_z() ; 00176 00177 for ( unsigned i = 0 ; i < sx ; i++ ) { 00178 for ( unsigned j = 0 ; j < sy ; j++ ) { 00179 for ( unsigned k = 0 ; k < sz ; k++ ) { 00180 t3DVector pt = g.get_origin() ; 00181 00182 double x = pt._x + i * g.get_spacing_x() ; 00183 double y = pt._y + j * g.get_spacing_y() ; 00184 double z = pt._z + k * g.get_spacing_z() ; 00185 00186 double f = torus( x , y , z ) ; 00187 00188 g.set_value( i , j , k , f ) ; 00189 } 00190 } 00191 } 00192 00193 00194 // 00195 // Check grid consistency. 00196 // 00197 00198 std::cerr << "Check the consistency of the grid..." 00199 << std::endl ; 00200 00201 if ( !check_grid( g ) ) { 00202 std::cerr << "The grid is not consistent" << std::endl ; 00203 return EXIT_FAILURE; 00204 } 00205 00206 // 00207 // Run the MC algorithm. 00208 // 00209 00210 std::cerr << "Run the Marching Cubes algorithm..." 00211 << std::endl ; 00212 00213 SurfBuilder sb( &g ) ; 00214 00215 sb.run() ; 00216 00217 std::cerr << "Done!" << std::endl ; 00218 00219 return EXIT_SUCCESS ; 00220 } 00221 00222 00223