gvl_calc2.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. /*!
  2. \file lib/ogsf/gvl_calc2.c
  3. \brief OGSF library - loading and manipulating volumes, MarchingCubes 33 Algorithm (lower level functions)
  4. GRASS OpenGL gsurf OGSF Library
  5. Based on implementation of MarchingCubes 33 Algorithm by
  6. Thomas Lewiner, thomas.lewiner@polytechnique.org, Math Dept, PUC-Rio
  7. (C) 1999-2008 by the GRASS Development Team
  8. This program is free software under the
  9. GNU General Public License (>=v2).
  10. Read the file COPYING that comes with GRASS
  11. for details.
  12. \author Tomas Paudits, 2004
  13. \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
  14. */
  15. #include <float.h>
  16. #include <grass/gis.h>
  17. #include <grass/ogsf.h>
  18. #include "mc33_table.h"
  19. unsigned char m_case, m_config, m_subconfig;
  20. /*!
  21. \brief ADD
  22. \param face
  23. \param v
  24. \return
  25. */
  26. int mc33_test_face(char face, float *v)
  27. {
  28. float A, B, C, D;
  29. switch (face) {
  30. case -1:
  31. case 1:
  32. A = v[0];
  33. B = v[4];
  34. C = v[5];
  35. D = v[1];
  36. break;
  37. case -2:
  38. case 2:
  39. A = v[1];
  40. B = v[5];
  41. C = v[6];
  42. D = v[2];
  43. break;
  44. case -3:
  45. case 3:
  46. A = v[2];
  47. B = v[6];
  48. C = v[7];
  49. D = v[3];
  50. break;
  51. case -4:
  52. case 4:
  53. A = v[3];
  54. B = v[7];
  55. C = v[4];
  56. D = v[0];
  57. break;
  58. case -5:
  59. case 5:
  60. A = v[0];
  61. B = v[3];
  62. C = v[2];
  63. D = v[1];
  64. break;
  65. case -6:
  66. case 6:
  67. A = v[4];
  68. B = v[7];
  69. C = v[6];
  70. D = v[5];
  71. break;
  72. default:
  73. fprintf(stderr, "Invalid face code %d\n", face);
  74. A = B = C = D = 0;
  75. };
  76. return face * A * (A * C - B * D) >= 0;
  77. }
  78. /*!
  79. \brief ADD
  80. \param s
  81. \param v
  82. \return
  83. */
  84. int mc33_test_interior(char s, float *v)
  85. {
  86. float t, At = 0, Bt = 0, Ct = 0, Dt = 0, a, b;
  87. char test = 0;
  88. char edge = -1;
  89. switch (m_case) {
  90. case 4:
  91. case 10:
  92. a = (v[4] - v[0]) * (v[6] - v[2]) - (v[7] - v[3]) * (v[5] - v[1]);
  93. b = v[2] * (v[4] - v[0]) + v[0] * (v[6] - v[2])
  94. - v[1] * (v[7] - v[3]) - v[3] * (v[5] - v[1]);
  95. t = -b / (2 * a);
  96. if (t < 0 || t > 1)
  97. return s > 0;
  98. At = v[0] + (v[4] - v[0]) * t;
  99. Bt = v[3] + (v[7] - v[3]) * t;
  100. Ct = v[2] + (v[6] - v[2]) * t;
  101. Dt = v[1] + (v[5] - v[1]) * t;
  102. break;
  103. case 6:
  104. case 7:
  105. case 12:
  106. case 13:
  107. switch (m_case) {
  108. case 6:
  109. edge = cell_table[OFFSET_T6_1_1 + m_config].polys[0];
  110. break;
  111. case 7:
  112. edge = cell_table[OFFSET_T7_4_1 + m_config].polys[13];
  113. break;
  114. case 12:
  115. edge = cell_table[OFFSET_T12_2_S1 + m_config].polys[14];
  116. break;
  117. case 13:
  118. edge =
  119. cell_table[OFFSET_T13_5_1 + m_subconfig +
  120. m_config * 4].polys[2];
  121. break;
  122. }
  123. switch (edge) {
  124. case 0:
  125. t = v[0] / (v[0] - v[1]);
  126. At = 0;
  127. Bt = v[3] + (v[2] - v[3]) * t;
  128. Ct = v[7] + (v[6] - v[7]) * t;
  129. Dt = v[4] + (v[5] - v[4]) * t;
  130. break;
  131. case 1:
  132. t = v[1] / (v[1] - v[2]);
  133. At = 0;
  134. Bt = v[0] + (v[3] - v[0]) * t;
  135. Ct = v[4] + (v[7] - v[4]) * t;
  136. Dt = v[5] + (v[6] - v[5]) * t;
  137. break;
  138. case 2:
  139. t = v[2] / (v[2] - v[3]);
  140. At = 0;
  141. Bt = v[1] + (v[0] - v[1]) * t;
  142. Ct = v[5] + (v[4] - v[5]) * t;
  143. Dt = v[6] + (v[7] - v[6]) * t;
  144. break;
  145. case 3:
  146. t = v[3] / (v[3] - v[0]);
  147. At = 0;
  148. Bt = v[2] + (v[1] - v[2]) * t;
  149. Ct = v[6] + (v[5] - v[6]) * t;
  150. Dt = v[7] + (v[4] - v[7]) * t;
  151. break;
  152. case 4:
  153. t = v[4] / (v[4] - v[5]);
  154. At = 0;
  155. Bt = v[7] + (v[6] - v[7]) * t;
  156. Ct = v[3] + (v[2] - v[3]) * t;
  157. Dt = v[0] + (v[1] - v[0]) * t;
  158. break;
  159. case 5:
  160. t = v[5] / (v[5] - v[6]);
  161. At = 0;
  162. Bt = v[4] + (v[7] - v[4]) * t;
  163. Ct = v[0] + (v[3] - v[0]) * t;
  164. Dt = v[1] + (v[2] - v[1]) * t;
  165. break;
  166. case 6:
  167. t = v[6] / (v[6] - v[7]);
  168. At = 0;
  169. Bt = v[5] + (v[4] - v[5]) * t;
  170. Ct = v[1] + (v[0] - v[1]) * t;
  171. Dt = v[2] + (v[3] - v[2]) * t;
  172. break;
  173. case 7:
  174. t = v[7] / (v[7] - v[4]);
  175. At = 0;
  176. Bt = v[6] + (v[5] - v[6]) * t;
  177. Ct = v[2] + (v[1] - v[2]) * t;
  178. Dt = v[3] + (v[0] - v[3]) * t;
  179. break;
  180. case 8:
  181. t = v[0] / (v[0] - v[4]);
  182. At = 0;
  183. Bt = v[3] + (v[7] - v[3]) * t;
  184. Ct = v[2] + (v[6] - v[2]) * t;
  185. Dt = v[1] + (v[5] - v[1]) * t;
  186. break;
  187. case 9:
  188. t = v[1] / (v[1] - v[5]);
  189. At = 0;
  190. Bt = v[0] + (v[4] - v[0]) * t;
  191. Ct = v[3] + (v[7] - v[3]) * t;
  192. Dt = v[2] + (v[6] - v[2]) * t;
  193. break;
  194. case 10:
  195. t = v[2] / (v[2] - v[6]);
  196. At = 0;
  197. Bt = v[1] + (v[5] - v[1]) * t;
  198. Ct = v[0] + (v[4] - v[0]) * t;
  199. Dt = v[3] + (v[7] - v[3]) * t;
  200. break;
  201. case 11:
  202. t = v[3] / (v[3] - v[7]);
  203. At = 0;
  204. Bt = v[2] + (v[6] - v[2]) * t;
  205. Ct = v[1] + (v[5] - v[1]) * t;
  206. Dt = v[0] + (v[4] - v[0]) * t;
  207. break;
  208. default:
  209. fprintf(stderr, "Invalid edge %d\n", edge);
  210. break;
  211. }
  212. break;
  213. default:
  214. fprintf(stderr, "Invalid ambiguous case %d\n", m_case);
  215. break;
  216. }
  217. if (At >= 0)
  218. test++;
  219. if (Bt >= 0)
  220. test += 2;
  221. if (Ct >= 0)
  222. test += 4;
  223. if (Dt >= 0)
  224. test += 8;
  225. switch (test) {
  226. case 0:
  227. return s > 0;
  228. case 1:
  229. return s > 0;
  230. case 2:
  231. return s > 0;
  232. case 3:
  233. return s > 0;
  234. case 4:
  235. return s > 0;
  236. case 5:
  237. if (At * Ct < Bt * Dt)
  238. return s > 0;
  239. break;
  240. case 6:
  241. return s > 0;
  242. case 7:
  243. return s < 0;
  244. case 8:
  245. return s > 0;
  246. case 9:
  247. return s > 0;
  248. case 10:
  249. if (At * Ct >= Bt * Dt)
  250. return s > 0;
  251. break;
  252. case 11:
  253. return s < 0;
  254. case 12:
  255. return s > 0;
  256. case 13:
  257. return s < 0;
  258. case 14:
  259. return s < 0;
  260. case 15:
  261. return s < 0;
  262. }
  263. return s < 0;
  264. }
  265. /*!
  266. \brief ADD
  267. \param c_ndx
  268. \param v
  269. \return
  270. */
  271. int mc33_process_cube(int c_ndx, float *v)
  272. {
  273. m_case = cases[c_ndx][0];
  274. m_config = cases[c_ndx][1];
  275. m_subconfig = 0;
  276. switch (m_case) {
  277. case 0:
  278. return -1;
  279. case 1:
  280. return OFFSET_T1 + m_config;
  281. case 2:
  282. return OFFSET_T2 + m_config;
  283. case 3:
  284. if (mc33_test_face(test[OFFSET_TEST3 + m_config][0], v))
  285. return OFFSET_T3_2 + m_config; /* 3.2 */
  286. else
  287. return OFFSET_T3_1 + m_config; /* 3.1 */
  288. case 4:
  289. if (mc33_test_interior(test[OFFSET_TEST4 + m_config][0], v))
  290. return OFFSET_T4_1 + m_config; /* 4.1 */
  291. else
  292. return OFFSET_T4_2 + m_config; /* 4.2 */
  293. case 5:
  294. return OFFSET_T5 + m_config;
  295. case 6:
  296. if (mc33_test_face(test[OFFSET_TEST6 + m_config][0], v))
  297. return OFFSET_T6_2 + m_config; /* 6.2 */
  298. else {
  299. if (mc33_test_interior(test[OFFSET_TEST6 + m_config][1], v))
  300. return OFFSET_T6_1_1 + m_config; /* 6.1.1 */
  301. else
  302. return OFFSET_T6_1_2 + m_config; /* 6.1.2 */
  303. }
  304. case 7:
  305. if (mc33_test_face(test[OFFSET_TEST7 + m_config][0], v))
  306. m_subconfig += 1;
  307. if (mc33_test_face(test[OFFSET_TEST7 + m_config][1], v))
  308. m_subconfig += 2;
  309. if (mc33_test_face(test[OFFSET_TEST7 + m_config][2], v))
  310. m_subconfig += 4;
  311. switch (subconfig7[m_subconfig]) {
  312. case 0:
  313. if (mc33_test_interior(test[OFFSET_TEST7 + m_config][3], v))
  314. return OFFSET_T7_4_2 + m_config; /* 7.4.2 */
  315. else
  316. return OFFSET_T7_4_1 + m_config; /* 7.4.1 */
  317. case 1:
  318. return OFFSET_T7_3_S1 + m_config; /* 7.3 */
  319. case 2:
  320. return OFFSET_T7_3_S2 + m_config; /* 7.3 */
  321. case 3:
  322. return OFFSET_T7_3_S3 + m_config; /* 7.3 */
  323. case 4:
  324. return OFFSET_T7_2_S1 + m_config; /* 7.2 */
  325. case 5:
  326. return OFFSET_T7_2_S2 + m_config; /* 7.2 */
  327. case 6:
  328. return OFFSET_T7_2_S3 + m_config; /* 7.2 */
  329. case 7:
  330. return OFFSET_T7_1 + m_config; /* 7.1 */
  331. };
  332. case 8:
  333. return OFFSET_T8 + m_config;
  334. case 9:
  335. return OFFSET_T9 + m_config;
  336. case 10:
  337. if (mc33_test_face(test[OFFSET_TEST10 + m_config][0], v)) {
  338. if (mc33_test_face(test[OFFSET_TEST10 + m_config][1], v))
  339. return OFFSET_T10_1_1_S2 + m_config; /* 10.1.1 */
  340. else {
  341. return OFFSET_T10_2_S1 + m_config; /* 10.2 */
  342. }
  343. }
  344. else {
  345. if (mc33_test_face(test[OFFSET_TEST10 + m_config][1], v)) {
  346. return OFFSET_T10_2_S2 + m_config; /* 10.2 */
  347. }
  348. else {
  349. if (mc33_test_interior(test[OFFSET_TEST10 + m_config][2], v))
  350. return OFFSET_T10_1_1_S1 + m_config; /* 10.1.1 */
  351. else
  352. return OFFSET_T10_1_2 + m_config; /* 10.1.2 */
  353. }
  354. }
  355. case 11:
  356. return OFFSET_T11 + m_config;
  357. case 12:
  358. if (mc33_test_face(test[OFFSET_TEST12 + m_config][0], v)) {
  359. if (mc33_test_face(test[OFFSET_TEST12 + m_config][1], v))
  360. return OFFSET_T12_1_1_S2 + m_config; /* 12.1.1 */
  361. else {
  362. return OFFSET_T12_2_S1 + m_config; /* 12.2 */
  363. }
  364. }
  365. else {
  366. if (mc33_test_face(test[OFFSET_TEST12 + m_config][1], v)) {
  367. return OFFSET_T12_2_S2 + m_config; /* 12.2 */
  368. }
  369. else {
  370. if (mc33_test_interior(test[OFFSET_TEST12 + m_config][2], v))
  371. return OFFSET_T12_1_1_S1 + m_config; /* 12.1.1 */
  372. else
  373. return OFFSET_T12_1_2 + m_config; /* 12.1.2 */
  374. }
  375. }
  376. case 13:
  377. if (mc33_test_face(test[OFFSET_TEST13 + m_config][0], v))
  378. m_subconfig += 1;
  379. if (mc33_test_face(test[OFFSET_TEST13 + m_config][1], v))
  380. m_subconfig += 2;
  381. if (mc33_test_face(test[OFFSET_TEST13 + m_config][2], v))
  382. m_subconfig += 4;
  383. if (mc33_test_face(test[OFFSET_TEST13 + m_config][3], v))
  384. m_subconfig += 8;
  385. if (mc33_test_face(test[OFFSET_TEST13 + m_config][4], v))
  386. m_subconfig += 16;
  387. if (mc33_test_face(test[OFFSET_TEST13 + m_config][5], v))
  388. m_subconfig += 32;
  389. switch (subconfig13[m_subconfig]) {
  390. case 0: /* 13.1 */
  391. return OFFSET_T13_1_S1 + m_config;
  392. case 1: /* 13.2 */
  393. return OFFSET_T13_2_S1 + 0 + m_config * 6;
  394. case 2: /* 13.2 */
  395. return OFFSET_T13_2_S1 + 1 + m_config * 6;
  396. case 3: /* 13.2 */
  397. return OFFSET_T13_2_S1 + 2 + m_config * 6;
  398. case 4: /* 13.2 */
  399. return OFFSET_T13_2_S1 + 3 + m_config * 6;
  400. case 5: /* 13.2 */
  401. return OFFSET_T13_2_S1 + 4 + m_config * 6;
  402. case 6: /* 13.2 */
  403. return OFFSET_T13_2_S1 + 5 + m_config * 6;
  404. case 7: /* 13.3 */
  405. return OFFSET_T13_3_S1 + 0 + m_config * 12;
  406. case 8: /* 13.3 */
  407. return OFFSET_T13_3_S1 + 1 + m_config * 12;
  408. case 9: /* 13.3 */
  409. return OFFSET_T13_3_S1 + 2 + m_config * 12;
  410. case 10: /* 13.3 */
  411. return OFFSET_T13_3_S1 + 3 + m_config * 12;
  412. case 11: /* 13.3 */
  413. return OFFSET_T13_3_S1 + 4 + m_config * 12;
  414. case 12: /* 13.3 */
  415. return OFFSET_T13_3_S1 + 5 + m_config * 12;
  416. case 13: /* 13.3 */
  417. return OFFSET_T13_3_S1 + 6 + m_config * 12;
  418. case 14: /* 13.3 */
  419. return OFFSET_T13_3_S1 + 7 + m_config * 12;
  420. case 15: /* 13.3 */
  421. return OFFSET_T13_3_S1 + 8 + m_config * 12;
  422. case 16: /* 13.3 */
  423. return OFFSET_T13_3_S1 + 9 + m_config * 12;
  424. case 17: /* 13.3 */
  425. return OFFSET_T13_3_S1 + 10 + m_config * 12;
  426. case 18: /* 13.3 */
  427. return OFFSET_T13_3_S1 + 11 + m_config * 12;
  428. case 19: /* 13.4 */
  429. return OFFSET_T13_4 + 0 + m_config * 4;
  430. case 20: /* 13.4 */
  431. return OFFSET_T13_4 + 1 + m_config * 4;
  432. case 21: /* 13.4 */
  433. return OFFSET_T13_4 + 2 + m_config * 4;
  434. case 22: /* 13.4 */
  435. return OFFSET_T13_4 + 3 + m_config * 4;
  436. case 23: /* 13.5 */
  437. m_subconfig = 0;
  438. if (mc33_test_interior(test[OFFSET_TEST13 + m_config][6], v))
  439. return OFFSET_T13_5_1 + 0 + m_config * 4;
  440. else
  441. return OFFSET_T13_5_2 + 0 + m_config * 4;
  442. case 24: /* 13.5 */
  443. m_subconfig = 1;
  444. if (mc33_test_interior(test[OFFSET_TEST13 + m_config][6], v))
  445. return OFFSET_T13_5_1 + 1 + m_config * 4;
  446. else
  447. return OFFSET_T13_5_2 + 1 + m_config * 4;
  448. case 25: /* 13.5 */
  449. m_subconfig = 2;
  450. if (mc33_test_interior(test[OFFSET_TEST13 + m_config][6], v))
  451. return OFFSET_T13_5_1 + 2 + m_config * 4;
  452. else
  453. return OFFSET_T13_5_2 + 2 + m_config * 4;
  454. case 26: /* 13.5 */
  455. m_subconfig = 3;
  456. if (mc33_test_interior(test[OFFSET_TEST13 + m_config][6], v))
  457. return OFFSET_T13_5_1 + 3 + m_config * 4;
  458. else
  459. return OFFSET_T13_5_2 + 3 + m_config * 4;
  460. case 27: /* 13.3 */
  461. return OFFSET_T13_3_S2 + 0 + m_config * 12;
  462. case 28: /* 13.3 */
  463. return OFFSET_T13_3_S2 + 1 + m_config * 12;
  464. case 29: /* 13.3 */
  465. return OFFSET_T13_3_S2 + 2 + m_config * 12;
  466. case 30: /* 13.3 */
  467. return OFFSET_T13_3_S2 + 3 + m_config * 12;
  468. case 31: /* 13.3 */
  469. return OFFSET_T13_3_S2 + 4 + m_config * 12;
  470. case 32: /* 13.3 */
  471. return OFFSET_T13_3_S2 + 5 + m_config * 12;
  472. case 33: /* 13.3 */
  473. return OFFSET_T13_3_S2 + 6 + m_config * 12;
  474. case 34: /* 13.3 */
  475. return OFFSET_T13_3_S2 + 7 + m_config * 12;
  476. case 35: /* 13.3 */
  477. return OFFSET_T13_3_S2 + 8 + m_config * 12;
  478. case 36: /* 13.3 */
  479. return OFFSET_T13_3_S2 + 9 + m_config * 12;
  480. case 37: /* 13.3 */
  481. return OFFSET_T13_3_S2 + 10 + m_config * 12;
  482. case 38: /* 13.3 */
  483. return OFFSET_T13_3_S2 + 11 + m_config * 12;
  484. case 39: /* 13.2 */
  485. return OFFSET_T13_2_S2 + 0 + m_config * 6;
  486. case 40: /* 13.2 */
  487. return OFFSET_T13_2_S2 + 1 + m_config * 6;
  488. case 41: /* 13.2 */
  489. return OFFSET_T13_2_S2 + 2 + m_config * 6;
  490. case 42: /* 13.2 */
  491. return OFFSET_T13_2_S2 + 3 + m_config * 6;
  492. case 43: /* 13.2 */
  493. return OFFSET_T13_2_S2 + 4 + m_config * 6;
  494. case 44: /* 13.2 */
  495. return OFFSET_T13_2_S2 + 5 + m_config * 6;
  496. case 45: /* 13.1 */
  497. return OFFSET_T13_1_S2 + m_config;
  498. default:
  499. fprintf(stderr, "Marching Cubes: Impossible case 13?\n");
  500. }
  501. case 14:
  502. return OFFSET_T14 + m_config;
  503. }
  504. return -1;
  505. }