25 #ifndef WMARCHINGCUBESALGORITHM_H
26 #define WMARCHINGCUBESALGORITHM_H
31 #include "../math/WMatrix.h"
32 #include "../WProgressCombiner.h"
33 #include "core/graphicsEngine/WTriangleMesh.h"
35 #include "WMarchingCubesCaseTables.h"
48 typedef std::map< unsigned int, WPointXYZId > ID2WPointXYZId;
58 typedef std::vector<WMCTriangle> WMCTriangleVECTOR;
114 template<
typename T >
115 boost::shared_ptr< WTriangleMesh >
generateSurface(
size_t nbCoordsX,
size_t nbCoordsY,
size_t nbCoordsZ,
117 const std::vector< T >* vals,
119 boost::shared_ptr< WProgressCombiner > mainProgress );
136 unsigned int nX,
unsigned int nY,
unsigned int nZ,
unsigned int nEdgeNo );
153 WPointXYZId interpolate(
double fX1,
double fY1,
double fZ1,
double fX2,
double fY2,
double fZ2,
double tVal1,
double tVal2 );
165 int getEdgeID(
unsigned int nX,
unsigned int nY,
unsigned int nZ,
unsigned int nEdgeNo );
175 unsigned int getVertexID(
unsigned int nX,
unsigned int nY,
unsigned int nZ );
192 const std::vector< T >* vals,
194 boost::shared_ptr< WProgressCombiner > mainProgress )
196 WAssert( vals,
"No value set provided." );
213 unsigned int nPointsInSlice = nX * nY;
215 boost::shared_ptr< WProgress > progress(
new WProgress(
"Marching Cubes",
m_nCellsZ ) );
216 mainProgress->addSubProgress( progress );
218 for(
unsigned int z = 0; z <
m_nCellsZ; z++ )
221 for(
unsigned int y = 0; y <
m_nCellsY; y++ )
223 for(
unsigned int x = 0; x <
m_nCellsX; x++ )
227 unsigned int tableIndex = 0;
228 if( ( *vals )[ z * nPointsInSlice + y * nX + x ] <
m_tIsoLevel )
230 if( ( *vals )[ z * nPointsInSlice + ( y + 1 ) * nX + x ] <
m_tIsoLevel )
232 if( ( *vals )[ z * nPointsInSlice + ( y + 1 ) * nX + ( x + 1 ) ] <
m_tIsoLevel )
234 if( ( *vals )[ z * nPointsInSlice + y * nX + ( x + 1 ) ] <
m_tIsoLevel )
236 if( ( *vals )[ ( z + 1 ) * nPointsInSlice + y * nX + x ] <
m_tIsoLevel )
238 if( ( *vals )[ ( z + 1 ) * nPointsInSlice + ( y + 1 ) * nX + x ] <
m_tIsoLevel )
240 if( ( *vals )[ ( z + 1 ) * nPointsInSlice + ( y + 1 ) * nX + ( x + 1 ) ] <
m_tIsoLevel )
242 if( ( *vals )[ ( z + 1 ) * nPointsInSlice + y * nX + ( x + 1 ) ] <
m_tIsoLevel )
247 if( wMarchingCubesCaseTables::edgeTable[tableIndex] != 0 )
249 if( wMarchingCubesCaseTables::edgeTable[tableIndex] & 8 )
252 unsigned int id =
getEdgeID( x, y, z, 3 );
255 if( wMarchingCubesCaseTables::edgeTable[tableIndex] & 1 )
258 unsigned int id =
getEdgeID( x, y, z, 0 );
261 if( wMarchingCubesCaseTables::edgeTable[tableIndex] & 256 )
264 unsigned int id =
getEdgeID( x, y, z, 8 );
268 if( x == m_nCellsX - 1 )
270 if( wMarchingCubesCaseTables::edgeTable[tableIndex] & 4 )
273 unsigned int id =
getEdgeID( x, y, z, 2 );
276 if( wMarchingCubesCaseTables::edgeTable[tableIndex] & 2048 )
279 unsigned int id =
getEdgeID( x, y, z, 11 );
283 if( y == m_nCellsY - 1 )
285 if( wMarchingCubesCaseTables::edgeTable[tableIndex] & 2 )
288 unsigned int id =
getEdgeID( x, y, z, 1 );
291 if( wMarchingCubesCaseTables::edgeTable[tableIndex] & 512 )
294 unsigned int id =
getEdgeID( x, y, z, 9 );
298 if( z == m_nCellsZ - 1 )
300 if( wMarchingCubesCaseTables::edgeTable[tableIndex] & 16 )
303 unsigned int id =
getEdgeID( x, y, z, 4 );
306 if( wMarchingCubesCaseTables::edgeTable[tableIndex] & 128 )
309 unsigned int id =
getEdgeID( x, y, z, 7 );
313 if( ( x == m_nCellsX - 1 ) && ( y == m_nCellsY - 1 ) )
314 if( wMarchingCubesCaseTables::edgeTable[tableIndex] & 1024 )
317 unsigned int id =
getEdgeID( x, y, z, 10 );
320 if( ( x == m_nCellsX - 1 ) && ( z == m_nCellsZ - 1 ) )
321 if( wMarchingCubesCaseTables::edgeTable[tableIndex] & 64 )
324 unsigned int id =
getEdgeID( x, y, z, 6 );
327 if( ( y == m_nCellsY - 1 ) && ( z == m_nCellsZ - 1 ) )
328 if( wMarchingCubesCaseTables::edgeTable[tableIndex] & 32 )
331 unsigned int id =
getEdgeID( x, y, z, 5 );
335 for(
int i = 0; wMarchingCubesCaseTables::triTable[tableIndex][i] != -1; i += 3 )
338 unsigned int pointID0, pointID1, pointID2;
339 pointID0 =
getEdgeID( x, y, z, wMarchingCubesCaseTables::triTable[tableIndex][i] );
340 pointID1 =
getEdgeID( x, y, z, wMarchingCubesCaseTables::triTable[tableIndex][i + 1] );
341 pointID2 =
getEdgeID( x, y, z, wMarchingCubesCaseTables::triTable[tableIndex][i + 2] );
342 triangle.
pointID[0] = pointID0;
343 triangle.
pointID[1] = pointID1;
344 triangle.
pointID[2] = pointID2;
352 unsigned int nextID = 0;
360 mapIterator->second.y / nbCoordsY,
361 mapIterator->second.z / nbCoordsZ );
364 WPosition pos =
WPosition( mapIterator->second.x, mapIterator->second.y, mapIterator->second.z );
366 std::vector< double > resultPos4D( 4 );
372 ( *mapIterator ).second.newID = nextID;
373 triMesh->addVertex( resultPos4D[0] / resultPos4D[3], resultPos4D[1] / resultPos4D[3], resultPos4D[2] / resultPos4D[3] );
374 triMesh->addTextureCoordinate( texCoord );
383 for(
unsigned int i = 0; i < 3; i++ )
385 unsigned int newID =
m_idToVertices[( *vecIterator ).pointID[i]].newID;
386 ( *vecIterator ).pointID[i] = newID;
388 triMesh->addTriangle( ( *vecIterator ).pointID[0], ( *vecIterator ).pointID[1], ( *vecIterator ).pointID[2] );
397 unsigned int nX,
unsigned int nY,
unsigned int nZ,
398 unsigned int nEdgeNo )
408 unsigned int v1x = nX;
409 unsigned int v1y = nY;
410 unsigned int v1z = nZ;
412 unsigned int v2x = nX;
413 unsigned int v2y = nY;
414 unsigned int v2z = nZ;
488 double val1 = ( *vals )[ v1z * nPointsInSlice + v1y * (
m_nCellsX + 1 ) + v1x ];
489 double val2 = ( *vals )[ v2z * nPointsInSlice + v2y * (
m_nCellsX + 1 ) + v2x ];
492 intersection.newID = 0;
496 #endif // WMARCHINGCUBESALGORITHM_H