1
//---------------------------------------------------------------------------
3
// Project: OpenWalnut ( http://www.openwalnut.org )
5
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6
// For more information see http://www.openwalnut.org/copying
8
// This file is part of OpenWalnut.
10
// OpenWalnut is free software: you can redistribute it and/or modify
11
// it under the terms of the GNU Lesser General Public License as published by
12
// the Free Software Foundation, either version 3 of the License, or
13
// (at your option) any later version.
15
// OpenWalnut is distributed in the hope that it will be useful,
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
// GNU Lesser General Public License for more details.
20
// You should have received a copy of the GNU Lesser General Public License
21
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
23
//---------------------------------------------------------------------------
27
#include "WMarchingLegoAlgorithm.h"
29
WMarchingLegoAlgorithm::WMarchingLegoAlgorithm()
34
WMarchingLegoAlgorithm::~WMarchingLegoAlgorithm()
38
void WMarchingLegoAlgorithm::addSurface( size_t x, size_t y, size_t z, size_t surface )
57
unsigned int id1 = getVertexID( pt1.x , pt1.y, pt1.z );
58
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id1, pt1 ) );
63
unsigned int id2 = getVertexID( pt2.x , pt2.y, pt2.z );
64
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id2, pt2 ) );
69
unsigned int id3 = getVertexID( pt3.x , pt3.y, pt3.z );
70
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id3, pt3 ) );
75
unsigned int id4 = getVertexID( pt4.x , pt4.y, pt4.z );
76
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id4, pt4 ) );
78
WMLTriangle triangle1;
79
triangle1.pointID[0] = id1;
80
triangle1.pointID[1] = id2;
81
triangle1.pointID[2] = id3;
82
WMLTriangle triangle2;
83
triangle2.pointID[0] = id3;
84
triangle2.pointID[1] = id4;
85
triangle2.pointID[2] = id1;
86
m_trivecTriangles.push_back( triangle1 );
87
m_trivecTriangles.push_back( triangle2 );
95
unsigned int id1 = getVertexID( pt1.x , pt1.y, pt1.z );
96
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id1, pt1 ) );
101
unsigned int id2 = getVertexID( pt2.x , pt2.y, pt2.z );
102
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id2, pt2 ) );
107
unsigned int id3 = getVertexID( pt3.x , pt3.y, pt3.z );
108
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id3, pt3 ) );
113
unsigned int id4 = getVertexID( pt4.x , pt4.y, pt4.z );
114
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id4, pt4 ) );
116
WMLTriangle triangle1;
117
triangle1.pointID[0] = id1;
118
triangle1.pointID[1] = id2;
119
triangle1.pointID[2] = id3;
120
WMLTriangle triangle2;
121
triangle2.pointID[0] = id3;
122
triangle2.pointID[1] = id4;
123
triangle2.pointID[2] = id1;
124
m_trivecTriangles.push_back( triangle1 );
125
m_trivecTriangles.push_back( triangle2 );
133
unsigned int id1 = getVertexID( pt1.x , pt1.y, pt1.z );
134
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id1, pt1 ) );
139
unsigned int id2 = getVertexID( pt2.x , pt2.y, pt2.z );
140
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id2, pt2 ) );
145
unsigned int id3 = getVertexID( pt3.x , pt3.y, pt3.z );
146
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id3, pt3 ) );
151
unsigned int id4 = getVertexID( pt4.x , pt4.y, pt4.z );
152
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id4, pt4 ) );
154
WMLTriangle triangle1;
155
triangle1.pointID[0] = id1;
156
triangle1.pointID[1] = id2;
157
triangle1.pointID[2] = id3;
158
WMLTriangle triangle2;
159
triangle2.pointID[0] = id3;
160
triangle2.pointID[1] = id4;
161
triangle2.pointID[2] = id1;
162
m_trivecTriangles.push_back( triangle1 );
163
m_trivecTriangles.push_back( triangle2 );
171
unsigned int id1 = getVertexID( pt1.x , pt1.y, pt1.z );
172
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id1, pt1 ) );
177
unsigned int id2 = getVertexID( pt2.x , pt2.y, pt2.z );
178
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id2, pt2 ) );
183
unsigned int id3 = getVertexID( pt3.x , pt3.y, pt3.z );
184
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id3, pt3 ) );
189
unsigned int id4 = getVertexID( pt4.x , pt4.y, pt4.z );
190
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id4, pt4 ) );
192
WMLTriangle triangle1;
193
triangle1.pointID[0] = id1;
194
triangle1.pointID[1] = id2;
195
triangle1.pointID[2] = id3;
196
WMLTriangle triangle2;
197
triangle2.pointID[0] = id3;
198
triangle2.pointID[1] = id4;
199
triangle2.pointID[2] = id1;
200
m_trivecTriangles.push_back( triangle1 );
201
m_trivecTriangles.push_back( triangle2 );
209
unsigned int id1 = getVertexID( pt1.x , pt1.y, pt1.z );
210
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id1, pt1 ) );
215
unsigned int id2 = getVertexID( pt2.x , pt2.y, pt2.z );
216
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id2, pt2 ) );
221
unsigned int id3 = getVertexID( pt3.x , pt3.y, pt3.z );
222
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id3, pt3 ) );
227
unsigned int id4 = getVertexID( pt4.x , pt4.y, pt4.z );
228
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id4, pt4 ) );
230
WMLTriangle triangle1;
231
triangle1.pointID[0] = id1;
232
triangle1.pointID[1] = id2;
233
triangle1.pointID[2] = id3;
234
WMLTriangle triangle2;
235
triangle2.pointID[0] = id3;
236
triangle2.pointID[1] = id4;
237
triangle2.pointID[2] = id1;
238
m_trivecTriangles.push_back( triangle1 );
239
m_trivecTriangles.push_back( triangle2 );
247
unsigned int id1 = getVertexID( pt1.x , pt1.y, pt1.z );
248
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id1, pt1 ) );
253
unsigned int id2 = getVertexID( pt2.x , pt2.y, pt2.z );
254
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id2, pt2 ) );
259
unsigned int id3 = getVertexID( pt3.x , pt3.y, pt3.z );
260
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id3, pt3 ) );
265
unsigned int id4 = getVertexID( pt4.x , pt4.y, pt4.z );
266
m_idToVertices.insert( ID2WMLPointXYZId::value_type( id4, pt4 ) );
268
WMLTriangle triangle1;
269
triangle1.pointID[0] = id1;
270
triangle1.pointID[1] = id2;
271
triangle1.pointID[2] = id3;
272
WMLTriangle triangle2;
273
triangle2.pointID[0] = id3;
274
triangle2.pointID[1] = id4;
275
triangle2.pointID[2] = id1;
276
m_trivecTriangles.push_back( triangle1 );
277
m_trivecTriangles.push_back( triangle2 );
285
size_t WMarchingLegoAlgorithm::getVertexID( size_t nX, size_t nY, size_t nZ )
287
return nZ * ( m_nCellsY + 1 ) * ( m_nCellsX + 1) + nY * ( m_nCellsX + 1 ) + nX;
290
boost::shared_ptr<WTriangleMesh> WMarchingLegoAlgorithm::genSurfaceOneValue( size_t nbCoordsX, size_t nbCoordsY, size_t nbCoordsZ,
291
const WMatrix< double >& mat,
292
const std::vector< size_t >* vals,
294
boost::shared_ptr< WProgressCombiner > mainProgress )
296
WAssert( vals, "No value set provided." );
298
m_idToVertices.clear();
299
m_trivecTriangles.clear();
301
m_nCellsX = nbCoordsX - 1;
302
m_nCellsY = nbCoordsY - 1;
303
m_nCellsZ = nbCoordsZ - 1;
307
size_t nX = nbCoordsX;
308
size_t nY = nbCoordsY;
310
size_t nPointsInSlice = nX * nY;
312
boost::shared_ptr< WProgress > progress;
315
progress = boost::shared_ptr< WProgress >( new WProgress( "Marching Legos", m_nCellsZ ) );
316
mainProgress->addSubProgress( progress );
319
// Generate isosurface.
320
for( size_t z = 0; z < m_nCellsZ; z++ )
326
for( size_t y = 0; y < m_nCellsY; y++ )
328
for( size_t x = 0; x < m_nCellsX; x++ )
330
if( ( *vals )[ z * nPointsInSlice + y * nX + x ] != isoValue )
335
if( x > 0 && ( ( *vals )[ z * nPointsInSlice + y * nX + x - 1 ] != isoValue ) )
337
addSurface( x, y, z, 1 );
339
if( x < m_nCellsX - 1 && ( ( *vals )[ z * nPointsInSlice + y * nX + x + 1 ] != isoValue ) )
341
addSurface( x, y, z, 2 );
344
if( y > 0 && ( ( *vals )[ z * nPointsInSlice + ( y - 1 ) * nX + x ] != isoValue ) )
346
addSurface( x, y, z, 3 );
349
if( y < m_nCellsY - 1 && ( ( *vals )[ z * nPointsInSlice + ( y + 1 ) * nX + x ] != isoValue ) )
351
addSurface( x, y, z, 4 );
354
if( z > 0 && ( ( *vals )[ ( z - 1 ) * nPointsInSlice + y * nX + x ] != isoValue ) )
356
addSurface( x, y, z, 5 );
359
if( z < m_nCellsZ - 1 && ( ( *vals )[ ( z + 1 ) * nPointsInSlice + y * nX + x ] != isoValue ) )
361
addSurface( x, y, z, 6 );
366
addSurface( x, y, z, 1 );
368
if( x == m_nCellsX - 1 )
370
addSurface( x, y, z, 2 );
375
addSurface( x, y, z, 3 );
378
if( y == m_nCellsY - 1 )
380
addSurface( x, y, z, 4 );
385
addSurface( x, y, z, 5 );
388
if( z == m_nCellsZ - 1 )
390
addSurface( x, y, z, 6 );
395
unsigned int nextID = 0;
396
boost::shared_ptr< WTriangleMesh > triMesh( new WTriangleMesh( m_idToVertices.size(), m_trivecTriangles.size() ) );
399
ID2WMLPointXYZId::iterator mapIterator = m_idToVertices.begin();
400
while( mapIterator != m_idToVertices.end() )
402
WPosition texCoord = WPosition( mapIterator->second.x / nbCoordsX,
403
mapIterator->second.y / nbCoordsY,
404
mapIterator->second.z / nbCoordsZ );
406
// transform from grid coordinate system to world coordinates
407
WPosition pos = WPosition( mapIterator->second.x, mapIterator->second.y, mapIterator->second.z );
409
std::vector< double > resultPos4D( 4 );
410
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;
411
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;
412
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;
413
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;
415
( *mapIterator ).second.newID = nextID;
416
triMesh->addVertex( resultPos4D[0] / resultPos4D[3],
417
resultPos4D[1] / resultPos4D[3],
418
resultPos4D[2] / resultPos4D[3] );
419
triMesh->addTextureCoordinate( texCoord );
424
// Now rename triangles.
425
WMLTriangleVECTOR::iterator vecIterator = m_trivecTriangles.begin();
426
while( vecIterator != m_trivecTriangles.end() )
428
for( unsigned int i = 0; i < 3; i++ )
430
unsigned int newID = m_idToVertices[( *vecIterator ).pointID[i]].newID;
431
( *vecIterator ).pointID[i] = newID;
433
triMesh->addTriangle( ( *vecIterator ).pointID[0], ( *vecIterator ).pointID[1], ( *vecIterator ).pointID[2] );