gpd.c 7.2 KB

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