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
WPointXYZId interpolate(double fX1, double fY1, double fZ1, double fX2, double fY2, double fZ2, double tVal1, double tVal2)
Interpolates between two grid points to produce the point at which the isosurface intersects an edge...
boost::shared_ptr< WTriangleMesh > generateSurface(size_t nbCoordsX, size_t nbCoordsY, size_t nbCoordsZ, const WMatrix< double > &mat, const std::vector< T > *vals, double isoValue, boost::shared_ptr< WProgressCombiner > mainProgress)
Generate the triangles for the surface on the given dataSet (inGrid, vals).
unsigned int pointID[3]
The IDs of the vertices of the triangle.
Class managing progress inside of modules.
unsigned int m_nCellsY
No. of cells in y direction.
Encapsulated ids representing a triangle.
unsigned int m_nCellsZ
No. of cells in z direction.
WMarchingCubesAlgorithm()
Constructor needed for matrix initalization.
ID2WPointXYZId m_idToVertices
List of WPointXYZIds which form the isosurface.
This class does the actual computation of marching cubes.
double m_tIsoLevel
The isovalue.
This only is a 3d double vector.
int getEdgeID(unsigned int nX, unsigned int nY, unsigned int nZ, unsigned int nEdgeNo)
Returns the edge ID.
unsigned int getVertexID(unsigned int nX, unsigned int nY, unsigned int nZ)
Returns the ID of the vertex given by by the IDs along the axis.
WMatrix< double > m_matrix
The 4x4 transformation matrix for the triangle vertices.
unsigned int m_nCellsX
No. of cells in x direction.
Triangle mesh data structure allowing for convenient access of the elements.
double z
z coordinates of the point.
Tests for the class computing the actual marching cubes.
WMCTriangleVECTOR m_trivecTriangles
List of WMCTriangleS which form the triangulation of the isosurface.
WPointXYZId calculateIntersection(const std::vector< T > *vals, unsigned int nX, unsigned int nY, unsigned int nZ, unsigned int nEdgeNo)
Calculates the intersection point id of the isosurface with an edge.
double y
y coordinates of the point.
A point consisting of its coordinates and ID.
unsigned int newID
ID of the point.
double x
x coordinates of the point.