 /*
  * Khoros: $Id: grid.c,v 1.2 1991/07/15 06:00:14 khoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: grid.c,v 1.2 1991/07/15 06:00:14 khoros Exp $";
#endif

 /*
  * $Log: grid.c,v $
 * Revision 1.2  1991/07/15  06:00:14  khoros
 * HellPatch1
 *
  */ 


/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.
 *
 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *---------------------------------------------------------------------
 */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include "xprism.h"	


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    file name: grid.c 
   >>>>               
   >>>>   description: routines for setting up and drawing the 
   >>>>			2D and 3D grid.
   >>>>              
   >>>>      routines:
   >>>>			draw_grid_2D
   >>>>			draw_grid_3D
   >>>>              
   >>>> modifications:
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */

/************************************************************
*
*  MODULE NAME: draw_grid_2D
*
*      PURPOSE: draws a grid over the plot
*
*        INPUT: gwin - pointer to the VPGraphicsWindow structure
*
*       OUTPUT: none
*
*    CALLED BY: plot_routine
*
*   WRITTEN BY: Mike Lang, Mark Young, Tom Sauer
*
*
*************************************************************/


draw_grid_2D()
{
	int	    i, num_lines, colorindex;
	Coord	    border[5], start, end, *grid_lines;

        if (gwin_attr->rescale_relabel == RELABEL)
            X2D_set_wc_min_max (gwin->id, gwin_attr->disp_label_min,
                                          gwin_attr->disp_label_max);

	i = 0;
	/* plus 2 because: 1 for round off, 1 more for 1st line */
        num_lines = 2 * (int) ceil( (double) 
                ((gwin_attr->disp_label_max.x - gwin_attr->disp_label_min.x) 
                   / gwin_attr->disp_label_major_intv.x)+1);
        num_lines += 2 *  (int) ceil( (double) 
                ((gwin_attr->disp_label_max.y - gwin_attr->disp_label_min.y) 
                  / gwin_attr->disp_label_major_intv.y)+1);
	grid_lines = (Coord *)
		 malloc((unsigned)(sizeof(Coord) * 2 * num_lines));

	/* Draw the vert. grid-lines on the x-y plane */
	start.z = gwin_attr->disp_label_min.z;	
	end.z = gwin_attr->disp_label_min.z;
	start.y = gwin_attr->disp_label_min.y;	
	end.y = gwin_attr->disp_label_max.y;
	start.x = gwin_attr->disp_label_min.x;	
	end.x = gwin_attr->disp_label_min.x;

	while (start.x <= gwin_attr->disp_label_max.x)
	{
	   grid_lines[i++] = start;
	   grid_lines[i++] = end;
	   start.x += gwin_attr->disp_label_major_intv.x;	
	   end.x = start.x;
	}

	/* Draw the horiz. grid-lines on the x-y plane */
	start.z = gwin_attr->disp_label_min.z;	
	end.z = gwin_attr->disp_label_min.z;
	start.x = gwin_attr->disp_label_min.x;	
	end.x = gwin_attr->disp_label_max.x;
	start.y = gwin_attr->disp_label_min.y;	
	end.y = gwin_attr->disp_label_min.y;

	while (start.y <= gwin_attr->disp_label_max.y)
	{
	   grid_lines[i++] = start;
	   grid_lines[i++] = end;
	   start.y += gwin_attr->disp_label_major_intv.y;	
	   end.y = start.y;
	}

	/*
         *  Need to set the grid color and set the grid to be dotted
         *  not a solid line. set line width to be real small.
	 */

	X3D_set_line_type(gwin->id, Grid_Dotted);
	X3D_set_line_width(gwin->id, ExtraFine);

	colorindex = gwin_attr->current_colors[GRID_COLOR]; 
	X2D_draw_segments(gwin->id, grid_lines, i, &Colors[colorindex]);

        /*
         *  Reset the graphic context back to a solid line so that we can
         *  draw the grid outline.
         */

	X3D_set_line_type(gwin->id, Solid);
        if (xp_device != xpX11)
	    X3D_set_line_width(gwin->id, ExtraWide);

	/* close up the grid */	
	border[0].y = gwin_attr->disp_label_min.y; 
	border[0].x = gwin_attr->disp_label_max.x;
	border[1].y = gwin_attr->disp_label_max.y; 
	border[1].x = gwin_attr->disp_label_max.x;
	border[2].y = gwin_attr->disp_label_max.y; 
	border[2].x = gwin_attr->disp_label_min.x;
	border[3].y = gwin_attr->disp_label_min.y; 
	border[3].x = gwin_attr->disp_label_min.x;
	border[4].y = gwin_attr->disp_label_min.y; 
	border[4].x = gwin_attr->disp_label_max.x;
 
	X2D_draw_polyline(gwin->id, border, 5, &Colors[colorindex]); 
        if (xp_device != xpX11)
	    X3D_set_line_width(gwin->id, MediumFine);

	/*
	 *  Clean up.  Reset the graphic context back to a solid line and
	 *  free up the malloc'ed grid_lines.
	 */

        if (gwin_attr->rescale_relabel == RELABEL)
            X2D_set_wc_min_max (gwin->id, gwin_attr->disp_scale_min,
                                          gwin_attr->disp_scale_max);

	XFlush(display);
	free(grid_lines);
}



