#ifdef SCCS
static char sccsid[]="@(#)plcube.c	1.2 Oki 93/05/25";
#endif
/*
 * plcube.c - PEXlib / PEXIC Cube
   cc -o plcube plcube.c -lPEX5 -lm -lX11                    -lnsl
   
			Copyright (c) 1992, 1993 by 
			Oki Electric Industry Co., Ltd.
			All Rights Reserved
	
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and that
 * both that copyright notice and this permission notice appear in
 * supporting documentation, and that the name of Oki not be
 * used in advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission. Oki
 * makes no representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
*/
/* 27-APR-93 made into structure stuffer - PEXlib version */
/* 12-MAY-92 debugged letters */
/* 17-JUN-91 trueblue.c - find true color visual for PEX testing */
/* 17-NOV-90 visual hacking */

#define NeedFunctionPrototypes 1

#include <X11/Xlib.h>
#include <X11/PEX5/PEXlib.h>

#define SET_POINT(p,a,b,c) {(p)->x=(a);(p)->y=(b);(p)->z=(c);}

#define RADIAN(x) ((x)*(3.1415927 / 180.0))

PEXColorRGB red     = {1,0,0};
PEXColorRGB green   = {0,1,0};
PEXColorRGB blue    = {0,0,1};
PEXColorRGB cyan    = {0,1,1};
PEXColorRGB magenta = {1,0,1};
PEXColorRGB yellow  = {1,1,0};

Display		*theDisplay;
PEXStructure     theStrux;

