gpd.c 9.3 KB

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