25 #ifndef WMARCHINGCUBESALGORITHM_H
26 #define WMARCHINGCUBESALGORITHM_H
32 #include "../WProgressCombiner.h"
33 #include "../math/WMatrix.h"
34 #include "WMarchingCubesCaseTables.h"
35 #include "core/graphicsEngine/WTriangleMesh.h"
48 typedef std::map< unsigned int, WPointXYZId > ID2WPointXYZId;
58 typedef std::vector<WMCTriangle> WMCTriangleVECTOR;
114 template<
typename T >
115 std::shared_ptr< WTriangleMesh >
generateSurface(
size_t nbCoordsX,
size_t nbCoordsY,
size_t nbCoordsZ,
117 const std::vector< T >* vals,
119 std::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 std::shared_ptr< WProgressCombiner > mainProgress )
196 WAssert( vals,
"No value set provided." );
213 unsigned int nPointsInSlice = nX * nY;
215 std::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 );
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 );
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 );
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 );
314 if( wMarchingCubesCaseTables::edgeTable[tableIndex] & 1024 )
317 unsigned int id =
getEdgeID( x, y, z, 10 );
321 if( wMarchingCubesCaseTables::edgeTable[tableIndex] & 64 )
324 unsigned int id =
getEdgeID( x, y, z, 6 );
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;
Tests for the class computing the actual marching cubes.
This class does the actual computation of marching cubes.
unsigned int m_nCellsZ
No. of cells in z direction.
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.
WMCTriangleVECTOR m_trivecTriangles
List of WMCTriangleS which form the triangulation of the isosurface.
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.
int getEdgeID(unsigned int nX, unsigned int nY, unsigned int nZ, unsigned int nEdgeNo)
Returns the edge ID.
WMarchingCubesAlgorithm()
Constructor needed for matrix initalization.
ID2WPointXYZId m_idToVertices
List of WPointXYZIds which form the isosurface.
double m_tIsoLevel
The isovalue.
unsigned int m_nCellsY
No. of cells in y direction.
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.
std::shared_ptr< WTriangleMesh > generateSurface(size_t nbCoordsX, size_t nbCoordsY, size_t nbCoordsZ, const WMatrix< double > &mat, const std::vector< T > *vals, double isoValue, std::shared_ptr< WProgressCombiner > mainProgress)
Generate the triangles for the surface on the given dataSet (inGrid, vals).
unsigned int m_nCellsX
No. of cells in x direction.
This only is a 3d double vector.
Class managing progress inside of modules.
Triangle mesh data structure allowing for convenient access of the elements.
Encapsulated ids representing a triangle.
unsigned int pointID[3]
The IDs of the vertices of the triangle.
A point consisting of its coordinates and ID.
double z
z coordinates of the point.
double x
x coordinates of the point.
double y
y coordinates of the point.
unsigned int newID
ID of the point.