home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume30 / gnuplot3 / patch02f / patch.3
Encoding:
Text File  |  1992-06-19  |  27.9 KB  |  1,021 lines

  1. diff -rc gnuplot/graph3d.c gnuplot3.2/graph3d.c
  2. *** gnuplot/graph3d.c    Fri Sep 20 09:36:52 1991
  3. --- gnuplot3.2/graph3d.c    Wed Mar 25 07:59:40 1992
  4. ***************
  5. *** 1,6 ****
  6.   /* GNUPLOT - graph3d.c */
  7.   /*
  8. !  * Copyright (C) 1986, 1987, 1990, 1991   Thomas Williams, Colin Kelley
  9.    *
  10.    * Permission to use, copy, and distribute this software and its
  11.    * documentation for any purpose with or without fee is hereby granted, 
  12. --- 1,10 ----
  13. + #ifndef lint
  14. + static char *RCSid = "$Id: graph3d.c,v 3.26 92/03/24 22:34:27 woo Exp Locker: woo $";
  15. + #endif
  16.   /* GNUPLOT - graph3d.c */
  17.   /*
  18. !  * Copyright (C) 1986, 1987, 1990, 1991, 1992   Thomas Williams, Colin Kelley
  19.    *
  20.    * Permission to use, copy, and distribute this software and its
  21.    * documentation for any purpose with or without fee is hereby granted, 
  22. ***************
  23. *** 21,31 ****
  24.    *       Gershon Elber and many others.
  25.    *
  26.    * Send your comments or suggestions to 
  27. !  *  pixar!info-gnuplot@sun.com.
  28.    * This is a mailing list; to join it send a note to 
  29. !  *  pixar!info-gnuplot-request@sun.com.  
  30.    * Send bug reports to
  31. !  *  pixar!bug-gnuplot@sun.com.
  32.    */
  33.   
  34.   #include <stdio.h>
  35. --- 25,35 ----
  36.    *       Gershon Elber and many others.
  37.    *
  38.    * Send your comments or suggestions to 
  39. !  *  info-gnuplot@ames.arc.nasa.gov.
  40.    * This is a mailing list; to join it send a note to 
  41. !  *  info-gnuplot-request@ames.arc.nasa.gov.  
  42.    * Send bug reports to
  43. !  *  bug-gnuplot@ames.arc.nasa.gov.
  44.    */
  45.   
  46.   #include <stdio.h>
  47. ***************
  48. *** 46,51 ****
  49. --- 50,76 ----
  50.   #endif
  51.   #endif
  52.   
  53. + /*
  54. +  * hidden_line_type_above, hidden_line_type_below - controls type of lines
  55. +  *   for above and below parts of the surface.
  56. +  * hidden_no_update - if TRUE lines will be hidden line removed but they
  57. +  *   are not assumed to be part of the surface (i.e. grid) and therefore
  58. +  *   do not influence the hidings.
  59. +  * hidden_max_index - length of hidden_low_bound and hidden_high_bound vecs.
  60. +  * hidden_first_row - TRUE if we are now drawing the first row of the surface.
  61. +  * hidden_active - TRUE if hidden lines are to be removed.
  62. +  * hidden_low_bound, hidden_high_bound - two vectors of size hidden_max_index
  63. +  *   that hold the above and below floating horisons.
  64. +  */
  65. + static int hidden_line_type_above, hidden_line_type_below, hidden_no_update;
  66. + static int hidden_max_index, hidden_first_row, hidden_active = FALSE;
  67. + static int *hidden_low_bound, *hidden_high_bound;
  68. + #define HIDDEN_BOUND(x)        (x < 0 ? 0 : x >= hidden_max_index ? \
  69. +                              hidden_max_index - 1 : x)
  70. + #define HIDDEN_LOW_BOUND(x) (hidden_low_bound[HIDDEN_BOUND(x)])
  71. + #define HIDDEN_HIGH_BOUND(x) (hidden_high_bound[HIDDEN_BOUND(x)])
  72. + #define SET_HIDDEN_BOUND(vec, x, y) (vec[HIDDEN_BOUND(x)] = y)
  73.   static plot3d_impulses();
  74.   static plot3d_lines();
  75.   static plot3d_points();
  76. ***************
  77. *** 70,75 ****
  78. --- 95,101 ----
  79.   static xtick();
  80.   static ytick();
  81.   static ztick();
  82. + static setlinestyle();
  83.   
  84.   #ifndef max        /* Lattice C has max() in math.h, but shouldn't! */
  85.   #define max(a,b) ((a > b) ? a : b)
  86. ***************
  87. *** 243,248 ****
  88. --- 269,539 ----
  89.       *yt = ((int) (res[1] * yscaler / w)) + ymiddle;
  90.   }
  91.   
  92. + /* And the functions to map from user 3D space to terminal z coordinate */
  93. + static double map3d_z(x, y, z)
  94. + double x, y, z;
  95. + {
  96. +     int i;
  97. +     double v[4], res,                 /* Homogeneous coords. vectors. */
  98. +     w = trans_mat[3][3];
  99. +     v[0] = map_x3d(x); /* Normalize object space to -1..1 */
  100. +     v[1] = map_y3d(y);
  101. +     v[2] = map_z3d(z);
  102. +     v[3] = 1.0;
  103. +     res = trans_mat[3][2];               /* Initiate it with the weight factor. */
  104. +     for (i = 0; i < 3; i++) res += v[i] * trans_mat[i][2];
  105. +     return res;
  106. + }
  107. + /* Initialize the line style using the current device and set hidden styles  */
  108. + /* to it as well if hidden line removal is enabled.                 */
  109. + static setlinestyle(style)
  110. + int style;
  111. + {
  112. +     register struct termentry *t = &term_tbl[term];
  113. +     (*t->linetype)(style);
  114. +     if (hidden3d) {
  115. +     hidden_line_type_above = style;
  116. +     hidden_line_type_below = style;
  117. +     }
  118. + }
  119. + /* Initialize the necessary steps for hidden line removal. This algorithm    */
  120. + /* is based on the "floating horizon" explicit surfaces hidden line removal. */
  121. + static void init_hidden_line_removal()
  122. + {
  123. +     hidden_max_index = xright - xleft + 1;
  124. +     hidden_low_bound = (int *) alloc(sizeof(int) * hidden_max_index, "hidden");
  125. +     hidden_high_bound = (int *) alloc(sizeof(int) * hidden_max_index, "hidden");
  126. + }
  127. + /* Reset the hidden line data to a fresh start.                     */
  128. + static void reset_hidden_line_removal()
  129. + {
  130. +     int i;
  131. +     for (i = 0; i < hidden_max_index; i++) {
  132. +         hidden_low_bound[i] = ytop;
  133. +         hidden_high_bound[i] = ybot;
  134. +     }
  135. + }
  136. + /* Terminates the hidden line removal process. Free any memory allocated by  */
  137. + /* init_hidden_line_removal above.                         */
  138. + static void term_hidden_line_removal()
  139. + {
  140. +     free(hidden_low_bound);
  141. +     free(hidden_high_bound);
  142. + }
  143. + /* Given a list of parallel iso_curves, make sure the first one is closest   */
  144. + /* to viewer or reverse in place the list otherwise.                 */
  145. + /* Returns a pointer to the new ordered list.                     */
  146. + static struct iso_curve *reorder_hidden_one_iso_list(orig_list)
  147. + struct iso_curve *orig_list;
  148. + {
  149. +     double first_crv_first_ptz, first_crv_last_ptz,
  150. +            last_crv_first_ptz, last_crv_last_ptz;
  151. +     struct iso_curve *first_crv = orig_list, *last_crv;
  152. +     for (last_crv = first_crv; last_crv->next; last_crv = last_crv->next);
  153. +     first_crv_first_ptz = map3d_z(first_crv->points[0].x,
  154. +                       first_crv->points[0].y,
  155. +                       0.0);
  156. +     first_crv_last_ptz = map3d_z(first_crv->points[first_crv->p_count-1].x,
  157. +                      first_crv->points[first_crv->p_count-1].y,
  158. +                      0.0);
  159. +     last_crv_first_ptz = map3d_z(last_crv->points[0].x,
  160. +                      last_crv->points[0].y,
  161. +                      0.0);
  162. +     last_crv_last_ptz = map3d_z(last_crv->points[last_crv->p_count-1].x,
  163. +                     last_crv->points[last_crv->p_count-1].y,
  164. +                     0.0);
  165. +     /* If first curve is in front of last - do nothing. */
  166. +     if ((first_crv_first_ptz > last_crv_first_ptz &&
  167. +          first_crv_first_ptz > last_crv_last_ptz) ||
  168. +         (first_crv_last_ptz > last_crv_first_ptz &&
  169. +          first_crv_last_ptz > last_crv_last_ptz))
  170. +         return orig_list;
  171. +     else {
  172. +         struct iso_curve *icrv1, *icrv2, *icrv3;
  173. +         /* Need to reverse the list order: */
  174. +         for (icrv1 = orig_list, icrv2 = icrv1->next; icrv2 != NULL; ) {
  175. +         icrv3 = icrv2->next;
  176. +         icrv2->next = icrv1;
  177. +         icrv1 = icrv2;
  178. +             icrv2 = icrv3;
  179. +         }
  180. +         orig_list->next = NULL; /* Now it is the last element. */
  181. +         return icrv1;
  182. +     }
  183. + }
  184. + /* Reorder the list of iso_curves in the surface plot, so it will be drawn   */
  185. + /* from near iso curve to far one in both direction.                 */
  186. + /* Returned is a pointer to new order iso curve list.                 */
  187. + static struct iso_curve *reorder_hidden_iso_curves(plot, num_iso_lines)
  188. +     struct surface_points *plot;
  189. +     int num_iso_lines;
  190. + {
  191. +     int i;
  192. +     struct iso_curve *iso_list1 = plot->iso_crvs, *itmp = iso_list1, *iso_list2;
  193. +     for (i = 1; i < num_iso_lines; i++) itmp = itmp->next;
  194. +     iso_list2 = itmp->next;
  195. +     itmp->next = NULL;
  196. +     iso_list1 = reorder_hidden_one_iso_list(iso_list1);
  197. +     iso_list2 = reorder_hidden_one_iso_list(iso_list2);
  198. +     for (itmp = iso_list1; itmp->next; itmp = itmp->next);
  199. +     itmp->next = iso_list2;
  200. +     plot->iso_crvs = iso_list1;
  201. +     return iso_list1;
  202. + }
  203. + /* Plot a line after removing is hidden part(s). */
  204. + static void hidden_line_plot_aux(x1, y1, x2, y2, style)
  205. + int x1, y1, x2, y2, style;
  206. + {
  207. +     register struct termentry *t = &term_tbl[term];
  208. +     if (x2 < x1 || (x2 == x1 && y1 == y2)) return;
  209. +     (*t->linetype)(style);
  210. +     (*t->move)(x1,y1);
  211. +     (*t->vector)(x2,y2);
  212. + }
  213. + /* Plot a line after removing is hidden part(s). */
  214. + static void hidden_line_plot(x1, y1, x2, y2)
  215. + int x1, y1, x2, y2;
  216. + {
  217. +     int x, last_x, last_y, visible_above, visible_below;
  218. +     float dy, y;
  219. +     if (x1 > x2) {
  220. +     x = x1;
  221. +     x1 = x2;
  222. +     x2 = x;
  223. +     y = y1;
  224. +     y1 = y2;
  225. +     y2 = y;
  226. +     }
  227. +     if (hidden_first_row) {
  228. +     /* All is visible and drawn as visible above. */
  229. +     dy = x1 != x2 ? ((float) (y2 - y1)) / ((float) (x2 - x1)) : VERYLARGE;
  230. +     for (x = x1, y = y1; x <= x2; x++, y = y1 + (x - x1) * dy) {
  231. +         SET_HIDDEN_BOUND(hidden_high_bound, x, (int) y);
  232. +         SET_HIDDEN_BOUND(hidden_low_bound, x, (int) y);
  233. +     }
  234. +         hidden_line_plot_aux(x1, y1, x2, y2, hidden_line_type_above);
  235. +     }
  236. +     else {
  237. +     if (x1 == x2) {
  238. +         if (y1 > y2) {
  239. +         y = y1;
  240. +         y1 = y2;
  241. +         y2 = y;
  242. +         }
  243. +         /* Clip properly this verical line to right bounds. Note clipping
  244. +          * may produce upto two segments.
  245. +          */
  246. +         if (y1 <= HIDDEN_LOW_BOUND(x1) && y2 <= HIDDEN_LOW_BOUND(x1))
  247. +         hidden_line_plot_aux(x1, y1, x2, y2, hidden_line_type_below);
  248. +         else if (y1 >= HIDDEN_HIGH_BOUND(x1) && y2 >= HIDDEN_HIGH_BOUND(x1))  
  249. +         hidden_line_plot_aux(x1, y1, x2, y2, hidden_line_type_above);
  250. +         else {
  251. +             if (y1 < HIDDEN_LOW_BOUND(x1) && y2 > HIDDEN_LOW_BOUND(x1))
  252. +             hidden_line_plot_aux(x1, y1, x2, HIDDEN_LOW_BOUND(x1),
  253. +                          hidden_line_type_below);
  254. +             if (y2 > HIDDEN_HIGH_BOUND(x1) && y1 < HIDDEN_HIGH_BOUND(x1))
  255. +             hidden_line_plot_aux(x1, HIDDEN_HIGH_BOUND(x1), x2, y2,
  256. +                          hidden_line_type_above);
  257. +         }
  258. +         return;
  259. +     }
  260. +     else
  261. +         dy = ((float) (y2 - y1)) / ((float) (x2 - x1));
  262. +     visible_above = y1 >= HIDDEN_HIGH_BOUND(x1);
  263. +     visible_below = y1 <= HIDDEN_LOW_BOUND(x1);
  264. +     if (visible_above || visible_below) {
  265. +         if (visible_above && visible_below) visible_below = FALSE;
  266. +         last_x = x1;
  267. +         last_y = y1;
  268. +     }
  269. +         for (x = x1, y = y1; x < x2; x++, y += dy)
  270. +     {
  271. +         if (y >= HIDDEN_HIGH_BOUND(x)) {
  272. +         if (visible_below) {
  273. +             hidden_line_plot_aux(last_x, last_y, x - 1, (int) (y - dy),
  274. +                      hidden_line_type_below);
  275. +             visible_below = FALSE;
  276. +         }
  277. +         if (!visible_above) {
  278. +             visible_above = TRUE;
  279. +             last_x = x;
  280. +             last_y = (int) y;
  281. +         }
  282. +         if (!hidden_no_update)
  283. +             SET_HIDDEN_BOUND(hidden_high_bound, x, (int) y);
  284. +         }
  285. +         else if (y <= HIDDEN_LOW_BOUND(x)) {
  286. +         if (visible_above) {
  287. +             hidden_line_plot_aux(last_x, last_y, x - 1, (int) (y - dy),
  288. +                      hidden_line_type_above);
  289. +             visible_above = FALSE;
  290. +         }
  291. +         if (!visible_below) {
  292. +             visible_below = TRUE;
  293. +             last_x = x;
  294. +             last_y = (int) y;
  295. +         }
  296. +         if (!hidden_no_update)
  297. +             SET_HIDDEN_BOUND(hidden_low_bound, x, (int) y);
  298. +         }
  299. +         else {
  300. +         if (visible_above) {
  301. +             hidden_line_plot_aux(last_x, last_y, x - 1, (int) (y - dy),
  302. +                      hidden_line_type_above);
  303. +             visible_above = visible_below = FALSE;
  304. +         }
  305. +         else if (visible_below) {
  306. +             hidden_line_plot_aux(last_x, last_y, x - 1, (int) (y - dy),
  307. +                      hidden_line_type_below);
  308. +             visible_below = FALSE;
  309. +         }
  310. +         }
  311. +     }
  312. +     if (visible_above) {
  313. +         hidden_line_plot_aux(last_x, last_y, x2, y2,
  314. +                  hidden_line_type_above);
  315. +     }
  316. +     else if (visible_below) {
  317. +         hidden_line_plot_aux(last_x, last_y, x2, y2,
  318. +                  hidden_line_type_below);
  319. +     }
  320. +     }
  321. + }
  322.   /* Test a single point to be within the xleft,xright,ybot,ytop bbox.
  323.    * Sets the returned integers 4 l.s.b. as follows:
  324.    * bit 0 if to the left of xleft.
  325. ***************
  326. *** 251,257 ****
  327.    * bit 3 if below of ybot.
  328.    * 0 is returned if inside.
  329.    */
  330. ! static int clip_point(x, y)
  331.   int x, y;
  332.   {
  333.       int ret_val = 0;
  334. --- 542,548 ----
  335.    * bit 3 if below of ybot.
  336.    * 0 is returned if inside.
  337.    */
  338. ! static int clip_point_for_clip_line(x, y)
  339.   int x, y;
  340.   {
  341.       int ret_val = 0;
  342. ***************
  343. *** 264,269 ****
  344. --- 555,573 ----
  345.       return ret_val;
  346.   }
  347.   
  348. + /* Test a single point to be within the xleft,xright,ybot,ytop bbox.
  349. +  * and it is not hidden if hidden lines are to be removed.
  350. +  */
  351. + static int clip_point(x, y)
  352. + int x, y;
  353. + {
  354. +     if (hidden_active &&
  355. +     HIDDEN_LOW_BOUND(x) <= y && HIDDEN_HIGH_BOUND(x) >= y)
  356. +     return FALSE;
  357. +     return clip_point_for_clip_line(x, y);
  358. + }
  359.   /* Clip the given line to drawing coords defined as xleft,xright,ybot,ytop.
  360.    *   This routine uses the cohen & sutherland bit mapping for fast clipping -
  361.    * see "Principles of Interactive Computer Graphics" Newman & Sproull page 65.
  362. ***************
  363. *** 274,281 ****
  364.       int x, y, dx, dy, x_intr[2], y_intr[2], count, pos1, pos2;
  365.       register struct termentry *t = &term_tbl[term];
  366.   
  367. !     pos1 = clip_point(x1, y1);
  368. !     pos2 = clip_point(x2, y2);
  369.       if (pos1 || pos2) {
  370.       if (pos1 & pos2) return;          /* segment is totally out. */
  371.   
  372. --- 578,585 ----
  373.       int x, y, dx, dy, x_intr[2], y_intr[2], count, pos1, pos2;
  374.       register struct termentry *t = &term_tbl[term];
  375.   
  376. !     pos1 = clip_point_for_clip_line(x1, y1);
  377. !     pos2 = clip_point_for_clip_line(x2, y2);
  378.       if (pos1 || pos2) {
  379.       if (pos1 & pos2) return;          /* segment is totally out. */
  380.   
  381. ***************
  382. *** 359,366 ****
  383.           return;
  384.       }
  385.   
  386. !     (*t->move)(x1,y1);
  387. !     (*t->vector)(x2,y2);
  388.   }
  389.   
  390.   /* Two routine to emulate move/vector sequence using line drawing routine. */
  391. --- 663,675 ----
  392.           return;
  393.       }
  394.   
  395. !     if (hidden_active) {
  396. !     hidden_line_plot(x1, y1, x2, y2);
  397. !     }
  398. !     else {
  399. !     (*t->move)(x1,y1);
  400. !     (*t->vector)(x2,y2);
  401. !     }
  402.   }
  403.   
  404.   /* Two routine to emulate move/vector sequence using line drawing routine. */
  405. ***************
  406. *** 569,574 ****
  407. --- 878,894 ----
  408.       if (fabs(z_max3d - z_min3d) < zero)
  409.       int_error("z_min3d should not equal z_max3d!",NO_CARET);
  410.   
  411. +     if (hidden3d) {
  412. +     struct surface_points *plot;
  413. +     
  414. +         /* Verify data is hidden line removable - nonparametric + grid based. */
  415. +         for (plot = plots; plot != NULL; plot = plot->next_sp) {
  416. +         if (parametric ||
  417. +             (plot->plot_type == DATA3D && !plot->has_grid_topology))
  418. +             int_error("Cannot hidden line remove parametric surface or non grid data\n", NO_CARET);
  419. +         }
  420. +     }
  421.   /* INITIALIZE TERMINAL */
  422.       if (!term_init) {
  423.       (*t->init)();
  424. ***************
  425. *** 587,592 ****
  426. --- 907,913 ----
  427.       xscale3d = 2.0/(x_max3d - x_min3d);
  428.   
  429.       (*t->linetype)(-2); /* border linetype */
  430.   /* PLACE TITLE */
  431.       if (*title != 0) {
  432.           int x, y;
  433. ***************
  434. *** 681,686 ****
  435. --- 1002,1012 ----
  436.       (*t->arrow)(sx, sy, ex, ey, this_arrow->head);
  437.       }
  438.   
  439. +     if (hidden3d) {
  440. +     init_hidden_line_removal();
  441. +     reset_hidden_line_removal();
  442. +     hidden_active = TRUE;
  443. +     }
  444.   
  445.   /* DRAW SURFACES AND CONTOURS */
  446.       real_z_min3d = min_z;
  447. ***************
  448. *** 700,710 ****
  449.       for (surface = 0;
  450.            surface < pcount;
  451.            this_plot = this_plot->next_sp, surface++) {
  452. !         (*t->linetype)(this_plot->line_type+1);
  453.   
  454.           if (draw_contour && this_plot->contours != NULL) {
  455.               struct gnuplot_contours *cntrs = this_plot->contours;
  456.   
  457.               if (key != 0) {
  458.                   if ((*t->justify_text)(RIGHT)) {
  459.                       clip_put_text(xl,
  460. --- 1026,1118 ----
  461.       for (surface = 0;
  462.            surface < pcount;
  463.            this_plot = this_plot->next_sp, surface++) {
  464. !         if ( hidden3d )
  465. !             hidden_no_update = FALSE;
  466.   
  467. +         if (draw_surface) {
  468. +             (*t->linetype)(this_plot->line_type);
  469. +             if (hidden3d) {
  470. +             hidden_line_type_above = this_plot->line_type;
  471. +             hidden_line_type_below = this_plot->line_type + 1;
  472. +             }
  473. +             
  474. +             if (key != 0) {
  475. +             if ((*t->justify_text)(RIGHT)) {
  476. +                 clip_put_text(xl,
  477. +                       yl,this_plot->title);
  478. +             }
  479. +             else {
  480. +                 if (inrange(xl-(t->h_char)*strlen(this_plot->title), 
  481. +                     xleft, xright))
  482. +                 clip_put_text(xl-(t->h_char)*strlen(this_plot->title),
  483. +                           yl,this_plot->title);
  484. +             }
  485. +             }
  486. +             
  487. +             switch(this_plot->plot_style) {
  488. +                 case IMPULSES: {
  489. +                 if (key != 0) {
  490. +                 clip_move(xl+(t->h_char),yl);
  491. +                 clip_vector(xl+4*(t->h_char),yl);
  492. +                 }
  493. +                 plot3d_impulses(this_plot);
  494. +                 break;
  495. +             }
  496. +             case LINES: {
  497. +                 if (key != 0) {
  498. +                 clip_move(xl+(int)(t->h_char),yl);
  499. +                 clip_vector(xl+(int)(4*(t->h_char)),yl);
  500. +                 }
  501. +                 plot3d_lines(this_plot);
  502. +                 break;
  503. +             }
  504. +             case ERRORBARS:    /* ignored; treat like points */
  505. +             case POINTS: {
  506. +                 if (key != 0 && !clip_point(xl+2*(t->h_char),yl)) {
  507. +                 (*t->point)(xl+2*(t->h_char),yl,
  508. +                         this_plot->point_type);
  509. +                 }
  510. +                 plot3d_points(this_plot);
  511. +                 break;
  512. +             }
  513. +             case LINESPOINTS: {
  514. +                 /* put lines */
  515. +                 if (key != 0) {
  516. +                 clip_move(xl+(t->h_char),yl);
  517. +                 clip_vector(xl+4*(t->h_char),yl);
  518. +                 }
  519. +                 plot3d_lines(this_plot);
  520. +             
  521. +                 /* put points */
  522. +                 if (key != 0 && !clip_point(xl+2*(t->h_char),yl)) {
  523. +                 (*t->point)(xl+2*(t->h_char),yl,
  524. +                         this_plot->point_type);
  525. +                 }
  526. +                 plot3d_points(this_plot);
  527. +                 break;
  528. +             }
  529. +             case DOTS: {
  530. +                 if (key != 0 && !clip_point(xl+2*(t->h_char),yl)) {
  531. +                 (*t->point)(xl+2*(t->h_char),yl, -1);
  532. +                 }
  533. +                 plot3d_dots(this_plot);
  534. +                 break;
  535. +             }
  536. +             }
  537. +             yl = yl - (t->v_char);
  538. +         }
  539. +         if ( hidden3d ) {
  540. +             hidden_no_update = TRUE;
  541. +             hidden_line_type_above = this_plot->line_type + (hidden3d ? 2 : 1);
  542. +             hidden_line_type_below = this_plot->line_type + (hidden3d ? 2 : 1);
  543. +         }
  544.           if (draw_contour && this_plot->contours != NULL) {
  545.               struct gnuplot_contours *cntrs = this_plot->contours;
  546.   
  547. +             (*t->linetype)(this_plot->line_type + (hidden3d ? 2 : 1));
  548.               if (key != 0) {
  549.                   if ((*t->justify_text)(RIGHT)) {
  550.                       clip_put_text(xl,
  551. ***************
  552. *** 769,847 ****
  553.               if (key != 0) yl = yl - (t->v_char);
  554.           }
  555.   
  556. !         if ( surface == 0 )
  557. !             draw_bottom_grid(this_plot,real_z_min3d,real_z_max3d);
  558. !         if (!draw_surface) continue;
  559. !         (*t->linetype)(this_plot->line_type);
  560. !         if (key != 0) {
  561. !             if ((*t->justify_text)(RIGHT)) {
  562. !                 clip_put_text(xl,
  563. !                     yl,this_plot->title);
  564. !             }
  565. !             else {
  566. !                 if (inrange(xl-(t->h_char)*strlen(this_plot->title), 
  567. !                          xleft, xright))
  568. !                  clip_put_text(xl-(t->h_char)*strlen(this_plot->title),
  569. !                              yl,this_plot->title);
  570. !             }
  571. !         }
  572. !  
  573. !         switch(this_plot->plot_style) {
  574. !             case IMPULSES: {
  575. !                if (key != 0) {
  576. !                   clip_move(xl+(t->h_char),yl);
  577. !                   clip_vector(xl+4*(t->h_char),yl);
  578. !                }
  579. !                plot3d_impulses(this_plot);
  580. !                break;
  581. !             }
  582. !             case LINES: {
  583. !                if (key != 0) {
  584. !                   clip_move(xl+(int)(t->h_char),yl);
  585. !                   clip_vector(xl+(int)(4*(t->h_char)),yl);
  586. !                }
  587. !                plot3d_lines(this_plot);
  588. !                break;
  589. !             }
  590. !             case ERRORBARS:    /* ignored; treat like points */
  591. !             case POINTS: {
  592. !                if (key != 0 && !clip_point(xl+2*(t->h_char),yl)) {
  593. !                   (*t->point)(xl+2*(t->h_char),yl,
  594. !                             this_plot->point_type);
  595. !                }
  596. !                plot3d_points(this_plot);
  597. !                break;
  598. !             }
  599. !             case LINESPOINTS: {
  600. !                /* put lines */
  601. !                if (key != 0) {
  602. !                   clip_move(xl+(t->h_char),yl);
  603. !                   clip_vector(xl+4*(t->h_char),yl);
  604. !                }
  605. !                plot3d_lines(this_plot);
  606. !                /* put points */
  607. !                if (key != 0 && !clip_point(xl+2*(t->h_char),yl)) {
  608. !                   (*t->point)(xl+2*(t->h_char),yl,
  609. !                             this_plot->point_type);
  610. !                }
  611. !                plot3d_points(this_plot);
  612. !                break;
  613. !             }
  614. !             case DOTS: {
  615. !                if (key != 0 && !clip_point(xl+2*(t->h_char),yl)) {
  616. !                   (*t->point)(xl+2*(t->h_char),yl, -1);
  617. !                }
  618. !                plot3d_dots(this_plot);
  619. !                break;
  620. !             }
  621. !         }
  622. !         yl = yl - (t->v_char);
  623.       }
  624.       (*t->text)();
  625.       (void) fflush(outfile);
  626.   }
  627.   
  628.   /* plot3d_impulses:
  629. --- 1177,1192 ----
  630.               if (key != 0) yl = yl - (t->v_char);
  631.           }
  632.   
  633. !         if (surface == 0)
  634. !             draw_bottom_grid(this_plot,real_z_min3d,real_z_max3d);
  635.       }
  636.       (*t->text)();
  637.       (void) fflush(outfile);
  638. +     if (hidden3d) {
  639. +         term_hidden_line_removal();
  640. +         hidden_active = FALSE;
  641. +     }
  642.   }
  643.   
  644.   /* plot3d_impulses:
  645. ***************
  646. *** 881,895 ****
  647.   static plot3d_lines(plot)
  648.       struct surface_points *plot;
  649.   {
  650. !     int i;
  651.       int x,y;                /* point in terminal coordinates */
  652.       struct termentry *t = &term_tbl[term];
  653. !     struct iso_curve *icrvs = plot->iso_crvs;
  654.   
  655. !     while ( icrvs ) {
  656. !     struct coordinate *points = icrvs->points;
  657.   
  658. !     for (i = 0; i < icrvs->p_count; i++) {
  659.           if (real_z_max3d<points[i].z)
  660.           real_z_max3d=points[i].z;
  661.           if (real_z_min3d>points[i].z)
  662. --- 1226,1280 ----
  663.   static plot3d_lines(plot)
  664.       struct surface_points *plot;
  665.   {
  666. !     int i, iso_count, num_iso_lines;
  667.       int x,y;                /* point in terminal coordinates */
  668.       struct termentry *t = &term_tbl[term];
  669. !     struct iso_curve *icrvs = plot->iso_crvs,
  670. !        *first_row_icrv, *last_row_icrv, *first_col_icrv, *icrv;
  671. !     struct coordinate *points;
  672.   
  673. !     if (hidden3d) {
  674. !     hidden_no_update = FALSE;
  675.   
  676. !     if (plot->plot_type == FUNC3D)
  677. !         num_iso_lines = iso_samples;
  678. !     else
  679. !         num_iso_lines = plot->num_iso_read;
  680. !     icrvs = reorder_hidden_iso_curves(plot, num_iso_lines);
  681. !     first_row_icrv = icrvs;
  682. !     for (last_row_icrv = icrvs, i = 1;
  683. !          i++ < num_iso_lines;
  684. !          last_row_icrv = last_row_icrv->next);
  685. !     first_col_icrv = last_row_icrv->next;
  686. !     reset_hidden_line_removal();
  687. !     iso_count = 1;
  688. !     }
  689. !     while (icrvs) {
  690. !     if (hidden3d) {
  691. !         if (iso_count == 1 || iso_count == num_iso_lines + 1) {
  692. !         hidden_first_row = TRUE;
  693. !         /* Draw other boundary so low/high bounds will be complete: */
  694. !         icrv = iso_count == 1 ? first_col_icrv : first_row_icrv;
  695. !         for (i = 0, points = icrv->points; i < icrv->p_count; i++) {
  696. !             map3d_xy(points[i].x, points[i].y, points[i].z, &x, &y);
  697. !             if (i > 0)
  698. !             clip_vector(x,y);
  699. !             else
  700. !             clip_move(x,y);
  701. !         }
  702. !         }
  703. !         else
  704. !         hidden_first_row = FALSE;
  705. !         iso_count++;
  706. !     }
  707. !     for (i = 0, points = icrvs->points; i < icrvs->p_count; i++) {
  708.           if (real_z_max3d<points[i].z)
  709.           real_z_max3d=points[i].z;
  710.           if (real_z_min3d>points[i].z)
  711. ***************
  712. *** 905,910 ****
  713. --- 1290,1308 ----
  714.   
  715.       icrvs = icrvs->next;
  716.       }
  717. +     if (hidden3d) {
  718. +     /* Draw other boundary so low/high bounds will be complete: */
  719. +     for (i = 0, points = last_row_icrv->points;
  720. +          i < last_row_icrv->p_count; i++) {
  721. +         map3d_xy(points[i].x, points[i].y, points[i].z, &x, &y);
  722. +         if (i > 0)
  723. +         clip_vector(x,y);
  724. +         else
  725. +         clip_move(x,y);
  726. +     }
  727. +     }
  728.   }
  729.   
  730.   /* plot3d_points:
  731. ***************
  732. *** 1165,1174 ****
  733.       dy = (y_max3d-y_min3d) / (grid_iso-1);
  734.   
  735.       for (i = 0; i < grid_iso; i++) {
  736. !             if (i == 0 || i == grid_iso-1)
  737. !             (*t->linetype)(-2);
  738.           else
  739. !             (*t->linetype)(-1);
  740.           map3d_xy(x_min3d, y, z_min3d, &ix, &iy);
  741.           clip_move(ix,iy);
  742.           update_extrema_pts(ix,iy,&min_sx_x,&min_sx_y,
  743. --- 1563,1572 ----
  744.       dy = (y_max3d-y_min3d) / (grid_iso-1);
  745.   
  746.       for (i = 0; i < grid_iso; i++) {
  747. !             if (i == 0 || i == grid_iso-1)            
  748. !             setlinestyle(-2);
  749.           else
  750. !             setlinestyle(-1);
  751.           map3d_xy(x_min3d, y, z_min3d, &ix, &iy);
  752.           clip_move(ix,iy);
  753.           update_extrema_pts(ix,iy,&min_sx_x,&min_sx_y,
  754. ***************
  755. *** 1184,1192 ****
  756.   
  757.       for (i = 0; i < grid_iso; i++) {
  758.               if (i == 0 || i == grid_iso-1)
  759. !             (*t->linetype)(-2);
  760.           else
  761. !             (*t->linetype)(-1);
  762.           map3d_xy(x, y_min3d, z_min3d, &ix, &iy);
  763.           clip_move(ix,iy);
  764.           update_extrema_pts(ix,iy,&min_sx_x,&min_sx_y,
  765. --- 1582,1590 ----
  766.   
  767.       for (i = 0; i < grid_iso; i++) {
  768.               if (i == 0 || i == grid_iso-1)
  769. !             setlinestyle(-2);
  770.           else
  771. !             setlinestyle(-1);
  772.           map3d_xy(x, y_min3d, z_min3d, &ix, &iy);
  773.           clip_move(ix,iy);
  774.           update_extrema_pts(ix,iy,&min_sx_x,&min_sx_y,
  775. ***************
  776. *** 1201,1207 ****
  777.       }
  778.       }
  779.       else {
  780. !     (*t->linetype)(-2);
  781.   
  782.       map3d_xy(x_min3d, y_min3d, z_min3d, &ix, &iy);
  783.       clip_move(ix,iy);
  784. --- 1599,1605 ----
  785.       }
  786.       }
  787.       else {
  788. !     setlinestyle(-2);
  789.   
  790.       map3d_xy(x_min3d, y_min3d, z_min3d, &ix, &iy);
  791.       clip_move(ix,iy);
  792. ***************
  793. *** 1245,1258 ****
  794.   
  795.       while ( icrvs ) {
  796.       struct coordinate *points = icrvs->points;
  797.   
  798.       for (i = 0; i < icrvs->p_count; i += icrvs->p_count-1) {
  799.           map3d_xy(points[i].x, points[i].y, z_min3d, &x, &y);
  800.           if (is_boundary) {
  801. !         (*t->linetype)(-2);
  802.           }
  803.           else {
  804. !             (*t->linetype)(-1);
  805.           }
  806.   
  807.           if (i > 0) {
  808. --- 1643,1660 ----
  809.   
  810.       while ( icrvs ) {
  811.       struct coordinate *points = icrvs->points;
  812. +     int saved_hidden_active = hidden_active;
  813. +     double z1 = map3d_z(points[0].x, points[0].y, 0.0),
  814. +            z2 = map3d_z(points[icrvs->p_count-1].x,
  815. +                             points[icrvs->p_count-1].y, 0.0);
  816.   
  817.       for (i = 0; i < icrvs->p_count; i += icrvs->p_count-1) {
  818.           map3d_xy(points[i].x, points[i].y, z_min3d, &x, &y);
  819.           if (is_boundary) {
  820. !         setlinestyle(-2);
  821.           }
  822.           else {
  823. !             setlinestyle(-1);
  824.           }
  825.   
  826.           if (i > 0) {
  827. ***************
  828. *** 1269,1276 ****
  829. --- 1671,1685 ----
  830.   
  831.           /* Draw a vertical line to surface corner from grid corner. */
  832.               map3d_xy(points[i].x, points[i].y, points[i].z, &x1, &y1);
  833. +             if (hidden3d) {
  834. +             if ((i == 0 && z1 > z2) ||
  835. +                 (i == icrvs->p_count-1 && z2 > z1)) {
  836. +                 hidden_active = FALSE; /* This one is always visible. */
  837. +             }                
  838. +             }
  839.               clip_vector(x1,y1);
  840.               clip_move(x,y);
  841. +         hidden_active = saved_hidden_active;
  842.           update_extrema_pts(x,y,&min_sx_x,&min_sx_y, &min_sy_x,&min_sy_y,
  843.                      points[i].x,points[i].y);
  844.           }
  845. ***************
  846. *** 1324,1330 ****
  847.       else
  848.           draw_non_param_grid(plot);
  849.   
  850. !     (*t->linetype)(-2); /* border linetype */
  851.   
  852.   /* label x axis tics */
  853.       if (xtics && xtic > 0.0) {
  854. --- 1733,1739 ----
  855.       else
  856.           draw_non_param_grid(plot);
  857.   
  858. !     setlinestyle(-2); /* border linetype */
  859.   
  860.   /* label x axis tics */
  861.       if (xtics && xtic > 0.0) {
  862. ***************
  863. *** 1557,1563 ****
  864.       }
  865.   
  866.       /* Make sure the vertical line is fully drawn. */
  867. !     (*t->linetype)(-2);    /* axis line type */
  868.   
  869.       map3d_xy(xpos, ypos, z_min3d, &x, &y);
  870.       clip_move(x,y);
  871. --- 1966,1972 ----
  872.       }
  873.   
  874.       /* Make sure the vertical line is fully drawn. */
  875. !     setlinestyle(-2);    /* axis line type */
  876.   
  877.       map3d_xy(xpos, ypos, z_min3d, &x, &y);
  878.       clip_move(x,y);
  879. ***************
  880. *** 1564,1570 ****
  881.       map3d_xy(xpos, ypos, min(end,z_max)+(log_z ? incr : 0.0), &x, &y);
  882.       clip_vector(x,y);
  883.   
  884. !     (*t->linetype)(-1); /* border linetype */
  885.   }
  886.   
  887.   /* DRAW_SERIES_3DXTICS: draw a user tic series, x axis */
  888. --- 1973,1979 ----
  889.       map3d_xy(xpos, ypos, min(end,z_max)+(log_z ? incr : 0.0), &x, &y);
  890.       clip_vector(x,y);
  891.   
  892. !     setlinestyle(-1); /* border linetype */
  893.   }
  894.   
  895.   /* DRAW_SERIES_3DXTICS: draw a user tic series, x axis */
  896. ***************
  897. *** 1651,1657 ****
  898.       }
  899.   
  900.       /* Make sure the vertical line is fully drawn. */
  901. !     (*t->linetype)(-2);    /* axis line type */
  902.   
  903.       map3d_xy(xpos, ypos, z_min3d, &x, &y);
  904.       clip_move(x,y);
  905. --- 2060,2066 ----
  906.       }
  907.   
  908.       /* Make sure the vertical line is fully drawn. */
  909. !     setlinestyle(-2);    /* axis line type */
  910.   
  911.       map3d_xy(xpos, ypos, z_min3d, &x, &y);
  912.       clip_move(x,y);
  913. ***************
  914. *** 1658,1664 ****
  915.       map3d_xy(xpos, ypos, min(end,z_max)+(log_z ? incr : 0.0), &x, &y);
  916.       clip_vector(x,y);
  917.   
  918. !     (*t->linetype)(-1); /* border linetype */
  919.   }
  920.   
  921.   /* DRAW_SET_3DXTICS: draw a user tic set, x axis */
  922. --- 2067,2073 ----
  923.       map3d_xy(xpos, ypos, min(end,z_max)+(log_z ? incr : 0.0), &x, &y);
  924.       clip_vector(x,y);
  925.   
  926. !     setlinestyle(-1); /* border linetype */
  927.   }
  928.   
  929.   /* DRAW_SET_3DXTICS: draw a user tic set, x axis */
  930. ***************
  931. *** 1722,1728 ****
  932.       }
  933.   
  934.       /* Make sure the vertical line is fully drawn. */
  935. !     (*t->linetype)(-2);    /* axis line type */
  936.   
  937.       map3d_xy(xpos, ypos, z_min, &x, &y);
  938.       clip_move(x,y);
  939. --- 2131,2137 ----
  940.       }
  941.   
  942.       /* Make sure the vertical line is fully drawn. */
  943. !     setlinestyle(-2);    /* axis line type */
  944.   
  945.       map3d_xy(xpos, ypos, z_min, &x, &y);
  946.       clip_move(x,y);
  947. ***************
  948. *** 1729,1735 ****
  949.       map3d_xy(xpos, ypos, z_max+(log_z ? incr : 0.0), &x, &y);
  950.       clip_vector(x,y);
  951.   
  952. !     (*t->linetype)(-1); /* border linetype */
  953.   }
  954.   
  955.   /* draw and label a x-axis ticmark */
  956. --- 2138,2144 ----
  957.       map3d_xy(xpos, ypos, z_max+(log_z ? incr : 0.0), &x, &y);
  958.       clip_vector(x,y);
  959.   
  960. !     setlinestyle(-1); /* border linetype */
  961.   }
  962.   
  963.   /* draw and label a x-axis ticmark */
  964.