GRASS GIS 8 Programmer's Manual  8.2.2dev(2023)-3d2c704037
gsd_surf.c
Go to the documentation of this file.
1 /*!
2  \file lib/ogsf/gsd_surf.c
3 
4  \brief OGSF library - loading and manipulating surfaces
5 
6  GRASS OpenGL gsurf OGSF Library
7 
8  (C) 1999-2008 by the GRASS Development Team
9 
10  This program is free software under the
11  GNU General Public License (>=v2).
12  Read the file COPYING that comes with GRASS
13  for details.
14 
15  \author Bill Brown USACERL (October 1993)
16  \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
17  */
18 
19 #include <stdlib.h>
20 
21 #include <grass/gis.h>
22 #include <grass/glocale.h>
23 #include <grass/ogsf.h>
24 
25 #include "gsget.h"
26 #include "rowcol.h"
27 
28 /*
29  #define CALC_AREA
30  */
31 
32 /*
33  #define DO_ARROW_SOLID
34  #define DEBUG_ARROW ((row && !(row%surf->y_modw))&&(col && !(col%surf->x_modw)))
35  */
36 
37 /*
38  #define DO_ARROW
39  */
40 
41 #define DEBUG_ARROW (0)
42 
43 /*!
44  \brief MACROS for use in gsd_ortho_wall ONLY !!!
45  */
46 #define SET_SCOLOR(sf) \
47  if(check_color[sf]) \
48  { \
49  tx = points[sf][i][X] - gsurfs[sf]->x_trans; \
50  ty = points[sf][i][Y] - gsurfs[sf]->y_trans; \
51  offset = XY2OFF(gsurfs[sf], tx, ty); \
52  colors[sf] = gs_mapcolor(cobuf[sf], coloratt[sf], offset); \
53  }
54 
55 static int transpoint_is_masked(geosurf *, Point3);
56 static int get_point_below(Point3 **, geosurf **, int, int, int, int *);
57 
58 static int FCmode;
59 
60 
61 /************************************************************************/
62 /* Notes on exageration:
63  vertical exageration is of two forms:
64  1) global exageration (from geoview struct)
65  2) vertical exageration for each surface (UN-IMPLEMENTED)
66  */
67 
68 /************************************************************************/
69 /* may need to add more parameters to tell it which window or off_screen
70  * pixmap to draw into.
71  */
72 
73 /*!
74  \brief ADD
75 
76  \param surf surface (geosurf)
77 
78  \return
79  \return -1 on error
80  */
81 int gsd_surf(geosurf * surf)
82 {
83  int desc, ret;
84 
85  G_debug(5, "gsd_surf(): id=%d", surf->gsurf_id);
86 
87  desc = ATT_TOPO;
88 
89  /* won't recalculate if update not needed, but may want to check
90  to see if lights are on */
91  gs_calc_normals(surf);
92 
93  switch (gs_get_att_src(surf, desc)) {
94  case NOTSET_ATT:
95  ret = (-1);
96 
97  break;
98 
99  case MAP_ATT:
100  ret = (gsd_surf_map(surf)); /* changed to use test draw routine */
101 
102 #ifdef DO_ARROW
103  gsd_norm_arrows(surf);
104 
105  /* Not ready yet - need to recalc normals for proper res
106  gsd_wire_arrows(surf);
107  */
108 #endif
109 
110  break;
111 
112  case CONST_ATT:
113  ret = (gsd_surf_const(surf, surf->att[desc].constant));
114 
115  break;
116 
117  case FUNC_ATT:
118  ret = (gsd_surf_func(surf, surf->att[desc].user_func));
119 
120  break;
121 
122  default:
123  ret = (-1);
124 
125  break;
126  }
127 
128  return (ret);
129 }
130 
131 /*!
132  \brief ADD
133 
134  Using tmesh - not confident with qstrips portability
135 
136  \param surf surface (geosurf)
137 
138  \return
139  */
141 {
142  int check_mask, check_color, check_transp;
143  int check_material, check_emis, check_shin;
144  typbuff *buff, *cobuff, *trbuff, *embuff, *shbuff;
145  int xmod, ymod, row, col, cnt, xcnt, ycnt;
146  long offset, y1off, y2off;
147  float x1, x2, y1, y2, tx, ty, tz, ttr;
148  float n[3], pt[4], xres, yres, ymax, zexag;
149  int em_src, sh_src, trans_src, col_src, curcolor;
150  gsurf_att *ematt, *shatt, *tratt, *coloratt;
151 
152 
153  /* Viewport variables for accelerated drawing */
154  GLdouble modelMatrix[16], projMatrix[16];
155  GLint viewport[4];
156  GLint window[4];
157 
158 #ifdef CALC_AREA
159  float sz, mag, tedge1[3], tedge2[3], crossp[3], triv[3][3];
160  double asurf = 0.0, axsurf = 0.0;
161 #endif
162 
163  int zeros, dr1, dr2, dr3, dr4;
164  int datarow1, datacol1, datarow2, datacol2;
165 
166  float kem, ksh, pkem, pksh;
167  unsigned int ktrans;
168 
169  G_debug(3, "gsd_surf_map_old");
170 
171  /* avoid scaling by zero */
172  GS_get_scale(&tx, &ty, &tz, 1);
173 
174  if (tz == 0.0) {
175  return (gsd_surf_const(surf, 0.0));
176  }
177  /* else if (surf->z_exag == 0.0)
178  {
179  return(gsd_surf_const(surf, surf->z_min));
180  }
181  NOT YET IMPLEMENTED */
182 
183  buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
184  cobuff = gs_get_att_typbuff(surf, ATT_COLOR, 0);
185 
186  gs_update_curmask(surf);
187  check_mask = surf->curmask ? 1 : 0;
188 
189  /*
190  checks ATT_TOPO & ATT_COLOR no_zero flags, make a mask from each,
191  combine it/them with any current mask, put in surf->curmask:
192  */
193  xmod = surf->x_mod;
194  ymod = surf->y_mod;
195  xres = xmod * surf->xres;
196  yres = ymod * surf->yres;
197  ymax = (surf->rows - 1) * surf->yres;
198 
199  xcnt = VCOLS(surf);
200  ycnt = VROWS(surf);
201 
202  /* Get viewport */
203  gsd_getwindow(window, viewport, modelMatrix, projMatrix);
204  /* adjust window */
205  window[0] += (int)(yres * 2);
206  window[1] -= (int)(yres * 2);
207  window[2] -= (int)(xres * 2);
208  window[3] += (int)(xres * 2);
209 
211  gsd_pushmatrix();
212  gsd_do_scale(1);
213  gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
214  zexag = surf->z_exag;
215 
216  /* CURRENTLY ALWAYS 1.0 */
217 #ifdef CALC_AREA
218  sz = GS_global_exag();
219 #endif
220 
221  /* TESTING */
222  /*
223  fprintf(stderr, "This machine has %d alpha bits\n", getgdesc(GD_BITS_NORM_DBL_ALPHA));
224  fprintf(stderr, "GD_BLEND = %d \n", getgdesc(GD_BLEND));
225  fprintf(stderr, "GD_CLIPPLANES = %d \n", getgdesc(GD_CLIPPLANES));
226  */
227 
228  /* TODO: get rid of (define) these magic numbers scaling the attribute vals */
229  check_transp = 0;
230  tratt = &(surf->att[ATT_TRANSP]);
231  ktrans = (255 << 24);
232  trans_src = surf->att[ATT_TRANSP].att_src;
233 
234  if (CONST_ATT == trans_src && surf->att[ATT_TRANSP].constant != 0.0) {
235  ktrans = (255 - (int)surf->att[ATT_TRANSP].constant) << 24;
236  gsd_blend(1);
237  gsd_zwritemask(0x0);
238  }
239  else if (MAP_ATT == trans_src) {
240  trbuff = gs_get_att_typbuff(surf, ATT_TRANSP, 0);
241  check_transp = trbuff ? 1 : 0;
242  gsd_blend(1);
243  gsd_zwritemask(0x0);
244  }
245 
246  check_emis = 0;
247  ematt = &(surf->att[ATT_EMIT]);
248  kem = 0.0;
249  pkem = 1.0;
250  em_src = surf->att[ATT_EMIT].att_src;
251 
252  if (CONST_ATT == em_src) {
253  kem = surf->att[ATT_EMIT].constant / 255.;
254  }
255  else if (MAP_ATT == em_src) {
256  embuff = gs_get_att_typbuff(surf, ATT_EMIT, 0);
257  check_emis = embuff ? 1 : 0;
258  }
259 
260  check_shin = 0;
261  shatt = &(surf->att[ATT_SHINE]);
262  ksh = 0.0;
263  pksh = 1.0;
264  sh_src = surf->att[ATT_SHINE].att_src;
265 
266  if (CONST_ATT == sh_src) {
267  ksh = surf->att[ATT_SHINE].constant / 255.;
268  gsd_set_material(1, 0, ksh, kem, 0x0);
269  }
270  else if (MAP_ATT == sh_src) {
271  shbuff = gs_get_att_typbuff(surf, ATT_SHINE, 0);
272  check_shin = shbuff ? 1 : 0;
273  }
274 
275  /* will need to check for color source of FUNC_ATT & NOTSET_ATT,
276  or else use more general and inefficient gets */
277  check_color = 1;
278  coloratt = &(surf->att[ATT_COLOR]);
279  col_src = surf->att[ATT_COLOR].att_src;
280 
281  if (col_src != MAP_ATT) {
282  if (col_src == CONST_ATT) {
283  curcolor = (int)surf->att[ATT_COLOR].constant;
284  }
285  else {
286  curcolor = surf->wire_color;
287  }
288 
289  check_color = 0;
290  }
291 
292  check_material = (check_shin || check_emis || (kem && check_color));
293 
294  /* would also be good to check if colormap == surfmap, to increase speed */
295  /* will also need to set check_transp, check_shine, etc & fix material */
296  cnt = 0;
297 
298  for (row = 0; row < ycnt; row++) {
299  if (GS_check_cancel()) {
300  gsd_popmatrix();
301  gsd_blend(0);
302  gsd_zwritemask(0xffffffff);
303 
304  return (-1);
305  }
306 
307  datarow1 = row * ymod;
308  datarow2 = (row + 1) * ymod;
309 
310  y1 = ymax - row * yres;
311  y2 = ymax - (row + 1) * yres;
312  y1off = row * ymod * surf->cols;
313  y2off = (row + 1) * ymod * surf->cols;
314 
315  gsd_bgntmesh();
316 
317  zeros = 0;
318  dr1 = dr2 = dr3 = dr4 = 1;
319 
320  if (check_mask) {
321  if (BM_get(surf->curmask, 0, datarow1)) {
322  /*TL*/ ++zeros;
323  dr1 = 0;
324  }
325 
326  if (BM_get(surf->curmask, 0, datarow2)) {
327  /*BL*/ ++zeros;
328  dr2 = 0;
329  }
330  }
331 
332  if (dr1 && dr2) {
333  offset = y1off; /* TL */
334  FNORM(surf->norms[offset], n);
335  pt[X] = 0;
336  pt[Y] = y1;
337  GET_MAPATT(buff, offset, pt[Z]);
338  pt[Z] *= zexag;
339 
340  if (check_color) {
341  curcolor = gs_mapcolor(cobuff, coloratt, offset);
342  }
343 
344  if (check_transp) {
345  GET_MAPATT(trbuff, offset, ttr);
346  ktrans = (char)SCALE_ATT(tratt, ttr, 0, 255);
347  ktrans = (char)(255 - ktrans) << 24;
348  }
349 
350  gsd_litvert_func(n, ktrans | curcolor, pt);
351 
352 #ifdef CALC_AREA
353  GS_v3eq(triv[cnt % 3], pt);
354 #endif
355 
356  cnt++;
357 
358  offset = y2off; /* BL */
359  FNORM(surf->norms[offset], n);
360  pt[X] = 0;
361  pt[Y] = y2;
362  GET_MAPATT(buff, offset, pt[Z]);
363  pt[Z] *= zexag;
364 
365  if (check_color) {
366  curcolor = gs_mapcolor(cobuff, coloratt, offset);
367  }
368 
369  if (check_transp) {
370  GET_MAPATT(trbuff, offset, ttr);
371  ktrans = (char)SCALE_ATT(tratt, ttr, 0, 255);
372  ktrans = (char)(255 - ktrans) << 24;
373  }
374 
375  if (check_material) {
376  if (check_emis) {
377  GET_MAPATT(embuff, offset, kem);
378  kem = SCALE_ATT(ematt, kem, 0., 1.);
379  }
380 
381  if (check_shin) {
382  GET_MAPATT(shbuff, offset, ksh);
383  ksh = SCALE_ATT(shatt, ksh, 0., 1.);
384  }
385 
386  if (pksh != ksh || pkem != kem || (kem && check_color)) {
387  /* expensive */
388  pksh = ksh;
389  pkem = kem;
390  gsd_set_material(check_shin, check_emis, ksh, kem,
391  curcolor);
392  }
393  }
394 
395  gsd_litvert_func(n, ktrans | curcolor, pt);
396 
397 #ifdef CALC_AREA
398  GS_v3eq(triv[cnt % 3], pt);
399 #endif
400 
401  cnt++;
402  }
403 
404  for (col = 0; col < xcnt; col++) {
405  datacol1 = col * xmod;
406  datacol2 = (col + 1) * xmod;
407 
408  x1 = col * xres;
409  x2 = (col + 1) * xres;
410 
411  zeros = 0;
412  dr1 = dr2 = dr3 = dr4 = 1;
413 
414  if (check_mask) {
415  if (BM_get(surf->curmask, datacol1, datarow1)) {
416  /*TL*/ ++zeros;
417  dr1 = 0;
418  }
419 
420  if (BM_get(surf->curmask, datacol1, datarow2)) {
421  /*BL*/ ++zeros;
422  dr2 = 0;
423  }
424 
425  if (BM_get(surf->curmask, datacol2, datarow2)) {
426  /*BR*/ ++zeros;
427  dr3 = 0;
428  }
429 
430  if (BM_get(surf->curmask, datacol2, datarow1)) {
431  /*TR*/ ++zeros;
432  dr4 = 0;
433  }
434 
435  if ((zeros > 1) && cnt) {
436  gsd_endtmesh();
437  cnt = 0;
438  gsd_bgntmesh();
439  continue;
440  }
441  }
442 
443  if (cnt > 252) {
444  /* not needed! - no limit for tmesh */
445  cnt = 0;
446  gsd_endtmesh();
447  gsd_bgntmesh();
448 
449  if (dr1) {
450  offset = y1off + datacol1; /* TL */
451  FNORM(surf->norms[offset], n);
452  pt[X] = x1;
453  pt[Y] = y1;
454  GET_MAPATT(buff, offset, pt[Z]);
455  pt[Z] *= zexag;
456 
457  if (gsd_checkpoint
458  (pt, window, viewport, modelMatrix, projMatrix)) {
459  gsd_endtmesh();
460  cnt = 0;
461  gsd_bgntmesh();
462  continue;
463  }
464 
465  if (check_color) {
466  curcolor = gs_mapcolor(cobuff, coloratt, offset);
467  }
468 
469  if (check_transp) {
470  GET_MAPATT(trbuff, offset, ttr);
471  ktrans = (char)SCALE_ATT(tratt, ttr, 0, 255);
472  ktrans = (char)(255 - ktrans) << 24;
473  }
474 
475  if (check_material) {
476  if (check_emis) {
477  GET_MAPATT(embuff, offset, kem);
478  kem = SCALE_ATT(ematt, kem, 0., 1.);
479  }
480 
481  if (check_shin) {
482  GET_MAPATT(shbuff, offset, ksh);
483  ksh = SCALE_ATT(shatt, ksh, 0., 1.);
484  }
485 
486  if (pksh != ksh || pkem != kem
487  || (kem && check_color)) {
488  pksh = ksh;
489  pkem = kem;
490  gsd_set_material(check_shin, check_emis,
491  ksh, kem, curcolor);
492  }
493  }
494 
495  gsd_litvert_func(n, ktrans | curcolor, pt);
496 
497 #ifdef CALC_AREA
498  GS_v3eq(triv[cnt % 3], pt);
499 #endif
500 
501  cnt++;
502  }
503 
504  if (dr2) {
505  offset = y2off + datacol1; /* BL */
506  FNORM(surf->norms[offset], n);
507  pt[X] = x1;
508  pt[Y] = y2;
509  GET_MAPATT(buff, offset, pt[Z]);
510  pt[Z] *= zexag;
511 
512  if (gsd_checkpoint
513  (pt, window, viewport, modelMatrix, projMatrix)) {
514  gsd_endtmesh();
515  cnt = 0;
516  gsd_bgntmesh();
517  continue;
518  }
519 
520  if (check_color) {
521  curcolor = gs_mapcolor(cobuff, coloratt, offset);
522  }
523 
524  if (check_transp) {
525  GET_MAPATT(trbuff, offset, ttr);
526  ktrans = (char)SCALE_ATT(tratt, ttr, 0, 255);
527  ktrans = (char)(255 - ktrans) << 24;
528  }
529 
530  if (check_material) {
531  if (check_emis) {
532  GET_MAPATT(embuff, offset, kem);
533  kem = SCALE_ATT(ematt, kem, 0., 1.);
534  }
535 
536  if (check_shin) {
537  GET_MAPATT(shbuff, offset, ksh);
538  ksh = SCALE_ATT(shatt, ksh, 0., 1.);
539  }
540 
541  if (pksh != ksh || pkem != kem
542  || (kem && check_color)) {
543  pksh = ksh;
544  pkem = kem;
545  gsd_set_material(check_shin, check_emis,
546  ksh, kem, curcolor);
547  }
548  }
549 
550  gsd_litvert_func(n, ktrans | curcolor, pt);
551 
552 #ifdef CALC_AREA
553  GS_v3eq(triv[cnt % 3], pt);
554 #endif
555 
556  cnt++;
557  }
558  }
559 
560  if (dr4) {
561  offset = y1off + datacol2; /* TR */
562  FNORM(surf->norms[offset], n);
563  pt[X] = x2;
564  pt[Y] = y1;
565  GET_MAPATT(buff, offset, pt[Z]);
566  pt[Z] *= zexag;
567 
568  if (gsd_checkpoint
569  (pt, window, viewport, modelMatrix, projMatrix)) {
570  gsd_endtmesh();
571  cnt = 0;
572  gsd_bgntmesh();
573  continue;
574  }
575 
576  if (check_color) {
577  curcolor = gs_mapcolor(cobuff, coloratt, offset);
578  }
579 
580  if (check_transp) {
581  GET_MAPATT(trbuff, offset, ttr);
582  ktrans = (char)SCALE_ATT(tratt, ttr, 0, 255);
583  ktrans = (char)(255 - ktrans) << 24;
584  }
585 
586  if (check_material) {
587  if (check_emis) {
588  GET_MAPATT(embuff, offset, kem);
589  kem = SCALE_ATT(ematt, kem, 0., 1.);
590  }
591 
592  if (check_shin) {
593  GET_MAPATT(shbuff, offset, ksh);
594  ksh = SCALE_ATT(shatt, ksh, 0., 1.);
595  }
596 
597  if (pksh != ksh || pkem != kem || (kem && check_color)) {
598  pksh = ksh;
599  pkem = kem;
600  gsd_set_material(check_shin, check_emis,
601  ksh, kem, curcolor);
602  }
603  }
604 
605  gsd_litvert_func(n, ktrans | curcolor, pt);
606 
607 #ifdef CALC_AREA
608  GS_v3eq(triv[cnt % 3], pt);
609 
610  if (cnt > 1) {
611  GS_v3eq(tedge1, triv[1]);
612  GS_v3eq(tedge2, triv[2]);
613  GS_v3sub(tedge1, triv[0]);
614  GS_v3sub(tedge2, triv[1]);
615  GS_v3cross(tedge1, tedge2, crossp);
616  GS_v3mag(crossp, &mag);
617  asurf += .5 * mag;
618  tedge1[Z] *= sz;
619  tedge2[Z] *= sz;
620  GS_v3cross(tedge1, tedge2, crossp);
621  GS_v3mag(crossp, &mag);
622  axsurf += .5 * mag;
623  }
624 #endif
625 
626  cnt++;
627  }
628 
629  if (dr3) {
630  offset = y2off + datacol2; /* BR */
631  FNORM(surf->norms[offset], n);
632  pt[X] = x2;
633  pt[Y] = y2;
634  GET_MAPATT(buff, offset, pt[Z]);
635  pt[Z] *= zexag;
636 
637  if (gsd_checkpoint
638  (pt, window, viewport, modelMatrix, projMatrix)) {
639  gsd_endtmesh();
640  cnt = 0;
641  gsd_bgntmesh();
642  continue;
643  }
644 
645  if (check_color) {
646  curcolor = gs_mapcolor(cobuff, coloratt, offset);
647  }
648 
649  if (check_transp) {
650  GET_MAPATT(trbuff, offset, ttr);
651  ktrans = (char)SCALE_ATT(tratt, ttr, 0, 255);
652  ktrans = (char)(255 - ktrans) << 24;
653  }
654 
655  if (check_material) {
656  if (check_emis) {
657  GET_MAPATT(embuff, offset, kem);
658  kem = SCALE_ATT(ematt, kem, 0., 1.);
659  }
660 
661  if (check_shin) {
662  GET_MAPATT(shbuff, offset, ksh);
663  ksh = SCALE_ATT(shatt, ksh, 0., 1.);
664  }
665 
666  if (pksh != ksh || pkem != kem || (kem && check_color)) {
667  pksh = ksh;
668  pkem = kem;
669  gsd_set_material(check_shin, check_emis,
670  ksh, kem, curcolor);
671  }
672  }
673 
674  gsd_litvert_func(n, ktrans | curcolor, pt);
675 
676 #ifdef CALC_AREA
677  GS_v3eq(triv[cnt % 3], pt);
678 
679  if (cnt > 1) {
680  GS_v3eq(tedge1, triv[1]);
681  GS_v3eq(tedge2, triv[2]);
682  GS_v3sub(tedge1, triv[0]);
683  GS_v3sub(tedge2, triv[1]);
684  GS_v3cross(tedge1, tedge2, crossp);
685  GS_v3mag(crossp, &mag);
686  asurf += .5 * mag;
687  tedge1[Z] *= sz;
688  tedge2[Z] *= sz;
689  GS_v3cross(tedge1, tedge2, crossp);
690  GS_v3mag(crossp, &mag);
691  axsurf += .5 * mag;
692  }
693 #endif
694 
695  cnt++;
696  }
697  } /* ea col */
698 
699  gsd_endtmesh();
700  } /* ea row */
701 
702  gsd_popmatrix();
703  gsd_blend(0);
704  gsd_zwritemask(0xffffffff);
705 
706  show_colormode();
707 
708 #ifdef CALC_AREA
709  G_debug(5, " Surface Area: %.12lf", asurf);
710  G_debug(5, " Exaggerated Surface Area: %.12lf", axsurf);
711 #endif
712 
713  return (0);
714 }
715 
716 /*!
717  \brief
718 
719  Using tmesh - not confident with qstrips portability
720 
721  \todo FIX: do_diff won't work right - needs normals - maybe
722  calculate on the fly
723 
724  \param surf surface (geosurf)
725  \param k
726 
727  \return
728  */
729 int gsd_surf_const(geosurf * surf, float k)
730 {
731  int do_diff, check_mask, check_color;
732  typbuff *cobuff;
733  int xmod, ymod, row, col, cnt, xcnt, ycnt;
734  long offset, y1off, y2off;
735  float x1, x2, y1, y2, tx, ty, tz;
736  float n[3], pt[4], xres, yres, ymax, zexag;
737  int col_src, curcolor;
738  gsurf_att *coloratt;
739 
740  /* Viewport variables */
741  GLdouble modelMatrix[16], projMatrix[16];
742  GLint viewport[4];
743  GLint window[4];
744 
745  int zeros, dr1, dr2, dr3, dr4;
746  int datarow1, datacol1, datarow2, datacol2;
747 
748  unsigned int ktrans = 255;
749 
750  G_debug(5, "gsd_surf_const(): id=%d", surf->gsurf_id);
751 
752  if (GS_check_cancel()) {
753  return (-1);
754  }
755 
756  cobuff = gs_get_att_typbuff(surf, ATT_COLOR, 0);
757 
758  gs_update_curmask(surf);
759  check_mask = surf->curmask ? 1 : 0;
760 
761  /*
762  checks ATT_TOPO & ATT_COLOR no_zero flags, make a mask from each,
763  combine it/them with any current mask, put in surf->curmask:
764  */
765  do_diff = (NULL != gsdiff_get_SDref());
766  xmod = surf->x_mod;
767  ymod = surf->y_mod;
768  xres = xmod * surf->xres;
769  yres = ymod * surf->yres;
770 
771  xcnt = VCOLS(surf);
772  ycnt = VROWS(surf);
773  ymax = (surf->rows - 1) * surf->yres;
774 
775  /* Get Viewport */
776  gsd_getwindow(window, viewport, modelMatrix, projMatrix);
777  /* adjust window */
778  window[0] += (int)(yres * 2);
779  window[1] -= (int)(yres * 2);
780  window[2] -= (int)(xres * 2);
781  window[3] += (int)(xres * 2);
782 
783 
785  gsd_pushmatrix();
786 
787  /* avoid scaling by zero */
788  GS_get_scale(&tx, &ty, &tz, 1);
789 
790  if (tz == 0.0) {
791  k = 0.0;
792  gsd_do_scale(0);
793  }
794  else {
795  gsd_do_scale(1);
796  }
797 
798  gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
799  zexag = surf->z_exag;
800 
801  if (CONST_ATT == surf->att[ATT_TRANSP].att_src) {
802  gsd_blend(1);
803  ktrans = 255 - (int)surf->att[ATT_TRANSP].constant;
804  gsd_zwritemask(0x0);
805  }
806 
807  ktrans = (ktrans << 24);
808 
809  /* will need to check for color source of FUNC_ATT & NOTSET_ATT,
810  or else use more general and inefficient gets */
811 
812  check_color = 1;
813  coloratt = &(surf->att[ATT_COLOR]);
814  col_src = surf->att[ATT_COLOR].att_src;
815 
816  if (col_src != MAP_ATT) {
817  if (col_src == CONST_ATT) {
818  curcolor = (int)surf->att[ATT_COLOR].constant;
819  }
820  else {
821  curcolor = surf->wire_color;
822  }
823 
824  check_color = 0;
825  }
826 
827  /* CONSTANTS */
828  pt[Z] = k * zexag;
829  n[X] = n[Y] = 0.0;
830  n[Z] = 1.0;
831 
832  /* just draw one polygon if no color mapped */
833  /* fast, but specular reflection will prob. be poor */
834  if (!check_color && !check_mask && !do_diff) {
835  gsd_bgnpolygon();
836 
837  pt[X] = pt[Y] = 0;
838  gsd_litvert_func(n, ktrans | curcolor, pt);
839 
840  pt[X] = xcnt * xres;
841  gsd_litvert_func(n, ktrans | curcolor, pt);
842 
843  pt[Y] = ycnt * yres;
844  gsd_litvert_func(n, ktrans | curcolor, pt);
845 
846  pt[X] = 0;
847  gsd_litvert_func(n, ktrans | curcolor, pt);
848 
849  gsd_endpolygon();
850  gsd_popmatrix();
851  gsd_blend(0);
852  gsd_zwritemask(0xffffffff);
853 
854  return (0);
855  }
856 
857  cnt = 0;
858 
859  for (row = 0; row < ycnt; row++) {
860  if (GS_check_cancel()) {
861  gsd_popmatrix();
862  gsd_blend(0);
863  gsd_zwritemask(0xffffffff);
864 
865  return (-1);
866  }
867 
868  datarow1 = row * ymod;
869  datarow2 = (row + 1) * ymod;
870 
871  y1 = ymax - row * yres;
872  y2 = ymax - (row + 1) * yres;
873  y1off = row * ymod * surf->cols;
874  y2off = (row + 1) * ymod * surf->cols;
875 
876  gsd_bgntmesh();
877 
878  zeros = 0;
879  dr1 = dr2 = dr3 = dr4 = 1;
880 
881  if (check_mask) {
882  if (BM_get(surf->curmask, 0, datarow1)) {
883  /*TL*/ ++zeros;
884  dr1 = 0;
885  }
886 
887  if (BM_get(surf->curmask, 0, datarow2)) {
888  /*BL*/ ++zeros;
889  dr2 = 0;
890  }
891  }
892 
893  if (dr1 && dr2) {
894  offset = y1off; /* TL */
895  pt[X] = 0;
896  pt[Y] = y1;
897 
898  if (check_color) {
899  curcolor = gs_mapcolor(cobuff, coloratt, offset);
900  }
901 
902  if (do_diff) {
903  pt[Z] = gsdiff_do_SD(k * zexag, offset);
904  }
905 
906  gsd_litvert_func(n, ktrans | curcolor, pt);
907  cnt++;
908 
909  offset = y2off; /* BL */
910  pt[X] = 0;
911  pt[Y] = y2;
912 
913  if (check_color) {
914  curcolor = gs_mapcolor(cobuff, coloratt, offset);
915  }
916 
917  if (do_diff) {
918  pt[Z] = gsdiff_do_SD(k * zexag, offset);
919  }
920 
921  gsd_litvert_func(n, ktrans | curcolor, pt);
922  cnt++;
923  }
924 
925  for (col = 0; col < xcnt; col++) {
926  datacol1 = col * xmod;
927  datacol2 = (col + 1) * xmod;
928 
929  x1 = col * xres;
930  x2 = (col + 1) * xres;
931 
932  zeros = 0;
933  dr1 = dr2 = dr3 = dr4 = 1;
934 
935  if (check_mask) {
936  if (BM_get(surf->curmask, datacol1, datarow1)) {
937  /*TL*/ ++zeros;
938  dr1 = 0;
939  }
940 
941  if (BM_get(surf->curmask, datacol1, datarow2)) {
942  /*BL*/ ++zeros;
943  dr2 = 0;
944  }
945 
946  if (BM_get(surf->curmask, datacol2, datarow2)) {
947  /*BR*/ ++zeros;
948  dr3 = 0;
949  }
950 
951  if (BM_get(surf->curmask, datacol2, datarow1)) {
952  /*TR*/ ++zeros;
953  dr4 = 0;
954  }
955 
956  if ((zeros > 1) && cnt) {
957  gsd_endtmesh();
958  cnt = 0;
959  gsd_bgntmesh();
960  continue;
961  }
962 
963  }
964 
965  if (cnt > 250) {
966  cnt = 0;
967  gsd_endtmesh();
968  gsd_bgntmesh();
969 
970  if (dr1) {
971  offset = y1off + datacol1; /* TL */
972  pt[X] = x1;
973  pt[Y] = y1;
974 
975  if (gsd_checkpoint
976  (pt, window, viewport, modelMatrix, projMatrix)) {
977  gsd_endtmesh();
978  cnt = 0;
979  gsd_bgntmesh();
980  continue;
981  }
982 
983  if (check_color) {
984  curcolor = gs_mapcolor(cobuff, coloratt, offset);
985  }
986 
987  if (do_diff) {
988  pt[Z] = gsdiff_do_SD(k * zexag, offset);
989  }
990 
991  gsd_litvert_func(n, ktrans | curcolor, pt);
992  cnt++;
993  }
994 
995  if (dr2) {
996  offset = y2off + datacol1; /* BL */
997  pt[X] = x1;
998  pt[Y] = y2;
999 
1000  if (gsd_checkpoint
1001  (pt, window, viewport, modelMatrix, projMatrix)) {
1002  gsd_endtmesh();
1003  cnt = 0;
1004  gsd_bgntmesh();
1005  continue;
1006  }
1007 
1008  if (check_color) {
1009  curcolor = gs_mapcolor(cobuff, coloratt, offset);
1010  }
1011 
1012  if (do_diff) {
1013  pt[Z] = gsdiff_do_SD(k * zexag, offset);
1014  }
1015 
1016  gsd_litvert_func(n, ktrans | curcolor, pt);
1017  cnt++;
1018  }
1019  }
1020 
1021  if (dr4) {
1022  offset = y1off + datacol2; /* TR */
1023  pt[X] = x2;
1024  pt[Y] = y1;
1025 
1026  if (gsd_checkpoint
1027  (pt, window, viewport, modelMatrix, projMatrix)) {
1028  gsd_endtmesh();
1029  cnt = 0;
1030  gsd_bgntmesh();
1031  continue;
1032  }
1033 
1034  if (check_color) {
1035  curcolor = gs_mapcolor(cobuff, coloratt, offset);
1036  }
1037 
1038  if (do_diff) {
1039  pt[Z] = gsdiff_do_SD(k * zexag, offset);
1040  }
1041 
1042  gsd_litvert_func(n, ktrans | curcolor, pt);
1043  cnt++;
1044  }
1045 
1046  if (dr3) {
1047  offset = y2off + datacol2; /* BR */
1048  pt[X] = x2;
1049  pt[Y] = y2;
1050 
1051  if (gsd_checkpoint
1052  (pt, window, viewport, modelMatrix, projMatrix)) {
1053  gsd_endtmesh();
1054  cnt = 0;
1055  gsd_bgntmesh();
1056  continue;
1057  }
1058 
1059  if (check_color) {
1060  curcolor = gs_mapcolor(cobuff, coloratt, offset);
1061  }
1062 
1063  if (do_diff) {
1064  pt[Z] = gsdiff_do_SD(k * zexag, offset);
1065  }
1066 
1067  gsd_litvert_func(n, ktrans | curcolor, pt);
1068  cnt++;
1069  }
1070  } /* ea col */
1071 
1072  gsd_endtmesh();
1073  } /* ea row */
1074 
1075  gsd_popmatrix();
1076  gsd_blend(0);
1077  gsd_zwritemask(0xffffffff);
1078 
1079  return (0);
1080 }
1081 
1082 /*!
1083  \brief Define user function
1084 
1085  Not yet supported
1086 
1087  \param gs surface (geosurf)
1088  \param user_func user function
1089 
1090  \return 1
1091  */
1092 int gsd_surf_func(geosurf * gs, int (*user_func) ())
1093 {
1094 
1095  return (1);
1096 }
1097 
1098 /*!
1099  \brief ADD
1100 
1101  \param npts1
1102  \param npts2
1103  \param surf1 first surface (geosurf)
1104  \param surf2 second surface (geosurf)
1105  \param points1
1106  \param points2
1107  \param norm
1108 
1109  \return 1
1110  */
1111 int gsd_triangulated_wall(int npts1, int npts2, geosurf * surf1,
1112  geosurf * surf2, Point3 * points1, Point3 * points2,
1113  float *norm)
1114 {
1115  int i, i1, i2, nlong, offset, col_src;
1116  int check_color1, check_color2, color1, color2;
1117  typbuff *cobuf1, *cobuf2;
1118  gsurf_att *coloratt1, *coloratt2;
1119 
1120  check_color1 = check_color2 = 1;
1121 
1122  col_src = surf1->att[ATT_COLOR].att_src;
1123 
1124  if (col_src != MAP_ATT) {
1125  if (col_src == CONST_ATT) {
1126  color1 = (int)surf1->att[ATT_COLOR].constant;
1127  }
1128  else {
1129  color1 = surf1->wire_color;
1130  }
1131 
1132  check_color1 = 0;
1133  }
1134 
1135  coloratt1 = &(surf1->att[ATT_COLOR]);
1136  cobuf1 = gs_get_att_typbuff(surf1, ATT_COLOR, 0);
1137 
1138  col_src = surf2->att[ATT_COLOR].att_src;
1139  if (col_src != MAP_ATT) {
1140  if (col_src == CONST_ATT) {
1141  color2 = (int)surf2->att[ATT_COLOR].constant;
1142  }
1143  else {
1144  color2 = surf2->wire_color;
1145  }
1146 
1147  check_color2 = 0;
1148  }
1149 
1150  coloratt2 = &(surf2->att[ATT_COLOR]);
1151  cobuf2 = gs_get_att_typbuff(surf2, ATT_COLOR, 0);
1152 
1154  gsd_pushmatrix();
1155  gsd_do_scale(1);
1156 
1157  gsd_bgntmesh();
1158 
1159  for (nlong = (npts1 > npts2 ? npts1 : npts2), i = 0; i < nlong; i++) {
1160  i1 = i * npts1 / nlong;
1161  i2 = i * npts2 / nlong;
1162  offset = XY2OFF(surf1, points1[i1][X], points1[i1][Y]);
1163 
1164  if (check_color1) {
1165  color1 = gs_mapcolor(cobuf1, coloratt1, offset);
1166  }
1167 
1168  offset = XY2OFF(surf1, points2[i2][X], points2[i2][Y]);
1169 
1170  if (check_color2) {
1171  color2 = gs_mapcolor(cobuf2, coloratt2, offset);
1172  }
1173 
1174  /* start with long line to ensure triangle */
1175  if (npts1 > npts2) {
1176  points1[i1][X] += surf1->x_trans;
1177  points1[i1][Y] += surf1->y_trans;
1178  points1[i1][Z] += surf1->z_trans;
1179  gsd_litvert_func(norm, color1, points1[i1]);
1180  points2[i2][X] += surf2->x_trans;
1181  points2[i2][Y] += surf2->y_trans;
1182  points2[i2][Z] += surf2->z_trans;
1183  gsd_litvert_func(norm, color2, points2[i2]);
1184  }
1185  else {
1186  points2[i2][X] += surf2->x_trans;
1187  points2[i2][Y] += surf2->y_trans;
1188  points2[i2][Z] += surf2->z_trans;
1189  gsd_litvert_func(norm, color2, points2[i2]);
1190  points1[i1][X] += surf1->x_trans;
1191  points1[i1][Y] += surf1->y_trans;
1192  points1[i1][Z] += surf1->z_trans;
1193  gsd_litvert_func(norm, color1, points1[i1]);
1194  }
1195  }
1196 
1197  gsd_endtmesh();
1198  gsd_popmatrix();
1199 
1200  return (1);
1201 }
1202 
1203 /*!
1204  \brief ADD
1205 
1206  \param mode
1207  */
1208 void gsd_setfc(int mode)
1209 {
1210  FCmode = mode;
1211 
1212  return;
1213 }
1214 
1215 /*!
1216  \brief ADD
1217 
1218  \return
1219  */
1220 int gsd_getfc(void)
1221 {
1222  return (FCmode);
1223 }
1224 
1225 /*!
1226  \brief ADD
1227 
1228  \param surf surface (geosurf)
1229  \param point
1230 
1231  \return
1232  */
1233 static int transpoint_is_masked(geosurf * surf, Point3 point)
1234 {
1235  Point3 tp;
1236 
1237  tp[X] = point[X] - surf->x_trans;
1238  tp[Y] = point[Y] - surf->y_trans;
1239 
1240  return (gs_point_is_masked(surf, tp));
1241 }
1242 
1243 /*!
1244  \brief ADD
1245 
1246  \param points
1247  \param gsurf
1248  \param ptn
1249  \param cursurf
1250  \param numsurfs
1251  \param belowsurf
1252 
1253  \return 0 if there is no surface below the current,
1254  \return -1 if the current surface is masked,
1255  \return 1 if the surface below the current surface is not masked
1256  (belowsurf is assigned)
1257  */
1258 static int get_point_below(Point3 ** points, geosurf ** gsurfs, int ptn,
1259  int cursurf, int numsurfs, int *belowsurf)
1260 {
1261  int n, found = -1;
1262  float nearz = 0.0, diff;
1263 
1264  if (gsurfs[cursurf]->curmask) {
1265  if (transpoint_is_masked(gsurfs[cursurf], points[cursurf][ptn])) {
1266  return (-1);
1267  }
1268  }
1269 
1270  for (n = 0; n < numsurfs; ++n) {
1271  diff = points[cursurf][ptn][Z] - points[n][ptn][Z];
1272 
1273  if (diff > 0) {
1274  if (!nearz || diff < nearz) {
1275  if (gsurfs[n]->curmask) {
1276  if (transpoint_is_masked(gsurfs[n], points[n][ptn])) {
1277  continue;
1278  }
1279  }
1280 
1281  nearz = diff;
1282  found = n;
1283  }
1284  }
1285  /* else if (diff == 0.0 && n != cursurf)
1286  {
1287  if (gsurfs[n]->curmask)
1288  {
1289  if (transpoint_is_masked(gsurfs[n], points[n][ptn]))
1290  {
1291  continue;
1292  }
1293  }
1294 
1295  nearz=diff;
1296  found = n;
1297  break;
1298  }
1299  */
1300  }
1301 
1302  if (found != -1) {
1303  *belowsurf = found;
1304 
1305  return (1);
1306  }
1307 
1308  return (0);
1309 }
1310 
1311 
1312 /*
1313  #define CPDEBUG
1314  */
1315 
1316 /*!
1317  \brief ADD
1318 
1319  \param np
1320  \param ns
1321  \param gsurfs
1322  \param points
1323  \param norm
1324 
1325  \return
1326  */
1327 int gsd_ortho_wall(int np, int ns, geosurf ** gsurfs, Point3 ** points,
1328  float *norm)
1329 {
1330  int n, i, offset, col_src, check_color[MAX_SURFS];
1331  int color, colors[MAX_SURFS], nocolor;
1332  typbuff *cobuf[MAX_SURFS];
1333  gsurf_att *coloratt[MAX_SURFS];
1334 
1335  nocolor = FCmode == FC_GREY ? 1 : 0;
1336 
1337  if (!nocolor) {
1338  for (n = 0; n < ns; ++n) {
1339  check_color[n] = 1;
1340 
1341  col_src = gsurfs[n]->att[ATT_COLOR].att_src;
1342 
1343  if (col_src != MAP_ATT) {
1344  if (col_src == CONST_ATT) {
1345  colors[n] = (int)gsurfs[n]->att[ATT_COLOR].constant;
1346  }
1347  else {
1348  colors[n] = gsurfs[n]->wire_color;
1349  }
1350 
1351  check_color[n] = 0;
1352  }
1353 
1354  coloratt[n] = &(gsurfs[n]->att[ATT_COLOR]);
1355  cobuf[n] = gs_get_att_typbuff(gsurfs[n], ATT_COLOR, 0);
1356  }
1357  }
1358 
1359 #ifdef CPDEBUG
1360  {
1362  }
1363 #endif
1364 
1365  /* changed from CM_DIFFUSE - July 25, 2005
1366  * should display proper color for cut planes
1367  */
1369 
1370  /* actually ought to write a GS_set_fencetransp() */
1371  if (nocolor) {
1372  color = 0x80808080;
1373  gsd_blend(1);
1374  gsd_zwritemask(0x0);
1375  }
1376 
1377  gsd_pushmatrix();
1378  gsd_do_scale(1);
1379 
1380  /* using segs_intersect here with segments projected to
1381  the 2d clipping plane */
1382  {
1383  float tx, ty;
1384  int bn, bnl, ctop, cbot, ctopl, cbotl, bsret;
1385  Point3 xing;
1386 
1387  if (nocolor) {
1388  ctop = cbot = ctopl = cbotl = color;
1389  }
1390 
1391  for (n = 0; n < ns; ++n) {
1392  for (i = 0; i < np; i++) {
1393  if (0 <
1394  (bsret =
1395  get_point_below(points, gsurfs, i, n, ns, &bn))) {
1396  gsd_bgntmesh();
1397 
1398  if (!nocolor) {
1399  SET_SCOLOR(n);
1400  SET_SCOLOR(bn);
1401 
1402  if (FCmode == FC_ABOVE) {
1403  ctop = cbot = colors[n];
1404  }
1405  else if (FCmode == FC_BELOW) {
1406  ctop = cbot = colors[bn];
1407  }
1408  else {
1409  cbot = colors[bn];
1410  ctop = colors[n];
1411  }
1412  }
1413 
1414  if (i) {
1415  /* need to find crossing? */
1416  if (!transpoint_is_masked(gsurfs[n], points[n][i - 1])
1417  && !transpoint_is_masked(gsurfs[bn],
1418  points[bn][i - 1])) {
1419  if (1 ==
1420  segs_intersect(0.0, points[n][i - 1][Z], 1.0,
1421  points[n][i][Z], 0.0,
1422  points[bn][i - 1][Z], 1.0,
1423  points[bn][i][Z], &tx, &ty)) {
1424  xing[Z] = ty;
1425  xing[Y] = points[n][i - 1][Y] + tx *
1426  (points[n][i][Y] - points[n][i - 1][Y]);
1427  xing[X] = points[n][i - 1][X] + tx *
1428  (points[n][i][X] - points[n][i - 1][X]);
1429  gsd_litvert_func(norm, ctop, xing);
1430  xing[Z] = points[bn][i - 1][Z] + tx *
1431  (points[bn][i][Z] - points[bn][i - 1][Z]);
1432  gsd_litvert_func(norm, cbot, xing);
1433  }
1434  }
1435  }
1436 
1437  gsd_litvert_func(norm, ctop, points[n][i]);
1438  gsd_litvert_func(norm, cbot, points[bn][i]);
1439  i++;
1440 
1441  bnl = -1;
1442 
1443  while (i < np && 0 < (bsret =
1444  get_point_below(points, gsurfs, i,
1445  n, ns, &bn))) {
1446 #ifdef CPDEBUG
1447  {
1448  int lower = 0;
1449 
1450  if (GS_check_cancel()) {
1451  break;
1452  }
1453  }
1454 #endif
1455 
1456  if (!nocolor) {
1457  ctopl = ctop;
1458  cbotl = cbot;
1459  SET_SCOLOR(n);
1460  SET_SCOLOR(bn);
1461 
1462  if (FCmode == FC_ABOVE) {
1463  ctop = cbot = colors[n];
1464  }
1465  else if (FCmode == FC_BELOW) {
1466  ctop = cbot = colors[bn];
1467  }
1468  else {
1469  cbot = colors[bn];
1470  ctop = colors[n];
1471  }
1472  }
1473 
1474  /*
1475  IF UPPER crossing :
1476  (crossing is between current & new lower surf)
1477  IF XING going DOWN:
1478  - plot crossing point (color previous upper)
1479  - endtmesh/bgntmesh
1480  - plot crossing point (color current upper)
1481  - plot "equivalent" point below (color current lower)
1482  IF XING going UP:
1483  - plot crossing point (color previous upper)
1484  - plot "equivalent" point below (color previous lower)
1485  - endtmesh/bgntmesh
1486  - plot crossing point (color current upper)
1487  ELSE IF LOWER crossing:
1488  (crossing between new & previous lower surfs):
1489  - plot "equivalent" point above (color previous upper)
1490  - plot crossing below (color previous lower)
1491  - endtmesh/bgntmesh
1492  - plot "equivalent" point above (color current upper)
1493  - plot crossing below (color current lower)
1494  */
1495  if (bnl >= 0 && bnl != bn) {
1496  /* crossing */
1497  float z1, z2;
1498  int upper = 0;
1499 
1500  if (!transpoint_is_masked(gsurfs[n],
1501  points[n][i - 1]) &&
1502  !transpoint_is_masked(gsurfs[bnl],
1503  points[bnl][i - 1]) &&
1504  !transpoint_is_masked(gsurfs[bn],
1505  points[bn][i - 1])) {
1506 
1507  if (1 == segs_intersect(0.0,
1508  points[n][i - 1][Z],
1509  1.0, points[n][i][Z],
1510  0.0,
1511  points[bn][i - 1][Z],
1512  1.0, points[bn][i][Z],
1513  &tx, &ty)) {
1514  /* crossing going up */
1515 
1516  G_debug(5,
1517  "crossing going up at surf %d no. %d",
1518  n, i);
1519 
1520  upper = 1;
1521  xing[Z] = ty;
1522  xing[Y] = points[n][i - 1][Y] + tx *
1523  (points[n][i][Y] -
1524  points[n][i - 1][Y]);
1525  xing[X] =
1526  points[n][i - 1][X] +
1527  tx * (points[n][i][X] -
1528  points[n][i - 1][X]);
1529  gsd_litvert_func(norm, ctopl, xing);
1530  z1 = xing[Z];
1531  xing[Z] = points[bnl][i - 1][Z] + tx *
1532  (points[bnl][i][Z] -
1533  points[bnl][i - 1][Z]);
1534  gsd_litvert_func(norm, cbotl, xing);
1535  xing[Z] = z1;
1536  gsd_endtmesh();
1537  gsd_bgntmesh();
1538  gsd_litvert_func(norm, ctop, xing);
1539  }
1540  else if (1 == segs_intersect(0.0,
1541  points[n][i -
1542  1][Z],
1543  1.0,
1544  points[n][i][Z],
1545  0.0,
1546  points[bnl][i -
1547  1]
1548  [Z], 1.0,
1549  points[bnl][i]
1550  [Z], &tx, &ty)) {
1551  /* crossing going down */
1552 
1553  G_debug(5,
1554  "crossing going down at surf %d no. %d",
1555  n, i);
1556 
1557  upper = 1;
1558  xing[Z] = ty;
1559  xing[Y] = points[n][i - 1][Y] + tx *
1560  (points[n][i][Y] -
1561  points[n][i - 1][Y]);
1562  xing[X] =
1563  points[n][i - 1][X] +
1564  tx * (points[n][i][X] -
1565  points[n][i - 1][X]);
1566  gsd_litvert_func(norm, ctopl, xing);
1567  z1 = xing[Z];
1568  xing[Z] = points[bnl][i - 1][Z] + tx *
1569  (points[bnl][i][Z] -
1570  points[bnl][i - 1][Z]);
1571  gsd_litvert_func(norm, cbotl, xing);
1572  xing[Z] = z1;
1573  gsd_endtmesh();
1574  gsd_bgntmesh();
1575  gsd_litvert_func(norm, ctop, xing);
1576  xing[Z] = points[bn][i - 1][Z] + tx *
1577  (points[bn][i][Z] -
1578  points[bn][i - 1][Z]);
1579  gsd_litvert_func(norm, cbot, xing);
1580  }
1581  }
1582 
1583  if (!upper &&
1584  !transpoint_is_masked(gsurfs[bn],
1585  points[bn][i - 1]) &&
1586  !transpoint_is_masked(gsurfs[bnl],
1587  points[bnl][i - 1])) {
1588 
1589  if (1 == segs_intersect(0.0,
1590  points[bn][i - 1][Z],
1591  1.0, points[bn][i][Z],
1592  0.0,
1593  points[bnl][i - 1][Z],
1594  1.0,
1595  points[bnl][i][Z],
1596  &tx, &ty)) {
1597 #ifdef CPDEBUG
1598  {
1599  lower = 1;
1600  }
1601 #endif
1602  G_debug(5,
1603  "lower crossing at surf %d no. %d between surfs %d & %d",
1604  n, i, bn, bnl);
1605 
1606  xing[Z] = ty;
1607  xing[Y] = points[bn][i - 1][Y] + tx *
1608  (points[bn][i][Y] -
1609  points[bn][i - 1][Y]);
1610  xing[X] = points[bn][i - 1][X] + tx *
1611  (points[bn][i][X] -
1612  points[bn][i - 1][X]);
1613  z2 = xing[Z];
1614  z1 = xing[Z] = points[n][i - 1][Z] + tx *
1615  (points[n][i][Z] -
1616  points[n][i - 1][Z]);
1617  gsd_litvert_func(norm, ctopl, xing);
1618  xing[Z] = z2;
1619  gsd_litvert_func(norm, cbotl, xing);
1620  gsd_endtmesh();
1621  gsd_bgntmesh();
1622  xing[Z] = z1;
1623  gsd_litvert_func(norm, ctop, xing);
1624  xing[Z] = z2;
1625  gsd_litvert_func(norm, cbot, xing);
1626  }
1627  }
1628 
1629 #ifdef CPDEBUG
1630  {
1631  if (!upper && !lower) {
1632  G_debug(5,
1633  "Crossing NOT found or masked:");
1634  G_debug(5,
1635  " current surf: %d [ %.2f %.2f %.2f -> %.2f %.2f %f",
1636  n, points[n][i - 1][X],
1637  points[n][i - 1][Y],
1638  points[n][i - 1][Z],
1639  points[n][i][X], points[n][i][Y],
1640  points[n][i][Z]);
1641  G_debug(5,
1642  " below surf: %d [ %.2f %.2f %.2f -> %.2f %.2f %f\n",
1643  bn, points[bn][i - 1][X],
1644  points[bn][i - 1][Y],
1645  points[bn][i - 1][Z],
1646  points[bn][i][X],
1647  points[bn][i][Y],
1648  points[bn][i][Z]);
1649  G_debug(5, gs
1650  " last below surf: %d [ %.2f %.2f %.2f -> %.2f %.2f %f\n",
1651  bnl, points[bnl][i - 1][X],
1652  points[bnl][i - 1][Y],
1653  points[bnl][i - 1][Z],
1654  points[bnl][i][X],
1655  points[bnl][i][Y],
1656  points[bnl][i][Z]);
1657  }
1658  }
1659 #endif
1660  }
1661 
1662  gsd_litvert_func(norm, ctop, points[n][i]);
1663  gsd_litvert_func(norm, cbot, points[bn][i]);
1664  bnl = bn;
1665  i++;
1666  }
1667 
1668  if (i < np) {
1669  /* need to find crossing? */
1670  if (!transpoint_is_masked(gsurfs[n], points[n][i - 1])
1671  && !transpoint_is_masked(gsurfs[bn],
1672  points[bn][i - 1])) {
1673  if (1 ==
1674  segs_intersect(0.0, points[n][i - 1][Z], 1.0,
1675  points[n][i][Z], 0.0,
1676  points[bn][i - 1][Z], 1.0,
1677  points[bn][i][Z], &tx, &ty)) {
1678  xing[Z] = ty;
1679  xing[Y] = points[n][i - 1][Y] + tx *
1680  (points[n][i][Y] - points[n][i - 1][Y]);
1681  xing[X] = points[n][i - 1][X] + tx *
1682  (points[n][i][X] - points[n][i - 1][X]);
1683  gsd_litvert_func(norm, ctop, xing);
1684  }
1685 
1686  i--;
1687  }
1688  }
1689 
1690  gsd_endtmesh();
1691  }
1692  }
1693  }
1694  }
1695 
1696  gsd_colormode(CM_DIFFUSE); /* set colormode back to DIFFUSE */
1697  gsd_popmatrix();
1698  gsd_blend(0);
1699  gsd_zwritemask(0xffffffff);
1700 
1701  return (1);
1702 }
1703 
1704 /*!
1705  \brief ADD
1706 
1707  bgn,end should already be in world modeling coords, but have to
1708  be reverse-translated to apply to each surface
1709 
1710  \param bgn,end 2d line for cutting plane
1711  \param norm indicates which way wall faces
1712 
1713  \return
1714  */
1715 int gsd_wall(float *bgn, float *end, float *norm)
1716 {
1717  geosurf *gsurfs[MAX_SURFS];
1718  Point3 *points[MAX_SURFS], *tmp;
1719  int nsurfs, ret, npts, npts1, n, i, err = 0;
1720  float bgn1[2], end1[2];
1721 
1722  if (norm[Z] > 0.0001 || norm[Z] < -.0001) {
1723  return (0); /* can't do tilted wall yet */
1724  }
1725 
1726  if (FCmode == FC_OFF) {
1727  return (0);
1728  }
1729 
1730  nsurfs = gs_getall_surfaces(gsurfs);
1731 
1732  for (n = 0; n < nsurfs; n++) {
1733  /* get drape points for surf */
1734  bgn1[X] = bgn[X] - gsurfs[n]->x_trans;
1735  bgn1[Y] = bgn[Y] - gsurfs[n]->y_trans;
1736  end1[X] = end[X] - gsurfs[n]->x_trans;
1737  end1[Y] = end[Y] - gsurfs[n]->y_trans;
1738  tmp = gsdrape_get_allsegments(gsurfs[n], bgn1, end1, &npts1);
1739 
1740  if (n) {
1741  if (npts != npts1) {
1742  G_warning(_("Cut-plane points mis-match between surfaces. "
1743  "Check resolution(s)."));
1744  err = 1;
1745  nsurfs = n;
1746 
1747  break;
1748  }
1749  }
1750 
1751  npts = npts1;
1752 
1753  if (n == nsurfs - 1) {
1754  /* last surf - don't need to copy */
1755  points[n] = tmp;
1756 
1757  for (i = 0; i < npts1; i++) {
1758  /* DOING translation here! */
1759  points[n][i][X] += gsurfs[n]->x_trans;
1760  points[n][i][Y] += gsurfs[n]->y_trans;
1761  points[n][i][Z] += gsurfs[n]->z_trans;
1762  }
1763 
1764  break;
1765  }
1766 
1767  /* allocate space in points and copy tmp to points */
1768  points[n] = (Point3 *) G_calloc(npts1, sizeof(Point3)); /* G_fatal_error */
1769 
1770  for (i = 0; i < npts1; i++) {
1771  GS_v3eq(points[n][i], tmp[i]);
1772 
1773  /* DOING translation here! */
1774  points[n][i][X] += gsurfs[n]->x_trans;
1775  points[n][i][Y] += gsurfs[n]->y_trans;
1776  points[n][i][Z] += gsurfs[n]->z_trans;
1777  }
1778  } /* done for */
1779 
1780  if (err) {
1781  for (n = 0; n < nsurfs; n++) {
1782  if (points[n]) {
1783  G_free(points[n]);
1784  }
1785  }
1786  return (0);
1787  }
1788 
1789 
1790  ret = gsd_ortho_wall(npts, nsurfs, gsurfs, points, norm);
1791 
1792  for (n = 0; n < nsurfs - 1; n++) {
1793  /* don't free last - it's constant */
1794  G_free(points[n]);
1795  }
1796 
1797  return (ret);
1798 }
1799 
1800 /*!
1801  \brief ADD
1802 
1803  Need to do Zexag scale of normal for arrow direction, drawing
1804  routine unexags z for arrow
1805 
1806  \param surf surface (geosurf)
1807 
1808  \return
1809  */
1811 {
1812  typbuff *buff, *cobuff;
1813  int check_mask, check_color;
1814  int xmod, ymod, row, col, cnt, xcnt, ycnt;
1815  long offset, y1off, y2off;
1816  float x1, x2, y1, y2, tx, ty, tz, sz;
1817  float n[3], pt[4], xres, yres, ymax, zexag;
1818  int col_src, curcolor;
1819  gsurf_att *coloratt;
1820 
1821  int zeros, dr1, dr2, dr3, dr4;
1822  int datarow1, datacol1, datarow2, datacol2;
1823 
1824  G_debug(3, "gsd_norm_arrows");
1825 
1826  /* avoid scaling by zero */
1827  GS_get_scale(&tx, &ty, &tz, 1);
1828 
1829  if (tz == 0.0) {
1830  return (0);
1831  }
1832 
1833  sz = GS_global_exag();
1834 
1835  /*
1836  checks ATT_TOPO & ATT_COLOR no_zero flags, make a mask from each,
1837  combine it/them with any current mask, put in surf->curmask:
1838  */
1839  gs_update_curmask(surf);
1840  check_mask = surf->curmask ? 1 : 0;
1841 
1842  check_color = 1;
1843  coloratt = &(surf->att[ATT_COLOR]);
1844  col_src = surf->att[ATT_COLOR].att_src;
1845 
1846  if (col_src != MAP_ATT) {
1847  if (col_src == CONST_ATT) {
1848  curcolor = (int)surf->att[ATT_COLOR].constant;
1849  }
1850  else {
1851  curcolor = surf->wire_color;
1852  }
1853 
1854  check_color = 0;
1855  }
1856 
1857  buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
1858  cobuff = gs_get_att_typbuff(surf, ATT_COLOR, 0);
1859 
1860  xmod = surf->x_mod;
1861  ymod = surf->y_mod;
1862  xres = xmod * surf->xres;
1863  yres = ymod * surf->yres;
1864  ymax = (surf->rows - 1) * surf->yres;
1865 
1866  xcnt = VCOLS(surf);
1867  ycnt = VROWS(surf);
1868 
1869  gsd_pushmatrix();
1870  gsd_do_scale(1);
1871  gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
1872 
1873  zexag = surf->z_exag;
1874  /* CURRENTLY ALWAYS 1.0 */
1875 
1876 #ifdef DO_ARROW_SOLID
1878 #else
1880 #endif
1881 
1882  cnt = 0;
1883 
1884  for (row = 0; row < ycnt; row++) {
1885  if (GS_check_cancel()) {
1886  gsd_popmatrix();
1887 
1888  return (-1);
1889  }
1890 
1891  datarow1 = row * ymod;
1892  datarow2 = (row + 1) * ymod;
1893 
1894  y1 = ymax - row * yres;
1895  y2 = ymax - (row + 1) * yres;
1896  y1off = row * ymod * surf->cols;
1897  y2off = (row + 1) * ymod * surf->cols;
1898 
1899  zeros = 0;
1900  dr1 = dr2 = dr3 = dr4 = 1;
1901 
1902  if (check_mask) {
1903  if (BM_get(surf->curmask, 0, datarow1)) {
1904  /*TL*/ ++zeros;
1905  dr1 = 0;
1906  }
1907 
1908  if (BM_get(surf->curmask, 0, datarow2)) {
1909  /*BL*/ ++zeros;
1910  dr2 = 0;
1911  }
1912  }
1913 
1914  if (dr1 && dr2) {
1915  offset = y1off; /* TL */
1916  FNORM(surf->norms[offset], n);
1917  pt[X] = 0;
1918  pt[Y] = y2;
1919  GET_MAPATT(buff, offset, pt[Z]);
1920  pt[Z] *= zexag;
1921 
1922  if (check_color) {
1923  curcolor = gs_mapcolor(cobuff, coloratt, offset);
1924  }
1925 
1926 #ifdef DO_ARROW_SOLID
1927  gsd_3darrow(pt, curcolor, xres * 2, xres / 2, n, sz);
1928 #else
1929  if (DEBUG_ARROW) {
1930  gsd_arrow(pt, 0x000000, xres * 2, n, sz, surf);
1931  }
1932 #endif
1933 
1934  cnt++;
1935 
1936  offset = y2off; /* BL */
1937  FNORM(surf->norms[offset], n);
1938  pt[X] = 0;
1939  pt[Y] = y2;
1940  GET_MAPATT(buff, offset, pt[Z]);
1941  pt[Z] *= zexag;
1942 
1943  if (check_color) {
1944  curcolor = gs_mapcolor(cobuff, coloratt, offset);
1945  }
1946 
1947 #ifdef DO_ARROW_SOLID
1948  gsd_3darrow(pt, curcolor, xres * 2, xres / 2, n, sz);
1949 #else
1950  if (DEBUG_ARROW) {
1951  gsd_arrow(pt, 0x000000, xres * 2, n, sz, surf);
1952  }
1953 #endif
1954 
1955  cnt++;
1956  }
1957 
1958  for (col = 0; col < xcnt; col++) {
1959  datacol1 = col * xmod;
1960  datacol2 = (col + 1) * xmod;
1961 
1962  x1 = col * xres;
1963  x2 = (col + 1) * xres;
1964 
1965  zeros = 0;
1966  dr1 = dr2 = dr3 = dr4 = 1;
1967 
1968  if (check_mask) {
1969  if (BM_get(surf->curmask, datacol1, datarow1)) {
1970  /*TL*/ ++zeros;
1971  dr1 = 0;
1972  }
1973 
1974  if (BM_get(surf->curmask, datacol1, datarow2)) {
1975  /*BL*/ ++zeros;
1976  dr2 = 0;
1977  }
1978 
1979  if (BM_get(surf->curmask, datacol2, datarow2)) {
1980  /*BR*/ ++zeros;
1981  dr3 = 0;
1982  }
1983 
1984  if (BM_get(surf->curmask, datacol2, datarow1)) {
1985  /*TR*/ ++zeros;
1986  dr4 = 0;
1987  }
1988 
1989  if ((zeros > 1) && cnt) {
1990  cnt = 0;
1991  continue;
1992  }
1993 
1994  }
1995 
1996  if (dr4) {
1997  offset = y1off + datacol2; /* TR */
1998  FNORM(surf->norms[offset], n);
1999  pt[X] = x2;
2000  pt[Y] = y1;
2001  GET_MAPATT(buff, offset, pt[Z]);
2002  pt[Z] *= zexag;
2003 
2004  if (check_color) {
2005  curcolor = gs_mapcolor(cobuff, coloratt, offset);
2006  }
2007 
2008 #ifdef DO_ARROW_SOLID
2009  gsd_3darrow(pt, curcolor, xres * 2, xres / 2, n, sz);
2010 #else
2011  if (DEBUG_ARROW) {
2012  gsd_arrow(pt, 0x000000, xres * 2, n, sz, surf);
2013  }
2014 #endif
2015 
2016  cnt++;
2017  }
2018 
2019  if (dr3) {
2020  offset = y2off + datacol2; /* BR */
2021  FNORM(surf->norms[offset], n);
2022  pt[X] = x2;
2023  pt[Y] = y2;
2024  GET_MAPATT(buff, offset, pt[Z]);
2025  pt[Z] *= zexag;
2026 
2027  if (check_color) {
2028  curcolor = gs_mapcolor(cobuff, coloratt, offset);
2029  }
2030 
2031 #ifdef DO_ARROW_SOLID
2032  gsd_3darrow(pt, curcolor, xres * 2, xres / 2, n, sz);
2033 #else
2034  if (DEBUG_ARROW) {
2035  gsd_arrow(pt, 0x000000, xres * 2, n, sz, surf);
2036  }
2037 #endif
2038 
2039  cnt++;
2040  }
2041  } /* ea col */
2042  } /* ea row */
2043  gsd_popmatrix();
2044 
2045  return (1);
2046 }
2047 
2048 
2049 /*!
2050  \brief Draw surface using triangle fan instead of strip
2051 
2052  Optimized by getting rid of BM_get mask check - GET_MAPPATT does same
2053  and returns zero if masked
2054 
2055  Only do in window check on Fan center(v0) to further optimize -- this runs
2056  the risk of trimming points in view !!
2057 
2058  \param surf surface (geosurf)
2059 
2060  \return
2061  */
2063 {
2064  int check_mask, check_color, check_transp;
2065  int check_material, check_emis, check_shin;
2066  typbuff *buff, *cobuff, *trbuff, *embuff, *shbuff;
2067  int xmod, ymod;
2068  int row, col, cnt, xcnt, ycnt;
2069  long y1off, y2off, y3off;
2070  long offset2[10];
2071  float pt2[10][2];
2072  int ii;
2073  float x1, x2, x3, y1, y2, y3, tx, ty, tz, ttr;
2074  float n[3], pt[4], xres, yres, ymax, zexag;
2075  int em_src, sh_src, trans_src, col_src, curcolor;
2076  gsurf_att *ematt, *shatt, *tratt, *coloratt;
2077 
2078 
2079  /* Viewport variables for accelerated drawing */
2080  GLdouble modelMatrix[16], projMatrix[16];
2081  GLint viewport[4];
2082  GLint window[4];
2083  int cnt1 = 0, cnt2 = 0;
2084 
2085  int datarow1, datacol1, datarow2, datacol2, datarow3, datacol3;
2086 
2087  float kem, ksh, pkem, pksh;
2088  unsigned int ktrans;
2089 
2090  int step_val = 2; /* should always be factor of 2 for fan */
2091  int start_val = 1; /* one half of step_val */
2092 
2093  /* avoid scaling by zero */
2094  GS_get_scale(&tx, &ty, &tz, 1);
2095 
2096  if (tz == 0.0) {
2097  return (gsd_surf_const(surf, 0.0));
2098  }
2099  /* else if (surf->z_exag == 0.0)
2100  {
2101  return(gsd_surf_const(surf, surf->z_min));
2102  }
2103  NOT YET IMPLEMENTED */
2104 
2105  buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
2106  cobuff = gs_get_att_typbuff(surf, ATT_COLOR, 0);
2107 
2108  gs_update_curmask(surf);
2109  check_mask = surf->curmask ? 1 : 0;
2110 
2111  /*
2112  checks ATT_TOPO & ATT_COLOR no_zero flags, make a mask from each,
2113  combine it/them with any current mask, put in surf->curmask:
2114  */
2115  xmod = surf->x_mod;
2116  ymod = surf->y_mod;
2117  xres = xmod * surf->xres;
2118  yres = ymod * surf->yres;
2119  ymax = (surf->rows - 1) * surf->yres;
2120 
2121  xcnt = VCOLS(surf);
2122  ycnt = VROWS(surf);
2123 
2124  /* Get viewport */
2125  gsd_getwindow(window, viewport, modelMatrix, projMatrix);
2126 
2127 
2129  gsd_pushmatrix();
2130  gsd_do_scale(1);
2131  gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
2132  zexag = surf->z_exag;
2133 
2134  /* adjust window */
2135  window[0] += (int)(yres * 4 * zexag);
2136  window[1] -= (int)(yres * 4 * zexag);
2137  window[2] -= (int)(xres * 4 * zexag);
2138  window[3] += (int)(xres * 4 * zexag);
2139 
2140  /* CURRENTLY ALWAYS 1.0 */
2141 #ifdef CALC_AREA
2142  sz = GS_global_exag();
2143 #endif
2144 
2145  /* TODO: get rid of (define) these magic numbers scaling the attribute vals */
2146  check_transp = 0;
2147  tratt = &(surf->att[ATT_TRANSP]);
2148  ktrans = (255 << 24);
2149  trans_src = surf->att[ATT_TRANSP].att_src;
2150 
2151  if (CONST_ATT == trans_src && surf->att[ATT_TRANSP].constant != 0.0) {
2152  ktrans = (255 - (int)surf->att[ATT_TRANSP].constant) << 24;
2153  gsd_blend(1);
2154  gsd_zwritemask(0x0);
2155  }
2156  else if (MAP_ATT == trans_src) {
2157  trbuff = gs_get_att_typbuff(surf, ATT_TRANSP, 0);
2158  check_transp = trbuff ? 1 : 0;
2159  gsd_blend(1);
2160  gsd_zwritemask(0x0);
2161  }
2162 
2163  check_emis = 0;
2164  ematt = &(surf->att[ATT_EMIT]);
2165  kem = 0.0;
2166  pkem = 1.0;
2167  em_src = surf->att[ATT_EMIT].att_src;
2168 
2169  if (CONST_ATT == em_src) {
2170  kem = surf->att[ATT_EMIT].constant / 255.;
2171  }
2172  else if (MAP_ATT == em_src) {
2173  embuff = gs_get_att_typbuff(surf, ATT_EMIT, 0);
2174  check_emis = embuff ? 1 : 0;
2175  }
2176 
2177  check_shin = 0;
2178  shatt = &(surf->att[ATT_SHINE]);
2179  ksh = 0.0;
2180  pksh = 1.0;
2181  sh_src = surf->att[ATT_SHINE].att_src;
2182 
2183  if (CONST_ATT == sh_src) {
2184  ksh = surf->att[ATT_SHINE].constant / 255.;
2185  gsd_set_material(1, 0, ksh, kem, 0x0);
2186  }
2187  else if (MAP_ATT == sh_src) {
2188  shbuff = gs_get_att_typbuff(surf, ATT_SHINE, 0);
2189  check_shin = shbuff ? 1 : 0;
2190  }
2191 
2192  /* will need to check for color source of FUNC_ATT & NOTSET_ATT,
2193  or else use more general and inefficient gets */
2194  check_color = 1;
2195  coloratt = &(surf->att[ATT_COLOR]);
2196  col_src = surf->att[ATT_COLOR].att_src;
2197 
2198  if (col_src != MAP_ATT) {
2199  if (col_src == CONST_ATT) {
2200  curcolor = (int)surf->att[ATT_COLOR].constant;
2201  }
2202  else {
2203  curcolor = surf->wire_color;
2204  }
2205 
2206  check_color = 0;
2207  }
2208 
2209  check_material = (check_shin || check_emis || (kem && check_color));
2210 
2211  /* would also be good to check if colormap == surfmap, to increase speed */
2212  /* will also need to set check_transp, check_shine, etc & fix material */
2213  cnt = 0;
2214 
2215  for (row = start_val; row < ycnt; row += step_val) {
2216  if (GS_check_cancel()) {
2217  gsd_popmatrix();
2218  gsd_blend(0);
2219  gsd_zwritemask(0xffffffff);
2220 
2221  return (-1);
2222  }
2223 
2224  /*
2225  if (row == 201 && new_fan == 0) {
2226  xmod *= 2;
2227  ymod *= 2;
2228  xres = xmod * surf->xres;
2229  yres = ymod * surf->yres;
2230  step_val *= 2;
2231  new_fan = 1;
2232  row -= 1;
2233  row /= 2;
2234  }
2235  */
2236  datarow1 = row * ymod;
2237  datarow2 = (row - (step_val / 2)) * ymod;
2238  datarow3 = (row + (step_val / 2)) * ymod;
2239 
2240 
2241  y1 = ymax - row * yres;
2242  y2 = ymax - (row - (step_val / 2)) * yres;
2243  y3 = ymax - (row + (step_val / 2)) * yres;
2244 
2245  y1off = row * ymod * surf->cols;
2246  y2off = (row - (step_val / 2)) * ymod * surf->cols;
2247  y3off = (row + (step_val / 2)) * ymod * surf->cols;
2248 
2249 
2250  for (col = start_val; col < xcnt; col += step_val) {
2251  datacol1 = col * xmod;
2252  datacol2 = (col - (step_val / 2)) * xmod;
2253  datacol3 = (col + (step_val / 2)) * xmod;
2254 
2255  x1 = col * xres;
2256  x2 = (col - (step_val / 2)) * xres;
2257  x3 = (col + (step_val / 2)) * xres;
2258 
2259 
2260  /* 0 */
2261  /*
2262  if (check_mask) {
2263  if (BM_get(surf->curmask, datacol1, datarow1))
2264  continue;
2265  }
2266  */
2267 
2268  cnt1++;
2269 
2270  /* Do not need BM_get because GET_MAPATT calls
2271  * same and returns zero if masked
2272  */
2273  offset2[0] = y1off + datacol1; /* fan center */
2274  pt2[0][X] = x1;
2275  pt2[0][Y] = y1; /* fan center */
2276  pt[X] = pt2[0][X];
2277  pt[Y] = pt2[0][Y];
2278  if (!GET_MAPATT(buff, offset2[0], pt[Z]))
2279  continue; /* masked */
2280  else {
2281  pt[Z] *= zexag;
2282  if (gsd_checkpoint
2283  (pt, window, viewport, modelMatrix, projMatrix))
2284  continue;
2285  }
2286 
2287 
2288  offset2[1] = y2off + datacol2;
2289  offset2[2] = y2off + datacol1;
2290  offset2[3] = y2off + datacol3;
2291  offset2[4] = y1off + datacol3;
2292  offset2[5] = y3off + datacol3;
2293  offset2[6] = y3off + datacol1;
2294  offset2[7] = y3off + datacol2;
2295  offset2[8] = y1off + datacol2;
2296  offset2[9] = y2off + datacol2; /* repeat 1st corner to close */
2297 
2298  pt2[1][X] = x2;
2299  pt2[1][Y] = y2;
2300  pt2[2][X] = x1;
2301  pt2[2][Y] = y2;
2302  pt2[3][X] = x3;
2303  pt2[3][Y] = y2;
2304  pt2[4][X] = x3;
2305  pt2[4][Y] = y1;
2306  pt2[5][X] = x3;
2307  pt2[5][Y] = y3;
2308  pt2[6][X] = x1;
2309  pt2[6][Y] = y3;
2310  pt2[7][X] = x2;
2311  pt2[7][Y] = y3;
2312  pt2[8][X] = x2;
2313  pt2[8][Y] = y1;
2314  pt2[9][X] = x2;
2315  pt2[9][Y] = y2; /* repeat 1st corner to close */
2316 
2317 
2318  /* Run through triangle fan */
2319  gsd_bgntfan();
2320  for (ii = 0; ii < 10; ii++) {
2321 
2322  if (ii > 0) {
2323  pt[X] = pt2[ii][X];
2324  pt[Y] = pt2[ii][Y];
2325  if (!GET_MAPATT(buff, offset2[ii], pt[Z]))
2326  continue;
2327  pt[Z] *= zexag;
2328  }
2329 
2330  FNORM(surf->norms[offset2[ii]], n);
2331 
2332  if (check_color)
2333  curcolor = gs_mapcolor(cobuff, coloratt, offset2[ii]);
2334 
2335  if (check_transp) {
2336  GET_MAPATT(trbuff, offset2[ii], ttr);
2337  ktrans = (char)SCALE_ATT(tratt, ttr, 0, 255);
2338  ktrans = (char)(255 - ktrans) << 24;
2339  }
2340 
2341  if (check_material) {
2342  if (check_emis) {
2343  GET_MAPATT(embuff, offset2[ii], kem);
2344  kem = SCALE_ATT(ematt, kem, 0., 1.);
2345  }
2346 
2347  if (check_shin) {
2348  GET_MAPATT(shbuff, offset2[ii], ksh);
2349  ksh = SCALE_ATT(shatt, ksh, 0., 1.);
2350  }
2351 
2352  if (pksh != ksh || pkem != kem || (kem && check_color)) {
2353  pksh = ksh;
2354  pkem = kem;
2355  gsd_set_material(check_shin, check_emis,
2356  ksh, kem, curcolor);
2357  }
2358  }
2359 
2360  gsd_litvert_func(n, ktrans | curcolor, pt);
2361 
2362 
2363  } /* close ii loop */
2364  gsd_endtfan();
2365  cnt2++;
2366  } /* end col */
2367  } /* end row */
2368 
2369 
2370  gsd_popmatrix();
2371  gsd_blend(0);
2372  gsd_zwritemask(0xffffffff);
2373 
2374  return (0);
2375 }
int gs_mapcolor(typbuff *, gsurf_att *, int)
Call this one when you already know att_src is MAP_ATT.
Definition: gs.c:969
void gsd_endtfan(void)
ADD.
Definition: gsd_prim.c:346
if(!(yy_init))
Definition: sqlp.yy.c:775
#define CM_DIFFUSE
Definition: ogsf.h:148
long wire_color
Definition: ogsf.h:263
void gsd_blend(int)
Specify pixel arithmetic.
Definition: gsd_prim.c:996
int gs_getall_surfaces(geosurf **)
Get array of geosurf structs.
Definition: gs.c:108
#define ATT_SHINE
Definition: ogsf.h:77
void GS_v3sub(float *, float *)
Subtract vectors.
Definition: gs_util.c:212
int gsd_arrow(float *, unsigned long, float, float *, float, geosurf *)
ADD.
Definition: gsd_objs.c:923
unsigned long * norms
Definition: ogsf.h:274
void gsd_bgnpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition: gsd_prim.c:371
#define NOTSET_ATT
Definition: ogsf.h:82
#define FC_OFF
Definition: ogsf.h:106
#define VROWS(gs)
Definition: rowcol.h:13
#define SET_SCOLOR(sf)
MACROS for use in gsd_ortho_wall ONLY !!!
Definition: gsd_surf.c:46
int rows
Definition: ogsf.h:260
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition: gsd_prim.c:500
#define VCOLS(gs)
Definition: rowcol.h:14
#define ATT_TOPO
Definition: ogsf.h:73
int gs_get_att_src(geosurf *, int)
Get attribute source.
Definition: gs.c:656
int segs_intersect(float, float, float, float, float, float, float, float, float *, float *)
Line intersect.
Definition: gsdrape.c:1210
void gsd_endpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition: gsd_prim.c:386
int gsd_surf_const(geosurf *surf, float k)
Using tmesh - not confident with qstrips portability.
Definition: gsd_surf.c:729
#define XY2OFF(gs, px, py)
Definition: rowcol.h:24
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:149
Point3 * gsdrape_get_allsegments(geosurf *, float *, float *, int *)
Get all segments.
Definition: gsdrape.c:401
int gsd_getfc(void)
ADD.
Definition: gsd_surf.c:1220
#define FUNC_ATT
Definition: ogsf.h:85
#define FC_BELOW
Definition: ogsf.h:108
float Point3[3]
Definition: ogsf.h:201
#define NULL
Definition: ccmath.h:32
#define GSD_BOTH
Definition: ogsf.h:103
#define MAX_SURFS
Definition: ogsf.h:38
int gsd_surf_map(geosurf *surf)
Draw surface using triangle fan instead of strip.
Definition: gsd_surf.c:2062
#define G_calloc(m, n)
Definition: defs/gis.h:113
IFLAG att_src
Definition: ogsf.h:247
float z_exag
Definition: ogsf.h:266
int gsd_wall(float *bgn, float *end, float *norm)
ADD.
Definition: gsd_surf.c:1715
void GS_v3cross(float *, float *, float *)
Get the cross product v3 = v1 cross v2.
Definition: gs_util.c:406
int gsd_surf_map_old(geosurf *surf)
ADD.
Definition: gsd_surf.c:140
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
Definition: symbol/read.c:220
int gsd_ortho_wall(int np, int ns, geosurf **gsurfs, Point3 **points, float *norm)
ADD.
Definition: gsd_surf.c:1327
int gsd_norm_arrows(geosurf *surf)
ADD.
Definition: gsd_surf.c:1810
#define DEBUG_ARROW
Definition: gsd_surf.c:41
#define FC_GREY
Definition: ogsf.h:110
int cols
Definition: ogsf.h:260
void show_colormode(void)
Print color mode to stderr.
Definition: gsd_prim.c:150
void gsd_colormode(int)
Set color mode.
Definition: gsd_prim.c:97
int gsd_surf(geosurf *surf)
ADD.
Definition: gsd_surf.c:81
double yres
Definition: ogsf.h:265
int x_mod
Definition: ogsf.h:271
float gsdiff_do_SD(float, int)
ADD.
Definition: gsdiff.c:94
int gsd_checkpoint(float *, int *, int *, double *, double *)
float x_trans
Definition: ogsf.h:267
#define CM_COLOR
Definition: ogsf.h:145
int gs_update_curmask(geosurf *)
Update current maps.
Definition: gs_bm.c:232
#define MAP_ATT
Definition: ogsf.h:83
void gsd_translate(float, float, float)
Multiply the current matrix by a translation matrix.
Definition: gsd_prim.c:538
int y_mod
Definition: ogsf.h:271
#define ATT_COLOR
Definition: ogsf.h:74
void gsd_bgntfan(void)
ADD.
Definition: gsd_prim.c:336
int BM_get(struct BM *, int, int)
Gets &#39;val&#39; from the bitmap.
Definition: bitmap.c:223
void gsd_3darrow(float *, unsigned long, float, float, float *, float)
Draw 3d north arrow.
Definition: gsd_objs.c:1082
struct BM * curmask
Definition: ogsf.h:275
int(* user_func)()
Definition: ogsf.h:250
#define Z
Definition: ogsf.h:139
int gsd_surf_func(geosurf *gs, int(*user_func)())
Define user function.
Definition: gsd_surf.c:1092
float GS_global_exag(void)
Get global z-exag value.
Definition: gs2.c:1999
gsurf_att att[MAX_ATTS]
Definition: ogsf.h:261
void gsd_zwritemask(unsigned long)
Write out z-mask.
Definition: gsd_prim.c:240
void gsd_setfc(int mode)
ADD.
Definition: gsd_surf.c:1208
float y_trans
Definition: ogsf.h:267
typbuff * gs_get_att_typbuff(geosurf *, int, int)
Get attribute data buffer.
Definition: gs.c:681
#define Y
Definition: ogsf.h:138
void GS_v3eq(float *, float *)
Copy vector values.
Definition: gs_util.c:178
int gs_point_is_masked(geosurf *, float *)
Check if point is masked.
Definition: gs.c:1317
void gsd_getwindow(int *, int *, double *, double *)
Get viewport.
Definition: gsd_prim.c:553
#define ATT_TRANSP
Definition: ogsf.h:76
int gsurf_id
Definition: ogsf.h:259
int gsd_triangulated_wall(int npts1, int npts2, geosurf *surf1, geosurf *surf2, Point3 *points1, Point3 *points2, float *norm)
ADD.
Definition: gsd_surf.c:1111
void G_warning(const char *,...) __attribute__((format(printf
void gsd_litvert_func(float *, unsigned long, float *)
Set the current normal vector & specify vertex.
Definition: gsd_prim.c:660
Definition: ogsf.h:204
void GS_v3mag(float *, float *)
Magnitude of vector.
Definition: gs_util.c:421
geosurf * gsdiff_get_SDref(void)
ADD.
Definition: gsdiff.c:77
int GS_check_cancel(void)
Check for cancel.
Definition: gsx.c:30
#define _(str)
Definition: glocale.h:10
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition: gsd_prim.c:510
#define X
Definition: ogsf.h:137
#define FNORM(i, nv)
Definition: gsget.h:50
void GS_get_scale(float *, float *, float *, int)
Get axis scale.
Definition: gs2.c:3240
#define SCALE_ATT(att, val, low, high)
Definition: gsget.h:22
void gsd_bgntmesh(void)
ADD.
Definition: gsd_prim.c:296
void gsd_endtmesh(void)
ADD.
Definition: gsd_prim.c:306
#define ATT_EMIT
Definition: ogsf.h:78
void gsd_set_material(int, int, float, float, int)
Set material.
Definition: gsd_prim.c:806
float z_trans
Definition: ogsf.h:267
double xres
Definition: ogsf.h:265
#define CONST_ATT
Definition: ogsf.h:84
void GS_set_draw(int)
Sets which buffer to draw to.
Definition: gs2.c:2462
void gsd_do_scale(int)
Set current scale.
Definition: gsd_views.c:355
int G_debug(int, const char *,...) __attribute__((format(printf
Definition: ogsf.h:257
float constant
Definition: ogsf.h:251
#define FC_ABOVE
Definition: ogsf.h:107
int gs_calc_normals(geosurf *)
Calculate normals.
Definition: gs_norms.c:124
#define GET_MAPATT(buff, offset, att)
Definition: gsget.h:27