GRASS Programmer's Manual  6.4.2(2012)
gs.c
Go to the documentation of this file.
00001 
00019 #include <stdlib.h>
00020 #include <stdio.h>
00021 
00022 #include <grass/gstypes.h>
00023 #include <grass/glocale.h>
00024 
00025 #include "gsget.h"
00026 #include "rowcol.h"
00027 
00028 #define FIRST_SURF_ID 110658
00029 
00030 static geosurf *Surf_top;
00031 static int Invertmask;
00032 
00033 /***********************************************************************/
00034 void gs_err(const char *msg)
00035 {
00036     G_warning("%s", msg);
00037 
00038     return;
00039 }
00040 
00047 void gs_init(void)
00048 {
00049     Surf_top = NULL;
00050 
00051     return;
00052 }
00053 
00062 geosurf *gs_get_surf(int id)
00063 {
00064     geosurf *gs;
00065 
00066     G_debug(5, "gs_get_surf():");
00067 
00068     for (gs = Surf_top; gs; gs = gs->next) {
00069         if (gs->gsurf_id == id) {
00070             G_debug(5, "  id=%d", id);
00071             return (gs);
00072         }
00073     }
00074 
00075     return (NULL);
00076 }
00077 
00086 geosurf *gs_get_prev_surface(int id)
00087 {
00088     geosurf *ps;
00089 
00090     G_debug(5, "gs_get_prev_surface");
00091 
00092     for (ps = Surf_top; ps; ps = ps->next) {
00093         if (ps->gsurf_id == id - 1) {
00094             return (ps);
00095         }
00096     }
00097 
00098     return (NULL);
00099 }
00100 
00108 int gs_getall_surfaces(geosurf ** gsurfs)
00109 {
00110     geosurf *gs;
00111     int i;
00112 
00113     for (i = 0, gs = Surf_top; gs; gs = gs->next, i++) {
00114         gsurfs[i] = gs;
00115     }
00116 
00117     G_debug(5, "gs_num_surfaces(): num=%d", i);
00118 
00119     return (i);
00120 }
00121 
00127 int gs_num_surfaces(void)
00128 {
00129     geosurf *gs;
00130     int i;
00131 
00132     for (i = 0, gs = Surf_top; gs; gs = gs->next, i++) ;
00133 
00134     G_debug(5, "gs_num_surfaces(): num=%d", i);
00135 
00136     return (i);
00137 }
00138 
00139 
00149 int gs_att_is_set(geosurf * surf, IFLAG att)
00150 {
00151     geosurf *gs;
00152 
00153     if (surf) {
00154         return (NOTSET_ATT != surf->att[att].att_src);
00155     }
00156 
00157     /* if surf == NULL, look at all surfs */
00158     for (gs = Surf_top; gs; gs = gs->next) {
00159         if (NOTSET_ATT != gs->att[att].att_src) {
00160             return (1);
00161         }
00162     }
00163 
00164     return (0);
00165 }
00166 
00172 geosurf *gs_get_last_surface(void)
00173 {
00174     geosurf *ls;
00175 
00176     if (!Surf_top) {
00177         return (NULL);
00178     }
00179 
00180     for (ls = Surf_top; ls->next; ls = ls->next) ;
00181 
00182     G_debug(5, "gs_get_last_surface(): last surface id=%d", ls->gsurf_id);
00183 
00184     return (ls);
00185 }
00186 
00187 
00193 geosurf *gs_get_new_surface(void)
00194 {
00195     geosurf *ns, *ls;
00196 
00197     ns = (geosurf *) G_malloc(sizeof(geosurf)); /* G_fatal_error */
00198     if (!ns) {
00199         return (NULL);
00200     }
00201 
00202     if ((ls = gs_get_last_surface())) {
00203         ls->next = ns;
00204         ns->gsurf_id = ls->gsurf_id + 1;
00205     }
00206     else {
00207         Surf_top = ns;
00208         ns->gsurf_id = FIRST_SURF_ID;
00209     }
00210 
00211     ns->next = NULL;
00212 
00213     G_debug(5, "gs_get_new_surface(): id=%d", ns->gsurf_id);
00214 
00215     return (ns);
00216 }
00217 
00232 int gs_init_surf(geosurf * gs, double ox, double oy, int rows, int cols,
00233                  double xres, double yres)
00234 {
00235     geosurf *ps;
00236     int i;
00237 
00238     if (!gs) {
00239         return (-1);
00240     }
00241 
00242     G_debug(5, "gs_init_surf() id=%d", gs->gsurf_id);
00243 
00244     /* default attributes */
00245     for (i = 0; i < MAX_ATTS; i++) {
00246         gs->att[i].att_src = NOTSET_ATT;
00247         gs->att[i].att_type = ATTY_INT;
00248         gs->att[i].hdata = -1;
00249         gs->att[i].user_func = NULL;
00250         gs->att[i].constant = 0.;
00251         gs->att[i].lookup = NULL;
00252         gs->att[i].min_nz = gs->att[i].max_nz = gs->att[i].range_nz = 0;
00253         gs->att[i].default_null = 0.;
00254     }
00255 
00256     /* default values */
00257     gs->ox = ox;
00258     gs->oy = oy;
00259     gs->rows = rows;
00260     gs->cols = cols;
00261     gs->xres = xres;
00262     gs->yres = yres;
00263     gs->x_mod = 2;
00264     gs->y_mod = 2;
00265     gs->x_modw = rows / 30;
00266     gs->y_modw = rows / 30;
00267     gs->xmin = ox;
00268     gs->xmax = ox + (cols - 1) * xres;
00269     gs->xrange = gs->xmax - gs->xmin;
00270     gs->ymin = oy;
00271     gs->ymax = oy + (rows - 1) * yres;
00272     gs->yrange = gs->ymax - gs->ymin;
00273     gs->zmin = gs->zmin_nz = gs->zminmasked = 0;
00274     gs->zmax = gs->zmax_nz = 0;
00275     gs->zrange = gs->zrange_nz = 0;
00276     gs->wire_color = 0x00888888;
00277     gs->x_trans = gs->y_trans = gs->z_trans = 0.0;
00278     gs->nz_topo = gs->nz_color = 0;
00279     gs->norm_needupdate = 1;
00280     gs->mask_needupdate = 1;
00281     gs->curmask = NULL;
00282     gs->norms = NULL;
00283 
00284     gs->draw_mode = DM_GOURAUD;
00285 
00286     /* default z_exag value */
00287     if (gs->gsurf_id == FIRST_SURF_ID) {
00288         gs->z_exag = 1.0;
00289     }
00290     else {
00291         ps = gs_get_prev_surface(gs->gsurf_id);
00292         gs->z_exag = ps->z_exag;
00293     }
00294 
00295     return (0);
00296 }
00297 
00306 int gs_init_normbuff(geosurf * gs)
00307 {
00308     long size;
00309 
00310     if (!gs) {
00311         return (0);
00312     }
00313 
00314     if (gs->norms) {
00315         G_free(gs->norms);
00316     }
00317 
00318     size = gs->rows * gs->cols * sizeof(unsigned long);
00319 
00320     gs->norms = (unsigned long *)G_malloc(size);        /* G_fatal_error */
00321     if (!gs->norms) {
00322         return (-1);
00323     }
00324 
00325     gs->norm_needupdate = 1;
00326 
00327     return (1);
00328 }
00329 
00337 void print_frto(float (*ft)[4])
00338 {
00339     fprintf(stderr, "FROM: %f, %f, %f\n", ft[FROM][X], ft[FROM][Y],
00340             ft[FROM][Z]);
00341     fprintf(stderr, "TO: %f, %f, %f\n", ft[TO][X], ft[TO][Y], ft[TO][Z]);
00342 
00343     return;
00344 }
00345 
00353 void print_realto(float *rt)
00354 {
00355     fprintf(stderr, "REAL TO: %f, %f, %f\n", rt[X], rt[Y], rt[Z]);
00356 
00357     return;
00358 }
00359 
00367 void print_256lookup(int *buff)
00368 {
00369     int i;
00370 
00371     for (i = 0; i < 256; i++) {
00372         if (!(i % 8)) {
00373             fprintf(stderr, "\n");
00374         }
00375 
00376         fprintf(stderr, "%x ", buff[i]);
00377     }
00378 
00379     fprintf(stderr, "\n");
00380 
00381     return;
00382 }
00383 
00391 void print_surf_fields(geosurf * s)
00392 {
00393     fprintf(stderr, "ID: %d\n", s->gsurf_id);
00394     fprintf(stderr, "rows: %d cols: %d\n", s->rows, s->cols);
00395     fprintf(stderr, "draw_mode: %x\n", s->draw_mode);
00396     fprintf(stderr, "wire_color: %lx\n", s->wire_color);
00397     fprintf(stderr, "ox: %lf oy: %lf\n", s->ox, s->oy);
00398     fprintf(stderr, "xres: %lf yres: %lf\n", s->xres, s->yres);
00399     fprintf(stderr, "z_exag: %f \n", s->z_exag);
00400     fprintf(stderr, "x_trans: %f y_trans: %f z_trans: %f\n",
00401             s->x_trans, s->y_trans, s->z_trans);
00402     fprintf(stderr, "xmin: %f ymin: %f zmin: %f\n",
00403             s->xmin, s->ymin, s->zmin);
00404     fprintf(stderr, "xmax: %f ymax: %f zmax: %f\n",
00405             s->xmax, s->ymax, s->zmax);
00406     fprintf(stderr, "x_mod: %d y_mod: %d x_modw: %d y_modw: %d\n",
00407             s->x_mod, s->y_mod, s->x_modw, s->y_modw);
00408 
00409     return;
00410 }
00411 
00419 void print_view_fields(geoview * gv)
00420 {
00421     fprintf(stderr, "coord_sys: %d\n", gv->coord_sys);
00422     fprintf(stderr, "view_proj: %d\n", gv->view_proj);
00423     fprintf(stderr, "infocus: %d\n", gv->infocus);
00424     print_frto(gv->from_to);
00425     fprintf(stderr, "twist: %d fov: %d\n", gv->twist, gv->fov);
00426     fprintf(stderr, "incl: %d look: %d\n", gv->incl, gv->look);
00427     fprintf(stderr, "real_to: %f %f %f\n",
00428             gv->real_to[X], gv->real_to[Y], gv->real_to[Z]);
00429     fprintf(stderr, "vert_exag: %f scale: %f \n", gv->vert_exag, gv->scale);
00430 
00431     return;
00432 }
00433 
00441 void gs_set_defaults(geosurf * gs, float *defs, float *null_defs)
00442 {
00443     int i;
00444 
00445     G_debug(5, "gs_set_defaults(): id=%d", gs->gsurf_id);
00446 
00447     for (i = 0; i < MAX_ATTS; i++) {
00448         gs->att[i].constant = defs[i];
00449         gs->att[i].default_null = null_defs[i];
00450         gs->att[i].lookup = NULL;
00451         gs->att[i].hdata = -1;
00452         gs->att[i].att_src = NOTSET_ATT;
00453     }
00454 
00455     return;
00456 }
00457 
00463 void gs_delete_surf(int id)
00464 {
00465     geosurf *fs;
00466 
00467     G_debug(5, "gs_delete_surf");
00468 
00469     fs = gs_get_surf(id);
00470 
00471     if (fs) {
00472         gs_free_surf(fs);
00473     }
00474 
00475     return;
00476 }
00477 
00487 int gs_free_surf(geosurf * fs)
00488 {
00489     geosurf *gs;
00490     int found = 0;
00491 
00492     G_debug(5, "gs_free_surf");
00493 
00494     if (Surf_top) {
00495         if (fs == Surf_top) {
00496             if (Surf_top->next) {
00497                 /* can't free top if last */
00498                 found = 1;
00499                 Surf_top = fs->next;
00500             }
00501             else {
00502                 gs_free_unshared_buffs(fs);
00503 
00504                 if (fs->curmask) {
00505                     G_free(fs->curmask);
00506                 }
00507 
00508                 if (fs->norms) {
00509                     G_free(fs->norms);
00510                 }
00511 
00512                 G_free(fs);
00513                 Surf_top = NULL;
00514             }
00515         }
00516         else {
00517             for (gs = Surf_top; gs && !found; gs = gs->next) {
00518                 if (gs->next) {
00519                     if (gs->next == fs) {
00520                         found = 1;
00521                         gs->next = fs->next;
00522                     }
00523                 }
00524             }
00525         }
00526 
00527         if (found) {
00528             gs_free_unshared_buffs(fs);
00529 
00530             if (fs->curmask) {
00531                 G_free(fs->curmask);
00532             }
00533 
00534             if (fs->norms) {
00535                 G_free(fs->norms);
00536             }
00537 
00538             G_free(fs);
00539             fs = NULL;
00540         }
00541 
00542         return (found);
00543     }
00544 
00545     return (-1);
00546 }
00547 
00557 void gs_free_unshared_buffs(geosurf * fs)
00558 {
00559     geosurf *gs;
00560     int i, j, same;
00561     int old_datah;
00562 
00563     G_debug(5, "gs_free_unshared_buffs");
00564 
00565     /* for each attribute 
00566        if !same, free buff   
00567      */
00568     for (i = 0; i < MAX_ATTS; i++) {
00569         same = 0;
00570 
00571         if (0 < (old_datah = fs->att[i].hdata)) {
00572             /* for ea att of all other surfs */
00573             for (gs = Surf_top; gs; gs = gs->next) {
00574                 for (j = 0; j < MAX_ATTS; j++) {
00575                     if (old_datah == gs->att[j].hdata) {
00576                         same = 1;
00577                     }
00578                 }
00579             }
00580 
00581             if (!same) {
00582                 gsds_free_datah(old_datah);
00583             }
00584         }
00585     }
00586 
00587     return;
00588 }
00589 
00597 int gs_num_datah_reused(int dh)
00598 {
00599     geosurf *gs;
00600     int ref, j;
00601 
00602     G_debug(5, "gs_num_datah_reused");
00603 
00604     /* for each attribute 
00605        if same, ++reference
00606      */
00607     /* for ea att of all surfs */
00608     ref = 0;
00609 
00610     for (gs = Surf_top; gs; gs = gs->next) {
00611         for (j = 0; j < MAX_ATTS; j++) {
00612             if (dh == gs->att[j].hdata) {
00613                 ref++;
00614             }
00615         }
00616     }
00617 
00618     return (ref);
00619 }
00620 
00630 int gs_get_att_type(geosurf * gs, int desc)
00631 {
00632     G_debug(5, "gs_get_att_type");
00633 
00634     if (!LEGAL_ATT(desc)) {
00635         return (-1);
00636     }
00637 
00638     if (gs) {
00639         if (gs->att[desc].att_src != NOTSET_ATT) {
00640             return (gs->att[desc].att_type);
00641         }
00642     }
00643 
00644     return (-1);
00645 }
00646 
00656 int gs_get_att_src(geosurf * gs, int desc)
00657 {
00658     if (gs)
00659         G_debug(5, "gs_get_att_src(): id=%d, desc=%d", gs->gsurf_id, desc);
00660     if (!LEGAL_ATT(desc)) {
00661         return (-1);
00662     }
00663 
00664     if (gs) {
00665         return (gs->att[desc].att_src);
00666     }
00667 
00668     return (-1);
00669 }
00670 
00681 typbuff *gs_get_att_typbuff(geosurf * gs, int desc, int to_write)
00682 {
00683     typbuff *tb;
00684     geosurf *gsref;
00685 
00686     if (gs) {
00687         G_debug(5, "gs_get_att_typbuff(): id=%d desc=%d to_write=%d",
00688                 gs->gsurf_id, desc, to_write);
00689         if ((tb = gsds_get_typbuff(gs->att[desc].hdata, to_write))) {
00690             tb->tfunc = NULL;
00691 
00692             if (desc == ATT_TOPO) {
00693                 gsref = gsdiff_get_SDref();
00694 
00695                 if (gsref && gsref != gs) {
00696                     tb->tfunc = gsdiff_do_SD;
00697                 }
00698             }
00699 
00700             return (tb);
00701         }
00702     }
00703 
00704     return (NULL);
00705 }
00706 
00717 int gs_malloc_att_buff(geosurf * gs, int desc, int type)
00718 {
00719     int hdata, dims[2], ndims;
00720 
00721     G_debug(5, "gs_malloc_att_buff");
00722 
00723     if (gs) {
00724         if (0 < (hdata = gs->att[desc].hdata)) {
00725             dims[0] = gs->rows;
00726             dims[1] = gs->cols;
00727             ndims = 2;
00728             gs_set_att_type(gs, desc, type);
00729 
00730             return (gsds_alloc_typbuff(hdata, dims, ndims, type));
00731         }
00732     }
00733 
00734     return (-1);
00735 }
00736 
00746 int gs_malloc_lookup(geosurf * gs, int desc)
00747 {
00748     int size;
00749 
00750     G_debug(5, "gs_malloc_lookup");
00751 
00752     if (gs) {
00753         if (gs->att[desc].lookup) {
00754             G_free(gs->att[desc].lookup);
00755             gs->att[desc].lookup = NULL;
00756         }
00757 
00758         switch (gs->att[desc].att_type) {
00759         case (ATTY_SHORT):
00760             size = 32768 * sizeof(int);
00761 
00762             /* positive integers only, because use as array index */
00763             gs->att[desc].lookup = (int *)G_malloc(size);       /* G_fatal_error */
00764             if (!gs->att[desc].lookup) {
00765                 return (-1);
00766             }
00767 
00768             break;
00769         case (ATTY_CHAR):
00770             size = 256 * sizeof(int);
00771 
00772             /* unsigned char */
00773             gs->att[desc].lookup = (int *)G_malloc(size);
00774             if (!gs->att[desc].lookup) {
00775                 return (-1);
00776             }
00777 
00778             break;
00779         default:
00780             G_warning("bad type: gs_malloc_lookup");
00781             return (-1);
00782         }
00783 
00784         if (gs->att[desc].lookup) {
00785             return (0);
00786         }
00787 
00788     }
00789 
00790     return (-1);
00791 }
00792 
00803 int gs_set_att_type(geosurf * gs, int desc, int type)
00804 {
00805 
00806     G_debug(5, "gs_set_att_type(): desc=%d, type=%d", desc, type);
00807 
00808     if (gs && LEGAL_TYPE(type)) {
00809         gs->att[desc].att_type = type;
00810 
00811         return (0);
00812     }
00813 
00814     return (-1);
00815 }
00816 
00827 int gs_set_att_src(geosurf * gs, int desc, int src)
00828 {
00829     if (gs)
00830         G_debug(5, "gs_set_att_src(): id=%d desc=%d src=%d",
00831                 gs->gsurf_id, desc, src);
00832 
00833     /* check if old source was MAP_ATT, free buff */
00834     if (MAP_ATT == gs_get_att_src(gs, desc)) {
00835         if (1 == gs_num_datah_reused(gs->att[desc].hdata)) {
00836             /* only reference */
00837             G_debug(5, "gs_set_att_src(): replacing existing map");
00838             gsds_free_datah(gs->att[desc].hdata);
00839         }
00840 
00841         if (ATT_TOPO == desc) {
00842             if (gs->norms) {
00843                 G_free(gs->norms);
00844             }
00845 
00846             gs->norms = NULL;
00847             gs->norm_needupdate = 0;
00848         }
00849     }
00850 
00851     if (gs && LEGAL_SRC(src)) {
00852         gs->att[desc].att_src = src;
00853 
00854         return (0);
00855     }
00856 
00857     return (-1);
00858 }
00859 
00872 int gs_set_att_const(geosurf * gs, int desc, float constant)
00873 {
00874 
00875     if (gs) {
00876         G_debug(5, "gs_set_att_const(): id=%d, desc=%d, const=%f",
00877                 gs->gsurf_id, desc, constant);
00878         gs->att[desc].constant = constant;
00879 
00880         if (ATT_MASK == desc) {
00881             gs->mask_needupdate = 1;
00882         }
00883         else {
00884             gs_set_att_src(gs, desc, CONST_ATT);
00885         }
00886 
00887         Gs_update_attrange(gs, desc);
00888 
00889         return (0);
00890     }
00891 
00892     return (-1);
00893 }
00894 
00900 void gs_set_maskmode(int invert)
00901 {
00902     Invertmask = invert;
00903 
00904     return;
00905 }
00906 
00915 int gs_mask_defined(geosurf * gs)
00916 {
00917     return (gs->att[ATT_MASK].att_src != NOTSET_ATT);
00918 }
00919 
00933 int gs_masked(typbuff * tb, int col, int row, int offset)
00934 {
00935     int ret;
00936 
00937     ret = 1;
00938 
00939     if (tb->bm) {
00940         ret = BM_get(tb->bm, col, row);
00941     }
00942     else if (tb->cb) {
00943         ret = tb->cb[offset];
00944     }
00945     else if (tb->sb) {
00946         ret = tb->sb[offset];
00947     }
00948     else if (tb->ib) {
00949         ret = tb->ib[offset];
00950     }
00951     else if (tb->fb) {
00952         ret = tb->fb[offset];
00953     }
00954 
00955     return (Invertmask ? ret : !ret);
00956 }
00957 
00969 int gs_mapcolor(typbuff * cobuff, gsurf_att * coloratt, int offset)
00970 {
00971     if (coloratt->lookup) {
00972         /* for now, but may add larger color lookup capabilities later,
00973            so would have to use GET_MAPATT */
00974         return (coloratt->lookup[cobuff->cb[offset]]);
00975     }
00976 
00977     return (cobuff->ib[offset]);
00978 }
00979 
00980 /*
00981    In the following functions, "extents" refers to translated extents for 
00982    a single surface, while "range" refers to accumulated extents of all
00983    loaded surfaces
00984  */
00985 
00998 int gs_get_zextents(geosurf * gs, float *min, float *max, float *mid)
00999 {
01000     *min = gs->zmin + gs->z_trans;
01001     *max = gs->zmax + gs->z_trans;
01002     *mid = (*max + *min) / 2.;
01003 
01004     return (1);
01005 }
01006 
01016 int gs_get_xextents(geosurf * gs, float *min, float *max)
01017 {
01018     *min = gs->xmin + gs->x_trans;
01019     *max = gs->xmax + gs->x_trans;
01020 
01021     return (1);
01022 }
01023 
01033 int gs_get_yextents(geosurf * gs, float *min, float *max)
01034 {
01035     *min = gs->ymin + gs->y_trans;
01036     *max = gs->ymax + gs->y_trans;
01037 
01038     return (1);
01039 }
01040 
01041 
01054 int gs_get_zrange0(float *min, float *max)
01055 {
01056     geosurf *gs;
01057 
01058     if (Surf_top) {
01059         *min = Surf_top->zmin;
01060         *max = Surf_top->zmax;
01061     }
01062     else {
01063         return (-1);
01064     }
01065 
01066     for (gs = Surf_top->next; gs; gs = gs->next) {
01067         if (gs->zmin < *min) {
01068             *min = gs->zmin;
01069         }
01070 
01071         if (gs->zmax > *max) {
01072             *max = gs->zmax;
01073         }
01074     }
01075 
01076     return (1);
01077 }
01078 
01088 int gs_get_zrange(float *min, float *max)
01089 {
01090     geosurf *gs;
01091     float tmin, tmax, tmid;
01092 
01093     if (Surf_top) {
01094         gs_get_zextents(Surf_top, &tmin, &tmax, &tmid);
01095         *min = tmin;
01096         *max = tmax;
01097     }
01098     else {
01099         return (-1);
01100     }
01101 
01102     for (gs = Surf_top->next; gs; gs = gs->next) {
01103         gs_get_zextents(gs, &tmin, &tmax, &tmid);
01104 
01105         if (tmin < *min) {
01106             *min = tmin;
01107         }
01108 
01109         if (tmax > *max) {
01110             *max = tmax;
01111         }
01112     }
01113 
01114     return (1);
01115 }
01116 
01126 int gs_get_xrange(float *min, float *max)
01127 {
01128     geosurf *gs;
01129     float tmin, tmax;
01130 
01131     if (Surf_top) {
01132         gs_get_xextents(Surf_top, &tmin, &tmax);
01133         *min = tmin;
01134         *max = tmax;
01135     }
01136     else {
01137         return (-1);
01138     }
01139 
01140     for (gs = Surf_top->next; gs; gs = gs->next) {
01141         gs_get_xextents(gs, &tmin, &tmax);
01142 
01143         if (tmin < *min) {
01144             *min = tmin;
01145         }
01146 
01147         if (tmax > *max) {
01148             *max = tmax;
01149         }
01150     }
01151 
01152     return (1);
01153 }
01154 
01164 int gs_get_yrange(float *min, float *max)
01165 {
01166     geosurf *gs;
01167     float tmin, tmax;
01168 
01169     if (Surf_top) {
01170         gs_get_yextents(Surf_top, &tmin, &tmax);
01171         *min = tmin;
01172         *max = tmax;
01173     }
01174     else {
01175         return (-1);
01176     }
01177 
01178     for (gs = Surf_top->next; gs; gs = gs->next) {
01179         gs_get_yextents(gs, &tmin, &tmax);
01180 
01181         if (tmin < *min) {
01182             *min = tmin;
01183         }
01184 
01185         if (tmax > *max) {
01186             *max = tmax;
01187         }
01188     }
01189 
01190     return (1);
01191 }
01192 
01203 int gs_get_data_avg_zmax(float *azmax)
01204 {
01205     float zmax;
01206     int i;
01207     geosurf *gs;
01208 
01209     zmax = *azmax = 0.0;
01210 
01211     if (Surf_top) {
01212         for (i = 0, gs = Surf_top; gs; i++, gs = gs->next) {
01213             zmax += (gs->zmax + gs->z_trans);
01214         }
01215 
01216         *azmax = zmax / i;
01217 
01218         return (1);
01219     }
01220 
01221     return (-1);
01222 }
01223 
01232 int gs_get_datacenter(float *cen)
01233 {
01234     float zmin, zmax, ymin, ymax, xmin, xmax;
01235     geosurf *gs;
01236 
01237     if (Surf_top) {
01238         zmin = Surf_top->zmin;
01239         zmax = Surf_top->zmax;
01240         ymin = Surf_top->ymin;
01241         ymax = Surf_top->ymax;
01242         xmin = Surf_top->xmin;
01243         xmax = Surf_top->xmax;
01244 
01245         for (gs = Surf_top->next; gs; gs = gs->next) {
01246             if (gs->zmin < zmin) {
01247                 zmin = gs->zmin;
01248             }
01249 
01250             if (gs->zmax > zmax) {
01251                 zmax = gs->zmax;
01252             }
01253 
01254             if (gs->ymin < ymin) {
01255                 ymin = gs->ymin;
01256             }
01257 
01258             if (gs->ymax > ymax) {
01259                 ymax = gs->ymax;
01260             }
01261 
01262             if (gs->xmin < xmin) {
01263                 xmin = gs->xmin;
01264             }
01265 
01266             if (gs->xmax > xmax) {
01267                 xmax = gs->xmax;
01268             }
01269         }
01270 
01271         cen[X] = (xmin + xmax) / 2. - xmin;
01272         cen[Y] = (ymin + ymax) / 2. - ymin;
01273         cen[Z] = (zmin + zmax) / 2.;
01274 
01275         return (1);
01276     }
01277 
01278     cen[X] = cen[Y] = cen[Z] = 0.0;
01279 
01280     return (-1);
01281 }
01282 
01283 
01290 int gs_setall_norm_needupdate(void)
01291 {
01292     geosurf *gs;
01293 
01294     if (Surf_top) {
01295         Surf_top->norm_needupdate = 1;
01296     }
01297     else {
01298         return (-1);
01299     }
01300 
01301     for (gs = Surf_top->next; gs; gs = gs->next) {
01302         gs->norm_needupdate = 1;
01303     }
01304 
01305     return (1);
01306 }
01307 
01317 int gs_point_is_masked(geosurf * gs, float *pt)
01318 {
01319     int vrow, vcol, drow, dcol;
01320     int retmask = 0, npts = 0;
01321     float p2[2];
01322 
01323     if (!gs->curmask) {
01324         return (0);
01325     }
01326 
01327     vrow = Y2VROW(gs, pt[Y]);
01328     vcol = X2VCOL(gs, pt[X]);
01329 
01330     /* check right & bottom edges */
01331     if (pt[X] == VCOL2X(gs, VCOLS(gs))) {
01332         /* right edge */
01333         vcol -= 1;
01334     }
01335 
01336     if (pt[Y] == VROW2Y(gs, VROWS(gs))) {
01337         /* bottom edge */
01338         vrow -= 1;
01339     }
01340 
01341     drow = VROW2DROW(gs, vrow);
01342     dcol = VCOL2DCOL(gs, vcol);
01343 
01344     if (BM_get(gs->curmask, dcol, drow)) {
01345         retmask |= MASK_TL;
01346         npts++;
01347     }
01348 
01349     dcol = VCOL2DCOL(gs, vcol + 1);
01350 
01351     if (BM_get(gs->curmask, dcol, drow)) {
01352         retmask |= MASK_TR;
01353         npts++;
01354     }
01355 
01356     drow = VROW2DROW(gs, vrow + 1);
01357 
01358     if (BM_get(gs->curmask, dcol, drow)) {
01359         retmask |= MASK_BR;
01360         npts++;
01361     }
01362 
01363     dcol = VCOL2DCOL(gs, vcol);
01364 
01365     if (BM_get(gs->curmask, dcol, drow)) {
01366         retmask |= MASK_BL;
01367         npts++;
01368     }
01369 
01370     if (npts != 1) {
01371         /* zero or masked */
01372         return (retmask | npts);
01373     }
01374 
01375     p2[X] = VCOL2X(gs, vcol);
01376     p2[Y] = VROW2Y(gs, vrow + 1);
01377 
01378     switch (retmask) {
01379     case MASK_TL:
01380         if ((pt[X] - p2[X]) / VXRES(gs) > (pt[Y] - p2[Y]) / VYRES(gs)) {
01381             /* lower triangle */
01382             return (0);
01383         }
01384 
01385         return (retmask | npts);
01386     case MASK_TR:
01387 
01388         return (retmask | npts);
01389     case MASK_BR:
01390         if ((pt[X] - p2[X]) / VXRES(gs) <= (pt[Y] - p2[Y]) / VYRES(gs)) {
01391             /* upper triangle */
01392             return (0);
01393         }
01394 
01395         return (retmask | npts);
01396     case MASK_BL:
01397 
01398         return (retmask | npts);
01399     }
01400 
01401     /* Assume that if we get here it is an error */
01402     return (0);
01403 }
01404 
01417 int gs_distance_onsurf(geosurf * gs, float *p1, float *p2, float *dist,
01418                        int use_exag)
01419 {
01420     Point3 *tmp;
01421     int np, i;
01422     float exag, length;
01423 
01424     if (in_vregion(gs, p1) && in_vregion(gs, p2)) {
01425         if (NULL == (tmp = gsdrape_get_segments(gs, p1, p2, &np))) {
01426             return (0);
01427         }
01428 
01429         length = 0.;
01430 
01431         if (use_exag) {
01432             exag = GS_global_exag();
01433             tmp[0][Z] *= exag;
01434 
01435             for (i = 0; i < (np - 1); i++) {
01436                 tmp[i + 1][Z] *= exag;
01437                 length += GS_distance(tmp[i], tmp[i + 1]);
01438             }
01439         }
01440         else {
01441             for (i = 0; i < (np - 1); i++) {
01442                 length += GS_distance(tmp[i], tmp[i + 1]);
01443             }
01444         }
01445 
01446         *dist = length;
01447 
01448         return (1);
01449     }
01450 
01451     return (0);
01452 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines