Loading...
Searching...
No Matches
gvd.c
Go to the documentation of this file.
/*!
\file lib/ogsf/gvd.c
\brief OGSF library - loading and manipulating vector sets (lower level
functions)
(C) 1999-2008, 2011 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 (December 1993)
\author Doxygenized by Martin Landa (June 2008)
*/
#include <stdio.h>
#include <stdlib.h>
#include <grass/gis.h>
#include <grass/ogsf.h>
#include "rowcol.h"
#define CHK_FREQ 5
/* check for cancel every CHK_FREQ lines */
/*!
\brief Clip segment
\todo to use fast clipping and move to gs.c
\param gs surface
\param bgn begin point
\param end end point
\param region region settings
\return 1 segment inside region
\return 0 segment outside region
*/
int gs_clip_segment(geosurf *gs, float *bgn, float *end, 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];
}
/* for now, ignore any segments with an end outside */
return (bgn[X] >= left && bgn[X] <= right && end[X] >= left &&
end[X] <= right && bgn[Y] >= bottom && bgn[Y] <= top &&
end[Y] >= bottom && end[Y] <= top);
}
/*!
\brief Draw vector set
Need to think about translations - If user translates surface,
vector should automatically go with it, but translating vector should
translate it relative to surface on which it's displayed?
Handling mask checking here, but may be more appropriate to
handle in get_drape_segments?
\param gv vector set
\param gs surface
\param do_fast non-zero for fast mode
\return
*/
int gvd_vect(geovect *gv, geosurf *gs, int do_fast)
{
int i, j, k;
float bgn[3], end[3], tx, ty, tz, konst;
float zmin, zmax, fudge;
Point3 *points;
int npts, src, check;
geoline *gln;
G_debug(5, "gvd_vect(): id=%d", gv->gvect_id);
if (GS_check_cancel()) {
return 0;
}
gs_update_curmask(gs);
src = gs_get_att_src(gs, ATT_TOPO);
GS_get_scale(&tx, &ty, &tz, 1);
gs_get_zrange(&zmin, &zmax);
fudge = (zmax - zmin) / 500.;
if (src == CONST_ATT) {
konst = gs->att[ATT_TOPO].constant;
bgn[Z] = end[Z] = konst + gv->z_trans;
}
gsd_pushmatrix();
/* avoid scaling by zero */
if (tz == 0.0) {
src = CONST_ATT;
konst = 0.0;
bgn[Z] = end[Z] = konst;
gsd_do_scale(0);
}
else {
gsd_do_scale(1);
}
gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans + fudge);
gsd_colormode(CM_COLOR);
check = 0;
if (do_fast) {
if (!gv->fastlines) {
gv_decimate_lines(gv);
}
gln = gv->fastlines;
}
else {
gln = gv->lines;
}
for (; gln; gln = gln->next) {
G_debug(5, "gvd_vect(): type = %d dims = %d", gln->type, gln->dims);
if (!(++check % CHK_FREQ)) {
if (GS_check_cancel()) {
gsd_linewidth(1);
gsd_popmatrix();
return 0;
}
}
if (gln->highlighted > 0) {
gsd_color_func(gv->hstyle->color);
gsd_linewidth(gv->hstyle->width);
}
else if (gv->tstyle && gv->tstyle->active) {
gsd_color_func(gln->style->color);
gsd_linewidth(gln->style->width);
}
else {
gsd_color_func(gv->style->color);
gsd_linewidth(gv->style->width);
}
/* line */
if (gln->type == OGSF_LINE) {
/* 2D line */
if (gln->dims == 2 || !gv->use_z) {
G_debug(5, "gvd_vect(): 2D vector line");
for (k = 0; k < gln->npts - 1; k++) {
if (gln->dims == 3) {
bgn[X] = gln->p3[k][X] + gv->x_trans - gs->ox;
bgn[Y] = gln->p3[k][Y] + gv->y_trans - gs->oy;
end[X] = gln->p3[k + 1][X] + gv->x_trans - gs->ox;
end[Y] = gln->p3[k + 1][Y] + gv->y_trans - gs->oy;
}
else {
bgn[X] = gln->p2[k][X] + gv->x_trans - gs->ox;
bgn[Y] = gln->p2[k][Y] + gv->y_trans - gs->oy;
end[X] = gln->p2[k + 1][X] + gv->x_trans - gs->ox;
end[Y] = gln->p2[k + 1][Y] + gv->y_trans - gs->oy;
}
if (src == MAP_ATT) {
points = gsdrape_get_segments(gs, bgn, end, &npts);
gsd_bgnline();
for (i = 0, j = 0; i < npts; i++) {
if (gs_point_is_masked(gs, points[i])) {
if (j) {
gsd_endline();
gsd_bgnline();
j = 0;
}
continue;
}
points[i][Z] += gv->z_trans;
gsd_vert_func(points[i]);
j++;
if (j > 250) {
gsd_endline();
gsd_bgnline();
gsd_vert_func(points[i]);
j = 1;
}
}
gsd_endline();
}
/* need to handle mask! */
else if (src == CONST_ATT) {
/* for now - but later, do seg intersect maskedge */
if (gs_point_is_masked(gs, bgn) ||
gs_point_is_masked(gs, end))
continue;
if (gs_clip_segment(gs, bgn, end, NULL)) {
gsd_bgnline();
gsd_vert_func(bgn);
gsd_vert_func(end);
gsd_endline();
}
}
}
}
/* 3D line */
else {
G_debug(5, "gvd_vect(): 3D vector line");
points = (Point3 *)malloc(sizeof(Point3));
gsd_bgnline();
for (k = 0; k < gln->npts; k++) {
points[0][X] =
(float)(gln->p3[k][X] + gv->x_trans - gs->ox);
points[0][Y] =
(float)(gln->p3[k][Y] + gv->y_trans - gs->oy);
points[0][Z] = (float)(gln->p3[k][Z] + gv->z_trans);
gsd_vert_func(points[0]);
}
gsd_endline();
free(points);
}
}
/* polygon */
else if (gln->type == OGSF_POLYGON) {
/* 3D polygon */
if (gln->dims == 3) {
G_debug(5, "gvd_vect(): draw 3D polygon");
/* We want at least 3 points */
if (gln->npts >= 3) {
points = (Point3 *)malloc(2 * sizeof(Point3));
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
glEnable(GL_LIGHTING);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glShadeModel(GL_FLAT);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBegin(GL_POLYGON);
glColor3f(1.0, 0, 0);
gsd_color_func(gv->style->color);
glNormal3fv(gln->norm);
for (k = 0; k < gln->npts; k++) {
points[0][X] =
(float)(gln->p3[k][X] + gv->x_trans - gs->ox);
points[0][Y] =
(float)(gln->p3[k][Y] + gv->y_trans - gs->oy);
points[0][Z] = (float)(gln->p3[k][Z] + gv->z_trans);
glVertex3fv(points[0]);
}
glEnd();
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
G_free(points);
}
}
else {
/* 2D polygons */
/* TODO */
}
}
}
gsd_linewidth(1);
gsd_popmatrix();
return 1;
}
/*!
\brief Draw line on surface
\param gs surface
\param bgn first line point
\param end end line point
\param color color value
*/
void gvd_draw_lineonsurf(geosurf *gs, float *bgn, float *end, int color)
{
Point3 *points;
int npts, i, j;
gsd_color_func(color);
points = gsdrape_get_segments(gs, bgn, end, &npts);
gsd_bgnline();
for (i = 0, j = 0; i < npts; i++) {
if (gs_point_is_masked(gs, points[i])) {
if (j) {
gsd_endline();
gsd_bgnline();
j = 0;
}
continue;
}
gsd_vert_func(points[i]);
j++;
if (j > 250) {
gsd_endline();
gsd_bgnline();
gsd_vert_func(points[i]);
j = 1;
}
}
gsd_endline();
return;
}
G_free
void G_free(void *buf)
Free allocated memory.
Definition alloc.c:147
NULL
#define NULL
Definition ccmath.h:32
G_debug
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition debug.c:66
CHK_FREQ
#define CHK_FREQ
Definition gpd.c:22
GS_get_scale
void GS_get_scale(float *sx, float *sy, float *sz, int doexag)
Get axis scale.
Definition gs2.c:3239
gs_get_zrange
int gs_get_zrange(float *min, float *max)
Get z-range.
Definition gs.c:1086
gs_point_is_masked
int gs_point_is_masked(geosurf *gs, float *pt)
Check if point is masked.
Definition gs.c:1314
gs_get_att_src
int gs_get_att_src(geosurf *gs, int desc)
Get attribute source.
Definition gs.c:656
gs_update_curmask
int gs_update_curmask(geosurf *surf)
Update current maps.
Definition gs_bm.c:228
gsd_pushmatrix
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition gsd_prim.c:511
gsd_vert_func
void gsd_vert_func(float *pt)
ADD.
Definition gsd_prim.c:686
gsd_colormode
void gsd_colormode(int cm)
Set color mode.
Definition gsd_prim.c:98
gsd_popmatrix
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition gsd_prim.c:501
gsd_endline
void gsd_endline(void)
End line.
Definition gsd_prim.c:407
gsd_bgnline
void gsd_bgnline(void)
Begin line.
Definition gsd_prim.c:397
gsd_translate
void gsd_translate(float dx, float dy, float dz)
Multiply the current matrix by a translation matrix.
Definition gsd_prim.c:539
gsd_color_func
void gsd_color_func(unsigned int col)
Set current color.
Definition gsd_prim.c:698
gsd_linewidth
void gsd_linewidth(short n)
Set width of rasterized lines.
Definition gsd_prim.c:267
gsd_do_scale
void gsd_do_scale(int doexag)
Set current scale.
Definition gsd_views.c:355
gsdrape_get_segments
Point3 * gsdrape_get_segments(geosurf *gs, float *bgn, float *end, int *num)
ADD.
Definition gsdrape.c:350
GS_check_cancel
int GS_check_cancel(void)
Check for cancel.
Definition gsx.c:30
gv_decimate_lines
int gv_decimate_lines(geovect *gv)
Decimate line.
Definition gv_quick.c:231
gvd_draw_lineonsurf
void gvd_draw_lineonsurf(geosurf *gs, float *bgn, float *end, int color)
Draw line on surface.
Definition gvd.c:299
gvd_vect
int gvd_vect(geovect *gv, geosurf *gs, int do_fast)
Draw vector set.
Definition gvd.c:79
gs_clip_segment
int gs_clip_segment(geosurf *gs, float *bgn, float *end, float *region)
Clip segment.
Definition gvd.c:40
rowcol.h
VCOL2X
#define VCOL2X(gs, vcol)
Definition rowcol.h:40
VCOLS
#define VCOLS(gs)
Definition rowcol.h:14
VROWS
#define VROWS(gs)
Definition rowcol.h:13
VROW2Y
#define VROW2Y(gs, vrow)
Definition rowcol.h:39
X
#define X(j)
Y
#define Y(j)