test_msquares.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. #include "par_asset.h"
  2. #include "lodepng.h"
  3. #define PAR_MSQUARES_IMPLEMENTATION
  4. #include "par_msquares.h"
  5. #define CELLSIZE 32
  6. #define IMGWIDTH 1024
  7. #define IMGHEIGHT 1024
  8. #define THRESHOLD 0.0f
  9. #define OCEAN_COLOR 0x214562
  10. static void svg_begin(FILE* svgfile)
  11. {
  12. fputs(
  13. "<svg viewBox='-.1 -.1 1.2 1.2' width='500px' height='500px' "
  14. "version='1.1' "
  15. "xmlns='http://www.w3.org/2000/svg'>\n"
  16. "<g transform='translate(0 1) scale(1 -1)'>", svgfile);
  17. }
  18. static void svg_write_path(FILE* svgfile, par_msquares_mesh const* mesh,
  19. uint32_t color, float fill, float stroke)
  20. {
  21. par_msquares_boundary* polygon = par_msquares_extract_boundary(mesh);
  22. fprintf(svgfile, "<path\n"
  23. " fill='#%6.6x'\n"
  24. " stroke='#%6.6x'\n"
  25. " stroke-width='0.005'\n"
  26. " fill-opacity='%f'\n"
  27. " stroke-opacity='%f'\n"
  28. " d='", color, color, fill, stroke);
  29. for (int c = 0; c < polygon->nchains; c++) {
  30. float const* chain = polygon->chains[c];
  31. int length = (int) polygon->lengths[c];
  32. uint16_t first = 1;
  33. for (uint16_t s = 0; s < length; s++) {
  34. fprintf(svgfile, "%c%f,%f", first ? 'M' : 'L', chain[s * 2],
  35. chain[s * 2 + 1]);
  36. first = 0;
  37. }
  38. fputs("Z", svgfile);
  39. }
  40. fputs("'\n/>", svgfile);
  41. par_msquares_free_boundary(polygon);
  42. }
  43. static void test_multi()
  44. {
  45. unsigned dims[2] = {0, 0};
  46. int offset;
  47. unsigned char* pixels;
  48. uint16_t* index;
  49. float* pt;
  50. par_msquares_meshlist* mlist;
  51. par_msquares_mesh const* mesh;
  52. FILE* objfile, *svgfile;
  53. lodepng_decode_file(&pixels, &dims[0], &dims[1], "test/tverts.png", LCT_RGB,
  54. 8);
  55. mlist = par_msquares_color_multi(pixels, dims[0], dims[1], 12, 3,
  56. PAR_MSQUARES_CLEAN);
  57. objfile = fopen("build/msquares_multi_tverts.obj", "wt");
  58. svgfile = fopen("build/msquares_multi_tverts.svg", "wt");
  59. offset = 1;
  60. svg_begin(svgfile);
  61. for (int m = 0; m < par_msquares_get_count(mlist); m++) {
  62. mesh = par_msquares_get_mesh(mlist, m);
  63. pt = mesh->points;
  64. for (int i = 0; i < mesh->npoints; i++) {
  65. float z = mesh->dim > 2 ? pt[2] : 0;
  66. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  67. pt += mesh->dim;
  68. }
  69. index = mesh->triangles;
  70. for (int i = 0; i < mesh->ntriangles; i++) {
  71. int a = offset + *index++;
  72. int b = offset + *index++;
  73. int c = offset + *index++;
  74. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  75. }
  76. offset += mesh->npoints;
  77. svg_write_path(svgfile, mesh, mesh->color & 0xffffff, 0.5, 0.5);
  78. }
  79. fputs("</g>\n</svg>", svgfile);
  80. fclose(svgfile);
  81. fclose(objfile);
  82. par_msquares_free(mlist);
  83. free(pixels);
  84. lodepng_decode_file(&pixels, &dims[0], &dims[1], "test/rgb.png", LCT_RGB,
  85. 8);
  86. mlist = par_msquares_color_multi(pixels, dims[0], dims[1], CELLSIZE / 2, 3,
  87. PAR_MSQUARES_CLEAN);
  88. objfile = fopen("build/msquares_multi_rgb.obj", "wt");
  89. svgfile = fopen("build/msquares_multi_rgb.svg", "wt");
  90. offset = 1;
  91. svg_begin(svgfile);
  92. for (int m = 0; m < par_msquares_get_count(mlist); m++) {
  93. mesh = par_msquares_get_mesh(mlist, m);
  94. pt = mesh->points;
  95. for (int i = 0; i < mesh->npoints; i++) {
  96. float z = mesh->dim > 2 ? pt[2] : 0;
  97. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  98. pt += mesh->dim;
  99. }
  100. index = mesh->triangles;
  101. for (int i = 0; i < mesh->ntriangles; i++) {
  102. int a = offset + *index++;
  103. int b = offset + *index++;
  104. int c = offset + *index++;
  105. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  106. }
  107. offset += mesh->npoints;
  108. svg_write_path(svgfile, mesh, mesh->color, 0.5, 0.5);
  109. }
  110. fputs("</g>\n</svg>", svgfile);
  111. fclose(svgfile);
  112. fclose(objfile);
  113. par_msquares_free(mlist);
  114. free(pixels);
  115. lodepng_decode_file(&pixels, &dims[0], &dims[1], "test/rgba.png", LCT_RGBA,
  116. 8);
  117. mlist = par_msquares_color_multi(pixels, dims[0], dims[1], CELLSIZE / 2, 4,
  118. PAR_MSQUARES_HEIGHTS | PAR_MSQUARES_CONNECT | PAR_MSQUARES_CLEAN);
  119. objfile = fopen("build/msquares_multi_rgba.obj", "wt");
  120. svgfile = fopen("build/msquares_multi_rgba.svg", "wt");
  121. offset = 1;
  122. svg_begin(svgfile);
  123. for (int m = 0; m < par_msquares_get_count(mlist); m++) {
  124. mesh = par_msquares_get_mesh(mlist, m);
  125. pt = mesh->points;
  126. for (int i = 0; i < mesh->npoints; i++) {
  127. float z = mesh->dim > 2 ? pt[2] : 0;
  128. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  129. pt += mesh->dim;
  130. }
  131. index = mesh->triangles;
  132. for (int i = 0; i < mesh->ntriangles; i++) {
  133. int a = offset + *index++;
  134. int b = offset + *index++;
  135. int c = offset + *index++;
  136. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  137. }
  138. offset += mesh->npoints;
  139. svg_write_path(svgfile, mesh, mesh->color & 0xffffff, 0.5, 0.5);
  140. }
  141. fputs("</g>\n</svg>", svgfile);
  142. fclose(svgfile);
  143. fclose(objfile);
  144. par_msquares_free(mlist);
  145. free(pixels);
  146. int nbytes;
  147. par_byte* data;
  148. asset_get("msquares_color.png", &data, &nbytes);
  149. lodepng_decode_memory(&pixels, &dims[0], &dims[1], data, nbytes, LCT_RGBA,
  150. 8);
  151. free(data);
  152. mlist = par_msquares_color_multi(pixels, dims[0], dims[1], CELLSIZE, 4,
  153. PAR_MSQUARES_HEIGHTS | PAR_MSQUARES_CONNECT | PAR_MSQUARES_SIMPLIFY);
  154. objfile = fopen("build/msquares_multi_diagram.obj", "wt");
  155. offset = 1;
  156. for (int m = 0; m < par_msquares_get_count(mlist); m++) {
  157. mesh = par_msquares_get_mesh(mlist, m);
  158. pt = mesh->points;
  159. for (int i = 0; i < mesh->npoints; i++) {
  160. float z = mesh->dim > 2 ? pt[2] : 0;
  161. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  162. pt += mesh->dim;
  163. }
  164. index = mesh->triangles;
  165. for (int i = 0; i < mesh->ntriangles; i++) {
  166. int a = offset + *index++;
  167. int b = offset + *index++;
  168. int c = offset + *index++;
  169. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  170. }
  171. offset += mesh->npoints;
  172. }
  173. fclose(objfile);
  174. par_msquares_free(mlist);
  175. free(pixels);
  176. }
  177. static void test_color()
  178. {
  179. int nbytes;
  180. par_byte* data;
  181. asset_get("msquares_color.png", &data, &nbytes);
  182. unsigned dims[2] = {0, 0};
  183. unsigned char* pixels;
  184. lodepng_decode_memory(&pixels, &dims[0], &dims[1], data, nbytes, LCT_RGBA,
  185. 8);
  186. free(data);
  187. assert(dims[0] == IMGWIDTH);
  188. assert(dims[1] == IMGHEIGHT);
  189. int flags, i;
  190. uint16_t* index;
  191. float* pt;
  192. par_msquares_meshlist* mlist;
  193. par_msquares_mesh const* mesh;
  194. FILE* objfile;
  195. // -----------------------------
  196. // msquares_color_default
  197. // -----------------------------
  198. flags = 0;
  199. mlist = par_msquares_color(pixels, IMGWIDTH, IMGHEIGHT, CELLSIZE,
  200. OCEAN_COLOR, 4, flags);
  201. mesh = par_msquares_get_mesh(mlist, 0);
  202. objfile = fopen("build/msquares_color_default.obj", "wt");
  203. pt = mesh->points;
  204. for (i = 0; i < mesh->npoints; i++) {
  205. float z = mesh->dim > 2 ? pt[2] : 0;
  206. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  207. pt += mesh->dim;
  208. }
  209. index = mesh->triangles;
  210. for (i = 0; i < mesh->ntriangles; i++) {
  211. int a = 1 + *index++;
  212. int b = 1 + *index++;
  213. int c = 1 + *index++;
  214. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  215. }
  216. fclose(objfile);
  217. par_msquares_free(mlist);
  218. // -----------------------------
  219. // msquares_color_invert_heights
  220. // -----------------------------
  221. flags = PAR_MSQUARES_INVERT | PAR_MSQUARES_HEIGHTS;
  222. mlist = par_msquares_color(pixels, IMGWIDTH, IMGHEIGHT, CELLSIZE,
  223. OCEAN_COLOR, 4, flags);
  224. mesh = par_msquares_get_mesh(mlist, 0);
  225. objfile = fopen("build/msquares_color_invert_heights.obj", "wt");
  226. pt = mesh->points;
  227. for (i = 0; i < mesh->npoints; i++) {
  228. float z = mesh->dim > 2 ? pt[2] : 0;
  229. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  230. pt += mesh->dim;
  231. }
  232. index = mesh->triangles;
  233. for (i = 0; i < mesh->ntriangles; i++) {
  234. int a = 1 + *index++;
  235. int b = 1 + *index++;
  236. int c = 1 + *index++;
  237. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  238. }
  239. fclose(objfile);
  240. par_msquares_free(mlist);
  241. // -----------------------------
  242. // msquares_color_dual_heights
  243. // -----------------------------
  244. flags = PAR_MSQUARES_DUAL | PAR_MSQUARES_HEIGHTS | PAR_MSQUARES_SNAP |
  245. PAR_MSQUARES_CONNECT | PAR_MSQUARES_SIMPLIFY;
  246. mlist = par_msquares_color(pixels, IMGWIDTH, IMGHEIGHT, CELLSIZE,
  247. OCEAN_COLOR, 4, flags);
  248. mesh = par_msquares_get_mesh(mlist, 0);
  249. objfile = fopen("build/msquares_color_simplify.obj", "wt");
  250. pt = mesh->points;
  251. for (i = 0; i < mesh->npoints; i++) {
  252. float z = mesh->dim > 2 ? pt[2] : 0;
  253. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  254. pt += mesh->dim;
  255. }
  256. index = mesh->triangles;
  257. int offset = 1;
  258. for (i = 0; i < mesh->ntriangles; i++) {
  259. int a = offset + *index++;
  260. int b = offset + *index++;
  261. int c = offset + *index++;
  262. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  263. }
  264. offset = mesh->npoints + 1;
  265. mesh = par_msquares_get_mesh(mlist, 1);
  266. pt = mesh->points;
  267. for (i = 0; i < mesh->npoints; i++) {
  268. float z = mesh->dim > 2 ? pt[2] : 0;
  269. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  270. pt += mesh->dim;
  271. }
  272. index = mesh->triangles;
  273. for (i = 0; i < mesh->ntriangles; i++) {
  274. int a = offset + *index++;
  275. int b = offset + *index++;
  276. int c = offset + *index++;
  277. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  278. }
  279. fclose(objfile);
  280. par_msquares_free(mlist);
  281. free(pixels);
  282. }
  283. static void test_grayscale()
  284. {
  285. int nbytes;
  286. float* pixels;
  287. asset_get("msquares_island.1024.bin", (par_byte**) &pixels, &nbytes);
  288. int flags, i;
  289. uint16_t* index;
  290. float* pt;
  291. par_msquares_meshlist* mlist;
  292. par_msquares_mesh const* mesh;
  293. FILE* objfile, *svgfile;
  294. int offset = 1;
  295. // -----------------------------
  296. // msquares_gray_default
  297. // -----------------------------
  298. flags = 0;
  299. mlist = par_msquares_grayscale(pixels, IMGWIDTH, IMGHEIGHT, CELLSIZE,
  300. THRESHOLD, flags);
  301. assert(par_msquares_get_count(mlist) == 1);
  302. objfile = fopen("build/msquares_gray_default.obj", "wt");
  303. mesh = par_msquares_get_mesh(mlist, 0);
  304. pt = mesh->points;
  305. for (i = 0; i < mesh->npoints; i++) {
  306. float z = mesh->dim > 2 ? pt[2] : 0;
  307. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  308. pt += mesh->dim;
  309. }
  310. index = mesh->triangles;
  311. for (i = 0; i < mesh->ntriangles; i++) {
  312. int a = offset + *index++;
  313. int b = offset + *index++;
  314. int c = offset + *index++;
  315. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  316. }
  317. fclose(objfile);
  318. par_msquares_free(mlist);
  319. // -----------------------------
  320. // msquares_gray_invert
  321. // -----------------------------
  322. flags = PAR_MSQUARES_INVERT;
  323. mlist = par_msquares_grayscale(pixels, IMGWIDTH, IMGHEIGHT, CELLSIZE,
  324. THRESHOLD, flags);
  325. assert(par_msquares_get_count(mlist) == 1);
  326. objfile = fopen("build/msquares_gray_invert.obj", "wt");
  327. mesh = par_msquares_get_mesh(mlist, 0);
  328. pt = mesh->points;
  329. for (i = 0; i < mesh->npoints; i++) {
  330. float z = mesh->dim > 2 ? pt[2] : 0;
  331. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  332. pt += mesh->dim;
  333. }
  334. index = mesh->triangles;
  335. for (i = 0; i < mesh->ntriangles; i++) {
  336. int a = offset + *index++;
  337. int b = offset + *index++;
  338. int c = offset + *index++;
  339. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  340. }
  341. fclose(objfile);
  342. par_msquares_free(mlist);
  343. // -----------------------------
  344. // msquares_gray_dual
  345. // -----------------------------
  346. flags = PAR_MSQUARES_DUAL;
  347. mlist = par_msquares_grayscale(pixels, IMGWIDTH, IMGHEIGHT, CELLSIZE,
  348. THRESHOLD, flags);
  349. assert(par_msquares_get_count(mlist) == 2);
  350. objfile = fopen("build/msquares_gray_dual.obj", "wt");
  351. svgfile = fopen("build/msquares_gray_dual.svg", "wt");
  352. svg_begin(svgfile);
  353. mesh = par_msquares_get_mesh(mlist, 0);
  354. svg_write_path(svgfile, mesh, 0x050b0, 0.5, 1.0);
  355. pt = mesh->points;
  356. for (i = 0; i < mesh->npoints; i++) {
  357. float z = mesh->dim > 2 ? pt[2] : 0;
  358. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  359. pt += mesh->dim;
  360. }
  361. index = mesh->triangles;
  362. offset = 1;
  363. for (i = 0; i < mesh->ntriangles; i++) {
  364. int a = offset + *index++;
  365. int b = offset + *index++;
  366. int c = offset + *index++;
  367. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  368. }
  369. offset = mesh->npoints + 1;
  370. mesh = par_msquares_get_mesh(mlist, 1);
  371. svg_write_path(svgfile, mesh, 0x10e050, 1.0, 0.0);
  372. svg_write_path(svgfile, mesh, 0, 0.0, 1.0);
  373. pt = mesh->points;
  374. for (i = 0; i < mesh->npoints; i++) {
  375. float z = mesh->dim > 2 ? pt[2] : 0;
  376. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  377. pt += mesh->dim;
  378. }
  379. index = mesh->triangles;
  380. for (i = 0; i < mesh->ntriangles; i++) {
  381. int a = offset + *index++;
  382. int b = offset + *index++;
  383. int c = offset + *index++;
  384. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  385. }
  386. fclose(objfile);
  387. par_msquares_free(mlist);
  388. mlist = par_msquares_grayscale(pixels, IMGWIDTH, IMGHEIGHT, CELLSIZE,
  389. -0.02, flags);
  390. mesh = par_msquares_get_mesh(mlist, 0);
  391. svg_write_path(svgfile, mesh, 0xffffff, 0.0, 1.0);
  392. par_msquares_free(mlist);
  393. mlist = par_msquares_grayscale(pixels, IMGWIDTH, IMGHEIGHT, CELLSIZE,
  394. -0.06, flags);
  395. mesh = par_msquares_get_mesh(mlist, 0);
  396. svg_write_path(svgfile, mesh, 0xffffff, 0.0, 0.5);
  397. par_msquares_free(mlist);
  398. mlist = par_msquares_grayscale(pixels, IMGWIDTH, IMGHEIGHT, CELLSIZE,
  399. -0.1, flags);
  400. mesh = par_msquares_get_mesh(mlist, 0);
  401. svg_write_path(svgfile, mesh, 0xffffff, 0.0, 0.25);
  402. par_msquares_free(mlist);
  403. fputs("</g>\n</svg>", svgfile);
  404. fclose(svgfile);
  405. // -----------------------------
  406. // msquares_gray_heights
  407. // -----------------------------
  408. flags = PAR_MSQUARES_HEIGHTS;
  409. mlist = par_msquares_grayscale(pixels, IMGWIDTH, IMGHEIGHT, CELLSIZE,
  410. THRESHOLD, flags);
  411. mesh = par_msquares_get_mesh(mlist, 0);
  412. objfile = fopen("build/msquares_gray_heights.obj", "wt");
  413. pt = mesh->points;
  414. for (i = 0; i < mesh->npoints; i++) {
  415. float z = mesh->dim > 2 ? pt[2] : 0;
  416. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  417. pt += mesh->dim;
  418. }
  419. index = mesh->triangles;
  420. for (i = 0; i < mesh->ntriangles; i++) {
  421. int a = 1 + *index++;
  422. int b = 1 + *index++;
  423. int c = 1 + *index++;
  424. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  425. }
  426. fclose(objfile);
  427. par_msquares_free(mlist);
  428. // ------------------------------------
  429. // msquares_gray_heights_dual_snap
  430. // ------------------------------------
  431. flags = PAR_MSQUARES_HEIGHTS | PAR_MSQUARES_DUAL | PAR_MSQUARES_SNAP;
  432. mlist = par_msquares_grayscale(pixels, IMGWIDTH, IMGHEIGHT, CELLSIZE,
  433. THRESHOLD, flags);
  434. objfile = fopen("build/msquares_gray_heights_dual_snap.obj", "wt");
  435. mesh = par_msquares_get_mesh(mlist, 0);
  436. pt = mesh->points;
  437. for (i = 0; i < mesh->npoints; i++) {
  438. float z = mesh->dim > 2 ? pt[2] : 0;
  439. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  440. pt += mesh->dim;
  441. }
  442. index = mesh->triangles;
  443. offset = 1;
  444. for (i = 0; i < mesh->ntriangles; i++) {
  445. int a = offset + *index++;
  446. int b = offset + *index++;
  447. int c = offset + *index++;
  448. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  449. }
  450. offset = mesh->npoints + 1;
  451. mesh = par_msquares_get_mesh(mlist, 1);
  452. pt = mesh->points;
  453. for (i = 0; i < mesh->npoints; i++) {
  454. float z = mesh->dim > 2 ? pt[2] : 0;
  455. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  456. pt += mesh->dim;
  457. }
  458. index = mesh->triangles;
  459. for (i = 0; i < mesh->ntriangles; i++) {
  460. int a = offset + *index++;
  461. int b = offset + *index++;
  462. int c = offset + *index++;
  463. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  464. }
  465. fclose(objfile);
  466. par_msquares_free(mlist);
  467. // --------------------------------------------
  468. // msquares_gray_heights_dual_snap_connect
  469. // --------------------------------------------
  470. flags = PAR_MSQUARES_HEIGHTS | PAR_MSQUARES_DUAL | PAR_MSQUARES_SNAP |
  471. PAR_MSQUARES_CONNECT;
  472. mlist = par_msquares_grayscale(pixels, IMGWIDTH, IMGHEIGHT, CELLSIZE,
  473. THRESHOLD, flags);
  474. objfile = fopen("build/msquares_gray_heights_dual_snap_connect.obj", "wt");
  475. mesh = par_msquares_get_mesh(mlist, 0);
  476. pt = mesh->points;
  477. for (i = 0; i < mesh->npoints; i++) {
  478. float z = mesh->dim > 2 ? pt[2] : 0;
  479. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  480. pt += mesh->dim;
  481. }
  482. index = mesh->triangles;
  483. offset = 1;
  484. for (i = 0; i < mesh->ntriangles; i++) {
  485. int a = offset + *index++;
  486. int b = offset + *index++;
  487. int c = offset + *index++;
  488. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  489. }
  490. offset = mesh->npoints + 1;
  491. mesh = par_msquares_get_mesh(mlist, 1);
  492. pt = mesh->points;
  493. for (i = 0; i < mesh->npoints; i++) {
  494. float z = mesh->dim > 2 ? pt[2] : 0;
  495. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  496. pt += mesh->dim;
  497. }
  498. index = mesh->triangles;
  499. for (i = 0; i < mesh->ntriangles; i++) {
  500. int a = offset + *index++;
  501. int b = offset + *index++;
  502. int c = offset + *index++;
  503. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  504. }
  505. fclose(objfile);
  506. par_msquares_free(mlist);
  507. // ------------------------------
  508. // msquares_gray_heights_simplify
  509. // ------------------------------
  510. flags = PAR_MSQUARES_SIMPLIFY;
  511. mlist = par_msquares_grayscale(pixels, IMGWIDTH, IMGHEIGHT, CELLSIZE,
  512. THRESHOLD, flags);
  513. objfile = fopen("build/msquares_gray_heights_simplify.obj", "wt");
  514. mesh = par_msquares_get_mesh(mlist, 0);
  515. pt = mesh->points;
  516. for (i = 0; i < mesh->npoints; i++) {
  517. float z = mesh->dim > 2 ? pt[2] : 0;
  518. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  519. pt += mesh->dim;
  520. }
  521. index = mesh->triangles;
  522. offset = 1;
  523. for (i = 0; i < mesh->ntriangles; i++) {
  524. int a = offset + *index++;
  525. int b = offset + *index++;
  526. int c = offset + *index++;
  527. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  528. }
  529. fclose(objfile);
  530. par_msquares_free(mlist);
  531. // ------------------------------
  532. // msquares_gray_multi_simplify
  533. // ------------------------------
  534. float thresholds[] = {0.0, 0.1};
  535. mlist = par_msquares_grayscale_multi(pixels, IMGWIDTH, IMGHEIGHT, CELLSIZE,
  536. thresholds, 2, PAR_MSQUARES_SIMPLIFY);
  537. objfile = fopen("build/msquares_gray_multi_simplify.obj", "wt");
  538. assert(par_msquares_get_count(mlist) == 3);
  539. for (int m = 0; m < 3; m++) {
  540. mesh = par_msquares_get_mesh(mlist, m);
  541. pt = mesh->points;
  542. for (i = 0; i < mesh->npoints; i++) {
  543. float z = mesh->dim > 2 ? pt[2] : 0;
  544. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  545. pt += mesh->dim;
  546. }
  547. }
  548. offset = 1;
  549. for (int m = 0; m < 3; m++) {
  550. mesh = par_msquares_get_mesh(mlist, m);
  551. index = mesh->triangles;
  552. for (i = 0; i < mesh->ntriangles; i++) {
  553. int a = offset + *index++;
  554. int b = offset + *index++;
  555. int c = offset + *index++;
  556. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  557. }
  558. offset += mesh->npoints;
  559. }
  560. fclose(objfile);
  561. par_msquares_free(mlist);
  562. // ------------------------------
  563. // msquares_gray_multi_everything
  564. // ------------------------------
  565. mlist = par_msquares_grayscale_multi(pixels, IMGWIDTH, IMGHEIGHT, CELLSIZE,
  566. thresholds, 2, PAR_MSQUARES_SIMPLIFY | PAR_MSQUARES_HEIGHTS |
  567. PAR_MSQUARES_SNAP | PAR_MSQUARES_CONNECT);
  568. objfile = fopen("build/msquares_gray_multi_everything.obj", "wt");
  569. assert(par_msquares_get_count(mlist) == 3);
  570. for (int m = 0; m < 3; m++) {
  571. mesh = par_msquares_get_mesh(mlist, m);
  572. pt = mesh->points;
  573. for (i = 0; i < mesh->npoints; i++) {
  574. float z = mesh->dim > 2 ? pt[2] : 0;
  575. fprintf(objfile, "v %f %f %f\n", pt[0], pt[1], z);
  576. pt += mesh->dim;
  577. }
  578. }
  579. offset = 1;
  580. for (int m = 0; m < 3; m++) {
  581. mesh = par_msquares_get_mesh(mlist, m);
  582. index = mesh->triangles;
  583. for (i = 0; i < mesh->ntriangles; i++) {
  584. int a = offset + *index++;
  585. int b = offset + *index++;
  586. int c = offset + *index++;
  587. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  588. }
  589. offset += mesh->npoints;
  590. }
  591. fclose(objfile);
  592. par_msquares_free(mlist);
  593. free(pixels);
  594. }
  595. int main(int argc, char* argv[])
  596. {
  597. asset_init();
  598. test_color();
  599. test_grayscale();
  600. test_multi();
  601. return 0;
  602. }