main (argc, argv)
     int argc;
     char  *argv[];
{
  char			*displayString = (char *)0;
  PEXExtensionInfo	*info_return;
  char			err_msg[PEXErrorStringLength];
  int                   i;
  PEXCoord p[2];
  PEXCoord verts[30], *pts;
  PEXVector normals[30], *ns;
  PEXArrayOfFacetData fData;
  PEXArrayOfVertex vData;

  PEXVector shift, scale;
  PEXMatrix bldmat;
  PEXCoord  pt;
  double x_ang, y_ang, z_ang;

  for ( i = 1; i<argc; i++ ) {
    if ((strncmp(argv[i],"-display",strlen(argv[i]))) == 0) {
      if (++i > argc) { printf("not enough args"); exit(1); }
      displayString = argv[i];
    } else if ((strncmp(argv[i],"-strux",strlen(argv[i]))) == 0) {
      if (++i > argc) { printf("not enough args"); exit(1); }
      theStrux = atoi(argv[i]);
    }
  }

  /*
   * Open the display and initialize the PEX extension.
   *  - this is a pexdraw structure stuffer, pexdraw creates a structure and
   *    uses the system call to execute this program.
   */
  
  if (!(theDisplay = XOpenDisplay(displayString)))
    {
      printf ( "Could not open display %s\n",displayString);
      exit (1);
    }
  
  if (PEXInitialize(theDisplay, &info_return, PEXErrorStringLength, err_msg))
    {
      printf ("%s\n", err_msg);
      exit (1);	    
    }

  /* need the line because we cannot select */
  PEXSetLineColorIndex( theDisplay, theStrux, PEXOCStore, 2);
  p[0].x = 0; p[0].y = 0; p[0].z = 0;
  p[1].x = -1; p[1].y = -1; p[1].z = -1;
  PEXPolyline(theDisplay, theStrux, PEXOCStore, 2, p );

/*
 * make a cube, use PEXlib to generate facet normals.
 *
 *                          ( )-----( )
 *                           |     / |
 *                           |   /   |
 *                           | /     |
 *  (4)-----(*)-----(8)-----(A)-----($)
 *   | \     |     / |     / |     / |
 *   |   \   |   /   |   /   |   /   |
 *   |     \ | /     | /     | /     |
 *  (2)-----(+)-----(9)-----(B)-----(*)
 *   | \     |
 *   |   \   |
 *   |     \ |
 *  (0)-----(1)
 *
 * * doubled point 5,6 13,14
 * + points 3&7
 */

#define CUBE 0.4

  pts = verts;
  ns = normals;

  pts->x = 0.0;  pts->y = 0.0; pts->z = 0.0; pts++; /* 0 */
  pts->x = CUBE;  pts->y = 0.0; pts->z = 0.0; pts++;
  pts->x = 0.0;  pts->y = CUBE; pts->z = 0.0; pts++; /* 2 */
  pts->x = CUBE;  pts->y = CUBE; pts->z = 0.0; pts++;
  pts->x = 0.0;  pts->y = CUBE; pts->z = CUBE; pts++;
  pts->x = CUBE;  pts->y = CUBE; pts->z = CUBE; pts++;
  pts->x = CUBE;  pts->y = CUBE; pts->z = CUBE; pts++;
  pts->x = CUBE;  pts->y = CUBE; pts->z = 0.0; pts++;
  pts->x = CUBE;  pts->y = 0.0; pts->z = CUBE; pts++; /* 8 */
  pts->x = CUBE;  pts->y = 0.0; pts->z = 0.0; pts++; /* 9 == 1 */
  pts->x = 0.0;  pts->y = 0.0; pts->z = CUBE; pts++;
  pts->x = 0.0;  pts->y = 0.0; pts->z = 0.0; pts++; /* B == 0 */
  pts->x = 0.0;  pts->y = CUBE; pts->z = CUBE; pts++; /* $ */
  pts->x = 0.0;  pts->y = CUBE; pts->z = 0.0; pts++;
  pts->x = 0.0;  pts->y = CUBE; pts->z = 0.0; pts++;
  pts->x = 0.0;  pts->y = CUBE; pts->z = CUBE; pts++; /* $ */
  pts->x = 0.0;  pts->y = CUBE; pts->z = CUBE; pts++; /* $ */
  pts->x = 0.0;  pts->y = 0.0; pts->z = CUBE; pts++; /* A */
  pts->x = CUBE;  pts->y = CUBE; pts->z = CUBE; pts++;
  pts->x = CUBE;  pts->y = 0.0; pts->z = CUBE; pts++;

  fData.normal = normals;
  vData.no_data = verts;

  PEXGeoNormTriangleStrip( PEXGANormal, PEXGANone, PEXColorTypeRGB, fData,
			  20, vData );
  
  PEXTriangleStrip(  theDisplay, theStrux, PEXOCStore,
                     PEXGANormal, PEXGANone, PEXColorTypeRGB, fData,
                     20, vData );

/*************************************************************************
 * Cube is done, paste the letters on, start with the Red P.
 */
    shift.x = 0.1;
    shift.y = 0.03;
    shift.z = 0.41;
    PEXTranslate( &shift, bldmat );

  PEXSetLocalTransform( theDisplay, theStrux, PEXOCStore,
                      PEXPreConcatenate, bldmat);
  PEXSetSurfaceColor(  theDisplay, theStrux, PEXOCStore,
                       PEXColorTypeRGB, (PEXColor *)&red );
  PutP();

/* Green E */

    pt.x = 0.0;
    pt.y = 0.0;
    pt.z = 0.0;
    shift.x = 0;
    shift.y = -0.04; /* controls distance to face of cube */
    shift.z = -0.37; 
    scale.x = 1.0;
    scale.y = 1.0;
    scale.z = 1.0;
    x_ang = RADIAN(90);
    y_ang = 0;
    z_ang = 0;
    PEXBuildTransform(&pt, &shift, x_ang, y_ang, z_ang, &scale, bldmat);

  PEXSetLocalTransform( theDisplay, theStrux, PEXOCStore,
                      PEXPreConcatenate, bldmat);
  PEXSetSurfaceColor( theDisplay, theStrux, PEXOCStore,
                      PEXColorTypeRGB, (PEXColor *)&green );  
  PutE();

/* Blue X */

    pt.x = 0.0;
    pt.y = 0.0;
    pt.z = 0.0;
    shift.x = 0.31; /* controls distance to face of cube */
    shift.y = 0.0;  /* .37 - y from E */
    shift.z = -0.07;
    scale.x = 1.0;
    scale.y = 1.0;
    scale.z = 1.0;
    x_ang = 0;
    y_ang = RADIAN(90);
    z_ang = 0;
    PEXBuildTransform(&pt, &shift, x_ang, y_ang, z_ang, &scale, bldmat);

  PEXSetLocalTransform( theDisplay, theStrux, PEXOCStore,
                      PEXPreConcatenate, bldmat);
  PEXSetSurfaceColor( theDisplay, theStrux, PEXOCStore, 
                      PEXColorTypeRGB, (PEXColor *)&blue );
  PutX();

/* cyan P for the opposite side */

    pt.x = 0;
    pt.y = 0;
    pt.z = 0;
    shift.x = CUBE - 0.08;
    shift.y = -0.05;  /* distance to face of cube */
    shift.z = -0.33;  /* controls X */
    scale.x = 1.0;
    scale.y = 1.0;
    scale.z = 1.0;
    x_ang = RADIAN(90);
    y_ang = -RADIAN(90);
    z_ang = 0;

  PEXBuildTransform(&pt, &shift, x_ang, y_ang, z_ang, &scale, bldmat);

  PEXSetLocalTransform( theDisplay, theStrux, PEXOCStore,
                      PEXPreConcatenate, bldmat);
  PEXSetSurfaceColor( theDisplay, theStrux, PEXOCStore, 
                      PEXColorTypeRGB, (PEXColor *)&cyan );
  PutP();

/* magenta E */

    pt.x = 0.0;
    pt.y = 0.0;
    pt.z = 0.0;
    shift.x = 0;
    shift.y = -0.04; /* controls distance to face of cube */
    shift.z = -0.37; 
    scale.x = 1.0;
    scale.y = 1.0;
    scale.z = 1.0;
    x_ang = RADIAN(90);
    y_ang = 0;
    z_ang = 0;
    PEXBuildTransform(&pt, &shift, x_ang, y_ang, z_ang, &scale, bldmat);

  PEXSetLocalTransform( theDisplay, theStrux, PEXOCStore,
                      PEXPreConcatenate, bldmat);
  PEXSetSurfaceColor( theDisplay, theStrux, PEXOCStore,
                      PEXColorTypeRGB, (PEXColor *)&magenta );  
  PutE();

/* Finally, a Yellow X */

    pt.x = 0.0;
    pt.y = 0.0;
    pt.z = 0.0;
    shift.x = -0.1; /* controls distance to face of cube */
    shift.y = 0.0;  /* .37 - y from E */
    shift.z = -0.1;
    scale.x = 1.0;
    scale.y = 1.0;
    scale.z = 1.0;
    x_ang = 0;
    y_ang = RADIAN(90);
    z_ang = 0;
    PEXBuildTransform(&pt, &shift, x_ang, y_ang, z_ang, &scale, bldmat);

  PEXSetLocalTransform( theDisplay, theStrux, PEXOCStore,
                      PEXPreConcatenate, bldmat);
  PEXSetSurfaceColor( theDisplay, theStrux, PEXOCStore, 
                      PEXColorTypeRGB, (PEXColor *)&yellow );
  PutX();
  XSync(theDisplay,0);  /* Must Sync to force this stuff out be fore we exit */
}