/************************************************************
*
*  MODULE NAME: draw_grid_3D
*
*      PURPOSE: draws a grid over the plot
*
*        INPUT: gwin - pointer to the VPGraphicsWindow structure
*
*       OUTPUT: none
*
*    CALLED BY: plot_routine
*
*   WRITTEN BY: Mike Lang, Mark Young, Tom Sauer
*
*
*************************************************************/


draw_grid_3D()
{
	int	    i, num_lines, colorindex;
	Coord	    border[11], start, end, *grid_lines;

        if (gwin_attr->rescale_relabel == RELABEL)
            X3D_set_wc_min_max (gwin->id, gwin_attr->disp_label_min,
                                          gwin_attr->disp_label_max);

	i = 0;
	/* plus 2 because: 1 for round off, 1 more for 1st line */
	num_lines = 2 * (int) (ceil( (double) 
                 ((gwin_attr->disp_label_max.x - gwin_attr->disp_label_min.x) 
                 / gwin_attr->disp_label_major_intv.x)+1));
	num_lines += 2 *  (int) (ceil( (double) 
                 ((gwin_attr->disp_label_max.y - gwin_attr->disp_label_min.y) 
                 / gwin_attr->disp_label_major_intv.y)+1));
	num_lines += 2 * (int) (ceil( (double) 
                 ((gwin_attr->disp_label_max.z - gwin_attr->disp_label_min.z) 
                 / gwin_attr->disp_label_major_intv.z)+1));
	grid_lines = (Coord *)
		 malloc((unsigned)(sizeof(Coord) * 2 * num_lines));

	/* Draw the vert. grid-lines on the x-y plane */
	start.z = gwin_attr->disp_label_min.z;	
	end.z = gwin_attr->disp_label_min.z;
	start.y = gwin_attr->disp_label_min.y;	
	end.y = gwin_attr->disp_label_max.y;
	start.x = gwin_attr->disp_label_min.x;	
	end.x = gwin_attr->disp_label_min.x;

	while (start.x <= gwin_attr->disp_label_max.x)
	{
	   grid_lines[i++] = start;
	   grid_lines[i++] = end;
	   start.x += gwin_attr->disp_label_major_intv.x;	
	   end.x = start.x;
	}

	/* Draw the horiz. grid-lines on the x-y plane */
	start.z = gwin_attr->disp_label_min.z;	
	end.z = gwin_attr->disp_label_min.z;
	start.x = gwin_attr->disp_label_min.x;	
	end.x = gwin_attr->disp_label_max.x;
	start.y = gwin_attr->disp_label_min.y;	
	end.y = gwin_attr->disp_label_min.y;

	while (start.y <= gwin_attr->disp_label_max.y)
	{
	   grid_lines[i++] = start;
	   grid_lines[i++] = end;
	   start.y += gwin_attr->disp_label_major_intv.y;	
	   end.y = start.y;
	}

	/* Draw the horiz. grid-lines on the z-x back plane */
	start.y = gwin_attr->disp_label_max.y;	
	end.y = gwin_attr->disp_label_max.y;
	start.x = gwin_attr->disp_label_min.x;	
	end.x = gwin_attr->disp_label_max.x;
	start.z = gwin_attr->disp_label_min.z;	
	end.z = gwin_attr->disp_label_min.z;

	while (start.z <= gwin_attr->disp_label_max.z)
	{
	   grid_lines[i++] = start;
	   grid_lines[i++] = end;
	   start.z += gwin_attr->disp_label_major_intv.z;	
	   end.z = start.z;
	}

	/* Draw the vert. grid-lines on the z-x back plane */
	start.y = gwin_attr->disp_label_max.y;	
	end.y = gwin_attr->disp_label_max.y;
	start.z = gwin_attr->disp_label_min.z;	
	end.z = gwin_attr->disp_label_max.z;
	start.x = gwin_attr->disp_label_min.x;	
	end.x = gwin_attr->disp_label_min.x;

	while (start.x <= gwin_attr->disp_label_max.x)
	{
	   grid_lines[i++] = start;
	   grid_lines[i++] = end;
	   start.x += gwin_attr->disp_label_major_intv.x;	
	   end.x = start.x;
	}

	/* Draw the horiz grid-lines on the z-y left plane */
	start.x = gwin_attr->disp_label_min.x;	
	end.x = gwin_attr->disp_label_min.x;
	start.y = gwin_attr->disp_label_min.y;	
	end.y = gwin_attr->disp_label_max.y;
	start.z = gwin_attr->disp_label_min.z;	
	end.z = gwin_attr->disp_label_min.z;

	while (start.z <= gwin_attr->disp_label_max.z)
	{
	   grid_lines[i++] = start;
	   grid_lines[i++] = end;
	   start.z += gwin_attr->disp_label_major_intv.z;	
	   end.z = start.z;
	}

	/* Draw the vert. grid-lines on the z-y left plane */
	start.x = gwin_attr->disp_label_min.x;	
	end.x = gwin_attr->disp_label_min.x;
	start.z = gwin_attr->disp_label_min.z;	
	end.z = gwin_attr->disp_label_max.z;
	start.y = gwin_attr->disp_label_min.y;	
	end.y = gwin_attr->disp_label_min.y;

	while (start.y <= gwin_attr->disp_label_max.y)
	{
	   grid_lines[i++] = start;
	   grid_lines[i++] = end;
	   start.y += gwin_attr->disp_label_major_intv.y;	
	   end.y = start.y;
	}
	/*
	 *  Need to set the grid color and set the grid to be dotted
	 *  not a solid line. set line width to be real small.
	 */
	X3D_set_line_type(gwin->id, Grid_Dotted);
	X3D_set_line_width(gwin->id, ExtraFine);

	colorindex = gwin_attr->current_colors[GRID_COLOR]; 
	X3D_draw_segments(gwin->id, grid_lines, i, &Colors[colorindex]);

	/*
	 *  Reset the graphic context back to a solid line so that we can
	 *  draw the grid outline.
	 */
	X3D_set_line_type(gwin->id, Solid);
        if (xp_device != xpX11)
	    X3D_set_line_width(gwin->id, ExtraWide);

	/* now draw the border for the grid (cube) */
	border[0].x = gwin_attr->disp_label_min.x;
	border[0].y = gwin_attr->disp_label_min.y;  
	border[0].z = gwin_attr->disp_label_min.z;
	border[1].x = gwin_attr->disp_label_min.x;
	border[1].y = gwin_attr->disp_label_min.y;  
	border[1].z = gwin_attr->disp_label_max.z;
	border[2].x = gwin_attr->disp_label_min.x;
	border[2].y = gwin_attr->disp_label_max.y;  
	border[2].z = gwin_attr->disp_label_max.z;
	border[3].x = gwin_attr->disp_label_min.x;
	border[3].y = gwin_attr->disp_label_max.y;  
	border[3].z = gwin_attr->disp_label_min.z;
	border[4].x = gwin_attr->disp_label_min.x;
	border[4].y = gwin_attr->disp_label_min.y;  
	border[4].z = gwin_attr->disp_label_min.z;
	border[5].x = gwin_attr->disp_label_max.x;
	border[5].y = gwin_attr->disp_label_min.y;  
	border[5].z = gwin_attr->disp_label_min.z;
	border[6].x = gwin_attr->disp_label_max.x;
	border[6].y = gwin_attr->disp_label_max.y;  
	border[6].z = gwin_attr->disp_label_min.z;
	border[7].x = gwin_attr->disp_label_min.x;
	border[7].y = gwin_attr->disp_label_max.y;  
	border[7].z = gwin_attr->disp_label_min.z;
	border[8].x = gwin_attr->disp_label_min.x;
	border[8].y = gwin_attr->disp_label_max.y;  
	border[8].z = gwin_attr->disp_label_max.z;
	border[9].x = gwin_attr->disp_label_max.x;
	border[9].y = gwin_attr->disp_label_max.y;  
	border[9].z = gwin_attr->disp_label_max.z;
	border[10].x = gwin_attr->disp_label_max.x;
	border[10].y = gwin_attr->disp_label_max.y;  
	border[10].z = gwin_attr->disp_label_min.z;
	X3D_draw_polyline(gwin->id, border, 11, &Colors[colorindex]); 
        if (xp_device != xpX11)
	    X3D_set_line_width(gwin->id, MediumFine);

	/*
	 *  Clean up.  free up the malloc'ed grid_lines.
	 */

        if (gwin_attr->rescale_relabel == RELABEL)
           X3D_set_wc_min_max (gwin->id, gwin_attr->disp_scale_min,
                                          gwin_attr->disp_scale_max);
	XFlush(display);
	free(grid_lines);
}
