thekla_atlas.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #include "thekla_atlas.h"
  2. #include <cfloat>
  3. // -- GODOT start --
  4. #include <stdio.h>
  5. // -- GODOT end --
  6. #include "nvmesh/halfedge/Edge.h"
  7. #include "nvmesh/halfedge/Mesh.h"
  8. #include "nvmesh/halfedge/Face.h"
  9. #include "nvmesh/halfedge/Vertex.h"
  10. #include "nvmesh/param/Atlas.h"
  11. #include "nvmath/Vector.inl"
  12. #include "nvmath/ftoi.h"
  13. #include "nvcore/Array.inl"
  14. using namespace Thekla;
  15. using namespace nv;
  16. inline Atlas_Output_Mesh * set_error(Atlas_Error * error, Atlas_Error code) {
  17. if (error) *error = code;
  18. return NULL;
  19. }
  20. static void input_to_mesh(const Atlas_Input_Mesh * input, HalfEdge::Mesh * mesh, Atlas_Error * error) {
  21. Array<uint> canonicalMap;
  22. canonicalMap.reserve(input->vertex_count);
  23. for (int i = 0; i < input->vertex_count; i++) {
  24. const Atlas_Input_Vertex & input_vertex = input->vertex_array[i];
  25. const float * pos = input_vertex.position;
  26. const float * nor = input_vertex.normal;
  27. const float * tex = input_vertex.uv;
  28. HalfEdge::Vertex * vertex = mesh->addVertex(Vector3(pos[0], pos[1], pos[2]));
  29. vertex->nor.set(nor[0], nor[1], nor[2]);
  30. vertex->tex.set(tex[0], tex[1]);
  31. canonicalMap.append(input_vertex.first_colocal);
  32. }
  33. mesh->linkColocalsWithCanonicalMap(canonicalMap);
  34. const int face_count = input->face_count;
  35. int non_manifold_faces = 0;
  36. for (int i = 0; i < face_count; i++) {
  37. const Atlas_Input_Face & input_face = input->face_array[i];
  38. int v0 = input_face.vertex_index[0];
  39. int v1 = input_face.vertex_index[1];
  40. int v2 = input_face.vertex_index[2];
  41. HalfEdge::Face * face = mesh->addFace(v0, v1, v2);
  42. if (face != NULL) {
  43. face->material = input_face.material_index;
  44. }
  45. else {
  46. non_manifold_faces++;
  47. }
  48. }
  49. mesh->linkBoundary();
  50. if (non_manifold_faces != 0 && error != NULL) {
  51. *error = Atlas_Error_Invalid_Mesh_Non_Manifold;
  52. }
  53. }
  54. static Atlas_Output_Mesh * mesh_atlas_to_output(const HalfEdge::Mesh * mesh, const Atlas & atlas, Atlas_Error * error) {
  55. Atlas_Output_Mesh * output = new Atlas_Output_Mesh;
  56. const MeshCharts * charts = atlas.meshAt(0);
  57. // Allocate vertices.
  58. const int vertex_count = charts->vertexCount();
  59. output->vertex_count = vertex_count;
  60. output->vertex_array = new Atlas_Output_Vertex[vertex_count];
  61. int w = 0;
  62. int h = 0;
  63. // Output vertices.
  64. const int chart_count = charts->chartCount();
  65. for (int i = 0; i < chart_count; i++) {
  66. const Chart * chart = charts->chartAt(i);
  67. uint vertexOffset = charts->vertexCountBeforeChartAt(i);
  68. const uint chart_vertex_count = chart->vertexCount();
  69. for (uint v = 0; v < chart_vertex_count; v++) {
  70. Atlas_Output_Vertex & output_vertex = output->vertex_array[vertexOffset + v];
  71. uint original_vertex = chart->mapChartVertexToOriginalVertex(v);
  72. output_vertex.xref = original_vertex;
  73. Vector2 uv = chart->chartMesh()->vertexAt(v)->tex;
  74. output_vertex.uv[0] = uv.x;
  75. output_vertex.uv[1] = uv.y;
  76. w = max(w, ftoi_ceil(uv.x));
  77. h = max(h, ftoi_ceil(uv.y));
  78. }
  79. }
  80. const int face_count = mesh->faceCount();
  81. output->index_count = face_count * 3;
  82. output->index_array = new int[face_count * 3];
  83. // -- GODOT start --
  84. int face_ofs = 0;
  85. // Set face indices.
  86. for (int f = 0; f < face_count; f++) {
  87. uint c = charts->faceChartAt(f);
  88. uint i = charts->faceIndexWithinChartAt(f);
  89. uint vertexOffset = charts->vertexCountBeforeChartAt(c);
  90. const Chart * chart = charts->chartAt(c);
  91. nvDebugCheck(chart->faceAt(i) == f);
  92. if (i >= chart->chartMesh()->faceCount()) {
  93. printf("WARNING: Faces may be missing in the final vertex, which could not be packed\n");
  94. continue;
  95. }
  96. const HalfEdge::Face * face = chart->chartMesh()->faceAt(i);
  97. const HalfEdge::Edge * edge = face->edge;
  98. //output->index_array[3*f+0] = vertexOffset + edge->vertex->id;
  99. //output->index_array[3*f+1] = vertexOffset + edge->next->vertex->id;
  100. //output->index_array[3*f+2] = vertexOffset + edge->next->next->vertex->id;
  101. output->index_array[3 * face_ofs + 0] = vertexOffset + edge->vertex->id;
  102. output->index_array[3 * face_ofs + 1] = vertexOffset + edge->next->vertex->id;
  103. output->index_array[3 * face_ofs + 2] = vertexOffset + edge->next->next->vertex->id;
  104. face_ofs++;
  105. }
  106. output->index_count = face_ofs * 3;
  107. // -- GODOT end --
  108. *error = Atlas_Error_Success;
  109. output->atlas_width = w;
  110. output->atlas_height = h;
  111. return output;
  112. }
  113. void Thekla::atlas_set_default_options(Atlas_Options * options) {
  114. if (options != NULL) {
  115. // These are the default values we use on The Witness.
  116. options->charter = Atlas_Charter_Default;
  117. options->charter_options.witness.proxy_fit_metric_weight = 2.0f;
  118. options->charter_options.witness.roundness_metric_weight = 0.01f;
  119. options->charter_options.witness.straightness_metric_weight = 6.0f;
  120. options->charter_options.witness.normal_seam_metric_weight = 4.0f;
  121. options->charter_options.witness.texture_seam_metric_weight = 0.5f;
  122. options->charter_options.witness.max_chart_area = FLT_MAX;
  123. options->charter_options.witness.max_boundary_length = FLT_MAX;
  124. options->mapper = Atlas_Mapper_Default;
  125. options->packer = Atlas_Packer_Default;
  126. options->packer_options.witness.packing_quality = 0;
  127. options->packer_options.witness.texel_area = 8;
  128. options->packer_options.witness.block_align = true;
  129. options->packer_options.witness.conservative = false;
  130. }
  131. }
  132. Atlas_Output_Mesh * Thekla::atlas_generate(const Atlas_Input_Mesh * input, const Atlas_Options * options, Atlas_Error * error) {
  133. // Validate args.
  134. if (input == NULL || options == NULL || error == NULL) return set_error(error, Atlas_Error_Invalid_Args);
  135. // Validate options.
  136. if (options->charter != Atlas_Charter_Witness) {
  137. return set_error(error, Atlas_Error_Invalid_Options);
  138. }
  139. if (options->charter == Atlas_Charter_Witness) {
  140. // @@ Validate input options!
  141. }
  142. if (options->mapper != Atlas_Mapper_LSCM) {
  143. return set_error(error, Atlas_Error_Invalid_Options);
  144. }
  145. if (options->mapper == Atlas_Mapper_LSCM) {
  146. // No options.
  147. }
  148. if (options->packer != Atlas_Packer_Witness) {
  149. return set_error(error, Atlas_Error_Invalid_Options);
  150. }
  151. if (options->packer == Atlas_Packer_Witness) {
  152. // @@ Validate input options!
  153. }
  154. // Validate input mesh.
  155. for (int i = 0; i < input->face_count; i++) {
  156. int v0 = input->face_array[i].vertex_index[0];
  157. int v1 = input->face_array[i].vertex_index[1];
  158. int v2 = input->face_array[i].vertex_index[2];
  159. if (v0 < 0 || v0 >= input->vertex_count ||
  160. v1 < 0 || v1 >= input->vertex_count ||
  161. v2 < 0 || v2 >= input->vertex_count)
  162. {
  163. return set_error(error, Atlas_Error_Invalid_Mesh);
  164. }
  165. }
  166. // Build half edge mesh.
  167. AutoPtr<HalfEdge::Mesh> mesh(new HalfEdge::Mesh);
  168. input_to_mesh(input, mesh.ptr(), error);
  169. if (*error == Atlas_Error_Invalid_Mesh) {
  170. return NULL;
  171. }
  172. Atlas atlas;
  173. // Charter.
  174. if (options->charter == Atlas_Charter_Extract) {
  175. return set_error(error, Atlas_Error_Not_Implemented);
  176. }
  177. else if (options->charter == Atlas_Charter_Witness) {
  178. SegmentationSettings segmentation_settings;
  179. segmentation_settings.proxyFitMetricWeight = options->charter_options.witness.proxy_fit_metric_weight;
  180. segmentation_settings.roundnessMetricWeight = options->charter_options.witness.roundness_metric_weight;
  181. segmentation_settings.straightnessMetricWeight = options->charter_options.witness.straightness_metric_weight;
  182. segmentation_settings.normalSeamMetricWeight = options->charter_options.witness.normal_seam_metric_weight;
  183. segmentation_settings.textureSeamMetricWeight = options->charter_options.witness.texture_seam_metric_weight;
  184. segmentation_settings.maxChartArea = options->charter_options.witness.max_chart_area;
  185. segmentation_settings.maxBoundaryLength = options->charter_options.witness.max_boundary_length;
  186. Array<uint> uncharted_materials;
  187. atlas.computeCharts(mesh.ptr(), segmentation_settings, uncharted_materials);
  188. }
  189. if (atlas.hasFailed())
  190. return NULL;
  191. // Mapper.
  192. if (options->mapper == Atlas_Mapper_LSCM) {
  193. atlas.parameterizeCharts();
  194. }
  195. if (atlas.hasFailed())
  196. return NULL;
  197. // Packer.
  198. if (options->packer == Atlas_Packer_Witness) {
  199. int packing_quality = options->packer_options.witness.packing_quality;
  200. float texel_area = options->packer_options.witness.texel_area;
  201. int block_align = options->packer_options.witness.block_align;
  202. int conservative = options->packer_options.witness.conservative;
  203. /*float utilization =*/ atlas.packCharts(packing_quality, texel_area, block_align, conservative);
  204. }
  205. if (atlas.hasFailed())
  206. return NULL;
  207. // Build output mesh.
  208. return mesh_atlas_to_output(mesh.ptr(), atlas, error);
  209. }
  210. void Thekla::atlas_free(Atlas_Output_Mesh * output) {
  211. if (output != NULL) {
  212. delete [] output->vertex_array;
  213. delete [] output->index_array;
  214. delete output;
  215. }
  216. }