00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef __VCG_MARCHING_CUBES
00026 #define __VCG_MARCHING_CUBES
00027
00028 #include <assert.h>
00029 #include <vcg/space/point3.h>
00030 #include <vcg/complex/trimesh/allocate.h>
00031 #include "mc_lookup_table.h"
00032
00033 namespace vcg
00034 {
00035 namespace tri
00036 {
00037
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00056
00064 template<class TRIMESH_TYPE, class WALKER_TYPE>
00065 class MarchingCubes
00066 {
00067 public:
00068 enum Dimension {X, Y, Z};
00069
00070 #if defined(__GNUC__)
00071 typedef unsigned int size_t;
00072 #else
00073 #ifdef _WIN64
00074 typedef unsigned __int64 size_t;
00075 #else
00076 typedef _W64 unsigned int size_t;
00077 #endif
00078 #endif
00079 typedef typename vcg::tri::Allocator< TRIMESH_TYPE > AllocatorType;
00080 typedef typename TRIMESH_TYPE::ScalarType ScalarType;
00081 typedef typename TRIMESH_TYPE::VertexType VertexType;
00082 typedef typename TRIMESH_TYPE::VertexPointer VertexPointer;
00083 typedef typename TRIMESH_TYPE::VertexIterator VertexIterator;
00084 typedef typename TRIMESH_TYPE::FaceType FaceType;
00085 typedef typename TRIMESH_TYPE::FacePointer FacePointer;
00086 typedef typename TRIMESH_TYPE::FaceIterator FaceIterator;
00087 typedef typename TRIMESH_TYPE::CoordType CoordType;
00088 typedef typename TRIMESH_TYPE::CoordType* CoordPointer;
00089
00095 MarchingCubes(TRIMESH_TYPE &mesh, WALKER_TYPE &walker)
00096 {
00097 _mesh = &mesh;
00098 _walker = &walker;
00099 };
00100
00105 void Initialize()
00106 {
00107 _mesh->Clear();
00108 };
00109
00114 void Finalize()
00115 {
00116 _mesh = NULL;
00117 _walker = NULL;
00118 };
00119
00126 void ProcessCell(const vcg::Point3i &min, const vcg::Point3i &max)
00127 {
00128 _case = _subconfig = _config = -1;
00129 assert(min[0]<max[0] && min[1]<max[1] && min[2]<max[2]);
00130 _corners[0].X()=min.X(); _corners[0].Y()=min.Y(); _corners[0].Z()=min.Z();
00131 _corners[1].X()=max.X(); _corners[1].Y()=min.Y(); _corners[1].Z()=min.Z();
00132 _corners[2].X()=max.X(); _corners[2].Y()=max.Y(); _corners[2].Z()=min.Z();
00133 _corners[3].X()=min.X(); _corners[3].Y()=max.Y(); _corners[3].Z()=min.Z();
00134 _corners[4].X()=min.X(); _corners[4].Y()=min.Y(); _corners[4].Z()=max.Z();
00135 _corners[5].X()=max.X(); _corners[5].Y()=min.Y(); _corners[5].Z()=max.Z();
00136 _corners[6].X()=max.X(); _corners[6].Y()=max.Y(); _corners[6].Z()=max.Z();
00137 _corners[7].X()=min.X(); _corners[7].Y()=max.Y(); _corners[7].Z()=max.Z();
00138
00139 for (int i=0; i<8; i++)
00140 _field[i] = _walker->V( _corners[i].X(), _corners[i].Y(), _corners[i].Z() );
00141
00142 unsigned char cubetype = 0;
00143 for (int i=0; i<8; i++)
00144 if (_field[i]>0) cubetype += 1<<i;
00145
00146 _case = MCLookUpTable::Cases(cubetype, 0);
00147 _config = MCLookUpTable::Cases(cubetype, 1);
00148 _subconfig = 0;
00149
00150 VertexPointer v12 = NULL;
00151
00152 switch( _case )
00153 {
00154 case 0 : { break ; }
00155 case 1 : { AddTriangles( MCLookUpTable::Tiling1(_config), 1 ); break; }
00156 case 2 : { AddTriangles( MCLookUpTable::Tiling2(_config), 2 ); break; }
00157 case 3 :
00158 {
00159
00160 if( TestFace( MCLookUpTable::Test3(_config)) )
00161 AddTriangles( MCLookUpTable::Tiling3_2(_config), 4 ) ;
00162 else
00163 AddTriangles( MCLookUpTable::Tiling3_1(_config), 2 ) ;
00164 break ;
00165 }
00166 case 4 :
00167 {
00168
00169 if( TestInterior( MCLookUpTable::Test4(_config) ) )
00170 AddTriangles( MCLookUpTable::Tiling4_1(_config), 2 ) ;
00171 else
00172 AddTriangles( MCLookUpTable::Tiling4_2(_config), 6 ) ;
00173 break ;
00174 }
00175 case 5 : { AddTriangles( MCLookUpTable::Tiling5(_config), 3 ); break; }
00176 case 6 :
00177 {
00178
00179 if( TestFace( MCLookUpTable::Test6(_config, 0)) )
00180 AddTriangles( MCLookUpTable::Tiling6_2(_config), 5 ) ;
00181 else
00182 {
00183 if( TestInterior( MCLookUpTable::Test6(_config, 1)) )
00184 AddTriangles( MCLookUpTable::Tiling6_1_1(_config), 3 ) ;
00185 else
00186 AddTriangles( MCLookUpTable::Tiling6_1_2(_config), 7 ) ;
00187 }
00188 break ;
00189 }
00190 case 7 :
00191 {
00192
00193
00194
00195 if( TestFace( MCLookUpTable::Test7(_config, 0) ) ) _subconfig += 1 ;
00196 if( TestFace( MCLookUpTable::Test7(_config, 1) ) ) _subconfig += 2 ;
00197 if( TestFace( MCLookUpTable::Test7(_config, 2) ) ) _subconfig += 4 ;
00198 switch( _subconfig )
00199 {
00200 case 0 : { AddTriangles( MCLookUpTable::Tiling7_1(_config), 3 ) ; break; }
00201 case 1 : { AddTriangles( MCLookUpTable::Tiling7_2(_config,0), 5 ) ; break; }
00202 case 2 : { AddTriangles( MCLookUpTable::Tiling7_2(_config,1), 5 ) ; break; }
00203 case 3 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling7_3(_config,0), 9, v12 ) ; break ; }
00204 case 4 : { AddTriangles( MCLookUpTable::Tiling7_2(_config, 2), 5 ) ; break ;}
00205 case 5 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling7_3(_config,1), 9, v12 ) ; break ; }
00206 case 6 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling7_3(_config,2), 9, v12 ) ; break ; }
00207 case 7 :
00208 {
00209 if( TestInterior( MCLookUpTable::Test7(_config, 3) ) )
00210 AddTriangles( MCLookUpTable::Tiling7_4_2(_config), 9 ) ;
00211 else
00212 AddTriangles( MCLookUpTable::Tiling7_4_1(_config), 5 ) ;
00213 break ;
00214 }
00215 };
00216 break ;
00217 }
00218 case 8 : { AddTriangles( MCLookUpTable::Tiling8(_config), 2 ) ; break ;}
00219 case 9 : { AddTriangles( MCLookUpTable::Tiling9(_config), 4 ) ; break ;}
00220 case 10 :
00221 {
00222 if( TestFace( MCLookUpTable::Test10(_config, 0)) )
00223 {
00224 if( TestFace( MCLookUpTable::Test10(_config,1) ) )
00225 AddTriangles( MCLookUpTable::Tiling10_1_1_(_config), 4 ) ;
00226 else
00227 {
00228 ComputeCVertex(v12);
00229 AddTriangles( MCLookUpTable::Tiling10_2(_config), 8, v12 ) ;
00230 }
00231 }
00232 else
00233 {
00234 if( TestFace( MCLookUpTable::Test10(_config, 1) ) )
00235 {
00236 ComputeCVertex(v12) ;
00237 AddTriangles( MCLookUpTable::Tiling10_2_(_config), 8, v12 ) ;
00238 }
00239 else
00240 {
00241 if( TestInterior( MCLookUpTable::Test10(_config, 2) ) )
00242 AddTriangles( MCLookUpTable::Tiling10_1_1(_config), 4 ) ;
00243 else
00244 AddTriangles( MCLookUpTable::Tiling10_1_2(_config), 8 ) ;
00245 }
00246 }
00247 break ;
00248 }
00249 case 11 : { AddTriangles( MCLookUpTable::Tiling11(_config), 4 ) ; break ; }
00250 case 12 :
00251 {
00252 if( TestFace( MCLookUpTable::Test12(_config, 0) ) )
00253 {
00254 if( TestFace( MCLookUpTable::Test12(_config, 1) ) )
00255 AddTriangles( MCLookUpTable::Tiling12_1_1_(_config), 4 ) ;
00256 else
00257 {
00258 ComputeCVertex(v12) ;
00259 AddTriangles( MCLookUpTable::Tiling12_2(_config), 8, v12 ) ;
00260 }
00261 }
00262 else
00263 {
00264 if( TestFace( MCLookUpTable::Test12(_config, 1) ) )
00265 {
00266 ComputeCVertex(v12) ;
00267 AddTriangles( MCLookUpTable::Tiling12_2_(_config), 8, v12 ) ;
00268 }
00269 else
00270 {
00271 if( TestInterior( MCLookUpTable::Test12(_config, 2) ) )
00272 AddTriangles( MCLookUpTable::Tiling12_1_1(_config), 4 ) ;
00273 else
00274 AddTriangles( MCLookUpTable::Tiling12_1_2(_config), 8 ) ;
00275 }
00276 }
00277 break ;
00278 }
00279 case 13 :
00280 {
00281
00282
00283
00284
00285
00286
00287 if( TestFace( MCLookUpTable::Test13(_config, 0) ) ) _subconfig += 1 ;
00288 if( TestFace( MCLookUpTable::Test13(_config, 1) ) ) _subconfig += 2 ;
00289 if( TestFace( MCLookUpTable::Test13(_config, 2) ) ) _subconfig += 4 ;
00290 if( TestFace( MCLookUpTable::Test13(_config, 3) ) ) _subconfig += 8 ;
00291 if( TestFace( MCLookUpTable::Test13(_config, 4) ) ) _subconfig += 16 ;
00292 if( TestFace( MCLookUpTable::Test13(_config, 5) ) ) _subconfig += 32 ;
00293 switch( MCLookUpTable::Subconfig13(_subconfig) )
00294 {
00295 case 0 : { AddTriangles( MCLookUpTable::Tiling13_1(_config) , 4 ) ; break ; }
00296 case 1 : { AddTriangles( MCLookUpTable::Tiling13_2(_config, 0), 6 ) ; break ; }
00297 case 2 : { AddTriangles( MCLookUpTable::Tiling13_2(_config, 1), 6 ) ; break ; }
00298 case 3 : { AddTriangles( MCLookUpTable::Tiling13_2(_config, 2), 6 ) ; break ; }
00299 case 4 : { AddTriangles( MCLookUpTable::Tiling13_2(_config, 3), 6 ) ; break ; }
00300 case 5 : { AddTriangles( MCLookUpTable::Tiling13_2(_config, 4), 6 ) ; break ; }
00301 case 6 : { AddTriangles( MCLookUpTable::Tiling13_2(_config, 5), 6 ) ; break ; }
00302 case 7 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3(_config, 0), 10, v12 ) ; break ; }
00303 case 8 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3(_config, 1), 10, v12 ) ; break ; }
00304 case 9 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3(_config, 2), 10, v12 ) ; break ; }
00305 case 10 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3(_config, 3), 10, v12 ) ; break ; }
00306 case 11 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3(_config, 4), 10, v12 ) ; break ; }
00307 case 12 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3(_config, 5), 10, v12 ) ; break ; }
00308 case 13 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3(_config, 6), 10, v12 ) ; break ; }
00309 case 14 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3(_config, 7), 10, v12 ) ; break ; }
00310 case 15 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3(_config, 8), 10, v12 ) ; break ; }
00311 case 16 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3(_config, 9), 10, v12 ) ; break ; }
00312 case 17 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3(_config,10), 10, v12 ) ; break ; }
00313 case 18 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3(_config,11), 10, v12 ) ; break ; }
00314 case 19 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_4(_config, 0), 12, v12 ) ; break ; }
00315 case 20 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_4(_config, 1), 12, v12 ) ; break ; }
00316 case 21 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_4(_config, 2), 12, v12 ) ; break ; }
00317 case 22 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_4(_config, 3), 12, v12 ) ; break ; }
00318 case 23 :
00319 {
00320 _subconfig = 0 ;
00321 if( TestInterior( MCLookUpTable::Test13(_config, 6) ) )
00322 AddTriangles( MCLookUpTable::Tiling13_5_1(_config, 0), 6 ) ;
00323 else
00324 AddTriangles( MCLookUpTable::Tiling13_5_2(_config, 0), 10 ) ;
00325 break ;
00326 }
00327 case 24 :
00328 {
00329 _subconfig = 1 ;
00330 if( TestInterior( MCLookUpTable::Test13(_config, 6) ) )
00331 AddTriangles( MCLookUpTable::Tiling13_5_1(_config, 1), 6 ) ;
00332 else
00333 AddTriangles( MCLookUpTable::Tiling13_5_2(_config, 1), 10 ) ;
00334 break ;
00335 }
00336 case 25 :
00337 {
00338 _subconfig = 2 ;
00339 if( TestInterior( MCLookUpTable::Test13(_config, 6) ) )
00340 AddTriangles( MCLookUpTable::Tiling13_5_1(_config, 2), 6 ) ;
00341 else
00342 AddTriangles( MCLookUpTable::Tiling13_5_2(_config, 2), 10 ) ;
00343 break ;
00344 }
00345 case 26 :
00346 {
00347 _subconfig = 3 ;
00348 if( TestInterior( MCLookUpTable::Test13(_config, 6) ) )
00349 AddTriangles( MCLookUpTable::Tiling13_5_1(_config, 3), 6 ) ;
00350 else
00351 AddTriangles( MCLookUpTable::Tiling13_5_2(_config, 3), 10 ) ;
00352 break ;
00353 }
00354 case 27 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3_(_config, 0), 10, v12 ) ; break ; }
00355 case 28 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3_(_config, 1), 10, v12 ) ; break ; }
00356 case 29 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3_(_config, 2), 10, v12 ) ; break ; }
00357 case 30 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3_(_config, 3), 10, v12 ) ; break ; }
00358 case 31 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3_(_config, 4), 10, v12 ) ; break ; }
00359 case 32 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3_(_config, 5), 10, v12 ) ; break ; }
00360 case 33 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3_(_config, 6), 10, v12 ) ; break ; }
00361 case 34 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3_(_config, 7), 10, v12 ) ; break ; }
00362 case 35 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3_(_config, 8), 10, v12 ) ; break ; }
00363 case 36 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3_(_config, 9), 10, v12 ) ; break ; }
00364 case 37 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3_(_config,10), 10, v12 ) ; break ; }
00365 case 38 : { ComputeCVertex(v12); AddTriangles( MCLookUpTable::Tiling13_3_(_config,11), 10, v12 ) ; break ; }
00366 case 39 : { AddTriangles( MCLookUpTable::Tiling13_2_(_config,0), 6 ) ; break ; }
00367 case 40 : { AddTriangles( MCLookUpTable::Tiling13_2_(_config,1), 6 ) ; break ; }
00368 case 41 : { AddTriangles( MCLookUpTable::Tiling13_2_(_config,2), 6 ) ; break ; }
00369 case 42 : { AddTriangles( MCLookUpTable::Tiling13_2_(_config,3), 6 ) ; break ; }
00370 case 43 : { AddTriangles( MCLookUpTable::Tiling13_2_(_config,4), 6 ) ; break ; }
00371 case 44 : { AddTriangles( MCLookUpTable::Tiling13_2_(_config,5), 6 ) ; break ; }
00372 case 45 : { AddTriangles( MCLookUpTable::Tiling13_1_(_config) , 4 ) ; break ; }
00373 default : { assert(false); }
00374 }
00375 break ;
00376 }
00377
00378 case 14 : { AddTriangles( MCLookUpTable::Tiling14(_config), 4 ) ; }
00379 break ;
00380 }
00381
00382 };
00383
00384 private:
00387 WALKER_TYPE *_walker;
00390 TRIMESH_TYPE *_mesh;
00391
00395 ScalarType _field[8];
00396
00400 vcg::Point3i _corners[8];
00401
00405 unsigned char _case;
00406
00410 unsigned char _config;
00411
00415 unsigned char _subconfig;
00416
00421 inline bool TestFace(signed char face)
00422 {
00423 ScalarType A,B,C,D ;
00424
00425 switch( face )
00426 {
00427 case -1 : case 1 : A = _field[0] ; B = _field[4] ; C = _field[5] ; D = _field[1] ; break ;
00428 case -2 : case 2 : A = _field[1] ; B = _field[5] ; C = _field[6] ; D = _field[2] ; break ;
00429 case -3 : case 3 : A = _field[2] ; B = _field[6] ; C = _field[7] ; D = _field[3] ; break ;
00430 case -4 : case 4 : A = _field[3] ; B = _field[7] ; C = _field[4] ; D = _field[0] ; break ;
00431 case -5 : case 5 : A = _field[0] ; B = _field[3] ; C = _field[2] ; D = _field[1] ; break ;
00432 case -6 : case 6 : A = _field[4] ; B = _field[7] ; C = _field[6] ; D = _field[5] ; break ;
00433 default : assert(false);
00434 };
00435
00436 return face * A * ( A*C - B*D ) >= 0 ;
00437 };
00438
00439
00444 inline bool TestInterior(signed char s)
00445 {
00446 ScalarType t, At=0, Bt=0, Ct=0, Dt=0, a, b ;
00447 char test = 0 ;
00448 char edge = -1 ;
00449
00450 switch( _case )
00451 {
00452 case 4 :
00453 case 10 :
00454 {
00455 a = (_field[4]-_field[0])*(_field[6]-_field[2]) - (_field[7]-_field[3])*(_field[5]-_field[1]);
00456 b = _field[2]*(_field[4]-_field[0])+_field[0]*(_field[6]-_field[2])-_field[1]*(_field[7]-_field[3])-_field[3]*(_field[5]-_field[1]);
00457 t = - b / (2*a) ;
00458 if( t<0 || t>1 )
00459 return s>0 ;
00460
00461 At = _field[0] + ( _field[4] - _field[0] ) * t ;
00462 Bt = _field[3] + ( _field[7] - _field[3] ) * t ;
00463 Ct = _field[2] + ( _field[6] - _field[2] ) * t ;
00464 Dt = _field[1] + ( _field[5] - _field[1] ) * t ;
00465 break ;
00466 }
00467 case 6 :
00468 case 7 :
00469 case 12 :
00470 case 13 :
00471 switch( _case )
00472 {
00473 case 6 : edge = MCLookUpTable::Test6 (_config, 2) ; break ;
00474 case 7 : edge = MCLookUpTable::Test7 (_config, 4) ; break ;
00475 case 12 : edge = MCLookUpTable::Test12(_config, 3) ; break ;
00476 case 13 : edge = MCLookUpTable::Tiling13_5_1(_config, _subconfig)[0] ; break ;
00477 }
00478 switch( edge )
00479 {
00480 case 0 :
00481 t = _field[0] / ( _field[0] - _field[1] ) ;
00482 At = 0 ;
00483 Bt = _field[3] + ( _field[2] - _field[3] ) * t ;
00484 Ct = _field[7] + ( _field[6] - _field[7] ) * t ;
00485 Dt = _field[4] + ( _field[5] - _field[4] ) * t ;
00486 break ;
00487 case 1 :
00488 t = _field[1] / ( _field[1] - _field[2] ) ;
00489 At = 0 ;
00490 Bt = _field[0] + ( _field[3] - _field[0] ) * t ;
00491 Ct = _field[4] + ( _field[7] - _field[4] ) * t ;
00492 Dt = _field[5] + ( _field[6] - _field[5] ) * t ;
00493 break ;
00494 case 2 :
00495 t = _field[2] / ( _field[2] - _field[3] ) ;
00496 At = 0 ;
00497 Bt = _field[1] + ( _field[0] - _field[1] ) * t ;
00498 Ct = _field[5] + ( _field[4] - _field[5] ) * t ;
00499 Dt = _field[6] + ( _field[7] - _field[6] ) * t ;
00500 break ;
00501 case 3 :
00502 t = _field[3] / ( _field[3] - _field[0] ) ;
00503 At = 0 ;
00504 Bt = _field[2] + ( _field[1] - _field[2] ) * t ;
00505 Ct = _field[6] + ( _field[5] - _field[6] ) * t ;
00506 Dt = _field[7] + ( _field[4] - _field[7] ) * t ;
00507 break ;
00508 case 4 :
00509 t = _field[4] / ( _field[4] - _field[5] ) ;
00510 At = 0 ;
00511 Bt = _field[7] + ( _field[6] - _field[7] ) * t ;
00512 Ct = _field[3] + ( _field[2] - _field[3] ) * t ;
00513 Dt = _field[0] + ( _field[1] - _field[0] ) * t ;
00514 break ;
00515 case 5 :
00516 t = _field[5] / ( _field[5] - _field[6] ) ;
00517 At = 0 ;
00518 Bt = _field[4] + ( _field[7] - _field[4] ) * t ;
00519 Ct = _field[0] + ( _field[3] - _field[0] ) * t ;
00520 Dt = _field[1] + ( _field[2] - _field[1] ) * t ;
00521 break ;
00522 case 6 :
00523 t = _field[6] / ( _field[6] - _field[7] ) ;
00524 At = 0 ;
00525 Bt = _field[5] + ( _field[4] - _field[5] ) * t ;
00526 Ct = _field[1] + ( _field[0] - _field[1] ) * t ;
00527 Dt = _field[2] + ( _field[3] - _field[2] ) * t ;
00528 break ;
00529 case 7 :
00530 t = _field[7] / ( _field[7] - _field[4] ) ;
00531 At = 0 ;
00532 Bt = _field[6] + ( _field[5] - _field[6] ) * t ;
00533 Ct = _field[2] + ( _field[1] - _field[2] ) * t ;
00534 Dt = _field[3] + ( _field[0] - _field[3] ) * t ;
00535 break ;
00536 case 8 :
00537 t = _field[0] / ( _field[0] - _field[4] ) ;
00538 At = 0 ;
00539 Bt = _field[3] + ( _field[7] - _field[3] ) * t ;
00540 Ct = _field[2] + ( _field[6] - _field[2] ) * t ;
00541 Dt = _field[1] + ( _field[5] - _field[1] ) * t ;
00542 break ;
00543 case 9 :
00544 t = _field[1] / ( _field[1] - _field[5] ) ;
00545 At = 0 ;
00546 Bt = _field[0] + ( _field[4] - _field[0] ) * t ;
00547 Ct = _field[3] + ( _field[7] - _field[3] ) * t ;
00548 Dt = _field[2] + ( _field[6] - _field[2] ) * t ;
00549 break ;
00550 case 10 :
00551 t = _field[2] / ( _field[2] - _field[6] ) ;
00552 At = 0 ;
00553 Bt = _field[1] + ( _field[5] - _field[1] ) * t ;
00554 Ct = _field[0] + ( _field[4] - _field[0] ) * t ;
00555 Dt = _field[3] + ( _field[7] - _field[3] ) * t ;
00556 break ;
00557 case 11 :
00558 t = _field[3] / ( _field[3] - _field[7] ) ;
00559 At = 0 ;
00560 Bt = _field[2] + ( _field[6] - _field[2] ) * t ;
00561 Ct = _field[1] + ( _field[5] - _field[1] ) * t ;
00562 Dt = _field[0] + ( _field[4] - _field[0] ) * t ;
00563 break ;
00564 default: { assert(false); break ; }
00565 }
00566 break ;
00567
00568 default : assert(false); break;
00569 }
00570
00571 if( At >= 0 ) test ++ ;
00572 if( Bt >= 0 ) test += 2 ;
00573 if( Ct >= 0 ) test += 4 ;
00574 if( Dt >= 0 ) test += 8 ;
00575 switch( test )
00576 {
00577 case 0 : return s>0 ;
00578 case 1 : return s>0 ;
00579 case 2 : return s>0 ;
00580 case 3 : return s>0 ;
00581 case 4 : return s>0 ;
00582 case 5 : if( At * Ct < Bt * Dt ) return s>0 ; break ;
00583 case 6 : return s>0 ;
00584 case 7 : return s<0 ;
00585 case 8 : return s>0 ;
00586 case 9 : return s>0 ;
00587 case 10 : if( At * Ct >= Bt * Dt ) return s>0 ; break ;
00588 case 11 : return s<0 ;
00589 case 12 : return s>0 ;
00590 case 13 : return s<0 ;
00591 case 14 : return s<0 ;
00592 case 15 : return s<0 ;
00593 }
00594 return s<0 ;
00595 };
00596
00601 inline void ComputeCVertex(VertexPointer &v12)
00602 {
00603 v12 = &*AllocatorType::AddVertices(*_mesh, 1);
00604 v12->P() = CoordType(0.0, 0.0, 0.0);
00605
00606 unsigned int count = 0;
00607 VertexPointer v = NULL;
00608 if (_walker->Exist(_corners[0], _corners[1], v) )
00609 {
00610 count++;
00611 v12->P() += v->P();
00612 }
00613 if (_walker->Exist(_corners[1], _corners[2], v) )
00614 {
00615 count++;
00616 v12->P() += v->P();
00617 }
00618 if (_walker->Exist(_corners[3], _corners[2], v) )
00619 {
00620 count++;
00621 v12->P() += v->P();
00622 }
00623 if (_walker->Exist(_corners[0], _corners[3], v) )
00624 {
00625 count++;
00626 v12->P() += v->P();
00627 }
00628 if (_walker->Exist(_corners[4], _corners[5], v) )
00629 {
00630 count++;
00631 v12->P() += v->P();
00632 }
00633 if (_walker->Exist(_corners[5], _corners[6], v) )
00634 {
00635 count++;
00636 v12->P() += v->P();
00637 }
00638 if (_walker->Exist(_corners[7], _corners[6], v) )
00639 {
00640 count++;
00641 v12->P() += v->P();
00642 }
00643 if (_walker->Exist(_corners[4], _corners[7], v) )
00644 {
00645 count++;
00646 v12->P() += v->P();
00647 }
00648 if (_walker->Exist(_corners[0], _corners[4], v) )
00649 {
00650 count++;
00651 v12->P() += v->P();
00652 }
00653 if (_walker->Exist(_corners[1], _corners[5], v) )
00654 {
00655 count++;
00656 v12->P() += v->P();
00657 }
00658 if (_walker->Exist(_corners[2], _corners[6], v) )
00659 {
00660 count++;
00661 v12->P() += v->P();
00662 }
00663 if (_walker->Exist(_corners[3], _corners[7], v) )
00664 {
00665 count++;
00666 v12->P() += v->P();
00667 }
00668 v12->P() /= (float) count;
00669 }
00676 inline void AddTriangles(const char *vertices_list, char n, VertexPointer v12=NULL)
00677 {
00678 VertexPointer vp = NULL;
00679 size_t face_idx = _mesh->face.size();
00680 size_t v12_idx = -1;
00681 size_t vertices_idx[3];
00682 if (v12 != NULL) v12_idx = v12 - &_mesh->vert[0];
00683 AllocatorType::AddFaces(*_mesh, (int) n);
00684
00685 for (int trig=0; trig<3*n; face_idx++ )
00686 {
00687 vp = NULL;
00688 memset(vertices_idx, -1, 3*sizeof(size_t));
00689 for (int vert=0; vert<3; vert++, trig++)
00690 {
00691
00692 switch ( vertices_list[trig] )
00693 {
00694 case 0: { _walker->GetXIntercept(_corners[0], _corners[1], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
00695 case 1: { _walker->GetYIntercept(_corners[1], _corners[2], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
00696 case 2: { _walker->GetXIntercept(_corners[3], _corners[2], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
00697 case 3: { _walker->GetYIntercept(_corners[0], _corners[3], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
00698 case 4: { _walker->GetXIntercept(_corners[4], _corners[5], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
00699 case 5: { _walker->GetYIntercept(_corners[5], _corners[6], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
00700 case 6: { _walker->GetXIntercept(_corners[7], _corners[6], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
00701 case 7: { _walker->GetYIntercept(_corners[4], _corners[7], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
00702 case 8: { _walker->GetZIntercept(_corners[0], _corners[4], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
00703 case 9: { _walker->GetZIntercept(_corners[1], _corners[5], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
00704 case 10: { _walker->GetZIntercept(_corners[2], _corners[6], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
00705 case 11: { _walker->GetZIntercept(_corners[3], _corners[7], vp); vertices_idx[vert] = vp - &_mesh->vert[0]; break; }
00706 case 12: { assert(v12 != NULL); vertices_idx[vert] = v12_idx; break; }
00707 default: { assert(false); }
00708 }
00709
00710
00711
00712 assert(vertices_idx[vert]<_mesh->vert.size());
00713 }
00714
00715 _mesh->face[face_idx].V(0) = &_mesh->vert[vertices_idx[0]];
00716 _mesh->face[face_idx].V(1) = &_mesh->vert[vertices_idx[1]];
00717 _mesh->face[face_idx].V(2) = &_mesh->vert[vertices_idx[2]];
00718 }
00719 };
00720
00721
00722 };
00723
00725
00726
00727 };
00728 };
00729
00730 #endif //__VCG_MARCHING_CUBES