gpd.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. /*!
  2. \file gpd.c
  3. \brief OGSF library - loading and manipulating point sets
  4. GRASS OpenGL gsurf OGSF Library
  5. (C) 1999-2008 by the GRASS Development Team
  6. This program is free software under the
  7. GNU General Public License (>=v2).
  8. Read the file COPYING that comes with GRASS
  9. for details.
  10. \author Bill Brown USACERL, GMSL/University of Illinois (December 1993)
  11. \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
  12. */
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <math.h>
  16. #include <grass/gstypes.h>
  17. #include "rowcol.h"
  18. #define CHK_FREQ 50
  19. /* BOB -- border allowed outside of viewport*/
  20. #define v_border 50
  21. /* ACS_MODIFY_BEGIN site_attr management ***************************************/
  22. static float _cur_size_;
  23. /*!
  24. \brief Substitutes gpd_obj()
  25. \param gs surface (geosurf)
  26. \param gp site (geosite)
  27. \param gpt point (point)
  28. \param site point
  29. \return 0
  30. */
  31. int gpd_obj_site_attr(geosurf * gs, geosite * gp, geopoint *gpt, Point3 site)
  32. {
  33. float size, z, y, x, z_scale, z_offset;
  34. int marker, color, i, ii, iii;
  35. int use_attr, has_drawn;
  36. int _put_aside_;
  37. _put_aside_ = 0;
  38. _cur_size_ = gp->size;
  39. z_scale = GS_global_exag();
  40. z_offset = 0.0;
  41. has_drawn = 0;
  42. for(i=0; i<GPT_MAX_ATTR; i++) {
  43. color = gp->color; marker = gp->marker; size = gp->size;
  44. use_attr = 0;
  45. if (gp->use_attr[i] & ST_ATT_COLOR) {
  46. use_attr = 1;
  47. color = gpt->color[i];
  48. }
  49. if (gp->use_attr[i] & ST_ATT_MARKER) {
  50. use_attr = 1;
  51. marker = gpt->marker[i];
  52. }
  53. if (gp->use_attr[i] & ST_ATT_SIZE) {
  54. use_attr = 1;
  55. size = gpt->size[i] * gp->size;
  56. if (gp->marker == ST_HISTOGRAM) _put_aside_ = 1;
  57. }
  58. /* ACS_MODIFY_BEGIN site_highlight management **********************************/
  59. if (gpt->highlight_color) color = gpt->highlight_color_value;
  60. if (gpt->highlight_marker) marker = gpt->highlight_marker_value;
  61. if (gpt->highlight_size) size *= gpt->highlight_size_value;
  62. /* ACS_MODIFY_END site_highlight management ************************************/
  63. if (_put_aside_) {
  64. if (use_attr == 1) {
  65. has_drawn = 1;
  66. /*******************************************************************************
  67. fixed size = gp->size
  68. this is mailny intended for "histograms" that grow in z, but not in xy
  69. square filling to right and then up
  70. 15 14 13 12
  71. 8 7 6 11
  72. 3 2 5 10
  73. 0 1 4 9
  74. *******************************************************************************/
  75. x = site[X];
  76. y = site[Y];
  77. ii = (int)(sqrt(i));
  78. iii = ii * ii + ii;
  79. if (i <= iii) {
  80. site[X] += ii * 2.2 * gp->size;
  81. site[Y] += (i-ii) * 2.2 * gp->size;
  82. } else {
  83. site[X] += (ii-(i-iii)) * 2.2 * gp->size;
  84. site[Y] += ii * 2.2 * gp->size;
  85. }
  86. gpd_obj(gs, color, size, marker, site);
  87. site[X] = x;
  88. site[Y] = y;
  89. }
  90. } else {
  91. if (i>0) z_offset += size;
  92. if (use_attr == 1) {
  93. has_drawn = 1;
  94. z = site[Z];
  95. site[Z] += z_offset / z_scale;
  96. gpd_obj(gs, color, size, marker, site);
  97. site[Z] = z;
  98. }
  99. z_offset += size;
  100. }
  101. }
  102. if (has_drawn == 0)
  103. gpd_obj(gs, color, size, marker, site);
  104. return(0);
  105. }
  106. /* ACS_MODIFY_END site_attr management *****************************************/
  107. /*!
  108. \brief Check if point is in region
  109. Check for cancel every CHK_FREQ points
  110. \param gs surface (geosurf)
  111. \param pt point (array(X,Y,Z))
  112. \param region region settings (array (top,bottom,left,right))
  113. \return 0 point outside of region
  114. \return 1 point inside region
  115. */
  116. int gs_point_in_region(geosurf * gs, float *pt, float *region)
  117. {
  118. float top, bottom, left, right;
  119. if (!region) {
  120. top = gs->yrange;
  121. bottom = VROW2Y(gs, VROWS(gs));
  122. left = 0.0;
  123. right = VCOL2X(gs, VCOLS(gs));
  124. }
  125. else {
  126. top = region[0];
  127. bottom = region[1];
  128. left = region[2];
  129. right = region[3];
  130. }
  131. return (pt[X] >= left && pt[X] <= right &&
  132. pt[Y] >= bottom && pt[Y] <= top);
  133. }
  134. /*!
  135. \brief ADD
  136. Do normal transforms before calling
  137. Note gs: NULL if 3d obj or const elev surface
  138. \todo add size1, size2 & dir1, dir2 (eg azimuth, elevation) variables
  139. \param gs surface (geosurf)
  140. \param size
  141. \param marker
  142. \param pt 3d point (Point3)
  143. */
  144. void gpd_obj(geosurf * gs, int color, float size, int marker, Point3 pt)
  145. {
  146. float sz, lpt[3];
  147. float siz[3];
  148. gsd_color_func(color);
  149. sz = GS_global_exag();
  150. GS_v3eq(lpt, pt); /* CHANGING Z OF POINT PASSED, so use copy */
  151. switch (marker) {
  152. /* ACS_MODIFY_BEGIN site_attr management ***************************************/
  153. case ST_HISTOGRAM:
  154. gsd_colormode(CM_DIFFUSE);
  155. gsd_pushmatrix();
  156. if (sz) {
  157. lpt[Z] *= sz;
  158. gsd_scale(1.0, 1.0, 1. / sz);
  159. }
  160. siz[0] = _cur_size_;
  161. siz[1] = _cur_size_;
  162. siz[2] = size;
  163. gsd_box(lpt, color, siz);
  164. gsd_popmatrix();
  165. gsd_colormode(CM_COLOR);
  166. break;
  167. /* ACS_MODIFY_END site_attr management ***************************************/
  168. case ST_DIAMOND:
  169. /*
  170. gsd_colormode(CM_AD);
  171. */
  172. gsd_colormode(CM_DIFFUSE);
  173. gsd_pushmatrix();
  174. if (sz) {
  175. lpt[Z] *= sz;
  176. gsd_scale(1.0, 1.0, 1. / sz);
  177. }
  178. gsd_diamond(lpt, color, size);
  179. gsd_popmatrix();
  180. gsd_colormode(CM_COLOR);
  181. break;
  182. case ST_BOX:
  183. gsd_colormode(CM_COLOR);
  184. gsd_pushmatrix();
  185. if (sz) {
  186. lpt[Z] *= sz;
  187. gsd_scale(1.0, 1.0, 1. / sz);
  188. }
  189. gsd_draw_box(lpt, color, size);
  190. gsd_popmatrix();
  191. break;
  192. case ST_SPHERE:
  193. /*
  194. gsd_colormode(CM_AD);
  195. */
  196. gsd_colormode(CM_DIFFUSE);
  197. gsd_pushmatrix();
  198. if (sz) {
  199. lpt[Z] *= sz;
  200. gsd_scale(1.0, 1.0, 1. / sz);
  201. }
  202. gsd_sphere(lpt, size);
  203. gsd_popmatrix();
  204. gsd_colormode(CM_COLOR);
  205. break;
  206. case ST_GYRO:
  207. gsd_colormode(CM_COLOR);
  208. gsd_pushmatrix();
  209. if (sz) {
  210. lpt[Z] *= sz;
  211. gsd_scale(1.0, 1.0, 1. / sz);
  212. }
  213. gsd_draw_gyro(lpt, color, size);
  214. gsd_popmatrix();
  215. break;
  216. case ST_ASTER:
  217. gsd_colormode(CM_COLOR);
  218. gsd_pushmatrix();
  219. if (sz) {
  220. lpt[Z] *= sz;
  221. gsd_scale(1.0, 1.0, 1. / sz);
  222. }
  223. gsd_draw_asterisk(lpt, color, size);
  224. gsd_popmatrix();
  225. break;
  226. case ST_CUBE:
  227. gsd_colormode(CM_DIFFUSE);
  228. gsd_pushmatrix();
  229. if (sz) {
  230. lpt[Z] *= sz;
  231. gsd_scale(1.0, 1.0, 1. / sz);
  232. }
  233. gsd_cube(lpt, color, size);
  234. gsd_popmatrix();
  235. gsd_colormode(CM_COLOR);
  236. break;
  237. default:
  238. case ST_X:
  239. gsd_colormode(CM_COLOR);
  240. gsd_x(gs, lpt, color, size);
  241. break;
  242. }
  243. return;
  244. }
  245. /*!
  246. \brief ADD
  247. Need to think about translations - If user translates surface,
  248. sites should automatically go with it, but translating sites should
  249. translate it relative to surface on which it's displayed
  250. Handling mask checking here
  251. \todo prevent scaling by 0
  252. \param gp site (geosite)
  253. \param gs surface (geosurf)
  254. \param do_fast (unused)
  255. \return 0
  256. \return 1
  257. */
  258. int gpd_2dsite(geosite * gp, geosurf * gs, int do_fast)
  259. {
  260. float site[3], konst;
  261. float size;
  262. int src, check, marker, color;
  263. geopoint *gpt;
  264. typbuff *buf;
  265. GLdouble modelMatrix[16], projMatrix[16];
  266. GLint viewport[4];
  267. GLint window[4];
  268. if (GS_check_cancel()) {
  269. return (0);
  270. }
  271. if (gs) {
  272. gs_update_curmask(gs);
  273. src = gs_get_att_src(gs, ATT_TOPO);
  274. if (src == CONST_ATT) {
  275. konst = gs->att[ATT_TOPO].constant;
  276. site[Z] = konst;
  277. }
  278. else {
  279. buf = gs_get_att_typbuff(gs, ATT_TOPO, 0);
  280. }
  281. /* Get viewport parameters for view check */
  282. gsd_getwindow(window, viewport, modelMatrix, projMatrix);
  283. gsd_pushmatrix();
  284. gsd_do_scale(1);
  285. gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans);
  286. gsd_linewidth(gp->width);
  287. check = 0;
  288. color = gp->color;
  289. marker = gp->marker;
  290. size = gp->size;
  291. for (gpt = gp->points; gpt; gpt = gpt->next) {
  292. if (!(++check % CHK_FREQ)) {
  293. if (GS_check_cancel()) {
  294. gsd_linewidth(1);
  295. gsd_popmatrix();
  296. return (0);
  297. }
  298. }
  299. site[X] = gpt->p3[X] + gp->x_trans - gs->ox;
  300. site[Y] = gpt->p3[Y] + gp->y_trans - gs->oy;
  301. if (gs_point_is_masked(gs, site)) {
  302. continue;
  303. }
  304. /* TODO: set other dynamic attributes */
  305. if (gp->attr_mode & ST_ATT_COLOR) {
  306. color = gpt->iattr;
  307. }
  308. if (src == MAP_ATT) {
  309. if (viewcell_tri_interp(gs, buf, site, 1)) {
  310. /* returns 0 if outside or masked */
  311. site[Z] += gp->z_trans;
  312. if (gsd_checkpoint
  313. (site, window, viewport, modelMatrix, projMatrix))
  314. continue;
  315. else
  316. /* ACS_MODIFY_OneLine site_attr management - was: gpd_obj(gs, color, size, marker, site); */
  317. gpd_obj_site_attr(gs, gp, gpt, site);
  318. }
  319. }
  320. else if (src == CONST_ATT) {
  321. if (gs_point_in_region(gs, site, NULL)) {
  322. site[Z] += gp->z_trans;
  323. if (gsd_checkpoint
  324. (site, window, viewport, modelMatrix, projMatrix))
  325. continue;
  326. else
  327. /* ACS_MODIFY_OneLine site_attr management - was: gpd_obj(NULL, color, size, marker, site); */
  328. gpd_obj_site_attr(NULL, gp, gpt, site);
  329. }
  330. }
  331. }
  332. gsd_linewidth(1);
  333. gsd_popmatrix();
  334. }
  335. return (1);
  336. }
  337. /*!
  338. \brief ADD
  339. \param gp site (geosite)
  340. \param xo,yo
  341. \param do_fast (unused)
  342. \return 0
  343. \return 1
  344. */
  345. int gpd_3dsite(geosite * gp, float xo, float yo, int do_fast)
  346. {
  347. float site[3], tz;
  348. float size;
  349. int check, color, marker;
  350. geopoint *gpt;
  351. GLdouble modelMatrix[16], projMatrix[16];
  352. GLint viewport[4];
  353. GLint window[4];
  354. if (GS_check_cancel()) {
  355. return (0);
  356. }
  357. gsd_getwindow(window, viewport, modelMatrix, projMatrix);
  358. gsd_pushmatrix();
  359. gsd_do_scale(1);
  360. tz = GS_global_exag();
  361. site[Z] = 0.0;
  362. check = 0;
  363. color = gp->color;
  364. marker = gp->marker;
  365. size = gp->size;
  366. gsd_linewidth(gp->width);
  367. for (gpt = gp->points; gpt; gpt = gpt->next) {
  368. if (!(++check % CHK_FREQ)) {
  369. if (GS_check_cancel()) {
  370. gsd_linewidth(1);
  371. gsd_popmatrix();
  372. return (0);
  373. }
  374. }
  375. site[X] = gpt->p3[X] + gp->x_trans - xo;
  376. site[Y] = gpt->p3[Y] + gp->y_trans - yo;
  377. if (tz) {
  378. site[Z] = gpt->p3[Z] + gp->z_trans;
  379. }
  380. /* TODO: set other dynamic attributes */
  381. if (gp->attr_mode & ST_ATT_COLOR) {
  382. color = gpt->iattr;
  383. }
  384. if (gsd_checkpoint(site, window, viewport, modelMatrix, projMatrix))
  385. continue;
  386. else
  387. /* clip points outside default region? */
  388. /* ACS_MODIFY_OneLine site_attr management - was: gpd_obj(NULL, color, size, marker, site); */
  389. gpd_obj_site_attr(NULL, gp, gpt, site);
  390. }
  391. gsd_linewidth(1);
  392. gsd_popmatrix();
  393. return (1);
  394. }