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 WMARCHINGLEGOALGORITHM_H
00026 #define WMARCHINGLEGOALGORITHM_H
00027
00028 #include <vector>
00029 #include <map>
00030 #include "../../common/math/WMatrix.h"
00031 #include "../../common/WProgressCombiner.h"
00032 #include "../WTriangleMesh.h"
00033 #include "../WExportWGE.h"
00034
00035
00036
00037
00038 struct WMLPointXYZId
00039 {
00040 unsigned int newID;
00041 double x;
00042 double y;
00043 double z;
00044 };
00045
00046 typedef std::map< unsigned int, WMLPointXYZId > ID2WMLPointXYZId;
00047
00048
00049
00050
00051 struct WMLTriangle
00052 {
00053 unsigned int pointID[3];
00054 };
00055
00056 typedef std::vector<WMLTriangle> WMLTriangleVECTOR;
00057
00058
00059
00060
00061
00062 class WGE_EXPORT WMarchingLegoAlgorithm
00063 {
00064 public:
00065
00066
00067
00068 WMarchingLegoAlgorithm();
00069
00070
00071
00072
00073 ~WMarchingLegoAlgorithm();
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 template< typename T >
00090 boost::shared_ptr< WTriangleMesh > generateSurface( size_t nbCoordsX, size_t nbCoordsY, size_t nbCoordsZ,
00091 const WMatrix< double >& mat,
00092 const std::vector< T >* vals,
00093 double isoValue );
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 boost::shared_ptr< WTriangleMesh > genSurfaceOneValue( size_t nbCoordsX, size_t nbCoordsY, size_t nbCoordsZ,
00110 const WMatrix< double >& mat,
00111 const std::vector< size_t >* vals,
00112 size_t isoValue );
00113
00114 protected:
00115 private:
00116
00117
00118
00119
00120
00121
00122
00123 void addSurface( size_t x, size_t y, size_t z, size_t surface );
00124
00125
00126
00127
00128
00129
00130
00131
00132 size_t getVertexID( size_t nX, size_t nY, size_t nZ );
00133
00134 unsigned int m_nCellsX;
00135 unsigned int m_nCellsY;
00136 unsigned int m_nCellsZ;
00137
00138 double m_tIsoLevel;
00139
00140 WMatrix< double > m_matrix;
00141
00142 ID2WMLPointXYZId m_idToVertices;
00143 WMLTriangleVECTOR m_trivecTriangles;
00144 };
00145
00146 template<typename T> boost::shared_ptr<WTriangleMesh> WMarchingLegoAlgorithm::generateSurface( size_t nbCoordsX, size_t nbCoordsY, size_t nbCoordsZ,
00147 const WMatrix< double >& mat,
00148 const std::vector< T >* vals,
00149 double isoValue )
00150 {
00151 WAssert( vals, "No value set provided." );
00152
00153 m_idToVertices.clear();
00154 m_trivecTriangles.clear();
00155
00156 m_nCellsX = nbCoordsX - 1;
00157 m_nCellsY = nbCoordsY - 1;
00158 m_nCellsZ = nbCoordsZ - 1;
00159
00160 m_matrix = mat;
00161
00162 m_tIsoLevel = isoValue;
00163
00164 size_t nX = nbCoordsX;
00165 size_t nY = nbCoordsY;
00166
00167 size_t nPointsInSlice = nX * nY;
00168
00169
00170 for( size_t z = 0; z < m_nCellsZ; z++ )
00171 {
00172 for( size_t y = 0; y < m_nCellsY; y++ )
00173 {
00174 for( size_t x = 0; x < m_nCellsX; x++ )
00175 {
00176 if( ( *vals )[ z * nPointsInSlice + y * nX + x ] < m_tIsoLevel )
00177 {
00178 continue;
00179 }
00180
00181 if( x > 0 && ( ( *vals )[ z * nPointsInSlice + y * nX + x - 1 ] < m_tIsoLevel ) )
00182 {
00183 addSurface( x, y, z, 1 );
00184 }
00185 if( x < m_nCellsX - 1 && ( ( *vals )[ z * nPointsInSlice + y * nX + x + 1 ] < m_tIsoLevel ) )
00186 {
00187 addSurface( x, y, z, 2 );
00188 }
00189
00190 if( y > 0 && ( ( *vals )[ z * nPointsInSlice + ( y - 1 ) * nX + x ] < m_tIsoLevel ) )
00191 {
00192 addSurface( x, y, z, 3 );
00193 }
00194
00195 if( y < m_nCellsY - 1 && ( ( *vals )[ z * nPointsInSlice + ( y + 1 ) * nX + x ] < m_tIsoLevel ) )
00196 {
00197 addSurface( x, y, z, 4 );
00198 }
00199
00200 if( z > 0 && ( ( *vals )[ ( z - 1 ) * nPointsInSlice + y * nX + x ] < m_tIsoLevel ) )
00201 {
00202 addSurface( x, y, z, 5 );
00203 }
00204
00205 if( z < m_nCellsZ - 1 && ( ( *vals )[ ( z + 1 ) * nPointsInSlice + y * nX + x ] < m_tIsoLevel ) )
00206 {
00207 addSurface( x, y, z, 6 );
00208 }
00209
00210 if( x == 0 )
00211 {
00212 addSurface( x, y, z, 1 );
00213 }
00214 if( x == m_nCellsX - 1 )
00215 {
00216 addSurface( x, y, z, 2 );
00217 }
00218
00219 if( y == 0 )
00220 {
00221 addSurface( x, y, z, 3 );
00222 }
00223
00224 if( y == m_nCellsY - 1 )
00225 {
00226 addSurface( x, y, z, 4 );
00227 }
00228
00229 if( z == 0 )
00230 {
00231 addSurface( x, y, z, 5 );
00232 }
00233
00234 if( z == m_nCellsZ - 1 )
00235 {
00236 addSurface( x, y, z, 6 );
00237 }
00238 }
00239 }
00240 }
00241 unsigned int nextID = 0;
00242 boost::shared_ptr< WTriangleMesh > triMesh( new WTriangleMesh( m_idToVertices.size(), m_trivecTriangles.size() ) );
00243
00244
00245 ID2WMLPointXYZId::iterator mapIterator = m_idToVertices.begin();
00246 while( mapIterator != m_idToVertices.end() )
00247 {
00248 WPosition texCoord = WPosition( mapIterator->second.x / nbCoordsX,
00249 mapIterator->second.y / nbCoordsY,
00250 mapIterator->second.z / nbCoordsZ );
00251
00252
00253 WPosition pos = WPosition( mapIterator->second.x, mapIterator->second.y, mapIterator->second.z );
00254
00255 std::vector< double > resultPos4D( 4 );
00256 resultPos4D[0] = m_matrix( 0, 0 ) * pos[0] + m_matrix( 0, 1 ) * pos[1] + m_matrix( 0, 2 ) * pos[2] + m_matrix( 0, 3 ) * 1;
00257 resultPos4D[1] = m_matrix( 1, 0 ) * pos[0] + m_matrix( 1, 1 ) * pos[1] + m_matrix( 1, 2 ) * pos[2] + m_matrix( 1, 3 ) * 1;
00258 resultPos4D[2] = m_matrix( 2, 0 ) * pos[0] + m_matrix( 2, 1 ) * pos[1] + m_matrix( 2, 2 ) * pos[2] + m_matrix( 2, 3 ) * 1;
00259 resultPos4D[3] = m_matrix( 3, 0 ) * pos[0] + m_matrix( 3, 1 ) * pos[1] + m_matrix( 3, 2 ) * pos[2] + m_matrix( 3, 3 ) * 1;
00260
00261 ( *mapIterator ).second.newID = nextID;
00262 triMesh->addVertex( resultPos4D[0] / resultPos4D[3],
00263 resultPos4D[1] / resultPos4D[3],
00264 resultPos4D[2] / resultPos4D[3] );
00265 triMesh->addTextureCoordinate( texCoord );
00266 nextID++;
00267 mapIterator++;
00268 }
00269
00270
00271 WMLTriangleVECTOR::iterator vecIterator = m_trivecTriangles.begin();
00272 while( vecIterator != m_trivecTriangles.end() )
00273 {
00274 for( unsigned int i = 0; i < 3; i++ )
00275 {
00276 unsigned int newID = m_idToVertices[( *vecIterator ).pointID[i]].newID;
00277 ( *vecIterator ).pointID[i] = newID;
00278 }
00279 triMesh->addTriangle( ( *vecIterator ).pointID[0], ( *vecIterator ).pointID[1], ( *vecIterator ).pointID[2] );
00280 vecIterator++;
00281 }
00282 return triMesh;
00283 }
00284 #endif // WMARCHINGLEGOALGORITHM_H