Commit 02e57dc2 authored by Mathias Goldau's avatar Mathias Goldau
Browse files

[MERGE]

parents ec0dae84 808bdc17
......@@ -44,7 +44,14 @@
WMarchingCubesModule::WMarchingCubesModule():
WModule()
WModule(),
m_nCellsX( 0 ),
m_nCellsY( 0 ),
m_nCellsZ( 0 ),
m_fCellLengthX( 1 ),
m_fCellLengthY( 1 ),
m_fCellLengthZ( 1 ),
m_tIsoLevel( 0 )
{
// WARNING: initializing connectors inside the constructor will lead to an exception.
// Implement WModule::initializeConnectors instead.
......@@ -142,6 +149,7 @@ void WMarchingCubesModule::properties()
void WMarchingCubesModule::slotPropertyChanged( std::string propertyName )
{
// TODO(wiebel): MC improve this method when corresponding infrastructure is ready
if( propertyName == "isoValue" )
{
// updateTextures();
......@@ -297,12 +305,23 @@ void WMarchingCubesModule::generateSurface( double isoValue )
}
WPointXYZId WMarchingCubesModule::calculateIntersection( unsigned int nX, unsigned int nY, unsigned int nZ,
unsigned int nEdgeNo )
WPointXYZId WMarchingCubesModule::calculateIntersection( unsigned int nX, unsigned int nY, unsigned int nZ, unsigned int nEdgeNo )
{
double x1, y1, z1, x2, y2, z2;
unsigned int v1x = nX, v1y = nY, v1z = nZ;
unsigned int v2x = nX, v2y = nY, v2z = nZ;
double x1;
double y1;
double z1;
double x2;
double y2;
double z2;
unsigned int v1x = nX;
unsigned int v1y = nY;
unsigned int v1z = nZ;
unsigned int v2x = nX;
unsigned int v2y = nY;
unsigned int v2z = nZ;
switch ( nEdgeNo )
{
......@@ -404,29 +423,29 @@ int WMarchingCubesModule::getEdgeID( unsigned int nX, unsigned int nY, unsigned
switch ( nEdgeNo )
{
case 0:
return getVertexID( nX, nY, nZ ) + 1;
return 3 * getVertexID( nX, nY, nZ ) + 1;
case 1:
return getVertexID( nX, nY + 1, nZ );
return 3 * getVertexID( nX, nY + 1, nZ );
case 2:
return getVertexID( nX + 1, nY, nZ ) + 1;
return 3 * getVertexID( nX + 1, nY, nZ ) + 1;
case 3:
return getVertexID( nX, nY, nZ );
return 3 * getVertexID( nX, nY, nZ );
case 4:
return getVertexID( nX, nY, nZ + 1 ) + 1;
return 3 * getVertexID( nX, nY, nZ + 1 ) + 1;
case 5:
return getVertexID( nX, nY + 1, nZ + 1 );
return 3 * getVertexID( nX, nY + 1, nZ + 1 );
case 6:
return getVertexID( nX + 1, nY, nZ + 1 ) + 1;
return 3 * getVertexID( nX + 1, nY, nZ + 1 ) + 1;
case 7:
return getVertexID( nX, nY, nZ + 1 );
return 3 * getVertexID( nX, nY, nZ + 1 );
case 8:
return getVertexID( nX, nY, nZ ) + 2;
return 3 * getVertexID( nX, nY, nZ ) + 2;
case 9:
return getVertexID( nX, nY + 1, nZ ) + 2;
return 3 * getVertexID( nX, nY + 1, nZ ) + 2;
case 10:
return getVertexID( nX + 1, nY + 1, nZ ) + 2;
return 3 * getVertexID( nX + 1, nY + 1, nZ ) + 2;
case 11:
return getVertexID( nX + 1, nY, nZ ) + 2;
return 3 * getVertexID( nX + 1, nY, nZ ) + 2;
default:
// Invalid edge no.
return -1;
......@@ -435,7 +454,7 @@ int WMarchingCubesModule::getEdgeID( unsigned int nX, unsigned int nY, unsigned
unsigned int WMarchingCubesModule::getVertexID( unsigned int nX, unsigned int nY, unsigned int nZ )
{
return 3* (nZ *(m_nCellsY + 1)*(m_nCellsX + 1) + nY*(m_nCellsX + 1) + nX);
return nZ * ( m_nCellsY + 1 ) * ( m_nCellsX + 1) + nY * ( m_nCellsX + 1 ) + nX;
}
void WMarchingCubesModule::renderSurface()
......
......@@ -48,12 +48,40 @@ struct WMCTriangle
typedef std::vector<WMCTriangle> WMCTriangleVECTOR;
// -------------------------------------------------------
//
// Numbering of edges (0..B) and vertices (0..7) per cube.
//
// 5--5--6
// /| /|
// 4 | 6 | A=10
// / 9 / A
// 4--7--7 |
// | | | |
// | 1-|1--2
// 8 / B /
// | 0 | 2 B=11
// |/ |/
// 0--3--3
//
// | /
// z y
// |/
// 0--x--
//
// -------------------------------------------------------
/**
* Module implementing the marching cubes algorithm with consistent triangulation for data
* given on rgualr grids with axis-aligned cells.
*/
class WMarchingCubesModule : public WModule
{
/**
* Only UnitTests may be friends.
*/
friend class WMarchingCubesModuleTest;
public:
/**
* Standard constructor.
......@@ -123,6 +151,7 @@ private:
* the isosurface intersects an edge.
*/
WPointXYZId interpolate( double fX1, double fY1, double fZ1, double fX2, double fY2, double fZ2, double tVal1, double tVal2 );
/**
* Returns the edge ID.
*/
......@@ -146,7 +175,7 @@ private:
ID2WPointXYZId m_idToVertices; //!< List of WPointXYZIds which form the isosurface.
WMCTriangleVECTOR m_trivecTriangles; //!< List of WMCTriangleS which form the triangulation of the isosurface.
// TODO(wiebel): MC commetnt this;
// TODO(wiebel): MC comment this;
void renderSurface();
void renderMesh( const WTriangleMesh& mesh );
......
......@@ -98,10 +98,14 @@ wmath::WVector3D WTriangleMesh::getTriangleNormal( size_t i ) const
wmath::WVector3D tempNormal = v1.crossProduct( v2 );
// TODO(wiebel): TM fix this hack for 0 length normals.
if( tempNormal.norm() < 1e-7 )
{
tempNormal = wmath::WVector3D( 1, 1, 1 );
// If the morm of the vector is below a certain threshold
// the triangle is either very small, or its edges are
// congruent (which also means that the triangle are is very
// small or zero) the triangle will probably not be visible.
// Thus we set its normal to zero.
tempNormal = wmath::WVector3D( 0, 0, 0 );
}
else
{
......
......@@ -25,21 +25,185 @@
#ifndef WMARCHINGCUBESMODULE_TEST_H
#define WMARCHINGCUBESMODULE_TEST_H
#include <vector>
#include <cxxtest/TestSuite.h>
#include "../WMarchingCubesModule.h"
/**
* TODO(wiebel): Document this!
* Test for WMarchingCubesModule
*/
class WMarchingCubesModuleTest : public CxxTest::TestSuite
{
public:
/**
* TODO(wiebel): Document this!
* Ensure instatiation does not throw and does initialization right.
*/
void testInstatiation()
{
TS_ASSERT_THROWS_NOTHING( WMarchingCubesModule() );
// Test initialization
WMarchingCubesModule mc;
TS_ASSERT_EQUALS( mc.m_nCellsX, 0 );
TS_ASSERT_EQUALS( mc.m_nCellsY, 0 );
TS_ASSERT_EQUALS( mc.m_nCellsZ, 0 );
TS_ASSERT_EQUALS( mc.m_fCellLengthX, 1 );
TS_ASSERT_EQUALS( mc.m_fCellLengthY, 1 );
TS_ASSERT_EQUALS( mc.m_fCellLengthZ, 1 );
TS_ASSERT_EQUALS( mc.m_tIsoLevel, 0 );
TS_ASSERT_EQUALS( mc.m_idToVertices.size(), 0 );
TS_ASSERT_EQUALS( mc.m_trivecTriangles.size(), 0 );
}
/**
* Test interpolate on edge
*/
void testInterpolate()
{
WMarchingCubesModule mc;
mc.m_tIsoLevel = 1.7; // mu = 0.5454...
WPointXYZId expected;
expected.newID = 0;
expected.x = 1.3545454545454545;
expected.y = 2.4545454545454545;
expected.z = 5.4090909090909091;
WPointXYZId result = mc.interpolate( 1.3, 2.4, 3.5,
1.4, 2.5, 7.0,
1.1, 2.2 );
double delta = 1e-9;
TS_ASSERT_DELTA( expected.x, result.x, delta );
TS_ASSERT_DELTA( expected.y, result.y, delta );
TS_ASSERT_DELTA( expected.z, result.z, delta );
TS_ASSERT_EQUALS( expected.newID, result.newID );
}
/**
* Test computation of veretexID
*/
void testGetVertexID()
{
WMarchingCubesModule mc;
mc.m_nCellsX = 10;
mc.m_nCellsY = 11;
mc.m_nCellsZ = 12;
unsigned int x = 4;
unsigned int y = 5;
unsigned int z = 6;
unsigned int nbVertsInXDir = ( mc.m_nCellsX + 1 );
unsigned int nbVertsInSlice = nbVertsInXDir * ( mc.m_nCellsY + 1 );
unsigned int expected = z * nbVertsInSlice + y * nbVertsInXDir + x;
TS_ASSERT_EQUALS( expected, mc.getVertexID( x, y, z ) );
}
/**
* Test computation of egeId
*/
void testGetEdgeID()
{
WMarchingCubesModule mc;
mc.m_nCellsX = 10;
mc.m_nCellsY = 11;
mc.m_nCellsZ = 12;
unsigned int nbVertsInXDir = ( mc.m_nCellsX + 1 );
unsigned int nbVertsInSlice = nbVertsInXDir * ( mc.m_nCellsY + 1 );
// test edge numbers for (0,0,0) case
TS_ASSERT_EQUALS( 1 , mc.getEdgeID( 0, 0, 0, 0 ) );
TS_ASSERT_EQUALS( 3 * nbVertsInXDir , mc.getEdgeID( 0, 0, 0, 1 ) );
TS_ASSERT_EQUALS( 3 * 1 + 1 , mc.getEdgeID( 0, 0, 0, 2 ) );
TS_ASSERT_EQUALS( 0 , mc.getEdgeID( 0, 0, 0, 3 ) );
TS_ASSERT_EQUALS( 3 * nbVertsInSlice + 1 , mc.getEdgeID( 0, 0, 0, 4 ) );
TS_ASSERT_EQUALS( 3 * ( nbVertsInSlice + nbVertsInXDir ), mc.getEdgeID( 0, 0, 0, 5 ) );
TS_ASSERT_EQUALS( 3 * ( 1 + nbVertsInSlice ) + 1, mc.getEdgeID( 0, 0, 0, 6 ) );
TS_ASSERT_EQUALS( 3 * nbVertsInSlice, mc.getEdgeID( 0, 0, 0, 7 ) );
TS_ASSERT_EQUALS( 2 , mc.getEdgeID( 0, 0, 0, 8 ) );
TS_ASSERT_EQUALS( 3 * nbVertsInXDir + 2, mc.getEdgeID( 0, 0, 0, 9 ) );
TS_ASSERT_EQUALS( 3 * ( 1 + nbVertsInXDir ) + 2, mc.getEdgeID( 0, 0, 0, 10 ) );
TS_ASSERT_EQUALS( 3 * 1 + 2, mc.getEdgeID( 0, 0, 0, 11 ) );
// wrong edge numbers should return -1
TS_ASSERT_EQUALS( -1 , mc.getEdgeID( 0, 0, 0, -1 ) );
TS_ASSERT_EQUALS( -1 , mc.getEdgeID( 0, 0, 0, 12 ) );
TS_ASSERT_DIFFERS( -1 , mc.getEdgeID( 0, 0, 0, 1 ) );
}
/**
* Test calculateIntersection
*/
void testCalculateIntersection()
{
WMarchingCubesModule mc;
mc.m_tIsoLevel = 1.7;
mc.m_fCellLengthX = 1;
mc.m_fCellLengthY = 1;
mc.m_fCellLengthZ = 1;
std::vector< unsigned char > data;
data.push_back( 0 );
data.push_back( 1 );
data.push_back( 2 );
data.push_back( 3 );
data.push_back( 4 );
data.push_back( 5 );
data.push_back( 6 );
data.push_back( 7 );
mc.m_vals = boost::shared_ptr< WValueSet< unsigned char > >( new WValueSet< unsigned char >( 0, 1, data, W_DT_UNSIGNED_CHAR ) );
WPointXYZId expected;
expected.newID = 0;
expected.x = 0.7;
expected.y = 1;
expected.z = 0;
WPointXYZId result = mc.calculateIntersection( 0, 0, 0, 1 );
double delta = 1e-9;
TS_ASSERT_DELTA( expected.x, result.x, delta );
TS_ASSERT_DELTA( expected.y, result.y, delta );
TS_ASSERT_DELTA( expected.z, result.z, delta );
TS_ASSERT_EQUALS( expected.newID, result.newID );
}
/**
* Test renderSurface
*/
void testRenderSurface()
{
// TODO(wiebel): MC need to test this for #116
}
/**
* Test renderMesh
*/
void testRenderMesh()
{
// TODO(wiebel): MC need to test this for #116
}
/**
* Test writing of surfaces
*/
void testSave()
{
// TODO(wiebel): MC need to test this for #117
}
/**
* Test reading of surfaces
*/
void testSomething( void )
void testLoad()
{
// TODO(wiebel): MC need to test this for #118
}
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment