fork(1) download
  1. #include <cstdio>
  2.  
  3. template<typename R, typename T>
  4. R* generate_uv_ids( T* index_buffer, int index_count, int vertex_count = 0 );
  5.  
  6. int i_buf[] = {0,1,2,2,1,3,2,1,4,4,3,5}; //test index buffer
  7. const int i_count = sizeof(i_buf) / sizeof(i_buf[0]);
  8.  
  9. int main() {
  10. int* vids = generate_uv_ids<int>( i_buf, i_count );
  11. printf("generated mapping: ");
  12. for( int i = 0; i < i_count; i+=3 )
  13. printf("(%d %d %d) ", vids[ i_buf[i] ], vids[ i_buf[i+1] ], vids[ i_buf[i+2] ] );
  14. delete[] vids;
  15. return 0;
  16. }
  17.  
  18.  
  19. template<typename R, typename T>
  20. R* generate_uv_ids( T* index_buffer, int index_count, int vertex_count ) {
  21.  
  22. //check preconditions
  23. if( ! index_buffer ) return nullptr;
  24. if( ! index_count ) return nullptr;
  25. if( ! vertex_count ) {
  26. for( int i = 0; i < index_count; i++ )
  27. vertex_count = vertex_count < index_buffer[i] ? index_buffer[i] : vertex_count;
  28. ++vertex_count;
  29. }
  30.  
  31. #define mask(a,b,c) ((a) << 4) | ((b) << 2) | (c)
  32. typedef unsigned char byte;
  33.  
  34. //a helper data structure for generating proper uv ids
  35. struct mask_to_values {
  36. byte mask;
  37. byte value[3];
  38. };
  39.  
  40. mask_to_values mv[] = {
  41.  
  42. { mask(3,3,3), {0,1,2} },
  43. { mask(3,3,0), {1,2,0} },
  44. { mask(3,3,1), {0,2,1} },
  45. { mask(3,3,2), {0,1,2} },
  46.  
  47. { mask(3,0,3), {1,0,2} },
  48. { mask(3,0,1), {2,0,1} },
  49. { mask(3,0,2), {1,0,2} },
  50.  
  51. { mask(3,1,3), {0,1,2} },
  52. { mask(3,1,0), {2,1,0} },
  53. { mask(3,1,2), {0,1,2} },
  54.  
  55. { mask(3,2,3), {0,2,1} },
  56. { mask(3,2,0), {1,2,0} },
  57. { mask(3,2,1), {0,2,1} },
  58.  
  59. { mask(0,3,3), {0,1,2} },
  60. { mask(0,3,1), {0,2,1} },
  61. { mask(0,3,2), {0,1,2} },
  62. { mask(0,1,3), {0,1,2} },
  63. { mask(0,1,2), {3,3,3} },
  64. { mask(0,2,3), {0,2,1} },
  65. { mask(0,2,1), {3,3,3} },
  66.  
  67. { mask(1,3,3), {1,2,0} },
  68. { mask(1,3,0), {1,2,0} },
  69. { mask(1,3,2), {1,0,2} },
  70. { mask(1,0,3), {1,0,2} },
  71. { mask(1,0,2), {3,3,3} },
  72. { mask(1,2,3), {1,2,0} },
  73. { mask(1,2,0), {3,3,3} },
  74.  
  75. { mask(2,3,3), {2,1,0} },
  76. { mask(2,3,0), {2,1,0} },
  77. { mask(2,3,1), {2,0,1} },
  78. { mask(2,0,3), {2,0,1} },
  79. { mask(2,0,1), {3,3,3} },
  80. { mask(2,1,3), {2,1,0} },
  81. { mask(2,1,0), {3,3,3} },
  82.  
  83. };
  84.  
  85. //get the memory for the resulting vid buffer, delete with delete[]
  86. R* vids = new R[ vertex_count ];
  87.  
  88. //init it with 3 (3 means vacant)
  89. for( int i = 0; i < vertex_count; i++ ) vids[ i ] = 3;
  90.  
  91. int bad_tri = 0; //number of tris for which no good 0,1,2 mapping exists
  92.  
  93. //loop through the index buffer
  94. for( int idx = 0; idx < index_count; idx+=3 ) {
  95.  
  96. byte m = mask( vids[ index_buffer[idx+0] ],
  97. vids[ index_buffer[idx+1] ],
  98. vids[ index_buffer[idx+2] ] ); //helper mask for searching in mv array
  99.  
  100. //loop through the mv array and find the mapping
  101. int i = 0; const int mv_size = sizeof(mv)/sizeof(mv[0]);
  102. for(; i < mv_size; i++ ) {
  103.  
  104. if( m == mv[i].mask ) {
  105. printf("mapping (%d %d %d) -> (%d %d %d)\n",
  106. vids[ index_buffer[idx+0] ], vids[ index_buffer[idx+1] ], vids[ index_buffer[idx+2] ],
  107. mv[i].value[0], mv[i].value[1], mv[i].value[2]);
  108. if( 3 == mv[i].value[0] ) break; //proper vids are already in place, early out
  109. //assign
  110. vids[index_buffer[idx+0]] = mv[i].value[0];
  111. vids[index_buffer[idx+1]] = mv[i].value[1];
  112. vids[index_buffer[idx+2]] = mv[i].value[2];
  113. break;
  114. }
  115. }
  116.  
  117. if( i == mv_size) { //no mask was found, means we've got a tri with no proper mapping
  118. bad_tri++; //print it to get the number of tris with wrong vertex ids, no or partial AA on them
  119. printf("mapping (%d %d %d) -> no mapping\n",
  120. vids[ index_buffer[idx+0] ], vids[ index_buffer[idx+1] ], vids[ index_buffer[idx+2] ] );
  121. }
  122.  
  123. }
  124.  
  125. //clean up any remaining 3s
  126. for( int i = 0; i < vertex_count; i++ ) vids[i] = vids[i] == 3 ? 0 : vids[i];
  127.  
  128. return vids;
  129. }
  130.  
Success #stdin #stdout 0s 3412KB
stdin
Standard input is empty
stdout
mapping (3 3 3) -> (0 1 2)
mapping (2 1 3) -> (2 1 0)
mapping (2 1 3) -> (2 1 0)
mapping (0 0 3) -> no mapping
generated mapping: (0 1 2) (2 1 0) (2 1 0) (0 0 0)