utVertexTriangleAdjacency.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #include "utVertexTriangleAdjacency.h"
  2. CPPUNIT_TEST_SUITE_REGISTRATION (VTAdjacency);
  3. void VTAdjacency :: setUp (void)
  4. {
  5. // build a test mesh with randomized input data
  6. // *******************************************************************************
  7. pMesh = new aiMesh();
  8. pMesh->mNumVertices = 500;
  9. pMesh->mNumFaces = 600;
  10. pMesh->mFaces = new aiFace[600];
  11. unsigned int iCurrent = 0;
  12. for (unsigned int i = 0; i < 600;++i)
  13. {
  14. aiFace& face = pMesh->mFaces[i];
  15. face.mNumIndices = 3;
  16. face.mIndices = new unsigned int[3];
  17. if (499 == iCurrent)iCurrent = 0;
  18. face.mIndices[0] = iCurrent++;
  19. while(face.mIndices[0] == ( face.mIndices[1] = (unsigned int)(((float)rand()/RAND_MAX)*499)));
  20. while(face.mIndices[0] == ( face.mIndices[2] = (unsigned int)(((float)rand()/RAND_MAX)*499)) ||
  21. face.mIndices[1] == face.mIndices[2]);
  22. }
  23. // build a second test mesh - this one is extremely small
  24. // *******************************************************************************
  25. pMesh2 = new aiMesh();
  26. pMesh2->mNumVertices = 5;
  27. pMesh2->mNumFaces = 3;
  28. pMesh2->mFaces = new aiFace[3];
  29. pMesh2->mFaces[0].mIndices = new unsigned int[3];
  30. pMesh2->mFaces[1].mIndices = new unsigned int[3];
  31. pMesh2->mFaces[2].mIndices = new unsigned int[3];
  32. pMesh2->mFaces[0].mIndices[0] = 1;
  33. pMesh2->mFaces[0].mIndices[1] = 3;
  34. pMesh2->mFaces[0].mIndices[2] = 2;
  35. pMesh2->mFaces[1].mIndices[0] = 0;
  36. pMesh2->mFaces[1].mIndices[1] = 2;
  37. pMesh2->mFaces[1].mIndices[2] = 3;
  38. pMesh2->mFaces[2].mIndices[0] = 3;
  39. pMesh2->mFaces[2].mIndices[1] = 0;
  40. pMesh2->mFaces[2].mIndices[2] = 4;
  41. // build a third test mesh which does not reference all vertices
  42. // *******************************************************************************
  43. pMesh3 = new aiMesh();
  44. pMesh3->mNumVertices = 500;
  45. pMesh3->mNumFaces = 600;
  46. pMesh3->mFaces = new aiFace[600];
  47. iCurrent = 0;
  48. for (unsigned int i = 0; i < 600;++i)
  49. {
  50. aiFace& face = pMesh3->mFaces[i];
  51. face.mNumIndices = 3;
  52. face.mIndices = new unsigned int[3];
  53. if (499 == iCurrent)iCurrent = 0;
  54. face.mIndices[0] = iCurrent++;
  55. if (499 == iCurrent)iCurrent = 0;
  56. face.mIndices[1] = iCurrent++;
  57. if (499 == iCurrent)iCurrent = 0;
  58. face.mIndices[2] = iCurrent++;
  59. if (rand() > RAND_MAX/2 && face.mIndices[0])
  60. {
  61. face.mIndices[0]--;
  62. }
  63. else if (face.mIndices[1]) face.mIndices[1]--;
  64. }
  65. }
  66. void VTAdjacency :: tearDown (void)
  67. {
  68. delete pMesh;
  69. pMesh = 0;
  70. delete pMesh2;
  71. pMesh2 = 0;
  72. delete pMesh3;
  73. pMesh3 = 0;
  74. }
  75. void VTAdjacency :: largeRandomDataSet (void)
  76. {
  77. checkMesh(pMesh);
  78. }
  79. void VTAdjacency :: smallDataSet (void)
  80. {
  81. checkMesh(pMesh2);
  82. }
  83. void VTAdjacency :: unreferencedVerticesSet (void)
  84. {
  85. checkMesh(pMesh3);
  86. }
  87. void VTAdjacency :: checkMesh (aiMesh* pMesh)
  88. {
  89. pAdj = new VertexTriangleAdjacency(pMesh->mFaces,pMesh->mNumFaces,pMesh->mNumVertices,true);
  90. unsigned int* const piNum = pAdj->mLiveTriangles;
  91. // check the primary adjacency table and check whether all faces
  92. // are contained in the list
  93. unsigned int maxOfs = 0;
  94. for (unsigned int i = 0; i < pMesh->mNumFaces;++i)
  95. {
  96. aiFace& face = pMesh->mFaces[i];
  97. for (unsigned int qq = 0; qq < 3 ;++qq)
  98. {
  99. const unsigned int idx = face.mIndices[qq];
  100. const unsigned int num = piNum[idx];
  101. // go to this offset
  102. const unsigned int ofs = pAdj->mOffsetTable[idx];
  103. maxOfs = std::max(ofs+num,maxOfs);
  104. unsigned int* pi = &pAdj->mAdjacencyTable[ofs];
  105. // and search for us ...
  106. unsigned int tt = 0;
  107. for (; tt < num;++tt,++pi)
  108. {
  109. if (i == *pi)
  110. {
  111. // mask our entry in the table. Finally all entries should be masked
  112. *pi = 0xffffffff;
  113. // there shouldn't be two entries for the same face
  114. break;
  115. }
  116. }
  117. // assert if *this* vertex has not been found in the table
  118. CPPUNIT_ASSERT(tt < num);
  119. }
  120. }
  121. // now check whether there are invalid faces
  122. const unsigned int* pi = pAdj->mAdjacencyTable;
  123. for (unsigned int i = 0; i < maxOfs;++i,++pi)
  124. {
  125. CPPUNIT_ASSERT(0xffffffff == *pi);
  126. }
  127. // check the numTrianglesPerVertex table
  128. for (unsigned int i = 0; i < pMesh->mNumFaces;++i)
  129. {
  130. aiFace& face = pMesh->mFaces[i];
  131. for (unsigned int qq = 0; qq < 3 ;++qq)
  132. {
  133. const unsigned int idx = face.mIndices[qq];
  134. // we should not reach 0 here ...
  135. CPPUNIT_ASSERT( 0 != piNum[idx]);
  136. piNum[idx]--;
  137. }
  138. }
  139. // check whether we reached 0 in all entries
  140. for (unsigned int i = 0; i < pMesh->mNumVertices;++i)
  141. {
  142. CPPUNIT_ASSERT(!piNum[i]);
  143. }
  144. delete pAdj;
  145. }