GRASS Programmer's Manual  6.4.2(2012)
gvd.c
Go to the documentation of this file.
00001 
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 
00022 #include <grass/gis.h>
00023 #include <grass/gstypes.h>
00024 
00025 #include "rowcol.h"
00026 
00027 #define CHK_FREQ 5
00028 /* check for cancel every CHK_FREQ lines */
00029 
00043 int gs_clip_segment(geosurf * gs, float *bgn, float *end, float *region)
00044 {
00045     float top, bottom, left, right;
00046 
00047     if (!region) {
00048         top = gs->yrange;
00049         bottom = VROW2Y(gs, VROWS(gs));
00050         left = 0.0;
00051         right = VCOL2X(gs, VCOLS(gs));
00052     }
00053     else {
00054         top = region[0];
00055         bottom = region[1];
00056         left = region[2];
00057         right = region[3];
00058     }
00059 
00060     /* for now, ignore any segments with an end outside */
00061     return (bgn[X] >= left && bgn[X] <= right &&
00062             end[X] >= left && end[X] <= right &&
00063             bgn[Y] >= bottom && bgn[Y] <= top &&
00064             end[Y] >= bottom && end[Y] <= top);
00065 }
00066 
00083 int gvd_vect(geovect * gv, geosurf * gs, int do_fast)
00084 {
00085     int i, j, k;
00086     float bgn[3], end[3], tx, ty, tz, konst;
00087     float zmin, zmax, fudge;
00088     Point3 *points;
00089     int npts, src, check;
00090     geoline *gln;
00091 
00092     G_debug(5, "gvd_vect(): id=%d", gv->gvect_id);
00093 
00094     if (GS_check_cancel()) {
00095         return (0);
00096     }
00097 
00098     gs_update_curmask(gs);
00099 
00100     src = gs_get_att_src(gs, ATT_TOPO);
00101     GS_get_scale(&tx, &ty, &tz, 1);
00102     gs_get_zrange(&zmin, &zmax);
00103     fudge = (zmax - zmin) / 500.;
00104 
00105     if (src == CONST_ATT) {
00106         konst = gs->att[ATT_TOPO].constant;
00107         bgn[Z] = end[Z] = konst;
00108     }
00109 
00110     gsd_pushmatrix();
00111 
00112     /* avoid scaling by zero */
00113     if (tz == 0.0) {
00114         src = CONST_ATT;
00115         konst = 0.0;
00116         bgn[Z] = end[Z] = konst;
00117         gsd_do_scale(0);
00118     }
00119     else {
00120         gsd_do_scale(1);
00121     }
00122 
00123     gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans + fudge);
00124 
00125     gsd_colormode(CM_COLOR);
00126     gsd_color_func(gv->color);
00127     gsd_linewidth(gv->width);
00128 
00129     check = 0;
00130     if (do_fast) {
00131         if (!gv->fastlines) {
00132             gv_decimate_lines(gv);
00133         }
00134 
00135         gln = gv->fastlines;
00136     }
00137     else {
00138         gln = gv->lines;
00139     }
00140 
00141     for (; gln; gln = gln->next) {
00142         G_debug(5, "gvd_vect(): type = %d dims = %d", gln->type, gln->dims);
00143 
00144         if (!(++check % CHK_FREQ)) {
00145             if (GS_check_cancel()) {
00146                 gsd_linewidth(1);
00147                 gsd_popmatrix();
00148 
00149                 return (0);
00150             }
00151         }
00152 
00153         if (gln->type == OGSF_LINE) {   /* line */
00154             if (gln->dims == 2) {       /* 2d line */
00155                 G_debug(5, "gvd_vect(): 2D vector line");
00156                 for (k = 0; k < gln->npts - 1; k++) {
00157                     bgn[X] = gln->p2[k][X] + gv->x_trans - gs->ox;
00158                     bgn[Y] = gln->p2[k][Y] + gv->y_trans - gs->oy;
00159                     end[X] = gln->p2[k + 1][X] + gv->x_trans - gs->ox;
00160                     end[Y] = gln->p2[k + 1][Y] + gv->y_trans - gs->oy;
00161 
00162                     if (src == MAP_ATT) {
00163                         points = gsdrape_get_segments(gs, bgn, end, &npts);
00164                         gsd_bgnline();
00165 
00166                         for (i = 0, j = 0; i < npts; i++) {
00167                             if (gs_point_is_masked(gs, points[i])) {
00168                                 if (j) {
00169                                     gsd_endline();
00170                                     gsd_bgnline();
00171                                     j = 0;
00172                                 }
00173                                 continue;
00174                             }
00175                             points[i][Z] += gv->z_trans;
00176                             gsd_vert_func(points[i]);
00177                             j++;
00178                             if (j > 250) {
00179                                 gsd_endline();
00180                                 gsd_bgnline();
00181                                 gsd_vert_func(points[i]);
00182                                 j = 1;
00183                             }
00184                         }
00185                         gsd_endline();
00186                     }
00187                     /* need to handle MASK! */
00188                     else if (src == CONST_ATT) {
00189                         /* for now - but later, do seg intersect maskedge */
00190                         if (gs_point_is_masked(gs, bgn) ||
00191                             gs_point_is_masked(gs, end))
00192                             continue;
00193 
00194                         if (gs_clip_segment(gs, bgn, end, NULL)) {
00195                             gsd_bgnline();
00196                             gsd_vert_func(bgn);
00197                             gsd_vert_func(end);
00198                             gsd_endline();
00199                         }
00200                     }
00201                 }
00202             }
00203             else {              /* 3D line */
00204 
00205                 G_debug(5, "gvd_vect(): 3D vector line");
00206                 points = (Point3 *) malloc(sizeof(Point3));
00207 
00208                 gsd_color_func(gv->color);
00209                 gsd_bgnline();
00210                 for (k = 0; k < gln->npts; k++) {
00211                     points[0][X] =
00212                         (float)(gln->p3[k][X] + gv->x_trans - gs->ox);
00213                     points[0][Y] =
00214                         (float)(gln->p3[k][Y] + gv->y_trans - gs->oy);
00215                     points[0][Z] = (float)(gln->p3[k][Z] + gv->z_trans);
00216 
00217                     gsd_vert_func(points[0]);
00218                 }
00219                 gsd_endline();
00220                 free(points);
00221             }
00222         }
00223         else if (gln->type == OGSF_POLYGON) {   /* polygon */
00224             if (gln->dims == 3) {       /* 3D polygon */
00225                 G_debug(5, "gvd_vect(): draw 3D polygon");
00226 
00227                 /* We want at least 3 points */
00228                 if (gln->npts >= 3) {
00229                     points = (Point3 *) malloc(2 * sizeof(Point3));
00230                     glEnable(GL_NORMALIZE);
00231 
00232                     glEnable(GL_COLOR_MATERIAL);
00233                     glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
00234 
00235                     glEnable(GL_LIGHTING);
00236                     glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
00237 
00238                     glShadeModel(GL_FLAT);
00239 
00240                     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00241 
00242                     glBegin(GL_POLYGON);
00243                     glColor3f(1.0, 0, 0);
00244                     gsd_color_func(gv->color);
00245                     glNormal3fv(gln->norm);
00246 
00247                     for (k = 0; k < gln->npts; k++) {
00248                         points[0][X] =
00249                             (float)(gln->p3[k][X] + gv->x_trans - gs->ox);
00250                         points[0][Y] =
00251                             (float)(gln->p3[k][Y] + gv->y_trans - gs->oy);
00252                         points[0][Z] = (float)(gln->p3[k][Z] + gv->z_trans);
00253                         glVertex3fv(points[0]);
00254                     }
00255                     glEnd();
00256                     glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
00257                     G_free(points);
00258                 }
00259             }
00260             else {              /* 2D polygons */
00261                 /* TODO */
00262             }
00263         }
00264     }
00265 
00266     gsd_linewidth(1);
00267     gsd_popmatrix();
00268 
00269     return (1);
00270 }
00271 
00280 void gvd_draw_lineonsurf(geosurf * gs, float *bgn, float *end, int color)
00281 {
00282     Point3 *points;
00283     int npts, i, j;
00284 
00285     gsd_color_func(color);
00286     points = gsdrape_get_segments(gs, bgn, end, &npts);
00287     gsd_bgnline();
00288 
00289     for (i = 0, j = 0; i < npts; i++) {
00290         if (gs_point_is_masked(gs, points[i])) {
00291             if (j) {
00292                 gsd_endline();
00293                 gsd_bgnline();
00294                 j = 0;
00295             }
00296 
00297             continue;
00298         }
00299 
00300         gsd_vert_func(points[i]);
00301         j++;
00302 
00303         if (j > 250) {
00304             gsd_endline();
00305             gsd_bgnline();
00306             gsd_vert_func(points[i]);
00307             j = 1;
00308         }
00309     }
00310 
00311     gsd_endline();
00312 
00313     return;
00314 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines