thekla_atlas.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. #include "thekla_atlas.h"
  2. #include <cfloat>
  3. #include <cstdio>
  4. #include <vector>
  5. #include <map>
  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 "nvmesh/raster/Raster.h"
  12. #include "nvmath/Vector.inl"
  13. #include "nvmath/ftoi.h"
  14. #include "nvcore/Array.inl"
  15. #define STBI_IMAGE_NO_ATOMIC
  16. #include "../../STB/stb_image_write.h"
  17. using namespace Thekla;
  18. using namespace nv;
  19. inline Atlas_Output_Mesh * set_error(Atlas_Error * error, Atlas_Error code) {
  20. if (error) *error = code;
  21. return NULL;
  22. }
  23. static void input_to_mesh(const Atlas_Input_Mesh * input, HalfEdge::Mesh * mesh, Atlas_Error * error) {
  24. Array<uint> canonicalMap;
  25. canonicalMap.reserve(input->vertex_count);
  26. for (int i = 0; i < input->vertex_count; i++) {
  27. const Atlas_Input_Vertex & input_vertex = input->vertex_array[i];
  28. const float * pos = input_vertex.position;
  29. const float * nor = input_vertex.normal;
  30. const float * tex = input_vertex.uv;
  31. HalfEdge::Vertex * vertex = mesh->addVertex(Vector3(pos[0], pos[1], pos[2]));
  32. vertex->nor.set(nor[0], nor[1], nor[2]);
  33. vertex->tex.set(tex[0], tex[1]);
  34. canonicalMap.append(input_vertex.first_colocal);
  35. }
  36. mesh->linkColocalsWithCanonicalMap(canonicalMap);
  37. const int face_count = input->face_count;
  38. int non_manifold_faces = 0;
  39. for (int i = 0; i < face_count; i++) {
  40. const Atlas_Input_Face & input_face = input->face_array[i];
  41. int v0 = input_face.vertex_index[0];
  42. int v1 = input_face.vertex_index[1];
  43. int v2 = input_face.vertex_index[2];
  44. HalfEdge::Face * face = mesh->addFace(v0, v1, v2);
  45. if (face != NULL) {
  46. face->material = input_face.material_index;
  47. }
  48. else {
  49. non_manifold_faces++;
  50. }
  51. }
  52. mesh->linkBoundary();
  53. if (non_manifold_faces != 0 && error != NULL) {
  54. *error = Atlas_Error_Invalid_Mesh_Non_Manifold;
  55. }
  56. }
  57. static Atlas_Output_Mesh * mesh_atlas_to_output(const HalfEdge::Mesh * mesh, const Atlas & atlas, Atlas_Error * error) {
  58. Atlas_Output_Mesh * output = new Atlas_Output_Mesh;
  59. const MeshCharts * charts = atlas.meshAt(0);
  60. // Allocate vertices.
  61. const int vertex_count = charts->vertexCount();
  62. output->vertex_count = vertex_count;
  63. output->vertex_array = new Atlas_Output_Vertex[vertex_count];
  64. int w = 0;
  65. int h = 0;
  66. // Output vertices.
  67. const int chart_count = charts->chartCount();
  68. for (int i = 0; i < chart_count; i++) {
  69. const Chart * chart = charts->chartAt(i);
  70. uint vertexOffset = charts->vertexCountBeforeChartAt(i);
  71. const uint chart_vertex_count = chart->vertexCount();
  72. for (uint v = 0; v < chart_vertex_count; v++) {
  73. Atlas_Output_Vertex & output_vertex = output->vertex_array[vertexOffset + v];
  74. uint original_vertex = chart->mapChartVertexToOriginalVertex(v);
  75. output_vertex.xref = original_vertex;
  76. Vector2 uv = chart->chartMesh()->vertexAt(v)->tex;
  77. output_vertex.uv[0] = uv.x;
  78. output_vertex.uv[1] = uv.y;
  79. w = max(w, ftoi_ceil(uv.x));
  80. h = max(h, ftoi_ceil(uv.y));
  81. }
  82. }
  83. const int face_count = mesh->faceCount();
  84. output->index_count = face_count * 3;
  85. output->index_array = new int[face_count * 3];
  86. // Set face indices.
  87. for (int f = 0; f < face_count; f++) {
  88. uint c = charts->faceChartAt(f);
  89. uint i = charts->faceIndexWithinChartAt(f);
  90. uint vertexOffset = charts->vertexCountBeforeChartAt(c);
  91. const Chart * chart = charts->chartAt(c);
  92. nvDebugCheck(chart->faceAt(i) == f);
  93. const HalfEdge::Face * face = chart->chartMesh()->faceAt(i);
  94. const HalfEdge::Edge * edge = face->edge;
  95. output->index_array[3*f+0] = vertexOffset + edge->vertex->id;
  96. output->index_array[3*f+1] = vertexOffset + edge->next->vertex->id;
  97. output->index_array[3*f+2] = vertexOffset + edge->next->next->vertex->id;
  98. }
  99. *error = Atlas_Error_Success;
  100. output->atlas_width = w;
  101. output->atlas_height = h;
  102. return output;
  103. }
  104. void Thekla::atlas_set_default_options(Atlas_Options * options) {
  105. if (options != NULL) {
  106. // These are the default values we use on The Witness.
  107. options->charter = Atlas_Charter_Default;
  108. options->charter_options.witness.proxy_fit_metric_weight = 2.0f;
  109. options->charter_options.witness.roundness_metric_weight = 0.01f;
  110. options->charter_options.witness.straightness_metric_weight = 6.0f;
  111. options->charter_options.witness.normal_seam_metric_weight = 4.0f;
  112. options->charter_options.witness.texture_seam_metric_weight = 0.5f;
  113. options->charter_options.witness.max_chart_area = FLT_MAX;
  114. options->charter_options.witness.max_boundary_length = FLT_MAX;
  115. options->mapper = Atlas_Mapper_Default;
  116. options->packer = Atlas_Packer_Default;
  117. options->packer_options.witness.packing_quality = 0;
  118. options->packer_options.witness.texel_area = 8;
  119. options->packer_options.witness.block_align = true;
  120. options->packer_options.witness.conservative = false;
  121. }
  122. }
  123. Atlas_Output_Mesh * Thekla::atlas_generate(const Atlas_Input_Mesh * input, const Atlas_Options * options, Atlas_Error * error) {
  124. // Validate args.
  125. if (input == NULL || options == NULL || error == NULL) return set_error(error, Atlas_Error_Invalid_Args);
  126. // Validate options.
  127. if (options->charter != Atlas_Charter_Witness) {
  128. return set_error(error, Atlas_Error_Invalid_Options);
  129. }
  130. if (options->charter == Atlas_Charter_Witness) {
  131. // @@ Validate input options!
  132. }
  133. if (options->mapper != Atlas_Mapper_LSCM) {
  134. return set_error(error, Atlas_Error_Invalid_Options);
  135. }
  136. if (options->mapper == Atlas_Mapper_LSCM) {
  137. // No options.
  138. }
  139. if (options->packer != Atlas_Packer_Witness) {
  140. return set_error(error, Atlas_Error_Invalid_Options);
  141. }
  142. if (options->packer == Atlas_Packer_Witness) {
  143. // @@ Validate input options!
  144. }
  145. // Validate input mesh.
  146. for (int i = 0; i < input->face_count; i++) {
  147. int v0 = input->face_array[i].vertex_index[0];
  148. int v1 = input->face_array[i].vertex_index[1];
  149. int v2 = input->face_array[i].vertex_index[2];
  150. if (v0 < 0 || v0 >= input->vertex_count ||
  151. v1 < 0 || v1 >= input->vertex_count ||
  152. v2 < 0 || v2 >= input->vertex_count)
  153. {
  154. return set_error(error, Atlas_Error_Invalid_Mesh);
  155. }
  156. }
  157. // Build half edge mesh.
  158. AutoPtr<HalfEdge::Mesh> mesh(new HalfEdge::Mesh);
  159. input_to_mesh(input, mesh.ptr(), error);
  160. if (*error == Atlas_Error_Invalid_Mesh) {
  161. return NULL;
  162. }
  163. Atlas atlas;
  164. // Charter.
  165. if (options->charter == Atlas_Charter_Extract) {
  166. return set_error(error, Atlas_Error_Not_Implemented);
  167. }
  168. else if (options->charter == Atlas_Charter_Witness) {
  169. SegmentationSettings segmentation_settings;
  170. segmentation_settings.proxyFitMetricWeight = options->charter_options.witness.proxy_fit_metric_weight;
  171. segmentation_settings.roundnessMetricWeight = options->charter_options.witness.roundness_metric_weight;
  172. segmentation_settings.straightnessMetricWeight = options->charter_options.witness.straightness_metric_weight;
  173. segmentation_settings.normalSeamMetricWeight = options->charter_options.witness.normal_seam_metric_weight;
  174. segmentation_settings.textureSeamMetricWeight = options->charter_options.witness.texture_seam_metric_weight;
  175. segmentation_settings.maxChartArea = options->charter_options.witness.max_chart_area;
  176. segmentation_settings.maxBoundaryLength = options->charter_options.witness.max_boundary_length;
  177. Array<uint> uncharted_materials;
  178. atlas.computeCharts(mesh.ptr(), segmentation_settings, uncharted_materials);
  179. }
  180. // Mapper.
  181. if (options->mapper == Atlas_Mapper_LSCM) {
  182. atlas.parameterizeCharts();
  183. }
  184. // Packer.
  185. if (options->packer == Atlas_Packer_Witness) {
  186. int packing_quality = options->packer_options.witness.packing_quality;
  187. float texel_area = options->packer_options.witness.texel_area;
  188. int block_align = options->packer_options.witness.block_align;
  189. int conservative = options->packer_options.witness.conservative;
  190. /*float utilization =*/ atlas.packCharts(packing_quality, texel_area, block_align, conservative);
  191. }
  192. // Build output mesh.
  193. return mesh_atlas_to_output(mesh.ptr(), atlas, error);
  194. }
  195. void Thekla::atlas_free(Atlas_Output_Mesh * output) {
  196. if (output != NULL) {
  197. delete [] output->vertex_array;
  198. delete [] output->index_array;
  199. delete output;
  200. }
  201. }
  202. // ATOMIC BEGIN
  203. struct ShaderData {
  204. int width;
  205. Vector3 objspace[3];
  206. float* floats;
  207. uint8_t* chartids;
  208. uint8_t chartid;
  209. unsigned char* data;
  210. unsigned char color[4];
  211. float fpcolor[4];
  212. };
  213. static bool pngAtlasCallback(
  214. void * param, int x, int y, Vector3::Arg tex,
  215. Vector3::Arg b, Vector3::Arg c, float area)
  216. {
  217. unsigned char* colors = ((ShaderData*) param)->data;
  218. Vector3* objspace = ((ShaderData*) param)->objspace;
  219. int width = ((ShaderData*) param)->width;
  220. int loc = x * 3 + y * 3 * width;
  221. Vector3 color = objspace[0] * tex.x +
  222. objspace[1] * tex.y +
  223. objspace[2] * tex.z;
  224. colors[loc++] = color.x * 255;
  225. colors[loc++] = color.y * 255;
  226. colors[loc++] = color.z * 255;
  227. return true;
  228. }
  229. static bool floatAtlasCallback(
  230. void * param, int x, int y, Vector3::Arg tex,
  231. Vector3::Arg b, Vector3::Arg c, float area)
  232. {
  233. float* floats = ((ShaderData*) param)->floats;
  234. Vector3* objspace = ((ShaderData*) param)->objspace;
  235. int width = ((ShaderData*) param)->width;
  236. int loc = x * 3 + y * 3 * width;
  237. Vector3 color = objspace[0] * tex.x +
  238. objspace[1] * tex.y +
  239. objspace[2] * tex.z;
  240. floats[loc++] = color.x;
  241. floats[loc++] = color.y;
  242. floats[loc++] = color.z;
  243. return true;
  244. }
  245. static bool pngSolidCallback(
  246. void * param, int x, int y, Vector3::Arg tex,
  247. Vector3::Arg b, Vector3::Arg c, float area)
  248. {
  249. unsigned char* colors = ((ShaderData*) param)->data;
  250. unsigned char* color = ((ShaderData*) param)->color;
  251. int width = ((ShaderData*) param)->width;
  252. int loc = x * 3 + y * 3 * width;
  253. colors[loc++] = color[0];
  254. colors[loc++] = color[1];
  255. colors[loc++] = color[2];
  256. return true;
  257. }
  258. static bool floatSolidCallback(
  259. void * param, int x, int y, Vector3::Arg tex,
  260. Vector3::Arg b, Vector3::Arg c, float area)
  261. {
  262. float* floats = ((ShaderData*) param)->floats;
  263. float* fpcolor = ((ShaderData*) param)->fpcolor;
  264. int width = ((ShaderData*) param)->width;
  265. int loc = x * 3 + y * 3 * width;
  266. floats[loc++] = fpcolor[0];
  267. floats[loc++] = fpcolor[1];
  268. floats[loc++] = fpcolor[2];
  269. return true;
  270. }
  271. static bool idSolidCallback(
  272. void * param, int x, int y, Vector3::Arg tex,
  273. Vector3::Arg b, Vector3::Arg c, float area)
  274. {
  275. uint8_t* ids = ((ShaderData*) param)->chartids;
  276. uint8_t id = ((ShaderData*) param)->chartid;
  277. int width = ((ShaderData*) param)->width;
  278. ids[x + y * width] = id;
  279. return true;
  280. }
  281. static Raster::Mode sRasterMode = Raster::Mode_Antialiased;
  282. void Thekla::atlas_write_debug_textures(const Atlas_Output_Mesh * atlas_mesh,
  283. const Atlas_Input_Mesh * obj_mesh,
  284. const char* worldSpaceTexturePath,
  285. const char* normalTexturePath,
  286. uint8_t** pchartids)
  287. {
  288. Vector3 minp(FLT_MAX);
  289. Vector3 maxp(FLT_MIN);
  290. for (int nvert = 0; nvert < atlas_mesh->vertex_count; nvert++) {
  291. const Atlas_Output_Vertex& overt = atlas_mesh->vertex_array[nvert];
  292. const Atlas_Input_Vertex& ivert = obj_mesh->vertex_array[overt.xref];
  293. minp.x = nv::min(ivert.position[0], minp.x);
  294. minp.y = nv::min(ivert.position[1], minp.y);
  295. minp.z = nv::min(ivert.position[2], minp.z);
  296. maxp.x = nv::max(ivert.position[0], maxp.x);
  297. maxp.y = nv::max(ivert.position[1], maxp.y);
  298. maxp.z = nv::max(ivert.position[2], maxp.z);
  299. }
  300. // Create an image representing the charts, with color representing the
  301. // approximate world-space position of each source vertex.
  302. int width = atlas_mesh->atlas_width;
  303. int height = atlas_mesh->atlas_height;
  304. const Vector2 extents(width, height);
  305. unsigned char* colors = (unsigned char*) calloc(width * height * 3, 1);
  306. uint8_t* chartids = pchartids ? (uint8_t*) calloc(width * height, 1) : 0;
  307. float* floats = (float*) calloc(width * height * sizeof(float) * 3, 1);
  308. const int* patlasIndex = atlas_mesh->index_array;
  309. Vector2 triverts[3];
  310. ShaderData shaderdata;
  311. shaderdata.width = width;
  312. shaderdata.data = colors;
  313. shaderdata.floats = floats;
  314. shaderdata.chartids = chartids;
  315. Vector3 objextent = maxp - minp;
  316. Vector3 offset = -minp;
  317. float objmextent = nv::max(nv::max(objextent.x, objextent.y), objextent.z);
  318. float scale = 1.0f / objmextent;
  319. for (int nface = 0; nface < atlas_mesh->index_count / 3; nface++) {
  320. Atlas_Output_Vertex& a = atlas_mesh->vertex_array[*patlasIndex++];
  321. Atlas_Output_Vertex& b = atlas_mesh->vertex_array[*patlasIndex++];
  322. Atlas_Output_Vertex& c = atlas_mesh->vertex_array[*patlasIndex++];
  323. Atlas_Input_Vertex& i = obj_mesh->vertex_array[a.xref];
  324. Atlas_Input_Vertex& j = obj_mesh->vertex_array[b.xref];
  325. Atlas_Input_Vertex& k = obj_mesh->vertex_array[c.xref];
  326. triverts[0].x = a.uv[0];
  327. triverts[0].y = a.uv[1];
  328. triverts[1].x = b.uv[0];
  329. triverts[1].y = b.uv[1];
  330. triverts[2].x = c.uv[0];
  331. triverts[2].y = c.uv[1];
  332. if (pchartids) {
  333. //shaderdata.chartid = a.chart_index + 1;
  334. //Raster::drawTriangle(sRasterMode, extents, true, triverts, idSolidCallback, &shaderdata);
  335. }
  336. shaderdata.objspace[0].x = (i.position[0] + offset.x) * scale;
  337. shaderdata.objspace[0].y = (i.position[1] + offset.y) * scale;
  338. shaderdata.objspace[0].z = (i.position[2] + offset.z) * scale;
  339. shaderdata.objspace[1].x = (j.position[0] + offset.x) * scale;
  340. shaderdata.objspace[1].y = (j.position[1] + offset.y) * scale;
  341. shaderdata.objspace[1].z = (j.position[2] + offset.z) * scale;
  342. shaderdata.objspace[2].x = (k.position[0] + offset.x) * scale;
  343. shaderdata.objspace[2].y = (k.position[1] + offset.y) * scale;
  344. shaderdata.objspace[2].z = (k.position[2] + offset.z) * scale;
  345. Raster::drawTriangle(sRasterMode, extents, true, triverts, pngAtlasCallback, &shaderdata);
  346. shaderdata.objspace[0].x = i.position[0];
  347. shaderdata.objspace[0].y = i.position[1];
  348. shaderdata.objspace[0].z = i.position[2];
  349. shaderdata.objspace[1].x = j.position[0];
  350. shaderdata.objspace[1].y = j.position[1];
  351. shaderdata.objspace[1].z = j.position[2];
  352. shaderdata.objspace[2].x = k.position[0];
  353. shaderdata.objspace[2].y = k.position[1];
  354. shaderdata.objspace[2].z = k.position[2];
  355. Raster::drawTriangle(sRasterMode, extents, true, triverts, floatAtlasCallback, &shaderdata);
  356. }
  357. stbi_write_png(worldSpaceTexturePath, width, height, 3, colors, 0);
  358. // Create an image representing facet normals.
  359. shaderdata.floats = floats = (float*) calloc(width * height * sizeof(float) * 3, 1);
  360. patlasIndex = atlas_mesh->index_array;
  361. for (int nface = 0; nface < atlas_mesh->index_count / 3; nface++) {
  362. Atlas_Output_Vertex& a = atlas_mesh->vertex_array[*patlasIndex++];
  363. Atlas_Output_Vertex& b = atlas_mesh->vertex_array[*patlasIndex++];
  364. Atlas_Output_Vertex& c = atlas_mesh->vertex_array[*patlasIndex++];
  365. Atlas_Input_Vertex& i = obj_mesh->vertex_array[a.xref];
  366. Atlas_Input_Vertex& j = obj_mesh->vertex_array[b.xref];
  367. Atlas_Input_Vertex& k = obj_mesh->vertex_array[c.xref];
  368. triverts[0].x = a.uv[0];
  369. triverts[0].y = a.uv[1];
  370. triverts[1].x = b.uv[0];
  371. triverts[1].y = b.uv[1];
  372. triverts[2].x = c.uv[0];
  373. triverts[2].y = c.uv[1];
  374. shaderdata.objspace[0].x = i.position[0];
  375. shaderdata.objspace[0].y = i.position[1];
  376. shaderdata.objspace[0].z = i.position[2];
  377. shaderdata.objspace[1].x = j.position[0];
  378. shaderdata.objspace[1].y = j.position[1];
  379. shaderdata.objspace[1].z = j.position[2];
  380. shaderdata.objspace[2].x = k.position[0];
  381. shaderdata.objspace[2].y = k.position[1];
  382. shaderdata.objspace[2].z = k.position[2];
  383. Vector3 A = shaderdata.objspace[1] - shaderdata.objspace[0];
  384. Vector3 B = shaderdata.objspace[2] - shaderdata.objspace[0];
  385. Vector3 N1 = normalize(cross(A, B));
  386. Vector3 N2 = 0.5f * (N1 + Vector3(1, 1, 1));
  387. shaderdata.color[0] = N2.x * 255;
  388. shaderdata.color[1] = N2.y * 255;
  389. shaderdata.color[2] = N2.z * 255;
  390. Raster::drawTriangle(sRasterMode, extents, true, triverts, pngSolidCallback, &shaderdata);
  391. shaderdata.fpcolor[0] = N1.x;
  392. shaderdata.fpcolor[1] = N1.y;
  393. shaderdata.fpcolor[2] = N1.z;
  394. Raster::drawTriangle(sRasterMode, extents, true, triverts, floatSolidCallback, &shaderdata);
  395. }
  396. stbi_write_png(normalTexturePath, width, height, 3, colors, 0);
  397. }
  398. void atlas_dump(
  399. const Atlas_Output_Mesh * atlas_mesh,
  400. const Atlas_Input_Mesh * obj_mesh,
  401. const char* oobjmesh,
  402. bool gbuffer,
  403. float** pcoordsdata,
  404. float** pnormsdata,
  405. uint8_t** pchartids,
  406. int size[2])
  407. {
  408. // Dump out the mutated mesh in simplified form and compute the AABB.
  409. printf("Writing %s...\n", oobjmesh);
  410. FILE* outobj = fopen(oobjmesh, "wt");
  411. float uscale = 1.f / atlas_mesh->atlas_width;
  412. float vscale = 1.f / atlas_mesh->atlas_height;
  413. Vector3 minp(FLT_MAX);
  414. Vector3 maxp(FLT_MIN);
  415. for (int nvert = 0; nvert < atlas_mesh->vertex_count; nvert++) {
  416. const Atlas_Output_Vertex& overt = atlas_mesh->vertex_array[nvert];
  417. const Atlas_Input_Vertex& ivert = obj_mesh->vertex_array[overt.xref];
  418. minp.x = nv::min(ivert.position[0], minp.x);
  419. minp.y = nv::min(ivert.position[1], minp.y);
  420. minp.z = nv::min(ivert.position[2], minp.z);
  421. maxp.x = nv::max(ivert.position[0], maxp.x);
  422. maxp.y = nv::max(ivert.position[1], maxp.y);
  423. maxp.z = nv::max(ivert.position[2], maxp.z);
  424. fprintf(outobj, "v %f %f %f\n", ivert.position[0], ivert.position[1], ivert.position[2]);
  425. fprintf(outobj, "vt %f %f\n", overt.uv[0] * uscale, 1 - overt.uv[1] * vscale);
  426. }
  427. for (int nface = 0; nface < atlas_mesh->index_count / 3; nface++) {
  428. int a = atlas_mesh->index_array[nface * 3] + 1;
  429. int b = atlas_mesh->index_array[nface * 3 + 1] + 1;
  430. int c = atlas_mesh->index_array[nface * 3 + 2] + 1;
  431. fprintf(outobj, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  432. }
  433. fclose(outobj);
  434. // Create an image representing the charts, with color representing the
  435. // approximate world-space position of each source vertex.
  436. int width = atlas_mesh->atlas_width;
  437. int height = atlas_mesh->atlas_height;
  438. const Vector2 extents(width, height);
  439. unsigned char* colors = (unsigned char*) calloc(width * height * 3, 1);
  440. uint8_t* chartids = pchartids ? (uint8_t*) calloc(width * height, 1) : 0;
  441. float* floats = (float*) calloc(width * height * sizeof(float) * 3, 1);
  442. const int* patlasIndex = atlas_mesh->index_array;
  443. Vector2 triverts[3];
  444. ShaderData shaderdata;
  445. shaderdata.width = width;
  446. shaderdata.data = colors;
  447. shaderdata.floats = floats;
  448. shaderdata.chartids = chartids;
  449. Vector3 objextent = maxp - minp;
  450. Vector3 offset = -minp;
  451. float objmextent = nv::max(nv::max(objextent.x, objextent.y), objextent.z);
  452. float scale = 1.0f / objmextent;
  453. for (int nface = 0; nface < atlas_mesh->index_count / 3; nface++) {
  454. Atlas_Output_Vertex& a = atlas_mesh->vertex_array[*patlasIndex++];
  455. Atlas_Output_Vertex& b = atlas_mesh->vertex_array[*patlasIndex++];
  456. Atlas_Output_Vertex& c = atlas_mesh->vertex_array[*patlasIndex++];
  457. Atlas_Input_Vertex& i = obj_mesh->vertex_array[a.xref];
  458. Atlas_Input_Vertex& j = obj_mesh->vertex_array[b.xref];
  459. Atlas_Input_Vertex& k = obj_mesh->vertex_array[c.xref];
  460. triverts[0].x = a.uv[0];
  461. triverts[0].y = a.uv[1];
  462. triverts[1].x = b.uv[0];
  463. triverts[1].y = b.uv[1];
  464. triverts[2].x = c.uv[0];
  465. triverts[2].y = c.uv[1];
  466. if (pchartids) {
  467. //shaderdata.chartid = a.chart_index + 1;
  468. //Raster::drawTriangle(sRasterMode, extents, true, triverts, idSolidCallback, &shaderdata);
  469. }
  470. shaderdata.objspace[0].x = (i.position[0] + offset.x) * scale;
  471. shaderdata.objspace[0].y = (i.position[1] + offset.y) * scale;
  472. shaderdata.objspace[0].z = (i.position[2] + offset.z) * scale;
  473. shaderdata.objspace[1].x = (j.position[0] + offset.x) * scale;
  474. shaderdata.objspace[1].y = (j.position[1] + offset.y) * scale;
  475. shaderdata.objspace[1].z = (j.position[2] + offset.z) * scale;
  476. shaderdata.objspace[2].x = (k.position[0] + offset.x) * scale;
  477. shaderdata.objspace[2].y = (k.position[1] + offset.y) * scale;
  478. shaderdata.objspace[2].z = (k.position[2] + offset.z) * scale;
  479. Raster::drawTriangle(sRasterMode, extents, true, triverts, pngAtlasCallback, &shaderdata);
  480. shaderdata.objspace[0].x = i.position[0];
  481. shaderdata.objspace[0].y = i.position[1];
  482. shaderdata.objspace[0].z = i.position[2];
  483. shaderdata.objspace[1].x = j.position[0];
  484. shaderdata.objspace[1].y = j.position[1];
  485. shaderdata.objspace[1].z = j.position[2];
  486. shaderdata.objspace[2].x = k.position[0];
  487. shaderdata.objspace[2].y = k.position[1];
  488. shaderdata.objspace[2].z = k.position[2];
  489. Raster::drawTriangle(sRasterMode, extents, true, triverts, floatAtlasCallback, &shaderdata);
  490. }
  491. if (gbuffer) {
  492. printf("Writing object_coords.png...\n");
  493. stbi_write_png("object_coords.png", width, height, 3, colors, 0);
  494. }
  495. *pcoordsdata = floats;
  496. // Create an image representing facet normals.
  497. shaderdata.floats = floats = (float*) calloc(width * height * sizeof(float) * 3, 1);
  498. patlasIndex = atlas_mesh->index_array;
  499. for (int nface = 0; nface < atlas_mesh->index_count / 3; nface++) {
  500. Atlas_Output_Vertex& a = atlas_mesh->vertex_array[*patlasIndex++];
  501. Atlas_Output_Vertex& b = atlas_mesh->vertex_array[*patlasIndex++];
  502. Atlas_Output_Vertex& c = atlas_mesh->vertex_array[*patlasIndex++];
  503. Atlas_Input_Vertex& i = obj_mesh->vertex_array[a.xref];
  504. Atlas_Input_Vertex& j = obj_mesh->vertex_array[b.xref];
  505. Atlas_Input_Vertex& k = obj_mesh->vertex_array[c.xref];
  506. triverts[0].x = a.uv[0];
  507. triverts[0].y = a.uv[1];
  508. triverts[1].x = b.uv[0];
  509. triverts[1].y = b.uv[1];
  510. triverts[2].x = c.uv[0];
  511. triverts[2].y = c.uv[1];
  512. shaderdata.objspace[0].x = i.position[0];
  513. shaderdata.objspace[0].y = i.position[1];
  514. shaderdata.objspace[0].z = i.position[2];
  515. shaderdata.objspace[1].x = j.position[0];
  516. shaderdata.objspace[1].y = j.position[1];
  517. shaderdata.objspace[1].z = j.position[2];
  518. shaderdata.objspace[2].x = k.position[0];
  519. shaderdata.objspace[2].y = k.position[1];
  520. shaderdata.objspace[2].z = k.position[2];
  521. Vector3 A = shaderdata.objspace[1] - shaderdata.objspace[0];
  522. Vector3 B = shaderdata.objspace[2] - shaderdata.objspace[0];
  523. Vector3 N1 = normalize(cross(A, B));
  524. Vector3 N2 = 0.5f * (N1 + Vector3(1, 1, 1));
  525. shaderdata.color[0] = N2.x * 255;
  526. shaderdata.color[1] = N2.y * 255;
  527. shaderdata.color[2] = N2.z * 255;
  528. Raster::drawTriangle(sRasterMode, extents, true, triverts, pngSolidCallback, &shaderdata);
  529. shaderdata.fpcolor[0] = N1.x;
  530. shaderdata.fpcolor[1] = N1.y;
  531. shaderdata.fpcolor[2] = N1.z;
  532. Raster::drawTriangle(sRasterMode, extents, true, triverts, floatSolidCallback, &shaderdata);
  533. }
  534. if (gbuffer) {
  535. printf("Writing facet_normals.png...\n");
  536. stbi_write_png("facet_normals.png", width, height, 3, colors, 0);
  537. }
  538. size[0] = width;
  539. size[1] = height;
  540. *pnormsdata = floats;
  541. if (pchartids) {
  542. *pchartids = chartids;
  543. }
  544. free(colors);
  545. }
  546. // ATOMIC END