123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513 |
- /*!
- \file gpd.c
-
- \brief OGSF library - loading and manipulating point sets
-
- GRASS OpenGL gsurf OGSF Library
-
- (C) 1999-2008 by the GRASS Development Team
-
- This program is free software under the
- GNU General Public License (>=v2).
- Read the file COPYING that comes with GRASS
- for details.
-
- \author Bill Brown USACERL, GMSL/University of Illinois (December 1993)
- \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <grass/gstypes.h>
- #include "rowcol.h"
- #define CHK_FREQ 50
- /* BOB -- border allowed outside of viewport*/
- #define v_border 50
- /* ACS_MODIFY_BEGIN site_attr management ***************************************/
- static float _cur_size_;
- /*!
- \brief Substitutes gpd_obj()
- \param gs surface (geosurf)
- \param gp site (geosite)
- \param gpt point (point)
- \param site point
- \return 0
- */
- int gpd_obj_site_attr(geosurf * gs, geosite * gp, geopoint *gpt, Point3 site)
- {
- float size, z, y, x, z_scale, z_offset;
- int marker, color, i, ii, iii;
- int use_attr, has_drawn;
- int _put_aside_;
-
- _put_aside_ = 0;
- _cur_size_ = gp->size;
-
- z_scale = GS_global_exag();
- z_offset = 0.0;
-
- has_drawn = 0;
-
- for(i=0; i<GPT_MAX_ATTR; i++) {
- color = gp->color; marker = gp->marker; size = gp->size;
- use_attr = 0;
-
- if (gp->use_attr[i] & ST_ATT_COLOR) {
- use_attr = 1;
- color = gpt->color[i];
- }
-
- if (gp->use_attr[i] & ST_ATT_MARKER) {
- use_attr = 1;
- marker = gpt->marker[i];
- }
-
- if (gp->use_attr[i] & ST_ATT_SIZE) {
- use_attr = 1;
- size = gpt->size[i] * gp->size;
- if (gp->marker == ST_HISTOGRAM) _put_aside_ = 1;
- }
-
- /* ACS_MODIFY_BEGIN site_highlight management **********************************/
- if (gpt->highlight_color) color = gpt->highlight_color_value;
- if (gpt->highlight_marker) marker = gpt->highlight_marker_value;
- if (gpt->highlight_size) size *= gpt->highlight_size_value;
- /* ACS_MODIFY_END site_highlight management ************************************/
-
- if (_put_aside_) {
- if (use_attr == 1) {
- has_drawn = 1;
-
- /*******************************************************************************
- fixed size = gp->size
- this is mailny intended for "histograms" that grow in z, but not in xy
- square filling to right and then up
- 15 14 13 12
- 8 7 6 11
- 3 2 5 10
- 0 1 4 9
- *******************************************************************************/
- x = site[X];
- y = site[Y];
-
- ii = (int)(sqrt(i));
- iii = ii * ii + ii;
-
- if (i <= iii) {
- site[X] += ii * 2.2 * gp->size;
- site[Y] += (i-ii) * 2.2 * gp->size;
- } else {
- site[X] += (ii-(i-iii)) * 2.2 * gp->size;
- site[Y] += ii * 2.2 * gp->size;
-
- }
-
- gpd_obj(gs, color, size, marker, site);
-
- site[X] = x;
- site[Y] = y;
- }
- } else {
- if (i>0) z_offset += size;
- if (use_attr == 1) {
- has_drawn = 1;
-
- z = site[Z];
- site[Z] += z_offset / z_scale;
-
- gpd_obj(gs, color, size, marker, site);
-
- site[Z] = z;
- }
-
- z_offset += size;
- }
- }
-
- if (has_drawn == 0)
- gpd_obj(gs, color, size, marker, site);
-
- return(0);
- }
- /* ACS_MODIFY_END site_attr management *****************************************/
- /*!
- \brief Check if point is in region
- Check for cancel every CHK_FREQ points
- \param gs surface (geosurf)
- \param pt point (array(X,Y,Z))
- \param region region settings (array (top,bottom,left,right))
- \return 0 point outside of region
- \return 1 point inside region
- */
- int gs_point_in_region(geosurf * gs, float *pt, float *region)
- {
- float top, bottom, left, right;
- if (!region) {
- top = gs->yrange;
- bottom = VROW2Y(gs, VROWS(gs));
- left = 0.0;
- right = VCOL2X(gs, VCOLS(gs));
- }
- else {
- top = region[0];
- bottom = region[1];
- left = region[2];
- right = region[3];
- }
- return (pt[X] >= left && pt[X] <= right &&
- pt[Y] >= bottom && pt[Y] <= top);
- }
- /*!
- \brief ADD
- Do normal transforms before calling
- Note gs: NULL if 3d obj or const elev surface
- \todo add size1, size2 & dir1, dir2 (eg azimuth, elevation) variables
- \param gs surface (geosurf)
- \param size
- \param marker
- \param pt 3d point (Point3)
- */
- void gpd_obj(geosurf * gs, int color, float size, int marker, Point3 pt)
- {
- float sz, lpt[3];
- float siz[3];
- gsd_color_func(color);
- sz = GS_global_exag();
- GS_v3eq(lpt, pt); /* CHANGING Z OF POINT PASSED, so use copy */
- switch (marker) {
- /* ACS_MODIFY_BEGIN site_attr management ***************************************/
- case ST_HISTOGRAM:
- gsd_colormode(CM_DIFFUSE);
- gsd_pushmatrix();
- if (sz) {
- lpt[Z] *= sz;
- gsd_scale(1.0, 1.0, 1. / sz);
- }
- siz[0] = _cur_size_;
- siz[1] = _cur_size_;
- siz[2] = size;
- gsd_box(lpt, color, siz);
- gsd_popmatrix();
- gsd_colormode(CM_COLOR);
- break;
- /* ACS_MODIFY_END site_attr management ***************************************/
- case ST_DIAMOND:
- /*
- gsd_colormode(CM_AD);
- */
- gsd_colormode(CM_DIFFUSE);
- gsd_pushmatrix();
- if (sz) {
- lpt[Z] *= sz;
- gsd_scale(1.0, 1.0, 1. / sz);
- }
- gsd_diamond(lpt, color, size);
- gsd_popmatrix();
- gsd_colormode(CM_COLOR);
- break;
- case ST_BOX:
- gsd_colormode(CM_COLOR);
- gsd_pushmatrix();
- if (sz) {
- lpt[Z] *= sz;
- gsd_scale(1.0, 1.0, 1. / sz);
- }
- gsd_draw_box(lpt, color, size);
- gsd_popmatrix();
- break;
- case ST_SPHERE:
- /*
- gsd_colormode(CM_AD);
- */
- gsd_colormode(CM_DIFFUSE);
- gsd_pushmatrix();
- if (sz) {
- lpt[Z] *= sz;
- gsd_scale(1.0, 1.0, 1. / sz);
- }
- gsd_sphere(lpt, size);
- gsd_popmatrix();
- gsd_colormode(CM_COLOR);
- break;
- case ST_GYRO:
- gsd_colormode(CM_COLOR);
- gsd_pushmatrix();
- if (sz) {
- lpt[Z] *= sz;
- gsd_scale(1.0, 1.0, 1. / sz);
- }
- gsd_draw_gyro(lpt, color, size);
- gsd_popmatrix();
- break;
- case ST_ASTER:
- gsd_colormode(CM_COLOR);
- gsd_pushmatrix();
- if (sz) {
- lpt[Z] *= sz;
- gsd_scale(1.0, 1.0, 1. / sz);
- }
- gsd_draw_asterisk(lpt, color, size);
- gsd_popmatrix();
- break;
- case ST_CUBE:
- gsd_colormode(CM_DIFFUSE);
- gsd_pushmatrix();
- if (sz) {
- lpt[Z] *= sz;
- gsd_scale(1.0, 1.0, 1. / sz);
- }
- gsd_cube(lpt, color, size);
- gsd_popmatrix();
- gsd_colormode(CM_COLOR);
- break;
- default:
- case ST_X:
- gsd_colormode(CM_COLOR);
- gsd_x(gs, lpt, color, size);
- break;
- }
- return;
- }
- /*!
- \brief ADD
- Need to think about translations - If user translates surface,
- sites should automatically go with it, but translating sites should
- translate it relative to surface on which it's displayed
- Handling mask checking here
-
- \todo prevent scaling by 0
- \param gp site (geosite)
- \param gs surface (geosurf)
- \param do_fast (unused)
- \return 0
- \return 1
- */
- int gpd_2dsite(geosite * gp, geosurf * gs, int do_fast)
- {
- float site[3], konst;
- float size;
- int src, check, marker, color;
- geopoint *gpt;
- typbuff *buf;
- GLdouble modelMatrix[16], projMatrix[16];
- GLint viewport[4];
- GLint window[4];
- if (GS_check_cancel()) {
- return (0);
- }
- if (gs) {
- gs_update_curmask(gs);
- src = gs_get_att_src(gs, ATT_TOPO);
- if (src == CONST_ATT) {
- konst = gs->att[ATT_TOPO].constant;
- site[Z] = konst;
- }
- else {
- buf = gs_get_att_typbuff(gs, ATT_TOPO, 0);
- }
- /* Get viewport parameters for view check */
- gsd_getwindow(window, viewport, modelMatrix, projMatrix);
- gsd_pushmatrix();
- gsd_do_scale(1);
- gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans);
- gsd_linewidth(gp->width);
- check = 0;
- color = gp->color;
- marker = gp->marker;
- size = gp->size;
- for (gpt = gp->points; gpt; gpt = gpt->next) {
- if (!(++check % CHK_FREQ)) {
- if (GS_check_cancel()) {
- gsd_linewidth(1);
- gsd_popmatrix();
- return (0);
- }
- }
- site[X] = gpt->p3[X] + gp->x_trans - gs->ox;
- site[Y] = gpt->p3[Y] + gp->y_trans - gs->oy;
- if (gs_point_is_masked(gs, site)) {
- continue;
- }
- /* TODO: set other dynamic attributes */
- if (gp->attr_mode & ST_ATT_COLOR) {
- color = gpt->iattr;
- }
- if (src == MAP_ATT) {
- if (viewcell_tri_interp(gs, buf, site, 1)) {
- /* returns 0 if outside or masked */
- site[Z] += gp->z_trans;
- if (gsd_checkpoint
- (site, window, viewport, modelMatrix, projMatrix))
- continue;
- else
- /* ACS_MODIFY_OneLine site_attr management - was: gpd_obj(gs, color, size, marker, site); */
- gpd_obj_site_attr(gs, gp, gpt, site);
- }
- }
- else if (src == CONST_ATT) {
- if (gs_point_in_region(gs, site, NULL)) {
- site[Z] += gp->z_trans;
- if (gsd_checkpoint
- (site, window, viewport, modelMatrix, projMatrix))
- continue;
- else
- /* ACS_MODIFY_OneLine site_attr management - was: gpd_obj(NULL, color, size, marker, site); */
- gpd_obj_site_attr(NULL, gp, gpt, site);
- }
- }
- }
- gsd_linewidth(1);
- gsd_popmatrix();
- }
- return (1);
- }
- /*!
- \brief ADD
- \param gp site (geosite)
- \param xo,yo
- \param do_fast (unused)
- \return 0
- \return 1
- */
- int gpd_3dsite(geosite * gp, float xo, float yo, int do_fast)
- {
- float site[3], tz;
- float size;
- int check, color, marker;
- geopoint *gpt;
- GLdouble modelMatrix[16], projMatrix[16];
- GLint viewport[4];
- GLint window[4];
- if (GS_check_cancel()) {
- return (0);
- }
- gsd_getwindow(window, viewport, modelMatrix, projMatrix);
- gsd_pushmatrix();
- gsd_do_scale(1);
- tz = GS_global_exag();
- site[Z] = 0.0;
- check = 0;
- color = gp->color;
- marker = gp->marker;
- size = gp->size;
- gsd_linewidth(gp->width);
- for (gpt = gp->points; gpt; gpt = gpt->next) {
- if (!(++check % CHK_FREQ)) {
- if (GS_check_cancel()) {
- gsd_linewidth(1);
- gsd_popmatrix();
- return (0);
- }
- }
- site[X] = gpt->p3[X] + gp->x_trans - xo;
- site[Y] = gpt->p3[Y] + gp->y_trans - yo;
- if (tz) {
- site[Z] = gpt->p3[Z] + gp->z_trans;
- }
- /* TODO: set other dynamic attributes */
- if (gp->attr_mode & ST_ATT_COLOR) {
- color = gpt->iattr;
- }
- if (gsd_checkpoint(site, window, viewport, modelMatrix, projMatrix))
- continue;
- else
- /* clip points outside default region? */
- /* ACS_MODIFY_OneLine site_attr management - was: gpd_obj(NULL, color, size, marker, site); */
- gpd_obj_site_attr(NULL, gp, gpt, site);
- }
- gsd_linewidth(1);
- gsd_popmatrix();
- return (1);
- }
|