/***********************************************************************/
/* Open Visualization Data Explorer                                    */
/* (C) Copyright IBM Corp. 1989,1999                                   */
/* ALL RIGHTS RESERVED                                                 */
/* This code licensed under the                                        */
/*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
/***********************************************************************/
/*********************************************************************/
/*                     I.B.M. CONFIENTIAL                           */
/*********************************************************************/

#include <dxconfig.h>


/*---------------------------------------------------------------------------*\
$Source: /home/gda/dxcvs/dx/src/exec/hwrender/xgl/hwUnconPointDraw.c,v $
$Log: hwUnconPointDraw.c,v $
Revision 1.3  1999/05/10 15:45:40  gda
Copyright message

Revision 1.2  1999/05/03 14:06:43  gda
moved to using dxconfig.h rather than command-line defines

Revision 1.1.1.1  1999/03/24 15:18:36  gda
Initial CVS Version

Revision 1.1.1.1  1999/03/19 20:59:49  gda
Initial CVS

Revision 10.1  1999/02/23 21:03:12  gda
OpenDX Baseline

Revision 9.1  1997/05/22 22:34:29  svs
Copy of release 3.1.4 code

 * Revision 8.0  1995/10/03  22:16:02  nsc
 * Copy of release 3.1 code
 *
 * Revision 7.4  1994/03/31  15:55:27  tjm
 * added versioning
 *
 * Revision 7.3  94/02/24  18:31:51  mjh
 * sun4/xgl maintenance: part 3, remove references to original DX field in
 * the xfield data structure.  XGL objects are now cached on the address of
 * the xfield.  XGL port now no longer requires STUBBED_CALLS preprocessor
 * definition.
 * 
 * Revision 7.2  94/02/13  18:52:49  mjh
 * sun4/xgl maintenance: remove RenderPass, use Xfield, integrate 2D code,
 * fix dot approximations for connection-dependent data, use mesh topology
 * info in Xfield directly
 * 
 * Revision 7.1  94/01/18  19:00:17  svs
 * changes since release 2.0.1
 * 
 * Revision 6.1  93/11/16  10:26:21  svs
 * ship level code, release 2.0
 * 
 * Revision 1.5  93/10/27  21:32:10  mjh
 * Handle connection-dependent colors w/o dumping core.  This routine
 * ought not be called for connection-dependent colors, but the other
 * graphics primitives need to for dot approximations.
 * 
 * Revision 1.4  93/09/28  09:40:17  tjm
 * fixed <DMCZAP71> colors are now clamped so that the maximum value for
 * r g or b is 1.0. 
 * 
 * Revision 1.3  93/07/28  19:34:06  mjh
 * apply 2D position hacks, install invalid connection/postion support
 * 
 * Revision 1.2  93/07/14  13:29:08  tjm
 * added solaris ifdefs
 * 
 * Revision 1.1  93/06/29  10:01:49  tjm
 * Initial revision
 * 
 * Revision 5.2  93/05/07  19:53:18  mjh
 * rewrite, optimize copies, use cache
 * 
 * Revision 5.1  93/03/30  14:42:02  ellen
 * Moved these files from the 5.0.2 Branch
 * 
 * Revision 5.0.2.3  93/03/12  16:12:18  owens
 * duh
 * 
 * Revision 5.0.2.2  93/03/12  16:05:38  owens
 * colors are BYTEs when using a color_map... not INTs
 * 
 * Revision 5.0.2.1  93/03/08  11:10:12  ellen
 * Added stuff to do point draw
 * 
\*---------------------------------------------------------------------------*/

#include <xgl/xgl.h>
#include "hwDeclarations.h"
#include "hwPortXGL.h"
#include "hwXfield.h"
#include "hwMemory.h"
#include "hwCacheUtilXGL.h"

#define COPYPNT2D *(struct p2d *)pt = pnts2d[ol] ; pt->z = 0 ;
#define COPYPNT3D *(Point *)pt = points[ol] ;
#define COPYCOLOR                                   \
if (color_map)                                      \
  CLAMP(&pt->color, &color_map[color_index[ol]]) ;  \