/*************************************************************************
 * The P polygon, with the lower gap closed to match the PEX cube.
 *  Followed by the E and X. The "facedness" of all of these needs to
 *  be touched up.
 */
PutP()
{
  PEXCoord points[30], *pts;

  pts = points;

  pts->x = 0.0;  pts->y = 0.02; pts->z = 0.0; pts++;
  pts->x = 0.0;  pts->y = 0.19; pts->z = 0.0; pts++;
  pts->x = 0.11;  pts->y = 0.19; pts->z = 0.0; pts++;
  pts->x = 0.14;  pts->y = 0.20; pts->z = 0.0; pts++;
  pts->x = 0.16;  pts->y = 0.21; pts->z = 0.0; pts++;
  pts->x = 0.17;  pts->y = 0.23; pts->z = 0.0; pts++;
  pts->x = 0.17;  pts->y = 0.26; pts->z = 0.0; pts++;
  pts->x = 0.16;  pts->y = 0.28; pts->z = 0.0; pts++;
  pts->x = 0.14;  pts->y = 0.29; pts->z = 0.0; pts++;
  pts->x = 0.11;  pts->y = 0.30; pts->z = 0.0; pts++;
  pts->x = 0.06;  pts->y = 0.30; pts->z = 0.0; pts++;
  pts->x = 0.06;  pts->y = 0.21; pts->z = 0.0; pts++;
  pts->x = 0.0;  pts->y = 0.21; pts->z = 0.0; pts++;
  pts->x = 0.0;  pts->y = 0.32; pts->z = 0.0; pts++;
  pts->x = 0.14;  pts->y = 0.32; pts->z = 0.0; pts++;
  pts->x = 0.18;  pts->y = 0.31; pts->z = 0.0; pts++;
  pts->x = 0.20;  pts->y = 0.30; pts->z = 0.0; pts++;
  pts->x = 0.22;  pts->y = 0.28; pts->z = 0.0; pts++;
  pts->x = 0.23;  pts->y = 0.26; pts->z = 0.0; pts++;
  pts->x = 0.23;  pts->y = 0.23; pts->z = 0.0; pts++;
  pts->x = 0.22;  pts->y = 0.21; pts->z = 0.0; pts++;
  pts->x = 0.20;  pts->y = 0.19; pts->z = 0.0; pts++;
  pts->x = 0.18;  pts->y = 0.18; pts->z = 0.0; pts++;
  pts->x = 0.14;  pts->y = 0.17; pts->z = 0.0; pts++;
  pts->x = 0.06;  pts->y = 0.17; pts->z = 0.0; pts++;
  pts->x = 0.06;  pts->y = 0.02; pts->z = 0.0; pts++;
  pts->x = 0.0;  pts->y = 0.02; pts->z = 0.0; pts++;

  PEXFillArea(  theDisplay, theStrux, PEXOCStore,
                PEXShapeComplex, True, 27, points );
}

