OpenWalnut  1.4.0
WTriangleMesh_test.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WTRIANGLEMESH_TEST_H
00026 #define WTRIANGLEMESH_TEST_H
00027 
00028 #include <algorithm>
00029 #include <list>
00030 #include <vector>
00031 
00032 #include <cxxtest/TestSuite.h>
00033 
00034 #include "../../common/math/linearAlgebra/WPosition.h"
00035 #include "../WTriangleMesh.h"
00036 #include "WTriangleMeshTraits.h"
00037 
00038 /**
00039  * Testing the WTriangleMesh class.
00040  */
00041 class WTriangleMeshTest : public CxxTest::TestSuite
00042 {
00043 public:
00044 // TODO(schurade): fix unit test from old triangle class
00045 //    /**
00046 //     * Ensure instatiation does not throw and does initialization right.
00047 //     */
00048 //    void testInstatiation()
00049 //    {
00050 //        TS_ASSERT_THROWS_NOTHING( WTriangleMesh() );
00051 //        WTriangleMesh mesh;
00052 //        TS_ASSERT_EQUALS( mesh.m_fastAddVertId, 0 );
00053 //        TS_ASSERT_EQUALS( mesh.m_fastAddTriangleId, 0 );
00054 //    }
00055 //
00056 //    /**
00057 //     * clearMesh should reset all members.
00058 //     */
00059 //    void testClearMesh()
00060 //    {
00061 //        WTriangleMesh mesh;
00062 //        mesh.m_fastAddVertId = 9;  // just a number
00063 //        mesh.m_fastAddTriangleId = 10;  // just a number
00064 //        mesh.m_vertices.resize( 11 );  // just some size
00065 //        mesh.m_triangles.resize( 13 );  // just some size
00066 //
00067 //        mesh.clearMesh();
00068 //
00069 //        TS_ASSERT_EQUALS( mesh.m_fastAddVertId, 0 );
00070 //        TS_ASSERT_EQUALS( mesh.m_fastAddTriangleId, 0 );
00071 //        TS_ASSERT_EQUALS( mesh.m_vertices.size(), 0 );
00072 //        TS_ASSERT_EQUALS( mesh.m_triangles.size(), 0 );
00073 //    }
00074 //
00075 //    /**
00076 //     * fastAddVert should increment the corresponding counter
00077 //     */
00078 //    void testFastAddVert()
00079 //    {
00080 //        WTriangleMesh mesh;
00081 //        mesh.resizeVertices( 2 );
00082 //        WPosition newVert;
00083 //
00084 //        TS_ASSERT_EQUALS( mesh.m_fastAddVertId, 0 );
00085 //        mesh.fastAddVert( newVert );
00086 //        TS_ASSERT_EQUALS( mesh.m_fastAddVertId, 1 );
00087 //        mesh.fastAddVert( newVert );
00088 //        TS_ASSERT_EQUALS( mesh.m_fastAddVertId, 2 );
00089 //    }
00090 //
00091 //    /**
00092 //     * fastAddTriangle should increment the corresponding counter
00093 //     */
00094 //    void testFastAddTriangle()
00095 //    {
00096 //        WTriangleMesh mesh;
00097 //        mesh.resizeTriangles( 2 );
00098 //
00099 //        TS_ASSERT_EQUALS( mesh.m_fastAddTriangleId, 0 );
00100 //        mesh.fastAddTriangle( 0, 1, 2 );
00101 //        TS_ASSERT_EQUALS( mesh.m_fastAddTriangleId, 1 );
00102 //        mesh.fastAddTriangle( 1, 2, 3 );
00103 //        TS_ASSERT_EQUALS( mesh.m_fastAddTriangleId, 2 );
00104 //    }
00105 //
00106 //    /**
00107 //     * setVertices should set the fastAddId and resize the member
00108 //     */
00109 //    void testSetVertices()
00110 //    {
00111 //        WTriangleMesh mesh;
00112 //        std::vector< WPosition > vertices( 4 );
00113 //
00114 //        TS_ASSERT_EQUALS( mesh.m_fastAddVertId, 0 );
00115 //        TS_ASSERT_EQUALS( mesh.m_vertices.size(), 0 );
00116 //        mesh.setVertices( vertices );
00117 //        TS_ASSERT_EQUALS( mesh.m_fastAddVertId, 4 );
00118 //        TS_ASSERT_EQUALS( mesh.m_vertices.size(), 4 );
00119 //    }
00120 //
00121 //    /**
00122 //     * setTriangles should set the fastAddId and resize the member
00123 //     */
00124 //    void testSetTriangles()
00125 //    {
00126 //        WTriangleMesh mesh;
00127 //        std::vector< Triangle > triangles( 5 );
00128 //
00129 //        TS_ASSERT_EQUALS( mesh.m_fastAddTriangleId, 0 );
00130 //        TS_ASSERT_EQUALS( mesh.m_triangles.size(), 0 );
00131 //        mesh.setTriangles( triangles );
00132 //        TS_ASSERT_EQUALS( mesh.m_fastAddTriangleId, 5 );
00133 //        TS_ASSERT_EQUALS( mesh.m_triangles.size(), 5 );
00134 //    }
00135 //
00136 //    /**
00137 //     * Test getTriangleNormal
00138 //     */
00139 //    void testgetTriangleNormal()
00140 //    {
00141 //        WTriangleMesh mesh;
00142 //
00143 //        mesh.resizeVertices( 5 );
00144 //        WPosition newVert0( 0, 0, 0 );
00145 //        mesh.fastAddVert( newVert0 );
00146 //
00147 //        WPosition newVert1( 1.3, 2.25, 3.435 );
00148 //        mesh.fastAddVert( newVert1 );
00149 //
00150 //        WPosition newVert2( 1, 2, 3 );
00151 //        mesh.fastAddVert( newVert2 );
00152 //
00153 //        WPosition newVert3( 1.2, 1.5, 1.7 );
00154 //        mesh.fastAddVert( newVert3 );
00155 //
00156 //        WPosition newVert4( 1, 1, 1 );
00157 //        mesh.fastAddVert( newVert4 );
00158 //
00159 //        // one triangles
00160 //        mesh.resizeTriangles( 1 );
00161 //        mesh.fastAddTriangle( 0, 2, 4 );
00162 //
00163 //        WVector3d expectedNormal( -0.40824829, 0.816496581, -0.40824829 );
00164 //
00165 //        double delta = 1e-7;
00166 //        TS_ASSERT_DELTA( mesh.getTriangleNormal( 0 )[0], expectedNormal[0], delta );
00167 //        TS_ASSERT_DELTA( mesh.getTriangleNormal( 0 )[1], expectedNormal[1], delta );
00168 //        TS_ASSERT_DELTA( mesh.getTriangleNormal( 0 )[2], expectedNormal[2], delta );
00169 //    }
00170 //
00171 //    /**
00172 //     * Test computeTriNormals
00173 //     */
00174 //    void testComputeTriNormals()
00175 //    {
00176 //        WTriangleMesh mesh;
00177 //
00178 //        mesh.resizeVertices( 5 );
00179 //        WPosition newVert0( 0, 0, 0 );
00180 //        mesh.fastAddVert( newVert0 );
00181 //
00182 //        WPosition newVert1( 1.3, 2.25, 3.435 );
00183 //        mesh.fastAddVert( newVert1 );
00184 //
00185 //        WPosition newVert2( 1, 2, 3 );
00186 //        mesh.fastAddVert( newVert2 );
00187 //
00188 //        WPosition newVert3( 1.2, 1.5, 1.7 );
00189 //        mesh.fastAddVert( newVert3 );
00190 //
00191 //        WPosition newVert4( 1, 1, 1 );
00192 //        mesh.fastAddVert( newVert4 );
00193 //
00194 //        // two triangles
00195 //        mesh.resizeTriangles( 2 );
00196 //        mesh.fastAddTriangle( 0, 2, 4 );
00197 //        mesh.fastAddTriangle( 0, 1, 4 );
00198 //
00199 //        TS_ASSERT_EQUALS( mesh.m_computedTriNormals, false );
00200 //        TS_ASSERT_EQUALS( mesh.m_triNormals.size(), 0 );
00201 //
00202 //        mesh.computeTriNormals();
00203 //
00204 //        TS_ASSERT_EQUALS( mesh.m_computedTriNormals, true );
00205 //        TS_ASSERT_EQUALS( mesh.m_triNormals.size(), 2 );
00206 //
00207 //        double delta = 1e-7;
00208 //        WVector3d expectedNormal( -0.40824829, 0.816496581, -0.40824829 );
00209 //        TS_ASSERT_DELTA( length( expectedNormal ), 1, delta ); // check ouu expectance :-)
00210 //
00211 //        TS_ASSERT_DELTA( length( mesh.m_triNormals[0] ), 1, delta );
00212 //        TS_ASSERT_DELTA( mesh.m_triNormals[0][0], expectedNormal[0], delta );
00213 //        TS_ASSERT_DELTA( mesh.m_triNormals[0][1], expectedNormal[1], delta );
00214 //        TS_ASSERT_DELTA( mesh.m_triNormals[0][2], expectedNormal[2], delta );
00215 //        TS_ASSERT_DELTA( length( mesh.m_triNormals[1] ), 1, delta );
00216 //    };
00217 //
00218 //    /**
00219 //     * Test computeVertNormals
00220 //     */
00221 //    void testComputeVertNormals()
00222 //    {
00223 //        WTriangleMesh mesh;
00224 //
00225 //        mesh.resizeVertices( 5 );
00226 //        WPosition newVert0( 0, 0, 0 );
00227 //        mesh.fastAddVert( newVert0 );
00228 //
00229 //        WPosition newVert1( 1.3, 2.25, 3.435 );
00230 //        mesh.fastAddVert( newVert1 );
00231 //
00232 //        WPosition newVert2( 1, 2, 3 );
00233 //        mesh.fastAddVert( newVert2 );
00234 //
00235 //        WPosition newVert3( 1.2, 1.5, 1.7 );
00236 //        mesh.fastAddVert( newVert3 );
00237 //
00238 //        WPosition newVert4( 1, 1, 1 );
00239 //        mesh.fastAddVert( newVert4 );
00240 //
00241 //        // two triangles
00242 //        mesh.resizeTriangles( 2 );
00243 //        mesh.fastAddTriangle( 0, 2, 4 );
00244 //        mesh.fastAddTriangle( 0, 1, 4 );
00245 //
00246 //        TS_ASSERT_EQUALS( mesh.m_computedVertNormals, false );
00247 //        TS_ASSERT_EQUALS( mesh.m_vertNormals.size(), 0 );
00248 //
00249 //        // check this too. We need the tri normals for the vert normals
00250 //        TS_ASSERT_EQUALS( mesh.m_computedTriNormals, false );
00251 //        TS_ASSERT_EQUALS( mesh.m_triNormals.size(), 0 );
00252 //
00253 //        // call the funtion itself
00254 //        mesh.computeVertNormals();
00255 //
00256 //        // what we expect
00257 //        WVector3d expectedNormal0( -0.40824829, 0.816496581, -0.40824829 );
00258 //        WVector3d expectedNormal1( -0.452271958, 0.814852852, -0.362580895 );
00259 //        double delta = 1e-7;
00260 //
00261 //        // check this triangle stuff too. We need the tri normals for the vert normals
00262 //        TS_ASSERT_EQUALS( mesh.m_computedTriNormals, true );
00263 //        TS_ASSERT_EQUALS( mesh.m_triNormals.size(), 2 );
00264 //        TS_ASSERT_DELTA( length( mesh.m_triNormals[0] ), 1, delta );
00265 //        TS_ASSERT_DELTA( mesh.m_triNormals[0][0], expectedNormal0[0], delta );
00266 //        TS_ASSERT_DELTA( mesh.m_triNormals[0][1], expectedNormal0[1], delta );
00267 //        TS_ASSERT_DELTA( mesh.m_triNormals[0][2], expectedNormal0[2], delta );
00268 //        TS_ASSERT_DELTA( mesh.m_triNormals[1][0], expectedNormal1[0], delta );
00269 //        TS_ASSERT_DELTA( mesh.m_triNormals[1][1], expectedNormal1[1], delta );
00270 //        TS_ASSERT_DELTA( mesh.m_triNormals[1][2], expectedNormal1[2], delta );
00271 //
00272 //        // check the vertex stuff
00273 //        TS_ASSERT_EQUALS( mesh.m_computedVertNormals, true );
00274 //        TS_ASSERT_EQUALS( mesh.m_vertNormals.size(), 5 );
00275 //        // vertex 2 belongs only to one triangle so it should have the normal of the triangle
00276 //        TS_ASSERT_DELTA( mesh.m_vertNormals[2][0], expectedNormal0[0], delta );
00277 //        TS_ASSERT_DELTA( mesh.m_vertNormals[2][1], expectedNormal0[1], delta );
00278 //        TS_ASSERT_DELTA( mesh.m_vertNormals[2][2], expectedNormal0[2], delta );
00279 //        // vertex 1 belongs only to one triangle so it should have the normal of the triangle
00280 //        TS_ASSERT_DELTA( mesh.m_vertNormals[1][0], expectedNormal1[0], delta );
00281 //        TS_ASSERT_DELTA( mesh.m_vertNormals[1][1], expectedNormal1[1], delta );
00282 //        TS_ASSERT_DELTA( mesh.m_vertNormals[1][2], expectedNormal1[2], delta );
00283 //
00284 //        // vertex 0 belongs to two triangles so it should have the average normal of the two triangles
00285 //        WVector3d expectedVertNormal = 0.5 * ( expectedNormal0 + expectedNormal1 );
00286 //        expectedVertNormal.normalize();
00287 //        TS_ASSERT_DELTA( mesh.m_vertNormals[0][0], expectedVertNormal[0], delta );
00288 //        TS_ASSERT_DELTA( mesh.m_vertNormals[0][1], expectedVertNormal[1], delta );
00289 //        TS_ASSERT_DELTA( mesh.m_vertNormals[0][2], expectedVertNormal[2], delta );
00290 //    }
00291 
00292     /**
00293      * Two WTriangleMeshes are considered to be equal only if they have the same
00294      * points in same order and the same indices of points for the triangles also
00295      * in same order.
00296      * From an objective point of view there might be different ordering resuling
00297      * in the same structure, but this is to expensive to compute.
00298      */
00299     void testEqualityOperator( void )
00300     {
00301         WTriangleMesh mesh( 3, 1 );
00302         mesh.addVertex( WPosition( 1,  0, 0 ) );
00303         mesh.addVertex( WPosition( 0,  1, 0 ) );
00304         mesh.addVertex( WPosition( 1,  0, 0 ) );
00305         mesh.addTriangle(  0,  1,  2 );
00306 
00307         WTriangleMesh expected( mesh );
00308 
00309         TS_ASSERT_EQUALS( expected, mesh );
00310         std::swap( mesh.m_triangles[0], mesh.m_triangles[1] );
00311         TS_ASSERT_DIFFERS( expected, mesh );
00312     }
00313 
00314     /**
00315      * Decompose the following scene into seven components A, B, C, D, E, F, G.
00316      \verbatim
00317 
00318      12      o-----o          o----o
00319             / \   / \         |\  /|
00320            /   \ /   \        | \/ |
00321      11   o-----o-----o       | /\ |
00322            \   / \   /        |/  \|
00323      10     \ /   \ /         o----o B
00324       9      o-----o  A
00325 
00326       8            o
00327       7      o     |\
00328             / \    | \
00329            /   \   |  \
00330       6   o-----o--+--o\
00331       5          \ o-+--o C
00332                   \ /
00333       4            o D
00334 
00335       3   o E (degenerated)
00336 
00337       2   o-----o F (degenerated)
00338 
00339       1   o-----o G
00340            \   /
00341             \ /
00342       0      o
00343 
00344           0  1  2  3  4 5     6    7
00345 
00346      \endverbatim
00347      */
00348     void testComponentDecomposition( void )
00349     {
00350         WTriangleMesh mesh( 25, 16 );
00351 
00352         mesh.addVertex( WPosition( 1,  0, 0 ) ); // 0
00353         mesh.addVertex( WPosition( 0,  1, 0 ) ); // 1
00354         mesh.addVertex( WPosition( 2,  1, 0 ) ); // 2
00355         mesh.addVertex( WPosition( 0,  2, 0 ) ); // 3
00356         mesh.addVertex( WPosition( 2,  2, 0 ) ); // 4
00357         mesh.addVertex( WPosition( 0,  3, 0 ) ); // 5
00358         mesh.addVertex( WPosition( 3,  4, 0 ) ); // 6
00359         mesh.addVertex( WPosition( 3,  5, 0 ) ); // 7
00360         mesh.addVertex( WPosition( 5,  5, 0 ) ); // 8
00361         mesh.addVertex( WPosition( 0,  6, 0 ) ); // 9
00362         mesh.addVertex( WPosition( 2,  6, 0 ) ); // 10
00363         mesh.addVertex( WPosition( 4,  6, 0 ) ); // 11
00364         mesh.addVertex( WPosition( 1,  7, 0 ) ); // 12
00365         mesh.addVertex( WPosition( 3,  8, 0 ) ); // 13
00366         mesh.addVertex( WPosition( 1,  9, 0 ) ); // 14
00367         mesh.addVertex( WPosition( 3,  9, 0 ) ); // 15
00368         mesh.addVertex( WPosition( 6, 10, 0 ) ); // 16
00369         mesh.addVertex( WPosition( 7, 10, 0 ) ); // 17
00370         mesh.addVertex( WPosition( 0, 11, 0 ) ); // 18
00371         mesh.addVertex( WPosition( 2, 11, 0 ) ); // 19
00372         mesh.addVertex( WPosition( 4, 11, 0 ) ); // 20
00373         mesh.addVertex( WPosition( 1, 12, 0 ) ); // 21
00374         mesh.addVertex( WPosition( 3, 12, 0 ) ); // 23
00375         mesh.addVertex( WPosition( 6, 12, 0 ) ); // 23
00376         mesh.addVertex( WPosition( 7, 12, 0 ) ); // 24
00377 
00378         mesh.addTriangle(  0,  1,  2 ); // 0
00379         mesh.addTriangle(  3,  4,  4 ); // 1
00380         mesh.addTriangle(  5,  5,  5 ); // 2
00381         mesh.addTriangle(  9, 10, 12 ); // 3
00382         mesh.addTriangle( 10,  6, 11 ); // 4
00383         mesh.addTriangle(  7,  8, 13 ); // 5
00384         mesh.addTriangle( 18, 14, 19 ); // 6
00385         mesh.addTriangle( 14, 15, 19 ); // 7
00386         mesh.addTriangle( 15, 20, 19 ); // 8
00387         mesh.addTriangle( 20, 22, 19 ); // 9
00388         mesh.addTriangle( 22, 21, 19 ); // 10
00389         mesh.addTriangle( 21, 18, 19 ); // 11
00390         mesh.addTriangle( 16, 17, 23 ); // 12
00391         mesh.addTriangle( 16, 17, 24 ); // 13
00392         mesh.addTriangle( 16, 23, 24 ); // 14
00393         mesh.addTriangle( 17, 23, 24 ); // 15
00394 
00395         boost::shared_ptr< std::list< boost::shared_ptr< WTriangleMesh > > > components = tm_utils::componentDecomposition( mesh );
00396         TS_ASSERT_EQUALS( components->size(), 7 );
00397 
00398         std::list< boost::shared_ptr< WTriangleMesh > >::const_iterator cit = components->begin();
00399         WTriangleMesh expected( 3, 1 );
00400         expected.addVertex( WPosition( 1, 0, 0 ) );
00401         expected.addVertex( WPosition( 0, 1, 0 ) );
00402         expected.addVertex( WPosition( 2, 1, 0 ) );
00403         expected.addTriangle( 0, 1, 2 );
00404         TS_ASSERT_EQUALS( **cit, expected );
00405 
00406 //        expected.resizeVertices( 2 );
00407 //        expected.m_vertices[ 0 ] = WPosition( 0, 2, 0 );
00408 //        expected.m_vertices[ 1 ] = WPosition( 2, 2, 0 );
00409 //        expected.resizeTriangles( 1 );
00410 //        Triangle x1 = { { 0, 1, 1 } }; // NOLINT
00411 //        expected.m_triangles[ 0 ] = x1;
00412 //        TS_ASSERT_EQUALS( **( ++cit ), expected );
00413 //
00414 //        expected.resizeVertices( 1 );
00415 //        expected.m_vertices[ 0 ] = WPosition( 0, 3, 0 );
00416 //        expected.resizeTriangles( 1 );
00417 //        Triangle x2 = { { 0, 0, 0 } }; // NOLINT
00418 //        expected.m_triangles[ 0 ] = x2;
00419 //        TS_ASSERT_EQUALS( **( ++cit ), expected );
00420 //
00421 //        expected.resizeVertices( 5 );
00422 //        expected.m_vertices[ 0 ] = WPosition( 0,  6, 0 );
00423 //        expected.m_vertices[ 1 ] = WPosition( 2,  6, 0 );
00424 //        expected.m_vertices[ 2 ] = WPosition( 1,  7, 0 );
00425 //        expected.m_vertices[ 3 ] = WPosition( 3,  4, 0 );
00426 //        expected.m_vertices[ 4 ] = WPosition( 4,  6, 0 );
00427 //        expected.resizeTriangles( 2 );
00428 //        Triangle x3 = { { 0, 1, 2 } }; // NOLINT
00429 //        Triangle x4 = { { 1, 3, 4 } }; // NOLINT
00430 //        expected.m_triangles[ 0 ] = x3;
00431 //        expected.m_triangles[ 1 ] = x4;
00432 //        TS_ASSERT_EQUALS( **( ++cit ), expected );
00433     }
00434 
00435     /**
00436      * On an empty mesh an empty list should be generated.
00437      */
00438     void testComponentDecompositionOnEmptyMesh( void )
00439     {
00440         WTriangleMesh mesh( 0, 0 );
00441         boost::shared_ptr< std::list< boost::shared_ptr< WTriangleMesh > > > result = tm_utils::componentDecomposition( mesh );
00442         TS_ASSERT( result->empty() );
00443     }
00444 };
00445 #endif  // WTRIANGLEMESH_TEST_H