1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453 |
- /*!
- \file lib/ogsf/gs.c
- \brief OGSF library - loading and manipulating surfaces (lower level functions)
- 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 (January 1993)
- \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <grass/ogsf.h>
- #include <grass/glocale.h>
- #include "gsget.h"
- #include "rowcol.h"
- #define FIRST_SURF_ID 110658
- static geosurf *Surf_top;
- static int Invertmask;
- /***********************************************************************/
- void gs_err(const char *msg)
- {
- G_warning("%s", msg);
- return;
- }
- /*!
- \brief Initialize library
- Still need to take care of library initialization,
- probably want to define a Surf_top of constant value (i.e., 0)
- */
- void gs_init(void)
- {
- Surf_top = NULL;
- return;
- }
- /*!
- \brief Get geosurf struct
- \param id surface id
- \return pointer to geosurf struct
- \return NULL if not found
- */
- geosurf *gs_get_surf(int id)
- {
- geosurf *gs;
- G_debug(5, "gs_get_surf():");
- for (gs = Surf_top; gs; gs = gs->next) {
- if (gs->gsurf_id == id) {
- G_debug(5, " id=%d", id);
- return (gs);
- }
- }
- return (NULL);
- }
- /*!
- \brief Get previous geosurf struct
- \param id current surface id
- \return pointer to geosurf struct
- \return NULL if not found
- */
- geosurf *gs_get_prev_surface(int id)
- {
- geosurf *ps;
- G_debug(5, "gs_get_prev_surface");
- for (ps = Surf_top; ps; ps = ps->next) {
- if (ps->gsurf_id == id - 1) {
- return (ps);
- }
- }
- return (NULL);
- }
- /*!
- \brief Get array of geosurf structs
- \param gsurfs pointer to array
- \return number of geosurfs
- */
- int gs_getall_surfaces(geosurf ** gsurfs)
- {
- geosurf *gs;
- int i;
- for (i = 0, gs = Surf_top; gs; gs = gs->next, i++) {
- gsurfs[i] = gs;
- }
- G_debug(5, "gs_num_surfaces(): num=%d", i);
- return (i);
- }
- /*!
- \brief Get number of surfaces
- \return number of surfaces
- */
- int gs_num_surfaces(void)
- {
- geosurf *gs;
- int i;
- for (i = 0, gs = Surf_top; gs; gs = gs->next, i++) ;
- G_debug(5, "gs_num_surfaces(): num=%d", i);
- return (i);
- }
- /*!
- \brief Check if attribute is set
- \param surf pointer to gsurf or NULL to look at all geosurfs
- \param att attribute id
- \return 1 attribute is set up
- \return 0 attribute is not set up
- */
- int gs_att_is_set(geosurf * surf, IFLAG att)
- {
- geosurf *gs;
- if (surf) {
- return (NOTSET_ATT != surf->att[att].att_src);
- }
- /* if surf == NULL, look at all surfs */
- for (gs = Surf_top; gs; gs = gs->next) {
- if (NOTSET_ATT != gs->att[att].att_src) {
- return (1);
- }
- }
- return (0);
- }
- /*!
- \brief Get last allocated geosurf struct from list
- \return pointer to geosurf struct
- */
- geosurf *gs_get_last_surface(void)
- {
- geosurf *ls;
- if (!Surf_top) {
- return (NULL);
- }
- for (ls = Surf_top; ls->next; ls = ls->next) ;
- G_debug(5, "gs_get_last_surface(): last surface id=%d", ls->gsurf_id);
- return (ls);
- }
- /*!
- \brief Allocate new geosurf struct
- \return pointer to geosurf struct
- */
- geosurf *gs_get_new_surface(void)
- {
- geosurf *ns, *ls;
- ns = (geosurf *) G_malloc(sizeof(geosurf)); /* G_fatal_error */
- if (!ns) {
- return (NULL);
- }
- if ((ls = gs_get_last_surface())) {
- ls->next = ns;
- ns->gsurf_id = ls->gsurf_id + 1;
- }
- else {
- Surf_top = ns;
- ns->gsurf_id = FIRST_SURF_ID;
- }
- ns->next = NULL;
- G_debug(5, "gs_get_new_surface(): id=%d", ns->gsurf_id);
- return (ns);
- }
- /*!
- \brief Initialize allocated geosurf struct
- \todo Now xmin & ox are the same, right? - get rid of ox, oy in geosurf struct?
- \param gs pointer to geosurf struct
- \param ox,oy x/y origin coordinates
- \param rows number of rows
- \param cols number of cols
- \param xres,yres x/y resolution value
- \return -1 on error
- \return 0 on success
- */
- int gs_init_surf(geosurf * gs, double ox, double oy, int rows, int cols,
- double xres, double yres)
- {
- geosurf *ps;
- int i;
- if (!gs) {
- return (-1);
- }
- G_debug(5, "gs_init_surf() id=%d", gs->gsurf_id);
- /* default attributes */
- for (i = 0; i < MAX_ATTS; i++) {
- gs->att[i].att_src = NOTSET_ATT;
- gs->att[i].att_type = ATTY_INT;
- gs->att[i].hdata = -1;
- gs->att[i].user_func = NULL;
- gs->att[i].constant = 0.;
- gs->att[i].lookup = NULL;
- gs->att[i].min_nz = gs->att[i].max_nz = gs->att[i].range_nz = 0;
- gs->att[i].default_null = 0.;
- }
- /* default values */
- gs->ox = ox;
- gs->oy = oy;
- gs->rows = rows;
- gs->cols = cols;
- gs->xres = xres;
- gs->yres = yres;
- gs->x_mod = 2;
- gs->y_mod = 2;
- gs->x_modw = rows / 30;
- gs->y_modw = rows / 30;
- gs->xmin = ox;
- gs->xmax = ox + (cols - 1) * xres;
- gs->xrange = gs->xmax - gs->xmin;
- gs->ymin = oy;
- gs->ymax = oy + (rows - 1) * yres;
- gs->yrange = gs->ymax - gs->ymin;
- gs->zmin = gs->zmin_nz = gs->zminmasked = 0;
- gs->zmax = gs->zmax_nz = 0;
- gs->zrange = gs->zrange_nz = 0;
- gs->wire_color = 0x00888888;
- gs->x_trans = gs->y_trans = gs->z_trans = 0.0;
- gs->nz_topo = gs->nz_color = 0;
- gs->norm_needupdate = 1;
- gs->mask_needupdate = 1;
- gs->curmask = NULL;
- gs->norms = NULL;
- gs->draw_mode = DM_GOURAUD;
- /* default z_exag value */
- if (gs->gsurf_id == FIRST_SURF_ID) {
- gs->z_exag = 1.0;
- }
- else {
- ps = gs_get_prev_surface(gs->gsurf_id);
- gs->z_exag = ps->z_exag;
- }
- return (0);
- }
- /*!
- \brief Init geosurf normbuff
- \param gs pointer to geosurf struct
- \return 0 on error
- \return 1 on success
- */
- int gs_init_normbuff(geosurf * gs)
- {
- long size;
- if (!gs) {
- return (0);
- }
- if (gs->norms) {
- G_free(gs->norms);
- }
- size = gs->rows * gs->cols * sizeof(unsigned long);
- gs->norms = (unsigned long *)G_malloc(size); /* G_fatal_error */
- if (!gs->norms) {
- return (-1);
- }
- gs->norm_needupdate = 1;
- return (1);
- }
- /*!
- \brief Debugging, print 'from/to' model coordinates to stderr
- \todo G_debug ?
- \param ft pointer to coordinates
- */
- void print_frto(float (*ft)[4])
- {
- fprintf(stderr, "FROM: %f, %f, %f\n", ft[FROM][X], ft[FROM][Y],
- ft[FROM][Z]);
- fprintf(stderr, "TO: %f, %f, %f\n", ft[TO][X], ft[TO][Y], ft[TO][Z]);
- return;
- }
- /*!
- \brief Debugging, print 'to' real coordinates to stderr
- \todo G_debug ?
- \param ft pointer to coordinates
- */
- void print_realto(float *rt)
- {
- fprintf(stderr, "REAL TO: %f, %f, %f\n", rt[X], rt[Y], rt[Z]);
- return;
- }
- /*!
- \brief Debugging, 256 integer values from buffer
- \todo G_debug ?
- \param ft pointer to buffer
- */
- void print_256lookup(int *buff)
- {
- int i;
- for (i = 0; i < 256; i++) {
- if (!(i % 8)) {
- fprintf(stderr, "\n");
- }
- fprintf(stderr, "%x ", buff[i]);
- }
- fprintf(stderr, "\n");
- return;
- }
- /*!
- \brief Debugging, print geosurf fields to stderr
- \todo G_debug ?
- \param s pointer to geosurf struct
- */
- void print_surf_fields(geosurf * s)
- {
- fprintf(stderr, "ID: %d\n", s->gsurf_id);
- fprintf(stderr, "rows: %d cols: %d\n", s->rows, s->cols);
- fprintf(stderr, "draw_mode: %x\n", s->draw_mode);
- fprintf(stderr, "wire_color: %lx\n", s->wire_color);
- fprintf(stderr, "ox: %lf oy: %lf\n", s->ox, s->oy);
- fprintf(stderr, "xres: %lf yres: %lf\n", s->xres, s->yres);
- fprintf(stderr, "z_exag: %f \n", s->z_exag);
- fprintf(stderr, "x_trans: %f y_trans: %f z_trans: %f\n",
- s->x_trans, s->y_trans, s->z_trans);
- fprintf(stderr, "xmin: %f ymin: %f zmin: %f\n",
- s->xmin, s->ymin, s->zmin);
- fprintf(stderr, "xmax: %f ymax: %f zmax: %f\n",
- s->xmax, s->ymax, s->zmax);
- fprintf(stderr, "x_mod: %d y_mod: %d x_modw: %d y_modw: %d\n",
- s->x_mod, s->y_mod, s->x_modw, s->y_modw);
- return;
- }
- /*!
- \brief Debugging, print geoview fields to stderr
- \todo G_debug ?
- \param gv pointer to geoview struct
- */
- void print_view_fields(geoview * gv)
- {
- fprintf(stderr, "coord_sys: %d\n", gv->coord_sys);
- fprintf(stderr, "view_proj: %d\n", gv->view_proj);
- fprintf(stderr, "infocus: %d\n", gv->infocus);
- print_frto(gv->from_to);
- fprintf(stderr, "twist: %d fov: %d\n", gv->twist, gv->fov);
- fprintf(stderr, "incl: %d look: %d\n", gv->incl, gv->look);
- fprintf(stderr, "real_to: %f %f %f\n",
- gv->real_to[X], gv->real_to[Y], gv->real_to[Z]);
- fprintf(stderr, "vert_exag: %f scale: %f \n", gv->vert_exag, gv->scale);
- return;
- }
- /*!
- \brief Set default attribute values
- \param gs pointer to geosurf struct
- \param defs array of default values (dim MAX_ATTRS)
- \param null_defs array of null default values (dim MAX_ATTRS)
- */
- void gs_set_defaults(geosurf * gs, float *defs, float *null_defs)
- {
- int i;
- G_debug(5, "gs_set_defaults(): id=%d", gs->gsurf_id);
- for (i = 0; i < MAX_ATTS; i++) {
- gs->att[i].constant = defs[i];
- gs->att[i].default_null = null_defs[i];
- gs->att[i].lookup = NULL;
- gs->att[i].hdata = -1;
- gs->att[i].att_src = NOTSET_ATT;
- }
- return;
- }
- /*!
- \brief Remove geosurf struct from list
- \param id surface id
- */
- void gs_delete_surf(int id)
- {
- geosurf *fs;
- G_debug(5, "gs_delete_surf");
- fs = gs_get_surf(id);
- if (fs) {
- gs_free_surf(fs);
- }
- return;
- }
- /*!
- \brief Free geosurf struct
- \param fs pointer to geosurf struct
- \return 1 found
- \return 0 not found
- \return -1 on error
- */
- int gs_free_surf(geosurf * fs)
- {
- geosurf *gs;
- int found = 0;
- G_debug(5, "gs_free_surf");
- if (Surf_top) {
- if (fs == Surf_top) {
- if (Surf_top->next) {
- /* can't free top if last */
- found = 1;
- Surf_top = fs->next;
- }
- else {
- gs_free_unshared_buffs(fs);
- if (fs->curmask) {
- G_free(fs->curmask);
- }
- if (fs->norms) {
- G_free(fs->norms);
- }
- G_free(fs);
- Surf_top = NULL;
- }
- }
- else {
- for (gs = Surf_top; gs && !found; gs = gs->next) {
- if (gs->next) {
- if (gs->next == fs) {
- found = 1;
- gs->next = fs->next;
- }
- }
- }
- }
- if (found) {
- gs_free_unshared_buffs(fs);
- if (fs->curmask) {
- G_free(fs->curmask);
- }
- if (fs->norms) {
- G_free(fs->norms);
- }
- G_free(fs);
- fs = NULL;
- }
- return (found);
- }
- return (-1);
- }
- /*!
- \brief Free unshared buffers of geosurf struct
- <i>fs</i> has already been taken out of the list
- This function is fairly revealing about how shared datsets work
- \param fs pointer to geosurf struct
- */
- void gs_free_unshared_buffs(geosurf * fs)
- {
- geosurf *gs;
- int i, j, same;
- int old_datah;
- G_debug(5, "gs_free_unshared_buffs");
- /* for each attribute
- if !same, free buff
- */
- for (i = 0; i < MAX_ATTS; i++) {
- same = 0;
- if (0 < (old_datah = fs->att[i].hdata)) {
- /* for ea att of all other surfs */
- for (gs = Surf_top; gs; gs = gs->next) {
- for (j = 0; j < MAX_ATTS; j++) {
- if ((old_datah == gs->att[j].hdata) && (fs != gs)) {
- same = 1;
- }
- }
- }
- if (!same) {
- gsds_free_datah(old_datah);
- }
- }
- }
- return;
- }
- /*!
- \brief Get number of reused values
- \param dh value
- \return number of reused values
- */
- int gs_num_datah_reused(int dh)
- {
- geosurf *gs;
- int ref, j;
- G_debug(5, "gs_num_datah_reused");
- /* for each attribute
- if same, ++reference
- */
- /* for ea att of all surfs */
- ref = 0;
- for (gs = Surf_top; gs; gs = gs->next) {
- for (j = 0; j < MAX_ATTS; j++) {
- if (dh == gs->att[j].hdata) {
- ref++;
- }
- }
- }
- return (ref);
- }
- /*!
- \brief Get attribute type
- \param gs pointer to geosurf struct
- \param desc attribute id
- \return -1 on error
- \return attribute type
- */
- int gs_get_att_type(geosurf * gs, int desc)
- {
- G_debug(5, "gs_get_att_type");
- if (!LEGAL_ATT(desc)) {
- return (-1);
- }
- if (gs) {
- if (gs->att[desc].att_src != NOTSET_ATT) {
- return (gs->att[desc].att_type);
- }
- }
- return (-1);
- }
- /*!
- \brief Get attribute source
- \param gs pointer to geosurf struct
- \param desc attribute id (descriptor)
- \return -1 on error
- \return attribute source id
- */
- int gs_get_att_src(geosurf * gs, int desc)
- {
- if (gs)
- G_debug(5, "gs_get_att_src(): id=%d, desc=%d", gs->gsurf_id, desc);
- if (!LEGAL_ATT(desc)) {
- return (-1);
- }
- if (gs) {
- return (gs->att[desc].att_src);
- }
- return (-1);
- }
- /*!
- \brief Get attribute data buffer
- \param gs pointer to geosurf struct
- \param desc attribute id (descriptor)
- \param to_write non-zero value for 'write'
- \return NULL on error
- \return pointer to typbuff
- */
- typbuff *gs_get_att_typbuff(geosurf * gs, int desc, int to_write)
- {
- typbuff *tb;
- geosurf *gsref;
- if (gs) {
- G_debug(5, "gs_get_att_typbuff(): id=%d desc=%d to_write=%d",
- gs->gsurf_id, desc, to_write);
- if ((tb = gsds_get_typbuff(gs->att[desc].hdata, to_write))) {
- tb->tfunc = NULL;
- if (desc == ATT_TOPO) {
- gsref = gsdiff_get_SDref();
- if (gsref && gsref != gs) {
- tb->tfunc = gsdiff_do_SD;
- }
- }
- return (tb);
- }
- }
- return (NULL);
- }
- /*!
- \brief Allocate attribute buffer
- \param gs pointer to geosurf struct
- \param desc attribute id (descriptor)
- \param type buffer type (based on raster map type)
- \return -1 on error
- \return amount of allocated memory
- */
- size_t gs_malloc_att_buff(geosurf * gs, int desc, int type)
- {
- int hdata, dims[2], ndims;
- G_debug(5, "gs_malloc_att_buff");
- if (gs) {
- if (0 < (hdata = gs->att[desc].hdata)) {
- dims[0] = gs->rows;
- dims[1] = gs->cols;
- ndims = 2;
- gs_set_att_type(gs, desc, type);
- return (gsds_alloc_typbuff(hdata, dims, ndims, type));
- }
- }
- return 0;
- }
- /*!
- \brief Allocate attribute lookup
- \param gs pointer to geosurf struct
- \param desc attribute id
- \return -1 on error
- \return pointer to typbuff (casted)
- */
- int gs_malloc_lookup(geosurf * gs, int desc)
- {
- int size;
- G_debug(5, "gs_malloc_lookup");
- if (gs) {
- if (gs->att[desc].lookup) {
- G_free(gs->att[desc].lookup);
- gs->att[desc].lookup = NULL;
- }
- switch (gs->att[desc].att_type) {
- case (ATTY_SHORT):
- size = 32768 * sizeof(int);
- /* positive integers only, because use as array index */
- gs->att[desc].lookup = (int *)G_malloc(size); /* G_fatal_error */
- if (!gs->att[desc].lookup) {
- return (-1);
- }
- break;
- case (ATTY_CHAR):
- size = 256 * sizeof(int);
- /* unsigned char */
- gs->att[desc].lookup = (int *)G_malloc(size);
- if (!gs->att[desc].lookup) {
- return (-1);
- }
- break;
- default:
- G_warning("bad type: gs_malloc_lookup");
- return (-1);
- }
- if (gs->att[desc].lookup) {
- return (0);
- }
- }
- return (-1);
- }
- /*!
- \brief Set attribute type
- \param gs pointer to geosurf struct
- \param desc attribute id
- \param type attribute type
- \return -1 on error
- \return 0 on success
- */
- int gs_set_att_type(geosurf * gs, int desc, int type)
- {
- G_debug(5, "gs_set_att_type(): desc=%d, type=%d", desc, type);
- if (gs && LEGAL_TYPE(type)) {
- gs->att[desc].att_type = type;
- return (0);
- }
- return (-1);
- }
- /*!
- \brief Set attribute source
- \param gs pointer to geosurf struct
- \param desc attribute id (descriptor)
- \param src source id
- \return -1 on error
- \return 0 on success
- */
- int gs_set_att_src(geosurf * gs, int desc, int src)
- {
- if (gs)
- G_debug(5, "gs_set_att_src(): id=%d desc=%d src=%d",
- gs->gsurf_id, desc, src);
- /* check if old source was MAP_ATT, free buff */
- if (MAP_ATT == gs_get_att_src(gs, desc)) {
- if (1 == gs_num_datah_reused(gs->att[desc].hdata)) {
- /* only reference */
- G_debug(5, "gs_set_att_src(): replacing existing map");
- gsds_free_datah(gs->att[desc].hdata);
- }
- if (ATT_TOPO == desc) {
- if (gs->norms) {
- G_free(gs->norms);
- }
- gs->norms = NULL;
- gs->norm_needupdate = 0;
- }
- }
- if (gs && LEGAL_SRC(src)) {
- gs->att[desc].att_src = src;
- return (0);
- }
- return (-1);
- }
- /*!
- \brief Set attribute constant value
- \todo set typbuf constant
- \param gs pointer to geosurf struct
- \param desc attribute id
- \param constant constant value
- \return 0 on success
- \return -1 on error
- */
- int gs_set_att_const(geosurf * gs, int desc, float constant)
- {
- if (gs) {
- G_debug(5, "gs_set_att_const(): id=%d, desc=%d, const=%f",
- gs->gsurf_id, desc, constant);
- gs->att[desc].constant = constant;
- if (ATT_MASK == desc) {
- gs->mask_needupdate = 1;
- }
- else {
- gs_set_att_src(gs, desc, CONST_ATT);
- }
- Gs_update_attrange(gs, desc);
- return (0);
- }
- return (-1);
- }
- /*!
- \brief Set geosurf mask mode
- \param invert invert mask
- */
- void gs_set_maskmode(int invert)
- {
- Invertmask = invert;
- return;
- }
- /*!
- \brief Check if mask is defined
- \param gs pointer to geosurf struct
- \return 1 if defined
- \return 0 not defined
- */
- int gs_mask_defined(geosurf * gs)
- {
- return (gs->att[ATT_MASK].att_src != NOTSET_ATT);
- }
- /*!
- \brief
- Should only be called when setting up the current mask (gs_bm.c)
- \param tb pointer to typbuff
- \param col number of cols
- \param row number of rows
- \param offset offset value
- \return 1
- \return 0
- */
- int gs_masked(typbuff * tb, int col, int row, int offset)
- {
- int ret;
- ret = 1;
- if (tb->bm) {
- ret = BM_get(tb->bm, col, row);
- }
- else if (tb->cb) {
- ret = tb->cb[offset];
- }
- else if (tb->sb) {
- ret = tb->sb[offset];
- }
- else if (tb->ib) {
- ret = tb->ib[offset];
- }
- else if (tb->fb) {
- ret = tb->fb[offset];
- }
- return (Invertmask ? ret : !ret);
- }
- /*!
- \brief
- Call this one when you already know att_src is MAP_ATT
- \param cobuff
- \param coloratt color attribute
- \param offset offset value
- \return packed color for catagory at offset
- */
- int gs_mapcolor(typbuff * cobuff, gsurf_att * coloratt, int offset)
- {
- if (coloratt->lookup) {
- /* for now, but may add larger color lookup capabilities later,
- so would have to use GET_MAPATT */
- return (coloratt->lookup[cobuff->cb[offset]]);
- }
- return (cobuff->ib[offset]);
- }
- /*
- In the following functions, "extents" refers to translated extents for
- a single surface, while "range" refers to accumulated extents of all
- loaded surfaces
- */
- /*!
- \brief Get z-extent values
- \todo pass flag to use zminmasked instead of zmin
- \param gs pointer to geosurf struct
- \param[out] min z-min value
- \param[out] max z-max value
- \param[out] mid z-middle value
- \return 1
- */
- int gs_get_zextents(geosurf * gs, float *min, float *max, float *mid)
- {
- *min = gs->zmin + gs->z_trans;
- *max = gs->zmax + gs->z_trans;
- *mid = (*max + *min) / 2.;
- return (1);
- }
- /*!
- \brief Get x-extent values
- \param gs pointer to geosurf struct
- \param[out] min x-min value
- \param[out] max x-max value
- \return 1
- */
- int gs_get_xextents(geosurf * gs, float *min, float *max)
- {
- *min = gs->xmin + gs->x_trans;
- *max = gs->xmax + gs->x_trans;
- return (1);
- }
- /*!
- \brief Get y-extent values
- \param gs pointer to geosurf struct
- \param[out] min y-min value
- \param[out] max y-max value
- \return 1
- */
- int gs_get_yextents(geosurf * gs, float *min, float *max)
- {
- *min = gs->ymin + gs->y_trans;
- *max = gs->ymax + gs->y_trans;
- return (1);
- }
- /*!
- \brief Get z-range
- \todo pass flag to use zminmasked instead of zmin
- could also have this return a weighted average for vertical "centroid"
- \param[out] min z-min value
- \param[out] max z-max value
- \return -1 on error (no surface)
- \return 1 on success
- */
- int gs_get_zrange0(float *min, float *max)
- {
- geosurf *gs;
- if (Surf_top) {
- *min = Surf_top->zmin;
- *max = Surf_top->zmax;
- }
- else {
- return (-1);
- }
- for (gs = Surf_top->next; gs; gs = gs->next) {
- if (gs->zmin < *min) {
- *min = gs->zmin;
- }
- if (gs->zmax > *max) {
- *max = gs->zmax;
- }
- }
- return (1);
- }
- /*!
- \brief Get z-range
- \param[out] min z-min value
- \param[out] max z-max value
- \return -1 on error (no surface)
- \return 1 on success
- */
- int gs_get_zrange(float *min, float *max)
- {
- geosurf *gs;
- float tmin, tmax, tmid;
- if (Surf_top) {
- gs_get_zextents(Surf_top, &tmin, &tmax, &tmid);
- *min = tmin;
- *max = tmax;
- }
- else {
- return (-1);
- }
- for (gs = Surf_top->next; gs; gs = gs->next) {
- gs_get_zextents(gs, &tmin, &tmax, &tmid);
- if (tmin < *min) {
- *min = tmin;
- }
- if (tmax > *max) {
- *max = tmax;
- }
- }
- return (1);
- }
- /*!
- \brief Get x-range
- \param[out] min x-min value
- \param[out] max x-max value
- \return -1 on error (no surface)
- \return 1 on success
- */
- int gs_get_xrange(float *min, float *max)
- {
- geosurf *gs;
- float tmin, tmax;
- if (Surf_top) {
- gs_get_xextents(Surf_top, &tmin, &tmax);
- *min = tmin;
- *max = tmax;
- }
- else {
- return (-1);
- }
- for (gs = Surf_top->next; gs; gs = gs->next) {
- gs_get_xextents(gs, &tmin, &tmax);
- if (tmin < *min) {
- *min = tmin;
- }
- if (tmax > *max) {
- *max = tmax;
- }
- }
- return (1);
- }
- /*!
- \brief Get y-range
- \param[out] min y-min value
- \param[out] max y-max value
- \return -1 on error (no surface)
- \return 1 on success
- */
- int gs_get_yrange(float *min, float *max)
- {
- geosurf *gs;
- float tmin, tmax;
- if (Surf_top) {
- gs_get_yextents(Surf_top, &tmin, &tmax);
- *min = tmin;
- *max = tmax;
- }
- else {
- return (-1);
- }
- for (gs = Surf_top->next; gs; gs = gs->next) {
- gs_get_yextents(gs, &tmin, &tmax);
- if (tmin < *min) {
- *min = tmin;
- }
- if (tmax > *max) {
- *max = tmax;
- }
- }
- return (1);
- }
- /*!
- \brief Get average z-max value
- Useful for setting position of cplane, lighting ball, etc.
- \param[out] azmax average z-max value
- \return -1 on error
- \return 1 on success
- */
- int gs_get_data_avg_zmax(float *azmax)
- {
- float zmax;
- int i;
- geosurf *gs;
- zmax = *azmax = 0.0;
- if (Surf_top) {
- for (i = 0, gs = Surf_top; gs; i++, gs = gs->next) {
- zmax += (gs->zmax + gs->z_trans);
- }
- *azmax = zmax / i;
- return (1);
- }
- return (-1);
- }
- /*!
- \brief Get data center point
- \param[out] center (array X,Y,Z)
- \return -1 on error
- \return 1 on success
- */
- int gs_get_datacenter(float *cen)
- {
- float zmin, zmax, ymin, ymax, xmin, xmax;
- geosurf *gs;
- if (Surf_top) {
- zmin = Surf_top->zmin;
- zmax = Surf_top->zmax;
- ymin = Surf_top->ymin;
- ymax = Surf_top->ymax;
- xmin = Surf_top->xmin;
- xmax = Surf_top->xmax;
- for (gs = Surf_top->next; gs; gs = gs->next) {
- if (gs->zmin < zmin) {
- zmin = gs->zmin;
- }
- if (gs->zmax > zmax) {
- zmax = gs->zmax;
- }
- if (gs->ymin < ymin) {
- ymin = gs->ymin;
- }
- if (gs->ymax > ymax) {
- ymax = gs->ymax;
- }
- if (gs->xmin < xmin) {
- xmin = gs->xmin;
- }
- if (gs->xmax > xmax) {
- xmax = gs->xmax;
- }
- }
- cen[X] = (xmin + xmax) / 2. - xmin;
- cen[Y] = (ymin + ymax) / 2. - ymin;
- cen[Z] = (zmin + zmax) / 2.;
- return (1);
- }
- cen[X] = cen[Y] = cen[Z] = 0.0;
- return (-1);
- }
- /*!
- \brief Set for geosurf need-to-update mark
- \return -1 no surface available
- \return 1 on success
- */
- int gs_setall_norm_needupdate(void)
- {
- geosurf *gs;
- if (Surf_top) {
- Surf_top->norm_needupdate = 1;
- }
- else {
- return (-1);
- }
- for (gs = Surf_top->next; gs; gs = gs->next) {
- gs->norm_needupdate = 1;
- }
- return (1);
- }
- /*!
- \brief Check if point is masked
- \param gs pointer to geosurf struct
- \param pt point coordinates (X,Y,Z)
- \return 1 masked
- \return 0 not masked
- */
- int gs_point_is_masked(geosurf * gs, float *pt)
- {
- int vrow, vcol, drow, dcol;
- int retmask = 0, npts = 0;
- float p2[2];
- if (!gs->curmask) {
- return (0);
- }
- vrow = Y2VROW(gs, pt[Y]);
- vcol = X2VCOL(gs, pt[X]);
- /* check right & bottom edges */
- if (pt[X] == VCOL2X(gs, VCOLS(gs))) {
- /* right edge */
- vcol -= 1;
- }
- if (pt[Y] == VROW2Y(gs, VROWS(gs))) {
- /* bottom edge */
- vrow -= 1;
- }
- drow = VROW2DROW(gs, vrow);
- dcol = VCOL2DCOL(gs, vcol);
- if (BM_get(gs->curmask, dcol, drow)) {
- retmask |= MASK_TL;
- npts++;
- }
- dcol = VCOL2DCOL(gs, vcol + 1);
- if (BM_get(gs->curmask, dcol, drow)) {
- retmask |= MASK_TR;
- npts++;
- }
- drow = VROW2DROW(gs, vrow + 1);
- if (BM_get(gs->curmask, dcol, drow)) {
- retmask |= MASK_BR;
- npts++;
- }
- dcol = VCOL2DCOL(gs, vcol);
- if (BM_get(gs->curmask, dcol, drow)) {
- retmask |= MASK_BL;
- npts++;
- }
- if (npts != 1) {
- /* zero or masked */
- return (retmask | npts);
- }
- p2[X] = VCOL2X(gs, vcol);
- p2[Y] = VROW2Y(gs, vrow + 1);
- switch (retmask) {
- case MASK_TL:
- if ((pt[X] - p2[X]) / VXRES(gs) > (pt[Y] - p2[Y]) / VYRES(gs)) {
- /* lower triangle */
- return (0);
- }
- return (retmask | npts);
- case MASK_TR:
- return (retmask | npts);
- case MASK_BR:
- if ((pt[X] - p2[X]) / VXRES(gs) <= (pt[Y] - p2[Y]) / VYRES(gs)) {
- /* upper triangle */
- return (0);
- }
- return (retmask | npts);
- case MASK_BL:
- return (retmask | npts);
- }
- /* Assume that if we get here it is an error */
- return (0);
- }
- /*!
- \brief Calculate distance on surface
- \param gs pointer to geosurf struct
- \param p1 from point
- \param p2 to point
- \param[out] dist distnace
- \param use_exag use exag for calculation
- \return 0 on error (points not in region)
- \return 1 on success
- */
- int gs_distance_onsurf(geosurf * gs, float *p1, float *p2, float *dist,
- int use_exag)
- {
- Point3 *tmp;
- int np, i;
- float exag, length;
- if (in_vregion(gs, p1) && in_vregion(gs, p2)) {
- if (NULL == (tmp = gsdrape_get_segments(gs, p1, p2, &np))) {
- return (0);
- }
- length = 0.;
- if (use_exag) {
- exag = GS_global_exag();
- tmp[0][Z] *= exag;
- for (i = 0; i < (np - 1); i++) {
- tmp[i + 1][Z] *= exag;
- length += GS_distance(tmp[i], tmp[i + 1]);
- }
- }
- else {
- for (i = 0; i < (np - 1); i++) {
- length += GS_distance(tmp[i], tmp[i + 1]);
- }
- }
- *dist = length;
- return (1);
- }
- return (0);
- }
|