GRASS GIS 8 Programmer's Manual 8.3.2(2024)-exported
Loading...
Searching...
No Matches
gvd.c
Go to the documentation of this file.
1/*!
2 \file lib/ogsf/gvd.c
3
4 \brief OGSF library - loading and manipulating vector sets (lower level
5 functions)
6
7 (C) 1999-2008, 2011 by the GRASS Development Team
8
9 This program is free software under the GNU General Public License
10 (>=v2). Read the file COPYING that comes with GRASS for details.
11
12 \author Bill Brown USACERL (December 1993)
13 \author Doxygenized by Martin Landa (June 2008)
14 */
15
16#include <stdio.h>
17#include <stdlib.h>
18
19#include <grass/gis.h>
20#include <grass/ogsf.h>
21
22#include "rowcol.h"
23
24#define CHK_FREQ 5
25/* check for cancel every CHK_FREQ lines */
26
27/*!
28 \brief Clip segment
29
30 \todo to use fast clipping and move to gs.c
31
32 \param gs surface
33 \param bgn begin point
34 \param end end point
35 \param region region settings
36
37 \return 1 segment inside region
38 \return 0 segment outside region
39 */
40int gs_clip_segment(geosurf *gs, float *bgn, float *end, float *region)
41{
42 float top, bottom, left, right;
43
44 if (!region) {
45 top = gs->yrange;
46 bottom = VROW2Y(gs, VROWS(gs));
47 left = 0.0;
48 right = VCOL2X(gs, VCOLS(gs));
49 }
50 else {
51 top = region[0];
52 bottom = region[1];
53 left = region[2];
54 right = region[3];
55 }
56
57 /* for now, ignore any segments with an end outside */
58 return (bgn[X] >= left && bgn[X] <= right && end[X] >= left &&
59 end[X] <= right && bgn[Y] >= bottom && bgn[Y] <= top &&
60 end[Y] >= bottom && end[Y] <= top);
61}
62
63/*!
64 \brief Draw vector set
65
66 Need to think about translations - If user translates surface,
67 vector should automatically go with it, but translating vector should
68 translate it relative to surface on which it's displayed?
69
70 Handling mask checking here, but may be more appropriate to
71 handle in get_drape_segments?
72
73 \param gv vector set
74 \param gs surface
75 \param do_fast non-zero for fast mode
76
77 \return
78 */
79int gvd_vect(geovect *gv, geosurf *gs, int do_fast)
80{
81 int i, j, k;
82 float bgn[3], end[3], tx, ty, tz, konst;
83 float zmin, zmax, fudge;
84 Point3 *points;
85 int npts, src, check;
86 geoline *gln;
87
88 G_debug(5, "gvd_vect(): id=%d", gv->gvect_id);
89
90 if (GS_check_cancel()) {
91 return 0;
92 }
93
95
96 src = gs_get_att_src(gs, ATT_TOPO);
97 GS_get_scale(&tx, &ty, &tz, 1);
98 gs_get_zrange(&zmin, &zmax);
99 fudge = (zmax - zmin) / 500.;
100
101 if (src == CONST_ATT) {
102 konst = gs->att[ATT_TOPO].constant;
103 bgn[Z] = end[Z] = konst + gv->z_trans;
104 }
105
107
108 /* avoid scaling by zero */
109 if (tz == 0.0) {
110 src = CONST_ATT;
111 konst = 0.0;
112 bgn[Z] = end[Z] = konst;
113 gsd_do_scale(0);
114 }
115 else {
116 gsd_do_scale(1);
117 }
118
119 gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans + fudge);
120
121 gsd_colormode(CM_COLOR);
122
123 check = 0;
124 if (do_fast) {
125 if (!gv->fastlines) {
127 }
128
129 gln = gv->fastlines;
130 }
131 else {
132 gln = gv->lines;
133 }
134
135 for (; gln; gln = gln->next) {
136 G_debug(5, "gvd_vect(): type = %d dims = %d", gln->type, gln->dims);
137
138 if (!(++check % CHK_FREQ)) {
139 if (GS_check_cancel()) {
140 gsd_linewidth(1);
142
143 return 0;
144 }
145 }
146
147 if (gln->highlighted > 0) {
148 gsd_color_func(gv->hstyle->color);
149 gsd_linewidth(gv->hstyle->width);
150 }
151 else if (gv->tstyle && gv->tstyle->active) {
152 gsd_color_func(gln->style->color);
153 gsd_linewidth(gln->style->width);
154 }
155 else {
156 gsd_color_func(gv->style->color);
157 gsd_linewidth(gv->style->width);
158 }
159
160 /* line */
161 if (gln->type == OGSF_LINE) {
162 /* 2D line */
163 if (gln->dims == 2 || !gv->use_z) {
164 G_debug(5, "gvd_vect(): 2D vector line");
165 for (k = 0; k < gln->npts - 1; k++) {
166 if (gln->dims == 3) {
167 bgn[X] = gln->p3[k][X] + gv->x_trans - gs->ox;
168 bgn[Y] = gln->p3[k][Y] + gv->y_trans - gs->oy;
169 end[X] = gln->p3[k + 1][X] + gv->x_trans - gs->ox;
170 end[Y] = gln->p3[k + 1][Y] + gv->y_trans - gs->oy;
171 }
172 else {
173 bgn[X] = gln->p2[k][X] + gv->x_trans - gs->ox;
174 bgn[Y] = gln->p2[k][Y] + gv->y_trans - gs->oy;
175 end[X] = gln->p2[k + 1][X] + gv->x_trans - gs->ox;
176 end[Y] = gln->p2[k + 1][Y] + gv->y_trans - gs->oy;
177 }
178
179 if (src == MAP_ATT) {
180 points = gsdrape_get_segments(gs, bgn, end, &npts);
181 gsd_bgnline();
182
183 for (i = 0, j = 0; i < npts; i++) {
184 if (gs_point_is_masked(gs, points[i])) {
185 if (j) {
186 gsd_endline();
187 gsd_bgnline();
188 j = 0;
189 }
190 continue;
191 }
192 points[i][Z] += gv->z_trans;
193 gsd_vert_func(points[i]);
194 j++;
195 if (j > 250) {
196 gsd_endline();
197 gsd_bgnline();
198 gsd_vert_func(points[i]);
199 j = 1;
200 }
201 }
202 gsd_endline();
203 }
204 /* need to handle MASK! */
205 else if (src == CONST_ATT) {
206 /* for now - but later, do seg intersect maskedge */
207 if (gs_point_is_masked(gs, bgn) ||
208 gs_point_is_masked(gs, end))
209 continue;
210
211 if (gs_clip_segment(gs, bgn, end, NULL)) {
212 gsd_bgnline();
213 gsd_vert_func(bgn);
214 gsd_vert_func(end);
215 gsd_endline();
216 }
217 }
218 }
219 }
220 /* 3D line */
221 else {
222 G_debug(5, "gvd_vect(): 3D vector line");
223 points = (Point3 *)malloc(sizeof(Point3));
224
225 gsd_bgnline();
226 for (k = 0; k < gln->npts; k++) {
227 points[0][X] =
228 (float)(gln->p3[k][X] + gv->x_trans - gs->ox);
229 points[0][Y] =
230 (float)(gln->p3[k][Y] + gv->y_trans - gs->oy);
231 points[0][Z] = (float)(gln->p3[k][Z] + gv->z_trans);
232
233 gsd_vert_func(points[0]);
234 }
235 gsd_endline();
236 free(points);
237 }
238 }
239 /* polygon */
240 else if (gln->type == OGSF_POLYGON) {
241 /* 3D polygon */
242 if (gln->dims == 3) {
243 G_debug(5, "gvd_vect(): draw 3D polygon");
244
245 /* We want at least 3 points */
246 if (gln->npts >= 3) {
247 points = (Point3 *)malloc(2 * sizeof(Point3));
248 glEnable(GL_NORMALIZE);
249
250 glEnable(GL_COLOR_MATERIAL);
251 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
252
253 glEnable(GL_LIGHTING);
254 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
255
256 glShadeModel(GL_FLAT);
257
258 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
259
260 glBegin(GL_POLYGON);
261 glColor3f(1.0, 0, 0);
262 gsd_color_func(gv->style->color);
263 glNormal3fv(gln->norm);
264
265 for (k = 0; k < gln->npts; k++) {
266 points[0][X] =
267 (float)(gln->p3[k][X] + gv->x_trans - gs->ox);
268 points[0][Y] =
269 (float)(gln->p3[k][Y] + gv->y_trans - gs->oy);
270 points[0][Z] = (float)(gln->p3[k][Z] + gv->z_trans);
271 glVertex3fv(points[0]);
272 }
273 glEnd();
274 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
275 G_free(points);
276 }
277 }
278 else {
279 /* 2D polygons */
280 /* TODO */
281 }
282 }
283 }
284
285 gsd_linewidth(1);
287
288 return 1;
289}
290
291/*!
292 \brief Draw line on surface
293
294 \param gs surface
295 \param bgn first line point
296 \param end end line point
297 \param color color value
298 */
299void gvd_draw_lineonsurf(geosurf *gs, float *bgn, float *end, int color)
300{
301 Point3 *points;
302 int npts, i, j;
303
304 gsd_color_func(color);
305 points = gsdrape_get_segments(gs, bgn, end, &npts);
306 gsd_bgnline();
307
308 for (i = 0, j = 0; i < npts; i++) {
309 if (gs_point_is_masked(gs, points[i])) {
310 if (j) {
311 gsd_endline();
312 gsd_bgnline();
313 j = 0;
314 }
315
316 continue;
317 }
318
319 gsd_vert_func(points[i]);
320 j++;
321
322 if (j > 250) {
323 gsd_endline();
324 gsd_bgnline();
325 gsd_vert_func(points[i]);
326 j = 1;
327 }
328 }
329
330 gsd_endline();
331
332 return;
333}
void G_free(void *buf)
Free allocated memory.
Definition alloc.c:150
#define NULL
Definition ccmath.h:32
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition debug.c:66
void GS_get_scale(float *sx, float *sy, float *sz, int doexag)
Get axis scale.
Definition gs2.c:3236
int gs_get_zrange(float *min, float *max)
Get z-range.
Definition gs.c:1086
int gs_point_is_masked(geosurf *gs, float *pt)
Check if point is masked.
Definition gs.c:1314
int gs_get_att_src(geosurf *gs, int desc)
Get attribute source.
Definition gs.c:656
int gs_update_curmask(geosurf *surf)
Update current maps.
Definition gs_bm.c:231
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition gsd_prim.c:511
void gsd_vert_func(float *pt)
ADD.
Definition gsd_prim.c:686
void gsd_colormode(int cm)
Set color mode.
Definition gsd_prim.c:98
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition gsd_prim.c:501
void gsd_endline(void)
End line.
Definition gsd_prim.c:407
void gsd_bgnline(void)
Begin line.
Definition gsd_prim.c:397
void gsd_translate(float dx, float dy, float dz)
Multiply the current matrix by a translation matrix.
Definition gsd_prim.c:539
void gsd_color_func(unsigned int col)
Set current color.
Definition gsd_prim.c:698
void gsd_linewidth(short n)
Set width of rasterized lines.
Definition gsd_prim.c:267
void gsd_do_scale(int doexag)
Set current scale.
Definition gsd_views.c:355
Point3 * gsdrape_get_segments(geosurf *gs, float *bgn, float *end, int *num)
ADD.
Definition gsdrape.c:349
int GS_check_cancel(void)
Check for cancel.
Definition gsx.c:30
int gv_decimate_lines(geovect *gv)
Decimate line.
Definition gv_quick.c:231
#define CHK_FREQ
Definition gvd.c:24
void gvd_draw_lineonsurf(geosurf *gs, float *bgn, float *end, int color)
Draw line on surface.
Definition gvd.c:299
int gvd_vect(geovect *gv, geosurf *gs, int do_fast)
Draw vector set.
Definition gvd.c:79
int gs_clip_segment(geosurf *gs, float *bgn, float *end, float *region)
Clip segment.
Definition gvd.c:40
#define VCOL2X(gs, vcol)
Definition rowcol.h:40
#define VCOLS(gs)
Definition rowcol.h:14
#define VROWS(gs)
Definition rowcol.h:13
#define VROW2Y(gs, vrow)
Definition rowcol.h:39
#define X(j)
#define Y(j)