else                                                \
  CLAMP(&pt->color, &fcolors[ol]) ;               

	  
Error
_dxfUnconnectedPointDraw (tdmPortHandleP portHandle, xfieldT *xf, int buttonUp)
{
  DEFPORT(portHandle);
  register Point *points ;
  register struct p2d {float x, y ;} *pnts2d ;
  register int n, ol, mod ;
  RGBColor *fcolors, *color_map ;
  int maxpoints, pt_type, rank, shape, is_2d ;
  char *fun, *color_index ;
  Xgl_pt_list *pt_list ;
  Type type ;
  
  DPRINT("\n(_dxfUnconnectedPointDraw") ;
  DPRINT1("\n%d invalid positions",
	  xf->invPositions? DXGetInvalidCount(xf->invPositions): 0) ;
  
  /*
   *  Extract required data from the xfield.
   */
  
  if (is_2d = IS_2D(xf->positions_array, type, rank, shape))
      pnts2d = (struct p2d *) DXGetArrayData (xf->positions_array) ;
  else
      points = (Point *) DXGetArrayData (xf->positions_array) ;

  if (DXGetArrayClass(xf->fcolors_array) == CLASS_CONSTANTARRAY)
      fcolors = (Pointer) DXGetArrayEntry (xf->fcolors, 0, NULL) ;
  else
      fcolors = (Pointer) DXGetArrayData(xf->fcolors_array) ;
  
  if (color_map = (RGBColor *) DXGetArrayData(xf->cmap_array))
      color_index = (char *) fcolors ;
  
  mod = buttonUp ? xf->attributes.buttonUp.density :
                   xf->attributes.buttonDown.density ;

  if (xf->colorsDep == dep_field)
    {
      float marker_color[3] ;

      if (color_map)
	  CLAMP(marker_color, &color_map[color_index[0]]) ;
      else
	  CLAMP(marker_color, fcolors) ;

      xgl_object_set
	  (XGLCTX, 
	   XGL_CTX_MARKER_COLOR, marker_color,
#ifdef solaris
	   XGL_CTX_MARKER, xgl_marker_dot,
#else
	   XGL_CTX_MARKER_DESCRIPTION, xgl_marker_dot,
#endif
	   XGL_CTX_MARKER_COLOR_SELECTOR, XGL_MARKER_COLOR_CONTEXT,
	   NULL) ;

      if (mod == 1 && !xf->invPositions && !is_2d)
	{
	  Xgl_pt_list pt_list ;
	  DPRINT("\nfast path") ;

	  pt_list.pt_type = XGL_PT_F3D ;
	  pt_list.pts.f3d = (Xgl_pt_f3d *) points ;
	  pt_list.bbox = NULL ;
	  pt_list.num_pts = xf->npositions ;

	  DPRINT("\ncalling xgl_multimarker") ;
	  xgl_multimarker (XGLCTX, &pt_list) ;
	  goto done ;
	}

      fun = "CpfPnt" ;
      pt_type = XGL_PT_F3D ;
    }
  else if (xf->colorsDep == dep_positions)
    {
      xgl_object_set
	  (XGLCTX, 
#ifdef solaris
	   XGL_CTX_MARKER, xgl_marker_dot,
#else
	   XGL_CTX_MARKER_DESCRIPTION, xgl_marker_dot,
#endif
	   XGL_CTX_MARKER_COLOR_SELECTOR, XGL_MARKER_COLOR_POINT,
	   NULL) ;

      fun = "CpvPnt" ;
      pt_type = XGL_PT_COLOR_F3D ;
    }
  else
    {
      /* #13070 bad or missing element type */
      DPRINT("\ncannot handle connection-dependent point colors") ;
      DXErrorGoto (ERROR_INTERNAL, "#13070") ;
    }

  DPRINT1 ("\n%s", fun) ;
  if ((pt_list = _dxf_GetPointCacheXGL (fun, mod, xf)))
    {
      DPRINT("\ngot points from cache") ;
      DPRINT("\ncalling xgl_multimarker") ;
      xgl_multimarker (XGLCTX, pt_list) ;
      goto done ;
    }

  /* set up to render every-nth-point */
  DPRINT("\ngenerating XGL points") ;
  maxpoints = (xf->npositions-1)/mod + 1 ;
  
  /* allocate xgl point list */
  if (!(pt_list = (Xgl_pt_list *) tdmAllocate(sizeof(Xgl_pt_list))))
      DXErrorGoto (ERROR_INTERNAL, "#13000") ;

  /* setup the Xgl_pt_list structure */
  if (pt_type == XGL_PT_F3D)
    {
      register Xgl_pt_f3d *pt ;
	
      pt_list->pts.f3d = (Xgl_pt_f3d *)
	  tdmAllocate(maxpoints*sizeof(Xgl_pt_f3d)) ;

      if (!pt_list->pts.f3d)
	  DXErrorGoto (ERROR_INTERNAL, "#13000") ;
      
      if (is_2d)
	  if (xf->invPositions)
	      for (n=0, ol=0, pt=pt_list->pts.f3d; ol<xf->npositions; ol+=mod)
		{
		  if (!DXIsElementValid (xf->invPositions, ol)) continue ;
		  COPYPNT2D ; n++ ; pt++ ;
		}
	  else
	      for (n=0, ol=0, pt=pt_list->pts.f3d; ol<xf->npositions; ol+=mod)
		{
		  COPYPNT2D ; n++ ; pt++ ;
		}
      else /* 3d */
	  if (xf->invPositions)
	      for (n=0, ol=0, pt=pt_list->pts.f3d; ol<xf->npositions; ol+=mod)
		{
		  if (!DXIsElementValid (xf->invPositions, ol)) continue ;
		  COPYPNT3D ; n++ ; pt++ ;
		}
	  else
	      for (n=0, ol=0, pt=pt_list->pts.f3d; ol<xf->npositions; ol+=mod)
		{
		  COPYPNT3D ; n++ ; pt++ ;
		}
    }
  else /* XGL_PT_COLOR_F3D */
    {
      register Xgl_pt_color_f3d *pt  ;

      pt_list->pts.color_f3d = (Xgl_pt_color_f3d *)
	  tdmAllocate(maxpoints*sizeof(Xgl_pt_color_f3d)) ;

      if (!pt_list->pts.color_f3d)
	  DXErrorGoto (ERROR_INTERNAL, "#13000") ;
      
      if (is_2d)
	  if (xf->invPositions)
	      for (n=0, ol=0, pt=pt_list->pts.color_f3d ;
		   ol < xf->npositions ; ol += mod)
		{
		  if (!DXIsElementValid (xf->invPositions, ol)) continue ;
		  COPYPNT2D ; COPYCOLOR ; n++ ; pt++ ;
		}
	  else
	      for (n=0, ol=0, pt=pt_list->pts.color_f3d ;
		   ol < xf->npositions ; ol += mod)
		{
		  COPYPNT2D ; COPYCOLOR ; n++ ; pt++ ;
		}
      else /* 3d */
	  if (xf->invPositions)
	      for (n=0, ol=0, pt=pt_list->pts.color_f3d ;
		   ol < xf->npositions ; ol += mod)
		{
		  if (!DXIsElementValid (xf->invPositions, ol)) continue ;
		  COPYPNT3D ; COPYCOLOR ; n++ ; pt++ ;
		}
	  else
	      for (n=0, ol=0, pt=pt_list->pts.color_f3d ;
		   ol < xf->npositions ; ol += mod)
		{
		  COPYPNT3D ; COPYCOLOR ; n++ ; pt++ ;
		}
    }

  /* draw all the points */
  pt_list->pt_type = pt_type ;
  pt_list->bbox = NULL ;
  pt_list->num_pts = n ;

  DPRINT("\ncalling xgl_multimarker") ;
  xgl_multimarker (XGLCTX, pt_list) ;
  
  /* cache them */
  _dxf_PutPointCacheXGL (fun, mod, xf, pt_list) ;
  
 done:
  DPRINT(")") ;
  return OK ;
  
 error:
  _dxf_FreePointCacheXGL (pt_list) ;
  DPRINT("\nerror)") ;
  return ERROR ;
}