PutE()
{
  PEXCoord points[30], *pts;

  pts = points;

  pts->x = 0.0; pts->y = 0.02; pts->z = 0; pts++;
  pts->x = 0.0; pts->y = 0.19; pts->z = 0; pts++;
  pts->x = 0.21; pts->y = 0.19; pts->z = 0; pts++;
  pts->x = 0.21; pts->y = 0.17; pts->z = 0; pts++;
  pts->x = 0.06; pts->y = 0.17; pts->z = 0; pts++;
  pts->x = 0.06; pts->y = 0.04; pts->z = 0; pts++;
  pts->x = 0.21; pts->y = 0.04; pts->z = 0; pts++;
  pts->x = 0.21; pts->y = 0.02; pts->z = 0; pts++;
  pts->x = 0.0; pts->y = 0.02; pts->z = 0; pts++;

  PEXFillArea(  theDisplay, theStrux, PEXOCStore,
                PEXShapeComplex, True, 9, points );

  pts = points;

  pts->x = 0.0; pts->y = 0.21; pts->z = 0; pts++;
  pts->x = 0.0; pts->y = 0.32; pts->z = 0; pts++;
  pts->x = 0.21; pts->y = 0.32; pts->z = 0; pts++;
  pts->x = 0.21; pts->y = 0.30; pts->z = 0; pts++;
  pts->x = 0.06; pts->y = 0.30; pts->z = 0; pts++;
  pts->x = 0.06; pts->y = 0.21; pts->z = 0; pts++;
  pts->x = 0.0; pts->y = 0.21; pts->z = 0; pts++;

  PEXFillArea(  theDisplay, theStrux, PEXOCStore,
                PEXShapeComplex, True, 7, points );
}

PutX()
{
  PEXCoord points[30], *pts;

  pts = points;

 pts->x = 0.00;  pts->y = 0.02; pts->z = 0.0; pts++;
 pts->x = 0.10;  pts->y = 0.17; pts->z = 0.0; pts++;
 pts->x = 0.00;  pts->y = 0.32; pts->z = 0.0; pts++;
 pts->x = 0.06;  pts->y = 0.32; pts->z = 0.0; pts++;
 pts->x = 0.14;  pts->y = 0.20; pts->z = 0.0; pts++;
 pts->x = 0.02;  pts->y = 0.02; pts->z = 0.0; pts++;
 pts->x = 0.00;  pts->y = 0.02; pts->z = 0.0; pts++;

  PEXFillArea(  theDisplay, theStrux, PEXOCStore,
                PEXShapeComplex, True, 7, points );
  pts = points;

 pts->x = 0.20;  pts->y = 0.02; pts->z = 0.0; pts++;
 pts->x = 0.12;  pts->y = 0.14; pts->z = 0.0; pts++;
 pts->x = 0.24;  pts->y = 0.32; pts->z = 0.0; pts++;
 pts->x = 0.26;  pts->y = 0.32; pts->z = 0.0; pts++;
 pts->x = 0.16;  pts->y = 0.17; pts->z = 0.0; pts++;
 pts->x = 0.26;  pts->y = 0.02; pts->z = 0.0; pts++;
 pts->x = 0.20;  pts->y = 0.02; pts->z = 0.0; pts++;

  PEXFillArea(  theDisplay, theStrux, PEXOCStore,
                PEXShapeComplex, True, 7, points );
}


