#include "utVertexTriangleAdjacency.h" CPPUNIT_TEST_SUITE_REGISTRATION (VTAdjacency); void VTAdjacency :: setUp (void) { // build a test mesh with randomized input data // ******************************************************************************* pMesh = new aiMesh(); pMesh->mNumVertices = 500; pMesh->mNumFaces = 600; pMesh->mFaces = new aiFace[600]; unsigned int iCurrent = 0; for (unsigned int i = 0; i < 600;++i) { aiFace& face = pMesh->mFaces[i]; face.mNumIndices = 3; face.mIndices = new unsigned int[3]; if (499 == iCurrent)iCurrent = 0; face.mIndices[0] = iCurrent++; while(face.mIndices[0] == ( face.mIndices[1] = unsigned int(((float)rand()/RAND_MAX)*499))); while(face.mIndices[0] == ( face.mIndices[2] = unsigned int(((float)rand()/RAND_MAX)*499)) || face.mIndices[1] == face.mIndices[2]); } // build a second test mesh - this one is extremely small // ******************************************************************************* pMesh2 = new aiMesh(); pMesh2->mNumVertices = 5; pMesh2->mNumFaces = 3; pMesh2->mFaces = new aiFace[3]; pMesh2->mFaces[0].mIndices = new unsigned int[3]; pMesh2->mFaces[1].mIndices = new unsigned int[3]; pMesh2->mFaces[2].mIndices = new unsigned int[3]; pMesh2->mFaces[0].mIndices[0] = 1; pMesh2->mFaces[0].mIndices[1] = 3; pMesh2->mFaces[0].mIndices[2] = 2; pMesh2->mFaces[1].mIndices[0] = 0; pMesh2->mFaces[1].mIndices[1] = 2; pMesh2->mFaces[1].mIndices[2] = 3; pMesh2->mFaces[2].mIndices[0] = 3; pMesh2->mFaces[2].mIndices[1] = 0; pMesh2->mFaces[2].mIndices[2] = 4; // build a third test mesh which does not reference all vertices // ******************************************************************************* pMesh3 = new aiMesh(); pMesh3->mNumVertices = 500; pMesh3->mNumFaces = 600; pMesh3->mFaces = new aiFace[600]; iCurrent = 0; for (unsigned int i = 0; i < 600;++i) { aiFace& face = pMesh3->mFaces[i]; face.mNumIndices = 3; face.mIndices = new unsigned int[3]; if (499 == iCurrent)iCurrent = 0; face.mIndices[0] = iCurrent++; if (499 == iCurrent)iCurrent = 0; face.mIndices[1] = iCurrent++; if (499 == iCurrent)iCurrent = 0; face.mIndices[2] = iCurrent++; if (rand() > RAND_MAX/2 && face.mIndices[0]) { face.mIndices[0]--; } else if (face.mIndices[1]) face.mIndices[1]--; } } void VTAdjacency :: tearDown (void) { delete pMesh; pMesh = 0; delete pMesh2; pMesh2 = 0; delete pMesh3; pMesh3 = 0; } void VTAdjacency :: largeRandomDataSet (void) { checkMesh(pMesh); } void VTAdjacency :: smallDataSet (void) { checkMesh(pMesh2); } void VTAdjacency :: unreferencedVerticesSet (void) { checkMesh(pMesh3); } void VTAdjacency :: checkMesh (aiMesh* pMesh) { pAdj = new VertexTriangleAdjacency(pMesh->mFaces,pMesh->mNumFaces,pMesh->mNumVertices,true); unsigned int* const piNum = pAdj->mLiveTriangles; // check the primary adjacency table and check whether all faces // are contained in the list unsigned int maxOfs = 0; for (unsigned int i = 0; i < pMesh->mNumFaces;++i) { aiFace& face = pMesh->mFaces[i]; for (unsigned int qq = 0; qq < 3 ;++qq) { const unsigned int idx = face.mIndices[qq]; const unsigned int num = piNum[idx]; // go to this offset const unsigned int ofs = pAdj->mOffsetTable[idx]; maxOfs = std::max(ofs+num,maxOfs); unsigned int* pi = &pAdj->mAdjacencyTable[ofs]; // and search for us ... unsigned int tt = 0; for (; tt < num;++tt,++pi) { if (i == *pi) { // mask our entry in the table. Finally all entries should be masked *pi = 0xffffffff; // there shouldn't be two entries for the same face break; } } // assert if *this* vertex has not been found in the table CPPUNIT_ASSERT(tt < num); } } // now check whether there are invalid faces const unsigned int* pi = pAdj->mAdjacencyTable; for (unsigned int i = 0; i < maxOfs;++i,++pi) { CPPUNIT_ASSERT(0xffffffff == *pi); } // check the numTrianglesPerVertex table for (unsigned int i = 0; i < pMesh->mNumFaces;++i) { aiFace& face = pMesh->mFaces[i]; for (unsigned int qq = 0; qq < 3 ;++qq) { const unsigned int idx = face.mIndices[qq]; // we should not reach 0 here ... CPPUNIT_ASSERT( 0 != piNum[idx]); piNum[idx]--; } } // check whether we reached 0 in all entries for (unsigned int i = 0; i < pMesh->mNumVertices;++i) { CPPUNIT_ASSERT(!piNum[i]); } delete pAdj; }