gpd.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  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 <stdlib.h>
  14. #include <math.h>
  15. #include <grass/gstypes.h>
  16. #include "rowcol.h"
  17. #define CHK_FREQ 50
  18. /* BOB -- border allowed outside of viewport */
  19. #define v_border 50
  20. /*!
  21. \brief Check if point is in region
  22. Check for cancel every CHK_FREQ points
  23. \param gs surface (geosurf)
  24. \param pt point (array(X,Y,Z))
  25. \param region region settings (array (top,bottom,left,right))
  26. \return 0 point outside of region
  27. \return 1 point inside region
  28. */
  29. int gs_point_in_region(geosurf * gs, float *pt, float *region)
  30. {
  31. float top, bottom, left, right;
  32. if (!region) {
  33. top = gs->yrange;
  34. bottom = VROW2Y(gs, VROWS(gs));
  35. left = 0.0;
  36. right = VCOL2X(gs, VCOLS(gs));
  37. }
  38. else {
  39. top = region[0];
  40. bottom = region[1];
  41. left = region[2];
  42. right = region[3];
  43. }
  44. return (pt[X] >= left && pt[X] <= right &&
  45. pt[Y] >= bottom && pt[Y] <= top);
  46. }
  47. /*!
  48. \brief Draw point representing object
  49. Do normal transforms before calling
  50. Note gs: NULL if 3d obj or const elev surface
  51. \param gs surface (geosurf)
  52. \param style object displaying style (highlighted or not)
  53. \param pt 3d point (Point3)
  54. */
  55. void gpd_obj(geosurf * gs, gvstyle * style, Point3 pt)
  56. {
  57. float sz, lpt[3];
  58. float siz[3];
  59. gsd_color_func(style->color);
  60. sz = GS_global_exag();
  61. GS_v3eq(lpt, pt); /* CHANGING Z OF POINT PASSED, so use copy */
  62. switch (style->symbol) {
  63. case ST_HISTOGRAM:
  64. gsd_colormode(CM_DIFFUSE);
  65. gsd_pushmatrix();
  66. if (sz) {
  67. lpt[Z] *= sz;
  68. gsd_scale(1.0, 1.0, 1. / sz);
  69. }
  70. siz[0] = style->size; /*TODO: Fix historgam drawing */
  71. siz[1] = style->size;
  72. siz[2] = style->size;
  73. gsd_box(lpt, style->color, siz);
  74. gsd_popmatrix();
  75. gsd_colormode(CM_COLOR);
  76. break;
  77. case ST_DIAMOND:
  78. /*
  79. gsd_colormode(CM_AD);
  80. */
  81. gsd_colormode(CM_DIFFUSE);
  82. gsd_pushmatrix();
  83. if (sz) {
  84. lpt[Z] *= sz;
  85. gsd_scale(1.0, 1.0, 1. / sz);
  86. }
  87. gsd_diamond(lpt, style->color, style->size);
  88. gsd_popmatrix();
  89. gsd_colormode(CM_COLOR);
  90. break;
  91. case ST_BOX:
  92. gsd_colormode(CM_COLOR);
  93. gsd_pushmatrix();
  94. if (sz) {
  95. lpt[Z] *= sz;
  96. gsd_scale(1.0, 1.0, 1. / sz);
  97. }
  98. gsd_draw_box(lpt, style->color, style->size);
  99. gsd_popmatrix();
  100. break;
  101. case ST_SPHERE:
  102. /*
  103. gsd_colormode(CM_AD);
  104. */
  105. gsd_colormode(CM_DIFFUSE);
  106. gsd_pushmatrix();
  107. if (sz) {
  108. lpt[Z] *= sz;
  109. gsd_scale(1.0, 1.0, 1. / sz);
  110. }
  111. gsd_sphere(lpt, style->size);
  112. gsd_popmatrix();
  113. gsd_colormode(CM_COLOR);
  114. break;
  115. case ST_GYRO:
  116. gsd_colormode(CM_COLOR);
  117. gsd_pushmatrix();
  118. if (sz) {
  119. lpt[Z] *= sz;
  120. gsd_scale(1.0, 1.0, 1. / sz);
  121. }
  122. gsd_draw_gyro(lpt, style->color, style->size);
  123. gsd_popmatrix();
  124. break;
  125. case ST_ASTER:
  126. gsd_colormode(CM_COLOR);
  127. gsd_pushmatrix();
  128. if (sz) {
  129. lpt[Z] *= sz;
  130. gsd_scale(1.0, 1.0, 1. / sz);
  131. }
  132. gsd_draw_asterisk(lpt, style->color, style->size);
  133. gsd_popmatrix();
  134. break;
  135. case ST_CUBE:
  136. gsd_colormode(CM_DIFFUSE);
  137. gsd_pushmatrix();
  138. if (sz) {
  139. lpt[Z] *= sz;
  140. gsd_scale(1.0, 1.0, 1. / sz);
  141. }
  142. gsd_cube(lpt, style->color, style->size);
  143. gsd_popmatrix();
  144. gsd_colormode(CM_COLOR);
  145. break;
  146. default:
  147. case ST_X:
  148. gsd_colormode(CM_COLOR);
  149. gsd_x(gs, lpt, style->color, style->size);
  150. break;
  151. }
  152. return;
  153. }
  154. /*!
  155. \brief ADD
  156. Need to think about translations - If user translates surface,
  157. sites should automatically go with it, but translating sites should
  158. translate it relative to surface on which it's displayed
  159. Handling mask checking here
  160. \todo prevent scaling by 0
  161. \param gp site (geosite)
  162. \param gs surface (geosurf)
  163. \param do_fast (unused)
  164. \return 0
  165. \return 1
  166. */
  167. int gpd_2dsite(geosite * gp, geosurf * gs, int do_fast)
  168. {
  169. float site[3], konst;
  170. int src, check;
  171. geopoint *gpt;
  172. typbuff *buf;
  173. GLdouble modelMatrix[16], projMatrix[16];
  174. GLint viewport[4];
  175. GLint window[4];
  176. if (GS_check_cancel()) {
  177. return (0);
  178. }
  179. if (gs) {
  180. gs_update_curmask(gs);
  181. src = gs_get_att_src(gs, ATT_TOPO);
  182. if (src == CONST_ATT) {
  183. konst = gs->att[ATT_TOPO].constant;
  184. site[Z] = konst;
  185. }
  186. else {
  187. buf = gs_get_att_typbuff(gs, ATT_TOPO, 0);
  188. }
  189. /* Get viewport parameters for view check */
  190. gsd_getwindow(window, viewport, modelMatrix, projMatrix);
  191. gsd_pushmatrix();
  192. gsd_do_scale(1);
  193. gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans);
  194. gsd_linewidth(gp->style->width);
  195. check = 0;
  196. for (gpt = gp->points; gpt; gpt = gpt->next) {
  197. if (!(++check % CHK_FREQ)) {
  198. if (GS_check_cancel()) {
  199. gsd_linewidth(1);
  200. gsd_popmatrix();
  201. return (0);
  202. }
  203. }
  204. site[X] = gpt->p3[X] + gp->x_trans - gs->ox;
  205. site[Y] = gpt->p3[Y] + gp->y_trans - gs->oy;
  206. if (gs_point_is_masked(gs, site)) {
  207. continue;
  208. }
  209. if (src == MAP_ATT) {
  210. if (viewcell_tri_interp(gs, buf, site, 1)) {
  211. /* returns 0 if outside or masked */
  212. site[Z] += gp->z_trans;
  213. if (gsd_checkpoint
  214. (site, window, viewport, modelMatrix, projMatrix))
  215. continue;
  216. else {
  217. if (gpt->highlighted > 0)
  218. gpd_obj(gs, gp->hstyle, site);
  219. else if (gp->thematic_layer > 0)
  220. gpd_obj(gs, gpt->style, site);
  221. else
  222. gpd_obj(gs, gp->style, site);
  223. }
  224. }
  225. }
  226. else if (src == CONST_ATT) {
  227. if (gs_point_in_region(gs, site, NULL)) {
  228. site[Z] += gp->z_trans;
  229. if (gsd_checkpoint
  230. (site, window, viewport, modelMatrix, projMatrix))
  231. continue;
  232. else {
  233. if (gpt->highlighted > 0)
  234. gpd_obj(gs, gp->hstyle, site);
  235. else if (gp->thematic_layer > 0)
  236. gpd_obj(gs, gpt->style, site);
  237. else
  238. gpd_obj(gs, gp->style, site);
  239. }
  240. }
  241. }
  242. }
  243. gsd_linewidth(1);
  244. gsd_popmatrix();
  245. }
  246. return (1);
  247. }
  248. /*!
  249. \brief ADD
  250. \param gp site (geosite)
  251. \param xo,yo
  252. \param do_fast (unused)
  253. \return 0
  254. \return 1
  255. */
  256. int gpd_3dsite(geosite * gp, float xo, float yo, int do_fast)
  257. {
  258. float site[3], tz;
  259. int check;
  260. geopoint *gpt;
  261. GLdouble modelMatrix[16], projMatrix[16];
  262. GLint viewport[4];
  263. GLint window[4];
  264. if (GS_check_cancel()) {
  265. return (0);
  266. }
  267. gsd_getwindow(window, viewport, modelMatrix, projMatrix);
  268. gsd_pushmatrix();
  269. gsd_do_scale(1);
  270. tz = GS_global_exag();
  271. site[Z] = 0.0;
  272. check = 0;
  273. gsd_linewidth(gp->style->width);
  274. for (gpt = gp->points; gpt; gpt = gpt->next) {
  275. if (!(++check % CHK_FREQ)) {
  276. if (GS_check_cancel()) {
  277. gsd_linewidth(1);
  278. gsd_popmatrix();
  279. return (0);
  280. }
  281. }
  282. site[X] = gpt->p3[X] + gp->x_trans - xo;
  283. site[Y] = gpt->p3[Y] + gp->y_trans - yo;
  284. if (tz) {
  285. site[Z] = gpt->p3[Z] + gp->z_trans;
  286. }
  287. if (gsd_checkpoint(site, window, viewport, modelMatrix, projMatrix))
  288. continue;
  289. else
  290. /* clip points outside default region? */
  291. {
  292. if (gpt->highlighted > 0)
  293. gpd_obj(NULL, gp->hstyle, site);
  294. else if (gp->thematic_layer > 0)
  295. gpd_obj(NULL, gpt->style, site);
  296. else
  297. gpd_obj(NULL, gp->style, site);
  298. }
  299. }
  300. gsd_linewidth(1);
  301. gsd_popmatrix();
  302. return (1);
  303. }